Merge git://git.kernel.org/pub/scm/linux/kernel/git/wim/linux-2.6-watchdog
authorLinus Torvalds <torvalds@g5.osdl.org>
Mon, 23 Oct 2006 22:56:26 +0000 (15:56 -0700)
committerLinus Torvalds <torvalds@g5.osdl.org>
Mon, 23 Oct 2006 22:56:26 +0000 (15:56 -0700)
* git://git.kernel.org/pub/scm/linux/kernel/git/wim/linux-2.6-watchdog: (33 commits)
  [WATCHDOG] remove experimental on iTCO_wdt.c
  [WATCHDOG] Atmel AT91RM9200 rename.
  [WATCHDOG] includes for sample watchdog program.
  [WATCHDOG] watchdog/iTCO_wdt: fix bug related to gcc uninit warning
  [WATCHDOG] add ich8 support to iTCO_wdt.c (patch 2)
  [WATCHDOG] add ich8 support to iTCO_wdt.c
  [WATCHDOG] ioremap balanced with iounmap for drivers/char/watchdog/s3c2410_wdt.c
  [WATCHDOG] w83697hf/hg WDT driver - Kconfig patch
  [WATCHDOG] w83697hf/hg WDT driver - autodetect patch
  [WATCHDOG] w83697hf/hg WDT driver - patch 16
  [WATCHDOG] w83697hf/hg WDT driver - patch 15
  [WATCHDOG] w83697hf/hg WDT driver - patch 14
  [WATCHDOG] w83697hf/hg WDT driver - patch 13
  [WATCHDOG] w83697hf/hg WDT driver - patch 12
  [WATCHDOG] w83697hf/hg WDT driver - patch 11
  [WATCHDOG] w83697hf/hg WDT driver - patch 10
  [WATCHDOG] w83697hf/hg WDT driver - patch 9
  [WATCHDOG] w83697hf/hg WDT driver - patch 8
  [WATCHDOG] w83697hf/hg WDT driver - patch 7
  [WATCHDOG] w83697hf/hg WDT driver - patch 6
  ...

2699 files changed:
Documentation/HOWTO
Documentation/MSI-HOWTO.txt
Documentation/cpu-hotplug.txt
Documentation/feature-removal-schedule.txt
Documentation/filesystems/00-INDEX
Documentation/filesystems/ext4.txt [new file with mode: 0644]
Documentation/hwmon/adm9240
Documentation/hwmon/f71805f
Documentation/hwmon/k8temp
Documentation/hwmon/smsc47m1
Documentation/hwmon/w83627ehf
Documentation/ibm-acpi.txt
Documentation/input/xpad.txt
Documentation/kernel-parameters.txt
Documentation/lockdep-design.txt
Documentation/memory-barriers.txt
Documentation/mips/time.README
Documentation/s390/CommonIO
Documentation/s390/cds.txt
Documentation/s390/driver-model.txt
Documentation/scsi/ChangeLog.megaraid_sas
Documentation/sysctl/kernel.txt
Documentation/video4linux/CARDLIST.cx88
MAINTAINERS
Makefile
arch/alpha/kernel/alpha_ksyms.c
arch/alpha/kernel/core_apecs.c
arch/alpha/kernel/core_cia.c
arch/alpha/kernel/core_irongate.c
arch/alpha/kernel/core_lca.c
arch/alpha/kernel/core_mcpcia.c
arch/alpha/kernel/core_polaris.c
arch/alpha/kernel/core_t2.c
arch/alpha/kernel/core_tsunami.c
arch/alpha/kernel/core_wildfire.c
arch/alpha/kernel/err_ev6.c
arch/alpha/kernel/err_ev7.c
arch/alpha/kernel/err_impl.h
arch/alpha/kernel/err_marvel.c
arch/alpha/kernel/err_titan.c
arch/alpha/kernel/irq.c
arch/alpha/kernel/irq_alpha.c
arch/alpha/kernel/irq_i8259.c
arch/alpha/kernel/irq_impl.h
arch/alpha/kernel/irq_pyxis.c
arch/alpha/kernel/irq_srm.c
arch/alpha/kernel/pci-noop.c
arch/alpha/kernel/pci_iommu.c
arch/alpha/kernel/process.c
arch/alpha/kernel/proto.h
arch/alpha/kernel/setup.c
arch/alpha/kernel/smp.c
arch/alpha/kernel/sys_alcor.c
arch/alpha/kernel/sys_cabriolet.c
arch/alpha/kernel/sys_dp264.c
arch/alpha/kernel/sys_eb64p.c
arch/alpha/kernel/sys_eiger.c
arch/alpha/kernel/sys_jensen.c
arch/alpha/kernel/sys_marvel.c
arch/alpha/kernel/sys_miata.c
arch/alpha/kernel/sys_mikasa.c
arch/alpha/kernel/sys_nautilus.c
arch/alpha/kernel/sys_noritake.c
arch/alpha/kernel/sys_rawhide.c
arch/alpha/kernel/sys_rx164.c
arch/alpha/kernel/sys_sable.c
arch/alpha/kernel/sys_takara.c
arch/alpha/kernel/sys_titan.c
arch/alpha/kernel/sys_wildfire.c
arch/alpha/kernel/time.c
arch/alpha/mm/numa.c
arch/arm/common/locomo.c
arch/arm/common/sa1111.c
arch/arm/common/sharpsl_pm.c
arch/arm/common/time-acorn.c
arch/arm/kernel/armksyms.c
arch/arm/kernel/ecard.c
arch/arm/kernel/irq.c
arch/arm/kernel/time.c
arch/arm/mach-aaec2000/core.c
arch/arm/mach-at91rm9200/at91rm9200_time.c
arch/arm/mach-at91rm9200/gpio.c
arch/arm/mach-clps711x/time.c
arch/arm/mach-clps7500/core.c
arch/arm/mach-ebsa110/core.c
arch/arm/mach-ep93xx/core.c
arch/arm/mach-footbridge/dc21285-timer.c
arch/arm/mach-footbridge/dc21285.c
arch/arm/mach-footbridge/isa-irq.c
arch/arm/mach-footbridge/isa-timer.c
arch/arm/mach-h720x/common.c
arch/arm/mach-h720x/cpu-h7201.c
arch/arm/mach-h720x/cpu-h7202.c
arch/arm/mach-imx/dma.c
arch/arm/mach-imx/irq.c
arch/arm/mach-imx/time.c
arch/arm/mach-integrator/core.c
arch/arm/mach-integrator/integrator_cp.c
arch/arm/mach-integrator/pci_v3.c
arch/arm/mach-integrator/time.c
arch/arm/mach-ixp2000/core.c
arch/arm/mach-ixp2000/ixdp2400.c
arch/arm/mach-ixp2000/ixdp2800.c
arch/arm/mach-ixp2000/ixdp2x00.c
arch/arm/mach-ixp2000/ixdp2x01.c
arch/arm/mach-ixp23xx/core.c
arch/arm/mach-ixp23xx/ixdp2351.c
arch/arm/mach-ixp4xx/common.c
arch/arm/mach-ixp4xx/nas100d-power.c
arch/arm/mach-ixp4xx/nslu2-power.c
arch/arm/mach-lh7a40x/arch-kev7a400.c
arch/arm/mach-lh7a40x/arch-lpd7a40x.c
arch/arm/mach-lh7a40x/common.h
arch/arm/mach-lh7a40x/irq-kev7a400.c
arch/arm/mach-lh7a40x/irq-lpd7a40x.c
arch/arm/mach-lh7a40x/time.c
arch/arm/mach-netx/generic.c
arch/arm/mach-netx/time.c
arch/arm/mach-omap1/board-osk.c
arch/arm/mach-omap1/fpga.c
arch/arm/mach-omap1/pm.c
arch/arm/mach-omap1/serial.c
arch/arm/mach-omap1/time.c
arch/arm/mach-omap2/board-apollon.c
arch/arm/mach-omap2/timer-gp.c
arch/arm/mach-pnx4008/dma.c
arch/arm/mach-pnx4008/time.c
arch/arm/mach-pxa/corgi.c
arch/arm/mach-pxa/dma.c
arch/arm/mach-pxa/idp.c
arch/arm/mach-pxa/irq.c
arch/arm/mach-pxa/lpd270.c
arch/arm/mach-pxa/lubbock.c
arch/arm/mach-pxa/mainstone.c
arch/arm/mach-pxa/poodle.c
arch/arm/mach-pxa/spitz.c
arch/arm/mach-pxa/ssp.c
arch/arm/mach-pxa/time.c
arch/arm/mach-pxa/tosa.c
arch/arm/mach-pxa/trizeps4.c
arch/arm/mach-realview/core.c
arch/arm/mach-rpc/dma.c
arch/arm/mach-s3c2410/bast-irq.c
arch/arm/mach-s3c2410/dma.c
arch/arm/mach-s3c2410/irq.c
arch/arm/mach-s3c2410/mach-amlm5900.c
arch/arm/mach-s3c2410/s3c2440-irq.c
arch/arm/mach-s3c2410/s3c244x-irq.c
arch/arm/mach-s3c2410/time.c
arch/arm/mach-s3c2410/usb-simtec.c
arch/arm/mach-sa1100/cpu-sa1110.c
arch/arm/mach-sa1100/dma.c
arch/arm/mach-sa1100/h3600.c
arch/arm/mach-sa1100/irq.c
arch/arm/mach-sa1100/neponset.c
arch/arm/mach-sa1100/ssp.c
arch/arm/mach-sa1100/time.c
arch/arm/mach-shark/core.c
arch/arm/mach-shark/irq.c
arch/arm/mach-versatile/core.c
arch/arm/mach-versatile/pci.c
arch/arm/mm/ioremap.c
arch/arm/oprofile/op_model_xscale.c
arch/arm/plat-iop/time.c
arch/arm/plat-omap/dma.c
arch/arm/plat-omap/gpio.c
arch/arm/plat-omap/mcbsp.c
arch/arm/plat-omap/timer32k.c
arch/arm/tools/mach-types
arch/arm/vfp/vfpmodule.c
arch/arm26/kernel/armksyms.c
arch/avr32/kernel/time.c
arch/avr32/mach-at32ap/extint.c
arch/avr32/mach-at32ap/intc.c
arch/frv/kernel/dma.c
arch/frv/kernel/irq-mb93091.c
arch/frv/kernel/irq-mb93093.c
arch/frv/kernel/irq-mb93493.c
arch/frv/kernel/irq.c
arch/frv/kernel/time.c
arch/i386/Kconfig.cpu
arch/i386/Makefile
arch/i386/defconfig
arch/i386/kernel/acpi/boot.c
arch/i386/kernel/acpi/cstate.c
arch/i386/kernel/alternative.c
arch/i386/kernel/apic.c
arch/i386/kernel/apm.c
arch/i386/kernel/cpu/mcheck/therm_throt.c
arch/i386/kernel/head.S
arch/i386/kernel/i8253.c
arch/i386/kernel/i8259.c
arch/i386/kernel/io_apic.c
arch/i386/kernel/irq.c
arch/i386/kernel/microcode.c
arch/i386/kernel/nmi.c
arch/i386/kernel/process.c
arch/i386/kernel/setup.c
arch/i386/kernel/smp.c
arch/i386/kernel/syscall_table.S
arch/i386/kernel/time.c
arch/i386/kernel/time_hpet.c
arch/i386/kernel/tsc.c
arch/i386/kernel/vm86.c
arch/i386/lib/semaphore.S
arch/i386/lib/usercopy.c
arch/i386/mach-visws/visws_apic.c
arch/i386/mach-voyager/voyager_basic.c
arch/i386/mach-voyager/voyager_smp.c
arch/i386/mm/discontig.c
arch/i386/pci/common.c
arch/i386/pci/direct.c
arch/i386/pci/fixup.c
arch/i386/pci/init.c
arch/i386/pci/irq.c
arch/i386/pci/pci.h
arch/ia64/configs/sn2_defconfig
arch/ia64/hp/sim/simeth.c
arch/ia64/hp/sim/simscsi.c
arch/ia64/hp/sim/simserial.c
arch/ia64/kernel/acpi.c
arch/ia64/kernel/irq.c
arch/ia64/kernel/irq_ia64.c
arch/ia64/kernel/machvec.c
arch/ia64/kernel/mca.c
arch/ia64/kernel/pal.S
arch/ia64/kernel/perfmon.c
arch/ia64/kernel/time.c
arch/ia64/mm/contig.c
arch/ia64/mm/discontig.c
arch/ia64/sn/kernel/huberror.c
arch/ia64/sn/kernel/setup.c
arch/ia64/sn/kernel/sn2/timer_interrupt.c
arch/ia64/sn/kernel/xpc_main.c
arch/ia64/sn/pci/pcibr/pcibr_ate.c
arch/ia64/sn/pci/pcibr/pcibr_provider.c
arch/ia64/sn/pci/tioca_provider.c
arch/ia64/sn/pci/tioce_provider.c
arch/m32r/kernel/irq.c
arch/m32r/kernel/setup.c
arch/m32r/kernel/setup_mappi.c
arch/m32r/kernel/signal.c
arch/m32r/kernel/smp.c
arch/m32r/kernel/sys_m32r.c
arch/m32r/kernel/time.c
arch/m32r/kernel/traps.c
arch/m68k/Kconfig
arch/m68k/amiga/amiints.c
arch/m68k/amiga/cia.c
arch/m68k/amiga/config.c
arch/m68k/apollo/config.c
arch/m68k/apollo/dma.c [deleted file]
arch/m68k/apollo/dn_ints.c
arch/m68k/atari/ataints.c
arch/m68k/atari/config.c
arch/m68k/atari/stdma.c
arch/m68k/atari/time.c
arch/m68k/bvme6000/config.c
arch/m68k/hp300/time.c
arch/m68k/hp300/time.h
arch/m68k/kernel/Makefile
arch/m68k/kernel/dma.c
arch/m68k/kernel/entry.S
arch/m68k/kernel/ints.c
arch/m68k/kernel/m68k_ksyms.c
arch/m68k/kernel/process.c
arch/m68k/kernel/setup.c
arch/m68k/kernel/time.c
arch/m68k/kernel/traps.c
arch/m68k/lib/string.c
arch/m68k/lib/uaccess.c
arch/m68k/mac/baboon.c
arch/m68k/mac/config.c
arch/m68k/mac/iop.c
arch/m68k/mac/macints.c
arch/m68k/mac/oss.c
arch/m68k/mac/psc.c
arch/m68k/mac/via.c
arch/m68k/mm/kmap.c
arch/m68k/mm/memory.c
arch/m68k/mm/sun3kmap.c
arch/m68k/mvme147/config.c
arch/m68k/mvme16x/config.c
arch/m68k/q40/config.c
arch/m68k/q40/q40ints.c
arch/m68k/sun3/Makefile
arch/m68k/sun3/config.c
arch/m68k/sun3/idprom.c
arch/m68k/sun3/sun3_ksyms.c [deleted file]
arch/m68k/sun3/sun3dvma.c
arch/m68k/sun3/sun3ints.c
arch/m68k/sun3x/time.c
arch/m68k/sun3x/time.h
arch/m68knommu/kernel/syscalltable.S
arch/mips/Kconfig
arch/mips/Makefile
arch/mips/au1000/common/Makefile
arch/mips/au1000/common/dbdma.c
arch/mips/au1000/common/dma.c
arch/mips/au1000/common/irq.c
arch/mips/au1000/common/time.c
arch/mips/au1000/common/usbdev.c [deleted file]
arch/mips/au1000/db1x00/board_setup.c
arch/mips/au1000/mtx-1/board_setup.c
arch/mips/au1000/pb1000/board_setup.c
arch/mips/au1000/pb1100/board_setup.c
arch/mips/au1000/pb1200/irqmap.c
arch/mips/au1000/pb1500/board_setup.c
arch/mips/basler/excite/excite_dbg_io.c
arch/mips/basler/excite/excite_iodev.c
arch/mips/basler/excite/excite_irq.c
arch/mips/cobalt/irq.c
arch/mips/cobalt/setup.c
arch/mips/configs/bigsur_defconfig
arch/mips/configs/jazz_defconfig [new file with mode: 0644]
arch/mips/configs/malta_defconfig
arch/mips/configs/pb1100_defconfig
arch/mips/configs/pb1500_defconfig
arch/mips/configs/pnx8550-jbs_defconfig
arch/mips/configs/pnx8550-v2pci_defconfig
arch/mips/configs/tb0287_defconfig
arch/mips/ddb5xxx/ddb5477/irq.c
arch/mips/dec/ecc-berr.c
arch/mips/dec/int-handler.S
arch/mips/dec/kn01-berr.c
arch/mips/dec/kn02xa-berr.c
arch/mips/dec/reset.c
arch/mips/dec/setup.c
arch/mips/emma2rh/common/irq.c
arch/mips/emma2rh/markeins/irq.c
arch/mips/gt64120/common/time.c
arch/mips/gt64120/ev64120/irq.c
arch/mips/gt64120/ev64120/setup.c
arch/mips/gt64120/momenco_ocelot/irq.c
arch/mips/gt64120/momenco_ocelot/setup.c
arch/mips/gt64120/wrppmc/irq.c
arch/mips/jazz/irq.c
arch/mips/jazz/setup.c
arch/mips/jmr3927/rbhma3100/irq.c
arch/mips/kernel/asm-offsets.c
arch/mips/kernel/cpu-probe.c
arch/mips/kernel/entry.S
arch/mips/kernel/genex.S
arch/mips/kernel/irq-msc01.c
arch/mips/kernel/irq-mv6434x.c
arch/mips/kernel/irq.c
arch/mips/kernel/linux32.c
arch/mips/kernel/proc.c
arch/mips/kernel/process.c
arch/mips/kernel/ptrace.c
arch/mips/kernel/ptrace32.c
arch/mips/kernel/rtlx.c
arch/mips/kernel/scall32-o32.S
arch/mips/kernel/scall64-64.S
arch/mips/kernel/scall64-n32.S
arch/mips/kernel/scall64-o32.S
arch/mips/kernel/smp-mt.c
arch/mips/kernel/smp.c
arch/mips/kernel/smtc-asm.S
arch/mips/kernel/smtc.c
arch/mips/kernel/stacktrace.c
arch/mips/kernel/time.c
arch/mips/kernel/traps.c
arch/mips/lasat/interrupt.c
arch/mips/math-emu/cp1emu.c
arch/mips/mips-boards/atlas/atlas_int.c
arch/mips/mips-boards/generic/time.c
arch/mips/mips-boards/malta/malta_int.c
arch/mips/mips-boards/sead/sead_int.c
arch/mips/mips-boards/sim/sim_int.c
arch/mips/mips-boards/sim/sim_time.c
arch/mips/mm/init.c
arch/mips/mm/ioremap.c
arch/mips/mm/pgtable-32.c
arch/mips/mm/pgtable-64.c
arch/mips/momentum/jaguar_atx/irq.c
arch/mips/momentum/jaguar_atx/setup.c
arch/mips/momentum/ocelot_3/irq.c
arch/mips/momentum/ocelot_3/setup.c
arch/mips/momentum/ocelot_c/cpci-irq.c
arch/mips/momentum/ocelot_c/irq.c
arch/mips/momentum/ocelot_c/setup.c
arch/mips/momentum/ocelot_c/uart-irq.c
arch/mips/momentum/ocelot_g/gt-irq.c
arch/mips/momentum/ocelot_g/irq.c
arch/mips/momentum/ocelot_g/setup.c
arch/mips/oprofile/op_impl.h
arch/mips/oprofile/op_model_mipsxx.c
arch/mips/oprofile/op_model_rm9000.c
arch/mips/pci/pci-ip32.c
arch/mips/philips/pnx8550/common/int.c
arch/mips/pmc-sierra/yosemite/irq.c
arch/mips/pmc-sierra/yosemite/setup.c
arch/mips/pmc-sierra/yosemite/smp.c
arch/mips/qemu/q-irq.c
arch/mips/sgi-ip22/ip22-berr.c
arch/mips/sgi-ip22/ip22-eisa.c
arch/mips/sgi-ip22/ip22-int.c
arch/mips/sgi-ip22/ip22-reset.c
arch/mips/sgi-ip22/ip22-time.c
arch/mips/sgi-ip27/ip27-irq.c
arch/mips/sgi-ip27/ip27-klnuma.c
arch/mips/sgi-ip27/ip27-timer.c
arch/mips/sgi-ip32/crime.c
arch/mips/sgi-ip32/ip32-irq.c
arch/mips/sgi-ip32/ip32-reset.c
arch/mips/sibyte/bcm1480/irq.c
arch/mips/sibyte/bcm1480/smp.c
arch/mips/sibyte/bcm1480/time.c
arch/mips/sibyte/sb1250/bcm1250_tbprof.c
arch/mips/sibyte/sb1250/bus_watcher.c
arch/mips/sibyte/sb1250/irq.c
arch/mips/sibyte/sb1250/smp.c
arch/mips/sibyte/sb1250/time.c
arch/mips/sni/irq.c
arch/mips/sni/setup.c
arch/mips/tx4927/common/tx4927_irq.c
arch/mips/tx4927/common/tx4927_setup.c
arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c
arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
arch/mips/tx4938/common/irq.c
arch/mips/tx4938/common/setup.c
arch/mips/tx4938/toshiba_rbtx4938/irq.c
arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c
arch/mips/vr41xx/common/icu.c
arch/mips/vr41xx/common/irq.c
arch/parisc/hpux/fs.c
arch/parisc/kernel/drivers.c
arch/parisc/kernel/firmware.c
arch/parisc/kernel/irq.c
arch/parisc/kernel/parisc_ksyms.c
arch/parisc/kernel/pci.c
arch/parisc/kernel/smp.c
arch/parisc/kernel/sys_parisc.c
arch/parisc/kernel/sys_parisc32.c
arch/parisc/kernel/time.c
arch/powerpc/Kconfig
arch/powerpc/boot/Makefile
arch/powerpc/boot/dts/mpc8349emitx.dts [new file with mode: 0644]
arch/powerpc/boot/of.c
arch/powerpc/configs/cell_defconfig
arch/powerpc/configs/iseries_defconfig
arch/powerpc/configs/maple_defconfig
arch/powerpc/configs/mpc834x_itx_defconfig
arch/powerpc/configs/pseries_defconfig
arch/powerpc/kernel/cputable.c
arch/powerpc/kernel/ibmebus.c
arch/powerpc/kernel/iommu.c
arch/powerpc/kernel/irq.c
arch/powerpc/kernel/misc_64.S
arch/powerpc/kernel/pci_32.c
arch/powerpc/kernel/pci_64.c
arch/powerpc/kernel/process.c
arch/powerpc/kernel/prom.c
arch/powerpc/kernel/smp.c
arch/powerpc/kernel/time.c
arch/powerpc/kernel/traps.c
arch/powerpc/mm/mem.c
arch/powerpc/mm/numa.c
arch/powerpc/platforms/82xx/mpc82xx.c
arch/powerpc/platforms/82xx/mpc82xx_ads.c
arch/powerpc/platforms/82xx/pq2ads.h
arch/powerpc/platforms/83xx/Kconfig
arch/powerpc/platforms/83xx/Makefile
arch/powerpc/platforms/83xx/mpc8360e_pb.c
arch/powerpc/platforms/85xx/mpc85xx_ads.c
arch/powerpc/platforms/85xx/mpc85xx_cds.c
arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
arch/powerpc/platforms/cell/Kconfig
arch/powerpc/platforms/cell/interrupt.c
arch/powerpc/platforms/cell/iommu.c
arch/powerpc/platforms/cell/spider-pic.c
arch/powerpc/platforms/cell/spu_base.c
arch/powerpc/platforms/cell/spufs/Makefile
arch/powerpc/platforms/cell/spufs/context.c
arch/powerpc/platforms/cell/spufs/file.c
arch/powerpc/platforms/cell/spufs/gang.c [new file with mode: 0644]
arch/powerpc/platforms/cell/spufs/inode.c
arch/powerpc/platforms/cell/spufs/run.c
arch/powerpc/platforms/cell/spufs/sched.c
arch/powerpc/platforms/cell/spufs/spufs.h
arch/powerpc/platforms/cell/spufs/switch.c
arch/powerpc/platforms/cell/spufs/syscalls.c
arch/powerpc/platforms/chrp/setup.c
arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c
arch/powerpc/platforms/iseries/irq.c
arch/powerpc/platforms/iseries/irq.h
arch/powerpc/platforms/iseries/lpevents.c
arch/powerpc/platforms/iseries/mf.c
arch/powerpc/platforms/iseries/smp.c
arch/powerpc/platforms/iseries/smp.h [new file with mode: 0644]
arch/powerpc/platforms/iseries/viopath.c
arch/powerpc/platforms/maple/pci.c
arch/powerpc/platforms/pasemi/pci.c
arch/powerpc/platforms/powermac/low_i2c.c
arch/powerpc/platforms/powermac/pfunc_base.c
arch/powerpc/platforms/powermac/pic.c
arch/powerpc/platforms/powermac/pic.h
arch/powerpc/platforms/powermac/smp.c
arch/powerpc/platforms/pseries/iommu.c
arch/powerpc/platforms/pseries/ras.c
arch/powerpc/platforms/pseries/setup.c
arch/powerpc/platforms/pseries/xics.c
arch/powerpc/platforms/pseries/xics.h
arch/powerpc/sysdev/cpm2_pic.c
arch/powerpc/sysdev/cpm2_pic.h
arch/powerpc/sysdev/fsl_soc.c
arch/powerpc/sysdev/i8259.c
arch/powerpc/sysdev/ipic.c
arch/powerpc/sysdev/mpic.c
arch/powerpc/sysdev/qe_lib/qe_ic.c
arch/powerpc/sysdev/qe_lib/qe_io.c
arch/powerpc/sysdev/tsi108_pci.c
arch/powerpc/xmon/xmon.c
arch/ppc/4xx_io/serial_sicc.c
arch/ppc/8260_io/enet.c
arch/ppc/8260_io/fcc_enet.c
arch/ppc/8xx_io/commproc.c
arch/ppc/8xx_io/cs4218_tdm.c
arch/ppc/8xx_io/enet.c
arch/ppc/8xx_io/fec.c
arch/ppc/kernel/smp.c
arch/ppc/kernel/time.c
arch/ppc/mm/init.c
arch/ppc/platforms/85xx/mpc8560_ads.c
arch/ppc/platforms/85xx/mpc85xx_cds_common.c
arch/ppc/platforms/85xx/stx_gp3.c
arch/ppc/platforms/85xx/tqm85xx.c
arch/ppc/platforms/apus_setup.c
arch/ppc/platforms/hdpu.c
arch/ppc/platforms/mpc8272ads_setup.c
arch/ppc/platforms/mpc866ads_setup.c
arch/ppc/platforms/mpc885ads_setup.c
arch/ppc/platforms/radstone_ppc7d.c
arch/ppc/platforms/sbc82xx.c
arch/ppc/syslib/cpc700.h
arch/ppc/syslib/cpc700_pic.c
arch/ppc/syslib/cpm2_pic.c
arch/ppc/syslib/cpm2_pic.h
arch/ppc/syslib/gt64260_pic.c
arch/ppc/syslib/i8259.c
arch/ppc/syslib/ibm440gx_common.c
arch/ppc/syslib/ipic.c
arch/ppc/syslib/m82xx_pci.c
arch/ppc/syslib/m8xx_setup.c
arch/ppc/syslib/m8xx_wdt.c
arch/ppc/syslib/mpc52xx_pic.c
arch/ppc/syslib/mv64360_pic.c
arch/ppc/syslib/open_pic.c
arch/ppc/syslib/open_pic2.c
arch/ppc/syslib/ppc403_pic.c
arch/ppc/syslib/ppc4xx_pic.c
arch/ppc/syslib/ppc85xx_rio.c
arch/ppc/syslib/ppc8xx_pic.c
arch/ppc/syslib/xilinx_pic.c
arch/s390/Kconfig
arch/s390/appldata/appldata_base.c
arch/s390/defconfig
arch/s390/kernel/compat_linux.c
arch/s390/kernel/s390_ext.c
arch/s390/kernel/s390_ksyms.c
arch/s390/kernel/smp.c
arch/s390/kernel/stacktrace.c
arch/s390/kernel/syscalls.S
arch/s390/kernel/time.c
arch/s390/kernel/traps.c
arch/s390/kernel/vtime.c
arch/s390/mm/fault.c
arch/sh/Kconfig
arch/sh/boards/hp6xx/hp6xx_apm.c
arch/sh/boards/hp6xx/pm.c
arch/sh/boards/hp6xx/setup.c
arch/sh/boards/landisk/landisk_pwb.c
arch/sh/boards/mpc1211/setup.c
arch/sh/boards/renesas/hs7751rvoip/io.c
arch/sh/boards/renesas/hs7751rvoip/irq.c
arch/sh/boards/renesas/hs7751rvoip/setup.c
arch/sh/boards/renesas/r7780rp/io.c
arch/sh/boards/renesas/r7780rp/irq.c
arch/sh/boards/renesas/r7780rp/setup.c
arch/sh/boards/renesas/rts7751r2d/io.c
arch/sh/boards/renesas/rts7751r2d/irq.c
arch/sh/boards/renesas/rts7751r2d/led.c
arch/sh/boards/renesas/rts7751r2d/setup.c
arch/sh/boards/shmin/setup.c
arch/sh/boards/snapgear/setup.c
arch/sh/cchips/hd6446x/hd64461/setup.c
arch/sh/cchips/hd6446x/hd64465/gpio.c
arch/sh/cchips/hd6446x/hd64465/setup.c
arch/sh/cchips/voyagergx/irq.c
arch/sh/drivers/dma/dma-g2.c
arch/sh/drivers/dma/dma-pvr2.c
arch/sh/drivers/dma/dma-sh.c
arch/sh/drivers/pci/ops-r7780rp.c
arch/sh/drivers/pci/ops-rts7751r2d.c
arch/sh/drivers/pci/pci-sh7751.c
arch/sh/drivers/pci/pci-st40.c
arch/sh/kernel/cpu/irq/intc2.c
arch/sh/kernel/cpu/irq/ipr.c
arch/sh/kernel/cpu/sh3/ex.S
arch/sh/kernel/cpu/sh4/ex.S
arch/sh/kernel/cpu/sh4/setup-sh7760.c
arch/sh/kernel/cpu/sh4/setup-sh7780.c
arch/sh/kernel/entry.S
arch/sh/kernel/irq.c
arch/sh/kernel/process.c
arch/sh/kernel/time.c
arch/sh/kernel/timers/timer-tmu.c
arch/sh/kernel/traps.c
arch/sh/mm/consistent.c
arch/sparc/Kconfig
arch/sparc/Makefile
arch/sparc/kernel/irq.c
arch/sparc/kernel/pcic.c
arch/sparc/kernel/prom.c
arch/sparc/kernel/setup.c
arch/sparc/kernel/sparc_ksyms.c
arch/sparc/kernel/sun4c_irq.c
arch/sparc/kernel/sun4d_irq.c
arch/sparc/kernel/sun4d_smp.c
arch/sparc/kernel/sun4m_irq.c
arch/sparc/kernel/sun4m_smp.c
arch/sparc/kernel/tick14.c
arch/sparc/kernel/time.c
arch/sparc/kernel/vmlinux.lds.S
arch/sparc/lib/locks.S
arch/sparc/mm/srmmu.c
arch/sparc/oprofile/Kconfig [new file with mode: 0644]
arch/sparc/oprofile/Makefile [new file with mode: 0644]
arch/sparc/oprofile/init.c [new file with mode: 0644]
arch/sparc64/defconfig
arch/sparc64/kernel/ebus.c
arch/sparc64/kernel/irq.c
arch/sparc64/kernel/of_device.c
arch/sparc64/kernel/pci_common.c
arch/sparc64/kernel/pci_psycho.c
arch/sparc64/kernel/pci_sabre.c
arch/sparc64/kernel/pci_schizo.c
arch/sparc64/kernel/power.c
arch/sparc64/kernel/sbus.c
arch/sparc64/kernel/setup.c
arch/sparc64/kernel/smp.c
arch/sparc64/kernel/time.c
arch/um/Kconfig
arch/um/Kconfig.char
arch/um/Kconfig.i386
arch/um/Makefile-x86_64
arch/um/drivers/cow_sys.h
arch/um/drivers/daemon_user.c
arch/um/drivers/fd.c
arch/um/drivers/line.c
arch/um/drivers/mcast_user.c
arch/um/drivers/mconsole_kern.c
arch/um/drivers/mmapper_kern.c
arch/um/drivers/net_kern.c
arch/um/drivers/net_user.c
arch/um/drivers/pcap_user.c
arch/um/drivers/pcap_user.h
arch/um/drivers/port_kern.c
arch/um/drivers/port_user.c
arch/um/drivers/pty.c
arch/um/drivers/slip_user.c
arch/um/drivers/tty.c
arch/um/drivers/ubd_kern.c
arch/um/drivers/xterm.c
arch/um/drivers/xterm_kern.c
arch/um/include/common-offsets.h
arch/um/include/irq_kern.h
arch/um/include/kern_util.h
arch/um/include/longjmp.h
arch/um/include/os.h
arch/um/include/sysdep-i386/kernel-offsets.h
arch/um/include/sysdep-x86_64/kernel-offsets.h
arch/um/include/um_malloc.h [new file with mode: 0644]
arch/um/include/user.h
arch/um/include/user_util.h
arch/um/kernel/irq.c
arch/um/kernel/process.c
arch/um/kernel/sigio.c
arch/um/kernel/skas/mmu.c
arch/um/kernel/time.c
arch/um/kernel/tt/uaccess_user.c
arch/um/os-Linux/drivers/ethertap_user.c
arch/um/os-Linux/helper.c
arch/um/os-Linux/irq.c
arch/um/os-Linux/main.c
arch/um/os-Linux/sigio.c
arch/um/os-Linux/time.c
arch/um/os-Linux/tt.c
arch/um/os-Linux/util.c
arch/um/sys-x86_64/ksyms.c
arch/um/sys-x86_64/stub_segv.c
arch/x86_64/Makefile
arch/x86_64/defconfig
arch/x86_64/ia32/ptrace32.c
arch/x86_64/kernel/apic.c
arch/x86_64/kernel/e820.c
arch/x86_64/kernel/early-quirks.c
arch/x86_64/kernel/entry.S
arch/x86_64/kernel/genapic_cluster.c
arch/x86_64/kernel/genapic_flat.c
arch/x86_64/kernel/i8259.c
arch/x86_64/kernel/io_apic.c
arch/x86_64/kernel/irq.c
arch/x86_64/kernel/pci-calgary.c
arch/x86_64/kernel/process.c
arch/x86_64/kernel/time.c
arch/x86_64/kernel/traps.c
arch/x86_64/kernel/vmlinux.lds.S
arch/x86_64/kernel/vsmp.c
arch/x86_64/mm/init.c
arch/x86_64/mm/numa.c
arch/x86_64/mm/srat.c
arch/x86_64/pci/Makefile
block/elevator.c
block/ll_rw_blk.c
crypto/Kconfig
crypto/api.c
crypto/serpent.c
drivers/Kconfig
drivers/acorn/block/mfmhd.c
drivers/acpi/acpi_memhotplug.c
drivers/acpi/asus_acpi.c
drivers/acpi/battery.c
drivers/acpi/cm_sbs.c
drivers/acpi/ec.c
drivers/acpi/events/evmisc.c
drivers/acpi/events/evrgnini.c
drivers/acpi/hardware/hwregs.c
drivers/acpi/ibm_acpi.c
drivers/acpi/motherboard.c
drivers/acpi/osl.c
drivers/acpi/pci_link.c
drivers/acpi/power.c
drivers/acpi/processor_core.c
drivers/acpi/processor_idle.c
drivers/acpi/sbs.c
drivers/acpi/tables/tbget.c
drivers/acpi/tables/tbrsdt.c
drivers/ata/Kconfig
drivers/ata/ahci.c
drivers/ata/ata_piix.c
drivers/ata/libata-core.c
drivers/ata/libata-scsi.c
drivers/ata/libata-sff.c
drivers/ata/pata_qdi.c
drivers/ata/pdc_adma.c
drivers/ata/sata_mv.c
drivers/ata/sata_nv.c
drivers/ata/sata_promise.c
drivers/ata/sata_qstor.c
drivers/ata/sata_sil.c
drivers/ata/sata_sil24.c
drivers/ata/sata_svw.c
drivers/ata/sata_sx4.c
drivers/ata/sata_vsc.c
drivers/atm/ambassador.c
drivers/atm/eni.c
drivers/atm/firestream.c
drivers/atm/fore200e.c
drivers/atm/he.c
drivers/atm/horizon.c
drivers/atm/idt77252.c
drivers/atm/iphase.c
drivers/atm/lanai.c
drivers/atm/nicstar.c
drivers/atm/zatm.c
drivers/base/bus.c
drivers/base/class.c
drivers/base/core.c
drivers/base/dd.c
drivers/base/dmapool.c
drivers/base/topology.c
drivers/block/DAC960.c
drivers/block/DAC960.h
drivers/block/acsi.c
drivers/block/acsi_slm.c
drivers/block/amiflop.c
drivers/block/aoe/aoe.h
drivers/block/aoe/aoeblk.c
drivers/block/aoe/aoechr.c
drivers/block/aoe/aoecmd.c
drivers/block/aoe/aoedev.c
drivers/block/aoe/aoemain.c
drivers/block/aoe/aoenet.c
drivers/block/ataflop.c
drivers/block/cciss.c
drivers/block/cpqarray.c
drivers/block/floppy.c
drivers/block/loop.c
drivers/block/ps2esdi.c
drivers/block/rd.c
drivers/block/swim3.c
drivers/block/swim_iop.c
drivers/block/sx8.c
drivers/block/ub.c
drivers/block/umem.c
drivers/block/xd.c
drivers/block/xd.h
drivers/block/z2ram.c
drivers/bluetooth/bcm203x.c
drivers/bluetooth/bfusb.c
drivers/bluetooth/bluecard_cs.c
drivers/bluetooth/bpa10x.c
drivers/bluetooth/bt3c_cs.c
drivers/bluetooth/btuart_cs.c
drivers/bluetooth/dtl1_cs.c
drivers/bluetooth/hci_usb.c
drivers/cdrom/cdrom.c
drivers/cdrom/cdu31a.c
drivers/cdrom/cm206.c
drivers/cdrom/mcdx.c
drivers/cdrom/sonycd535.c
drivers/char/Kconfig
drivers/char/agp/uninorth-agp.c
drivers/char/amiserial.c
drivers/char/applicom.c
drivers/char/cyclades.c
drivers/char/drm/drm_os_linux.h
drivers/char/ec3104_keyb.c
drivers/char/epca.c
drivers/char/esp.c
drivers/char/ftape/lowlevel/fdc-io.c
drivers/char/hangcheck-timer.c
drivers/char/hpet.c
drivers/char/hvc_console.c
drivers/char/hvcs.c
drivers/char/hvsi.c
drivers/char/ip2/i2lib.c
drivers/char/ip2/i2lib.h
drivers/char/ip2/ip2main.c
drivers/char/ipmi/ipmi_msghandler.c
drivers/char/ipmi/ipmi_si_intf.c
drivers/char/ipmi/ipmi_watchdog.c
drivers/char/isicom.c
drivers/char/istallion.c
drivers/char/keyboard.c
drivers/char/mbcs.c
drivers/char/mem.c
drivers/char/mmtimer.c
drivers/char/moxa.c
drivers/char/mwave/tp3780i.c
drivers/char/mxser.c
drivers/char/nwbutton.c
drivers/char/nwbutton.h
drivers/char/pcmcia/synclink_cs.c
drivers/char/ppdev.c
drivers/char/qtronix.c [deleted file]
drivers/char/random.c
drivers/char/rio/func.h
drivers/char/rio/host.h
drivers/char/rio/rio_linux.c
drivers/char/rio/rioctrl.c
drivers/char/rio/riointr.c
drivers/char/riscom8.c
drivers/char/rtc.c
drivers/char/ser_a2232.c
drivers/char/serial167.c
drivers/char/snsc.c
drivers/char/snsc_event.c
drivers/char/sonypi.c
drivers/char/specialix.c
drivers/char/stallion.c
drivers/char/sx.c
drivers/char/synclink.c
drivers/char/synclink_gt.c
drivers/char/synclinkmp.c
drivers/char/sysrq.c
drivers/char/tlclk.c
drivers/char/tpm/tpm.c
drivers/char/tpm/tpm_atmel.c
drivers/char/tpm/tpm_nsc.c
drivers/char/tpm/tpm_tis.c
drivers/char/viocons.c
drivers/char/vme_scc.c
drivers/char/vr41xx_giu.c
drivers/char/watchdog/alim7101_wdt.c
drivers/char/watchdog/eurotechwdt.c
drivers/char/watchdog/mpcore_wdt.c
drivers/char/watchdog/pcwd_usb.c
drivers/char/watchdog/s3c2410_wdt.c
drivers/char/watchdog/wdt.c
drivers/char/watchdog/wdt285.c
drivers/char/watchdog/wdt_pci.c
drivers/clocksource/acpi_pm.c
drivers/dma/ioatdma.c
drivers/dma/ioatdma.h
drivers/eisa/eisa-bus.c
drivers/fc4/soc.c
drivers/fc4/socal.c
drivers/firmware/dcdbas.c
drivers/firmware/dell_rbu.c
drivers/firmware/dmi_scan.c
drivers/firmware/efivars.c
drivers/hwmon/Kconfig
drivers/hwmon/adm9240.c
drivers/hwmon/lm78.c
drivers/hwmon/smsc47m1.c
drivers/hwmon/w83627ehf.c
drivers/hwmon/w83781d.c
drivers/hwmon/w83791d.c
drivers/i2c/busses/i2c-elektor.c
drivers/i2c/busses/i2c-ibm_iic.c
drivers/i2c/busses/i2c-iop3xx.c
drivers/i2c/busses/i2c-isa.c
drivers/i2c/busses/i2c-ite.c
drivers/i2c/busses/i2c-mpc.c
drivers/i2c/busses/i2c-mv64xxx.c
drivers/i2c/busses/i2c-ocores.c
drivers/i2c/busses/i2c-omap.c
drivers/i2c/busses/i2c-pca-isa.c
drivers/i2c/busses/i2c-powermac.c
drivers/i2c/busses/i2c-pxa.c
drivers/i2c/busses/i2c-rpx.c
drivers/i2c/busses/i2c-s3c2410.c
drivers/i2c/chips/isp1301_omap.c
drivers/i2c/chips/tps65010.c
drivers/ide/ide-cd.c
drivers/ide/ide-io.c
drivers/ide/ide-taskfile.c
drivers/ide/legacy/hd.c
drivers/ide/legacy/macide.c
drivers/ide/mips/swarm.c
drivers/ide/pci/generic.c
drivers/ide/pci/sgiioc4.c
drivers/ieee1394/nodemgr.c
drivers/ieee1394/ohci1394.c
drivers/ieee1394/pcilynx.c
drivers/infiniband/core/cm.c
drivers/infiniband/hw/amso1100/c2.c
drivers/infiniband/hw/amso1100/c2_ae.c
drivers/infiniband/hw/amso1100/c2_qp.c
drivers/infiniband/hw/amso1100/c2_rnic.c
drivers/infiniband/hw/ehca/ehca_irq.c
drivers/infiniband/hw/ehca/ehca_irq.h
drivers/infiniband/hw/ipath/ipath_diag.c
drivers/infiniband/hw/ipath/ipath_driver.c
drivers/infiniband/hw/ipath/ipath_intr.c
drivers/infiniband/hw/ipath/ipath_kernel.h
drivers/infiniband/hw/mthca/mthca_cq.c
drivers/infiniband/hw/mthca/mthca_eq.c
drivers/infiniband/hw/mthca/mthca_provider.c
drivers/infiniband/hw/mthca/mthca_qp.c
drivers/infiniband/hw/mthca/mthca_srq.c
drivers/infiniband/ulp/ipoib/ipoib_ib.c
drivers/infiniband/ulp/srp/ib_srp.c
drivers/infiniband/ulp/srp/ib_srp.h
drivers/input/gameport/fm801-gp.c
drivers/input/gameport/gameport.c
drivers/input/joystick/amijoy.c
drivers/input/joystick/iforce/iforce-packets.c
drivers/input/joystick/iforce/iforce-serio.c
drivers/input/joystick/iforce/iforce-usb.c
drivers/input/joystick/iforce/iforce.h
drivers/input/joystick/magellan.c
drivers/input/joystick/spaceball.c
drivers/input/joystick/spaceorb.c
drivers/input/joystick/stinger.c
drivers/input/joystick/twidjoy.c
drivers/input/joystick/warrior.c
drivers/input/keyboard/Kconfig
drivers/input/keyboard/amikbd.c
drivers/input/keyboard/atkbd.c
drivers/input/keyboard/corgikbd.c
drivers/input/keyboard/hil_kbd.c
drivers/input/keyboard/hilkbd.c
drivers/input/keyboard/lkkbd.c
drivers/input/keyboard/locomokbd.c
drivers/input/keyboard/newtonkbd.c
drivers/input/keyboard/omap-keypad.c
drivers/input/keyboard/spitzkbd.c
drivers/input/keyboard/stowaway.c
drivers/input/keyboard/sunkbd.c
drivers/input/keyboard/xtkbd.c
drivers/input/misc/Kconfig
drivers/input/misc/hp_sdc_rtc.c
drivers/input/misc/ixp4xx-beeper.c
drivers/input/misc/wistron_btns.c
drivers/input/mouse/Kconfig
drivers/input/mouse/alps.c
drivers/input/mouse/amimouse.c
drivers/input/mouse/hil_ptr.c
drivers/input/mouse/inport.c
drivers/input/mouse/lifebook.c
drivers/input/mouse/logibm.c
drivers/input/mouse/logips2pp.c
drivers/input/mouse/pc110pad.c
drivers/input/mouse/psmouse-base.c
drivers/input/mouse/psmouse.h
drivers/input/mouse/rpcmouse.c
drivers/input/mouse/sermouse.c
drivers/input/mouse/synaptics.c
drivers/input/mouse/vsxxxaa.c
drivers/input/serio/Kconfig
drivers/input/serio/ambakmi.c
drivers/input/serio/ct82c710.c
drivers/input/serio/gscps2.c
drivers/input/serio/hil_mlc.c
drivers/input/serio/hp_sdc.c
drivers/input/serio/i8042.c
drivers/input/serio/libps2.c
drivers/input/serio/maceps2.c
drivers/input/serio/parkbd.c
drivers/input/serio/pcips2.c
drivers/input/serio/q40kbd.c
drivers/input/serio/rpckbd.c
drivers/input/serio/sa1111ps2.c
drivers/input/serio/serio.c
drivers/input/serio/serio_raw.c
drivers/input/serio/serport.c
drivers/input/touchscreen/ads7846.c
drivers/input/touchscreen/corgi_ts.c
drivers/input/touchscreen/elo.c
drivers/input/touchscreen/gunze.c
drivers/input/touchscreen/h3600_ts_input.c
drivers/input/touchscreen/hp680_ts_input.c
drivers/input/touchscreen/mk712.c
drivers/input/touchscreen/mtouch.c
drivers/input/touchscreen/penmount.c
drivers/input/touchscreen/touchright.c
drivers/input/touchscreen/touchwin.c
drivers/isdn/act2000/act2000_isa.c
drivers/isdn/capi/capidrv.c
drivers/isdn/gigaset/bas-gigaset.c
drivers/isdn/gigaset/usb-gigaset.c
drivers/isdn/hardware/avm/avmcard.h
drivers/isdn/hardware/avm/b1.c
drivers/isdn/hardware/avm/b1dma.c
drivers/isdn/hardware/avm/c4.c
drivers/isdn/hardware/avm/t1isa.c
drivers/isdn/hardware/eicon/diva.c
drivers/isdn/hardware/eicon/divasmain.c
drivers/isdn/hisax/amd7930_fn.c
drivers/isdn/hisax/asuscom.c
drivers/isdn/hisax/avm_a1.c
drivers/isdn/hisax/avm_a1p.c
drivers/isdn/hisax/avm_pci.c
drivers/isdn/hisax/bkm_a4t.c
drivers/isdn/hisax/bkm_a8.c
drivers/isdn/hisax/config.c
drivers/isdn/hisax/diva.c
drivers/isdn/hisax/elsa.c
drivers/isdn/hisax/enternow_pci.c
drivers/isdn/hisax/gazel.c
drivers/isdn/hisax/hfc4s8s_l1.c
drivers/isdn/hisax/hfc_pci.c
drivers/isdn/hisax/hfc_sx.c
drivers/isdn/hisax/hfc_usb.c
drivers/isdn/hisax/hfcscard.c
drivers/isdn/hisax/hisax.h
drivers/isdn/hisax/hisax_fcpcipnp.c
drivers/isdn/hisax/icc.c
drivers/isdn/hisax/isac.c
drivers/isdn/hisax/isurf.c
drivers/isdn/hisax/ix1_micro.c
drivers/isdn/hisax/mic.c
drivers/isdn/hisax/netjet.h
drivers/isdn/hisax/niccy.c
drivers/isdn/hisax/nj_s.c
drivers/isdn/hisax/nj_u.c
drivers/isdn/hisax/s0box.c
drivers/isdn/hisax/saphir.c
drivers/isdn/hisax/sedlbauer.c
drivers/isdn/hisax/sportster.c
drivers/isdn/hisax/st5481_b.c
drivers/isdn/hisax/st5481_d.c
drivers/isdn/hisax/st5481_usb.c
drivers/isdn/hisax/teleint.c
drivers/isdn/hisax/teles0.c
drivers/isdn/hisax/teles3.c
drivers/isdn/hisax/telespci.c
drivers/isdn/hisax/w6692.c
drivers/isdn/hysdn/boardergo.c
drivers/isdn/hysdn/hysdn_defs.h
drivers/isdn/hysdn/hysdn_proclog.c
drivers/isdn/hysdn/hysdn_sched.c
drivers/isdn/i4l/isdn_common.c
drivers/isdn/icn/icn.c
drivers/isdn/isdnloop/isdnloop.c
drivers/isdn/isdnloop/isdnloop.h
drivers/isdn/pcbit/drv.c
drivers/isdn/pcbit/layer2.c
drivers/isdn/pcbit/layer2.h
drivers/isdn/sc/init.c
drivers/isdn/sc/interrupt.c
drivers/isdn/sc/packet.c
drivers/isdn/sc/shmem.c
drivers/leds/led-class.c
drivers/leds/ledtrig-timer.c
drivers/macintosh/adb-iop.c
drivers/macintosh/adb.c
drivers/macintosh/adbhid.c
drivers/macintosh/macio-adb.c
drivers/macintosh/smu.c
drivers/macintosh/via-cuda.c
drivers/macintosh/via-macii.c
drivers/macintosh/via-maciisi.c
drivers/macintosh/via-pmu.c
drivers/macintosh/via-pmu68k.c
drivers/macintosh/windfarm_pm112.c
drivers/macintosh/windfarm_pm81.c
drivers/macintosh/windfarm_pm91.c
drivers/mca/mca-bus.c
drivers/md/bitmap.c
drivers/md/dm-crypt.c
drivers/md/md.c
drivers/md/multipath.c
drivers/md/raid10.c
drivers/media/common/saa7146_core.c
drivers/media/dvb/b2c2/flexcop-pci.c
drivers/media/dvb/b2c2/flexcop-usb.c
drivers/media/dvb/bt8xx/bt878.c
drivers/media/dvb/bt8xx/dvb-bt8xx.c
drivers/media/dvb/cinergyT2/cinergyT2.c
drivers/media/dvb/dvb-core/Kconfig
drivers/media/dvb/dvb-usb/dibusb-common.c
drivers/media/dvb/dvb-usb/dibusb.h
drivers/media/dvb/dvb-usb/nova-t-usb2.c
drivers/media/dvb/dvb-usb/usb-urb.c
drivers/media/dvb/frontends/dib3000mc.c
drivers/media/dvb/frontends/dib3000mc.h
drivers/media/dvb/frontends/tda10086.h
drivers/media/dvb/frontends/tda826x.h
drivers/media/dvb/pluto2/pluto2.c
drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
drivers/media/dvb/ttusb-dec/ttusb_dec.c
drivers/media/video/Kconfig
drivers/media/video/arv.c
drivers/media/video/bt8xx/bttv-driver.c
drivers/media/video/cpia2/cpia2_usb.c
drivers/media/video/cpia_usb.c
drivers/media/video/cx25840/cx25840-vbi.c
drivers/media/video/cx88/cx88-alsa.c
drivers/media/video/cx88/cx88-cards.c
drivers/media/video/cx88/cx88-dvb.c
drivers/media/video/cx88/cx88-input.c
drivers/media/video/cx88/cx88-mpeg.c
drivers/media/video/cx88/cx88-video.c
drivers/media/video/dabusb.c
drivers/media/video/em28xx/em28xx-core.c
drivers/media/video/em28xx/em28xx-video.c
drivers/media/video/et61x251/et61x251_core.c
drivers/media/video/meye.c
drivers/media/video/ov511.c
drivers/media/video/planb.c
drivers/media/video/pvrusb2/pvrusb2-hdw.c
drivers/media/video/pvrusb2/pvrusb2-io.c
drivers/media/video/pwc/pwc-if.c
drivers/media/video/saa7115.c
drivers/media/video/saa7134/saa7134-alsa.c
drivers/media/video/saa7134/saa7134-core.c
drivers/media/video/saa7134/saa7134-oss.c
drivers/media/video/saa7134/saa7134-video.c
drivers/media/video/se401.c
drivers/media/video/sn9c102/sn9c102_core.c
drivers/media/video/stradis.c
drivers/media/video/stv680.c
drivers/media/video/tuner-types.c
drivers/media/video/usbvideo/konicawc.c
drivers/media/video/usbvideo/quickcam_messenger.c
drivers/media/video/usbvideo/usbvideo.c
drivers/media/video/videodev.c
drivers/media/video/vino.c
drivers/media/video/vivi.c
drivers/media/video/w9968cf.c
drivers/media/video/zc0301/zc0301_core.c
drivers/media/video/zoran_device.c
drivers/media/video/zoran_device.h
drivers/media/video/zr36120.c
drivers/message/fusion/linux_compat.h
drivers/message/fusion/mptbase.c
drivers/message/i2o/bus-osm.c
drivers/message/i2o/exec-osm.c
drivers/message/i2o/pci.c
drivers/mfd/ucb1x00-core.c
drivers/misc/Kconfig
drivers/misc/Makefile
drivers/misc/ibmasm/ibmasm.h
drivers/misc/ibmasm/lowlevel.c
drivers/misc/ibmasm/remote.c
drivers/misc/ioc4.c [new file with mode: 0644]
drivers/misc/lkdtm.c
drivers/misc/msi-laptop.c [new file with mode: 0644]
drivers/misc/tifm_7xx1.c
drivers/misc/tifm_core.c
drivers/mmc/at91_mci.c
drivers/mmc/au1xmmc.c
drivers/mmc/imxmmc.c
drivers/mmc/mmc_block.c
drivers/mmc/mmci.c
drivers/mmc/omap.c
drivers/mmc/pxamci.c
drivers/mmc/sdhci.c
drivers/mmc/tifm_sd.c
drivers/mmc/wbsd.c
drivers/mtd/maps/physmap.c
drivers/mtd/nand/cs553x_nand.c
drivers/net/3c501.c
drivers/net/3c501.h
drivers/net/3c505.c
drivers/net/3c507.c
drivers/net/3c509.c
drivers/net/3c515.c
drivers/net/3c523.c
drivers/net/3c527.c
drivers/net/3c59x.c
drivers/net/7990.c
drivers/net/8139cp.c
drivers/net/8139too.c
drivers/net/82596.c
drivers/net/8390.c
drivers/net/8390.h
drivers/net/Kconfig
drivers/net/a2065.c
drivers/net/acenic.c
drivers/net/acenic.h
drivers/net/amd8111e.c
drivers/net/apne.c
drivers/net/appletalk/cops.c
drivers/net/appletalk/ltpc.c
drivers/net/arcnet/arcnet.c
drivers/net/ariadne.c
drivers/net/arm/am79c961a.c
drivers/net/arm/at91_ether.c
drivers/net/arm/ep93xx_eth.c
drivers/net/arm/ether1.c
drivers/net/arm/ether3.c
drivers/net/at1700.c
drivers/net/atari_bionet.c
drivers/net/atari_pamsnet.c
drivers/net/atarilance.c
drivers/net/atp.c
drivers/net/au1000_eth.c
drivers/net/b44.c
drivers/net/bmac.c
drivers/net/bnx2.c
drivers/net/bonding/bond_alb.c
drivers/net/cassini.c
drivers/net/chelsio/cpl5_cmd.h
drivers/net/chelsio/cxgb2.c
drivers/net/chelsio/sge.c
drivers/net/chelsio/sge.h
drivers/net/cris/eth_v10.c
drivers/net/cs89x0.c
drivers/net/de600.c
drivers/net/de600.h
drivers/net/de620.c
drivers/net/declance.c
drivers/net/defxx.c
drivers/net/depca.c
drivers/net/dgrs.c
drivers/net/dl2k.c
drivers/net/dm9000.c
drivers/net/e100.c
drivers/net/e1000/e1000_ethtool.c
drivers/net/e1000/e1000_main.c
drivers/net/eepro.c
drivers/net/eepro100.c
drivers/net/eexpress.c
drivers/net/ehea/ehea.h
drivers/net/ehea/ehea_main.c
drivers/net/ehea/ehea_phyp.c
drivers/net/epic100.c
drivers/net/eth16i.c
drivers/net/ewrk3.c
drivers/net/fealnx.c
drivers/net/fec.c
drivers/net/fec_8xx/fec_main.c
drivers/net/forcedeth.c
drivers/net/fs_enet/fs_enet-main.c
drivers/net/gianfar.c
drivers/net/gianfar.h
drivers/net/hamachi.c
drivers/net/hamradio/baycom_epp.c
drivers/net/hamradio/baycom_par.c
drivers/net/hamradio/baycom_ser_fdx.c
drivers/net/hamradio/baycom_ser_hdx.c
drivers/net/hamradio/dmascc.c
drivers/net/hamradio/scc.c
drivers/net/hamradio/yam.c
drivers/net/hp100.c
drivers/net/ibm_emac/ibm_emac_core.c
drivers/net/ibm_emac/ibm_emac_debug.c
drivers/net/ibm_emac/ibm_emac_mal.c
drivers/net/ibmlana.c
drivers/net/ibmveth.c
drivers/net/ioc3-eth.c
drivers/net/irda/ali-ircc.c
drivers/net/irda/au1k_ir.c
drivers/net/irda/donauboe.c
drivers/net/irda/irda-usb.c
drivers/net/irda/irport.c
drivers/net/irda/irport.h
drivers/net/irda/mcs7780.c
drivers/net/irda/mcs7780.h
drivers/net/irda/nsc-ircc.c
drivers/net/irda/pxaficp_ir.c
drivers/net/irda/sa1100_ir.c
drivers/net/irda/smsc-ircc2.c
drivers/net/irda/stir4200.c
drivers/net/irda/via-ircc.c
drivers/net/irda/vlsi_ir.c
drivers/net/irda/w83977af_ir.c
drivers/net/isa-skeleton.c
drivers/net/iseries_veth.c
drivers/net/ixgb/ixgb_main.c
drivers/net/ixp2000/ixpdev.c
drivers/net/lance.c
drivers/net/lasi_82596.c
drivers/net/loopback.c
drivers/net/lp486e.c
drivers/net/mac89x0.c
drivers/net/mace.c
drivers/net/macmace.c
drivers/net/meth.c
drivers/net/mipsnet.c
drivers/net/mv643xx_eth.c
drivers/net/myri10ge/myri10ge.c
drivers/net/myri_code.h
drivers/net/myri_sbus.c
drivers/net/natsemi.c
drivers/net/netx-eth.c
drivers/net/ni5010.c
drivers/net/ni52.c
drivers/net/ni65.c
drivers/net/ns83820.c
drivers/net/pci-skeleton.c
drivers/net/pcmcia/3c574_cs.c
drivers/net/pcmcia/3c589_cs.c
drivers/net/pcmcia/axnet_cs.c
drivers/net/pcmcia/fmvj18x_cs.c
drivers/net/pcmcia/nmclan_cs.c
drivers/net/pcmcia/pcnet_cs.c
drivers/net/pcmcia/smc91c92_cs.c
drivers/net/pcmcia/xirc2ps_cs.c
drivers/net/pcnet32.c
drivers/net/phy/phy.c
drivers/net/plip.c
drivers/net/qla3xxx.c
drivers/net/r8169.c
drivers/net/rrunner.c
drivers/net/rrunner.h
drivers/net/s2io.c
drivers/net/s2io.h
drivers/net/saa9730.c
drivers/net/sb1000.c
drivers/net/sb1250-mac.c
drivers/net/seeq8005.c
drivers/net/sgiseeq.c
drivers/net/sis190.c
drivers/net/sis900.c
drivers/net/sk98lin/skge.c
drivers/net/sk_mca.c
drivers/net/skfp/skfddi.c
drivers/net/skge.c
drivers/net/skge.h
drivers/net/sky2.c
drivers/net/sky2.h
drivers/net/smc-ultra.c
drivers/net/smc911x.c
drivers/net/smc9194.c
drivers/net/smc91x.c
drivers/net/smc91x.h
drivers/net/sonic.c
drivers/net/sonic.h
drivers/net/spider_net.c
drivers/net/spider_net.h
drivers/net/spider_net_ethtool.c
drivers/net/starfire.c
drivers/net/sun3_82586.c
drivers/net/sun3lance.c
drivers/net/sunbmac.c
drivers/net/sundance.c
drivers/net/sungem.c
drivers/net/sunhme.c
drivers/net/sunlance.c
drivers/net/sunqe.c
drivers/net/tc35815.c
drivers/net/tg3.c
drivers/net/tlan.c
drivers/net/tokenring/3c359.c
drivers/net/tokenring/ibmtr.c
drivers/net/tokenring/lanstreamer.c
drivers/net/tokenring/madgemc.c
drivers/net/tokenring/olympic.c
drivers/net/tokenring/smctr.c
drivers/net/tokenring/tms380tr.c
drivers/net/tokenring/tms380tr.h
drivers/net/tulip/de2104x.c
drivers/net/tulip/de4x5.c
drivers/net/tulip/dmfe.c
drivers/net/tulip/interrupt.c
drivers/net/tulip/tulip.h
drivers/net/tulip/tulip_core.c
drivers/net/tulip/uli526x.c
drivers/net/tulip/winbond-840.c
drivers/net/tulip/xircom_cb.c
drivers/net/tulip/xircom_tulip_cb.c
drivers/net/typhoon.c
drivers/net/ucc_geth.c
drivers/net/ucc_geth.h
drivers/net/ucc_geth_phy.c
drivers/net/ucc_geth_phy.h
drivers/net/via-rhine.c
drivers/net/via-velocity.c
drivers/net/wan/cosa.c
drivers/net/wan/cycx_main.c
drivers/net/wan/dscc4.c
drivers/net/wan/farsync.c
drivers/net/wan/hd6457x.c
drivers/net/wan/lmc/lmc_main.c
drivers/net/wan/pc300_drv.c
drivers/net/wan/sbni.c
drivers/net/wan/sdla.c
drivers/net/wan/wanxl.c
drivers/net/wan/z85230.c
drivers/net/wan/z85230.h
drivers/net/wireless/airo.c
drivers/net/wireless/arlan-main.c
drivers/net/wireless/atmel.c
drivers/net/wireless/bcm43xx/bcm43xx_dma.c
drivers/net/wireless/bcm43xx/bcm43xx_dma.h
drivers/net/wireless/bcm43xx/bcm43xx_leds.c
drivers/net/wireless/bcm43xx/bcm43xx_main.c
drivers/net/wireless/bcm43xx/bcm43xx_wx.c
drivers/net/wireless/hostap/hostap_hw.c
drivers/net/wireless/ipw2100.c
drivers/net/wireless/ipw2200.c
drivers/net/wireless/netwave_cs.c
drivers/net/wireless/orinoco.c
drivers/net/wireless/orinoco.h
drivers/net/wireless/prism54/islpci_dev.c
drivers/net/wireless/prism54/islpci_dev.h
drivers/net/wireless/ray_cs.c
drivers/net/wireless/wavelan.c
drivers/net/wireless/wavelan.p.h
drivers/net/wireless/wavelan_cs.c
drivers/net/wireless/wavelan_cs.p.h
drivers/net/wireless/wl3501_cs.c
drivers/net/wireless/zd1201.c
drivers/net/wireless/zd1211rw/zd_mac.c
drivers/net/wireless/zd1211rw/zd_usb.c
drivers/net/yellowfin.c
drivers/net/znet.c
drivers/parisc/dino.c
drivers/parisc/eisa.c
drivers/parisc/gsc.c
drivers/parisc/gsc.h
drivers/parisc/power.c
drivers/parisc/sba_iommu.c
drivers/parisc/superio.c
drivers/parport/daisy.c
drivers/parport/ieee1284.c
drivers/parport/parport_amiga.c
drivers/parport/parport_atari.c
drivers/parport/parport_ax88796.c
drivers/parport/parport_gsc.c
drivers/parport/parport_ip32.c
drivers/parport/parport_mfc3.c
drivers/parport/parport_pc.c
drivers/parport/parport_sunbpp.c
drivers/parport/share.c
drivers/pci/Kconfig
drivers/pci/hotplug/acpi_pcihp.c
drivers/pci/hotplug/acpiphp.h
drivers/pci/hotplug/acpiphp_core.c
drivers/pci/hotplug/acpiphp_glue.c
drivers/pci/hotplug/acpiphp_ibm.c
drivers/pci/hotplug/cpci_hotplug_core.c
drivers/pci/hotplug/cpci_hotplug_pci.c
drivers/pci/hotplug/cpcihp_generic.c
drivers/pci/hotplug/cpqphp.h
drivers/pci/hotplug/cpqphp_core.c
drivers/pci/hotplug/cpqphp_ctrl.c
drivers/pci/hotplug/cpqphp_nvram.c
drivers/pci/hotplug/cpqphp_pci.c
drivers/pci/hotplug/cpqphp_sysfs.c
drivers/pci/hotplug/fakephp.c
drivers/pci/hotplug/ibmphp.h
drivers/pci/hotplug/pci_hotplug.h [deleted file]
drivers/pci/hotplug/pci_hotplug_core.c
drivers/pci/hotplug/pciehp.h
drivers/pci/hotplug/pciehp_core.c
drivers/pci/hotplug/pciehp_ctrl.c
drivers/pci/hotplug/pciehp_hpc.c
drivers/pci/hotplug/pcihp_skeleton.c
drivers/pci/hotplug/rpadlpar_sysfs.c
drivers/pci/hotplug/rpaphp.h
drivers/pci/hotplug/rpaphp_core.c
drivers/pci/hotplug/sgi_hotplug.c
drivers/pci/hotplug/shpchp.h
drivers/pci/hotplug/shpchp_hpc.c
drivers/pci/msi.c
drivers/pci/pcie/aer/aerdrv.c
drivers/pci/pcie/portdrv.h
drivers/pci/pcie/portdrv_core.c
drivers/pci/pcie/portdrv_pci.c
drivers/pci/probe.c
drivers/pci/quirks.c
drivers/pci/rom.c
drivers/pci/search.c
drivers/pcmcia/at91_cf.c
drivers/pcmcia/hd64465_ss.c
drivers/pcmcia/i82092.c
drivers/pcmcia/i82092aa.h
drivers/pcmcia/i82365.c
drivers/pcmcia/m32r_cfc.c
drivers/pcmcia/m32r_pcc.c
drivers/pcmcia/m8xx_pcmcia.c
drivers/pcmcia/omap_cf.c
drivers/pcmcia/pcmcia_resource.c
drivers/pcmcia/pd6729.c
drivers/pcmcia/soc_common.c
drivers/pcmcia/tcic.c
drivers/pcmcia/vrc4171_card.c
drivers/pcmcia/vrc4173_cardu.c
drivers/pcmcia/yenta_socket.c
drivers/pnp/pnpacpi/rsparser.c
drivers/pnp/resource.c
drivers/rtc/rtc-at91.c
drivers/rtc/rtc-ds1553.c
drivers/rtc/rtc-max6902.c
drivers/rtc/rtc-pl031.c
drivers/rtc/rtc-s3c.c
drivers/rtc/rtc-sa1100.c
drivers/rtc/rtc-sh.c
drivers/rtc/rtc-v3020.c
drivers/rtc/rtc-vr41xx.c
drivers/s390/block/dasd.c
drivers/s390/block/dasd_diag.c
drivers/s390/char/ctrlchar.c
drivers/s390/char/keyboard.c
drivers/s390/char/monwriter.c
drivers/s390/char/sclp.c
drivers/s390/cio/chsc.c
drivers/s390/cio/cio.c
drivers/s390/cio/css.c
drivers/s390/cio/css.h
drivers/s390/cio/device.c
drivers/s390/cio/device.h
drivers/s390/cio/device_fsm.c
drivers/s390/cio/device_id.c
drivers/s390/cio/device_ops.c
drivers/s390/cio/device_pgid.c
drivers/s390/cio/device_status.c
drivers/s390/cio/qdio.c
drivers/s390/crypto/ap_bus.c
drivers/s390/net/iucv.c
drivers/s390/scsi/zfcp_erp.c
drivers/sbus/char/aurora.c
drivers/sbus/char/bbc_envctrl.c
drivers/sbus/char/bbc_i2c.c
drivers/sbus/char/cpwatchdog.c
drivers/sbus/char/envctrl.c
drivers/sbus/char/openprom.c
drivers/sbus/char/uctrl.c
drivers/scsi/3w-9xxx.c
drivers/scsi/3w-xxxx.c
drivers/scsi/3w-xxxx.h
drivers/scsi/53c700.c
drivers/scsi/53c700.h
drivers/scsi/53c7xx.c
drivers/scsi/BusLogic.c
drivers/scsi/BusLogic.h
drivers/scsi/Kconfig
drivers/scsi/Makefile
drivers/scsi/NCR5380.c
drivers/scsi/NCR5380.h
drivers/scsi/NCR53C9x.c
drivers/scsi/NCR53C9x.h
drivers/scsi/NCR53c406a.c
drivers/scsi/NCR_D700.c
drivers/scsi/NCR_Q720.c
drivers/scsi/a100u2w.c
drivers/scsi/a2091.c
drivers/scsi/a3000.c
drivers/scsi/aacraid/rx.c
drivers/scsi/aacraid/sa.c
drivers/scsi/advansys.c
drivers/scsi/aha152x.c
drivers/scsi/aha1542.c
drivers/scsi/aha1740.c
drivers/scsi/aic7xxx/aic79xx_inline.h
drivers/scsi/aic7xxx/aic79xx_osm.c
drivers/scsi/aic7xxx/aic79xx_osm.h
drivers/scsi/aic7xxx/aic79xx_osm_pci.c
drivers/scsi/aic7xxx/aic7xxx_inline.h
drivers/scsi/aic7xxx/aic7xxx_osm.c
drivers/scsi/aic7xxx/aic7xxx_osm.h
drivers/scsi/aic7xxx/aic7xxx_osm_pci.c
drivers/scsi/aic7xxx_old.c
drivers/scsi/aic94xx/Kconfig
drivers/scsi/aic94xx/aic94xx_hwi.c
drivers/scsi/aic94xx/aic94xx_hwi.h
drivers/scsi/aic94xx/aic94xx_init.c
drivers/scsi/amiga7xx.h
drivers/scsi/arcmsr/arcmsr_hba.c
drivers/scsi/arm/acornscsi.c
drivers/scsi/arm/acornscsi.h
drivers/scsi/arm/cumana_2.c
drivers/scsi/arm/eesox.c
drivers/scsi/arm/fas216.c
drivers/scsi/arm/fas216.h
drivers/scsi/arm/powertec.c
drivers/scsi/arm/queue.c
drivers/scsi/arm/queue.h
drivers/scsi/arm/scsi.h
drivers/scsi/atari_NCR5380.c
drivers/scsi/atari_dma_emul.c
drivers/scsi/atari_scsi.c
drivers/scsi/atp870u.c
drivers/scsi/bvme6000.h
drivers/scsi/dc395x.c
drivers/scsi/dec_esp.c
drivers/scsi/dmx3191d.c
drivers/scsi/dpt/dpti_i2o.h
drivers/scsi/dpt_i2o.c
drivers/scsi/dpti.h
drivers/scsi/dtc.c
drivers/scsi/eata.c
drivers/scsi/eata_pio.c
drivers/scsi/esp.c
drivers/scsi/fd_mcs.c
drivers/scsi/fdomain.c
drivers/scsi/gdth.c
drivers/scsi/gdth.h
drivers/scsi/gvp11.c
drivers/scsi/hosts.h [deleted file]
drivers/scsi/hptiop.c
drivers/scsi/ibmmca.c
drivers/scsi/ibmvscsi/rpa_vscsi.c
drivers/scsi/in2000.c
drivers/scsi/initio.c
drivers/scsi/ipr.c
drivers/scsi/ipr.h
drivers/scsi/ips.c
drivers/scsi/ips.h
drivers/scsi/lpfc/lpfc_crtn.h
drivers/scsi/lpfc/lpfc_init.c
drivers/scsi/lpfc/lpfc_sli.c
drivers/scsi/mac53c94.c
drivers/scsi/mac_esp.c
drivers/scsi/megaraid.c
drivers/scsi/megaraid.h
drivers/scsi/megaraid/mega_common.h
drivers/scsi/megaraid/megaraid_mbox.c
drivers/scsi/megaraid/megaraid_sas.c
drivers/scsi/megaraid/megaraid_sas.h
drivers/scsi/mesh.c
drivers/scsi/mvme147.c
drivers/scsi/mvme16x.h
drivers/scsi/ncr53c8xx.c
drivers/scsi/ncr53c8xx.h
drivers/scsi/nsp32.c
drivers/scsi/nsp32.h
drivers/scsi/osst.c
drivers/scsi/pcmcia/nsp_cs.c
drivers/scsi/pcmcia/nsp_cs.h
drivers/scsi/pcmcia/sym53c500_cs.c
drivers/scsi/psi240i.c
drivers/scsi/qla1280.c
drivers/scsi/qla2xxx/qla_attr.c
drivers/scsi/qla2xxx/qla_dbg.h
drivers/scsi/qla2xxx/qla_def.h
drivers/scsi/qla2xxx/qla_gbl.h
drivers/scsi/qla2xxx/qla_gs.c
drivers/scsi/qla2xxx/qla_init.c
drivers/scsi/qla2xxx/qla_inline.h
drivers/scsi/qla2xxx/qla_isr.c
drivers/scsi/qla2xxx/qla_mbx.c
drivers/scsi/qla2xxx/qla_os.c
drivers/scsi/qla2xxx/qla_version.h
drivers/scsi/qla4xxx/Kconfig [new file with mode: 0644]
drivers/scsi/qla4xxx/Makefile [new file with mode: 0644]
drivers/scsi/qla4xxx/ql4_dbg.c [new file with mode: 0644]
drivers/scsi/qla4xxx/ql4_dbg.h [new file with mode: 0644]
drivers/scsi/qla4xxx/ql4_def.h [new file with mode: 0644]
drivers/scsi/qla4xxx/ql4_fw.h [new file with mode: 0644]
drivers/scsi/qla4xxx/ql4_glbl.h [new file with mode: 0644]
drivers/scsi/qla4xxx/ql4_init.c [new file with mode: 0644]
drivers/scsi/qla4xxx/ql4_inline.h [new file with mode: 0644]
drivers/scsi/qla4xxx/ql4_iocb.c [new file with mode: 0644]
drivers/scsi/qla4xxx/ql4_isr.c [new file with mode: 0644]
drivers/scsi/qla4xxx/ql4_mbx.c [new file with mode: 0644]
drivers/scsi/qla4xxx/ql4_nvram.c [new file with mode: 0644]
drivers/scsi/qla4xxx/ql4_nvram.h [new file with mode: 0644]
drivers/scsi/qla4xxx/ql4_os.c [new file with mode: 0644]
drivers/scsi/qla4xxx/ql4_version.h [new file with mode: 0644]
drivers/scsi/qlogicfas408.c
drivers/scsi/qlogicfas408.h
drivers/scsi/qlogicpti.c
drivers/scsi/qlogicpti_asm.c
drivers/scsi/raid_class.c
drivers/scsi/scsi.c
drivers/scsi/scsi_devinfo.c
drivers/scsi/scsi_error.c
drivers/scsi/scsi_lib.c
drivers/scsi/sd.c
drivers/scsi/seagate.c
drivers/scsi/seagate.h [deleted file]
drivers/scsi/sg.c
drivers/scsi/sgiwd93.c
drivers/scsi/st.c
drivers/scsi/stex.c
drivers/scsi/sun3_NCR5380.c
drivers/scsi/sun3_scsi.c
drivers/scsi/sun3_scsi_vme.c
drivers/scsi/sym53c416.c
drivers/scsi/sym53c8xx_2/sym_glue.c
drivers/scsi/t128.c
drivers/scsi/tmscsim.c
drivers/scsi/u14-34f.c
drivers/scsi/ultrastor.c
drivers/scsi/wd7000.c
drivers/serial/21285.c
drivers/serial/68328serial.c
drivers/serial/68360serial.c
drivers/serial/8250.c
drivers/serial/Kconfig
drivers/serial/amba-pl010.c
drivers/serial/amba-pl011.c
drivers/serial/atmel_serial.c
drivers/serial/clps711x.c
drivers/serial/cpm_uart/cpm_uart_core.c
drivers/serial/crisv10.c
drivers/serial/dz.c
drivers/serial/icom.c
drivers/serial/imx.c
drivers/serial/ioc3_serial.c
drivers/serial/ioc4_serial.c
drivers/serial/ip22zilog.c
drivers/serial/jsm/jsm.h
drivers/serial/jsm/jsm_neo.c
drivers/serial/m32r_sio.c
drivers/serial/mcfserial.c
drivers/serial/mpc52xx_uart.c
drivers/serial/mpsc.c
drivers/serial/mux.c
drivers/serial/netx-serial.c
drivers/serial/pmac_zilog.c
drivers/serial/pxa.c
drivers/serial/s3c2410.c
drivers/serial/sa1100.c
drivers/serial/serial_lh7a40x.c
drivers/serial/serial_txx9.c
drivers/serial/sh-sci.c
drivers/serial/sn_console.c
drivers/serial/sunhv.c
drivers/serial/sunsab.c
drivers/serial/sunsu.c
drivers/serial/sunzilog.c
drivers/serial/v850e_uart.c
drivers/serial/vr41xx_siu.c
drivers/sn/Kconfig
drivers/sn/Makefile
drivers/sn/ioc3.c
drivers/sn/ioc4.c [deleted file]
drivers/spi/pxa2xx_spi.c
drivers/spi/spi_mpc83xx.c
drivers/spi/spi_s3c24xx.c
drivers/tc/zs.c
drivers/telephony/ixj.c
drivers/usb/Makefile
drivers/usb/atm/cxacru.c
drivers/usb/atm/speedtch.c
drivers/usb/atm/ueagle-atm.c
drivers/usb/atm/usbatm.c
drivers/usb/class/cdc-acm.c
drivers/usb/class/usblp.c
drivers/usb/core/devio.c
drivers/usb/core/endpoint.c
drivers/usb/core/hcd.c
drivers/usb/core/hcd.h
drivers/usb/core/hub.c
drivers/usb/core/message.c
drivers/usb/gadget/at91_udc.c
drivers/usb/gadget/dummy_hcd.c
drivers/usb/gadget/goku_udc.c
drivers/usb/gadget/lh7a40x_udc.c
drivers/usb/gadget/net2280.c
drivers/usb/gadget/omap_udc.c
drivers/usb/gadget/pxa2xx_udc.c
drivers/usb/host/ehci-dbg.c
drivers/usb/host/ehci-hcd.c
drivers/usb/host/ehci-hub.c
drivers/usb/host/ehci-pci.c
drivers/usb/host/ehci-q.c
drivers/usb/host/ehci-sched.c
drivers/usb/host/ehci.h
drivers/usb/host/hc_crisv10.c
drivers/usb/host/isp116x-hcd.c
drivers/usb/host/ohci-hcd.c
drivers/usb/host/ohci-hub.c
drivers/usb/host/ohci-pnx4008.c
drivers/usb/host/ohci-q.c
drivers/usb/host/sl811-hcd.c
drivers/usb/host/u132-hcd.c
drivers/usb/host/uhci-hcd.c
drivers/usb/host/uhci-hub.c
drivers/usb/host/uhci-q.c
drivers/usb/image/mdc800.c
drivers/usb/image/microtek.c
drivers/usb/input/Kconfig
drivers/usb/input/Makefile
drivers/usb/input/acecad.c
drivers/usb/input/aiptek.c
drivers/usb/input/appletouch.c
drivers/usb/input/ati_remote.c
drivers/usb/input/ati_remote2.c
drivers/usb/input/hid-core.c
drivers/usb/input/hid-input.c
drivers/usb/input/hid.h
drivers/usb/input/hiddev.c
drivers/usb/input/itmtouch.c
drivers/usb/input/kbtab.c
drivers/usb/input/keyspan_remote.c
drivers/usb/input/mtouchusb.c
drivers/usb/input/powermate.c
drivers/usb/input/touchkitusb.c
drivers/usb/input/trancevibrator.c [deleted file]
drivers/usb/input/usbkbd.c
drivers/usb/input/usbmouse.c
drivers/usb/input/usbtouchscreen.c
drivers/usb/input/wacom.h
drivers/usb/input/wacom_sys.c
drivers/usb/input/wacom_wac.c
drivers/usb/input/wacom_wac.h
drivers/usb/input/xpad.c
drivers/usb/input/yealink.c
drivers/usb/misc/Kconfig
drivers/usb/misc/Makefile
drivers/usb/misc/adutux.c
drivers/usb/misc/appledisplay.c
drivers/usb/misc/auerswald.c
drivers/usb/misc/ftdi-elan.c
drivers/usb/misc/ldusb.c
drivers/usb/misc/legousbtower.c
drivers/usb/misc/phidgetkit.c
drivers/usb/misc/phidgetmotorcontrol.c
drivers/usb/misc/sisusbvga/sisusb.c
drivers/usb/misc/trancevibrator.c [new file with mode: 0644]
drivers/usb/misc/usblcd.c
drivers/usb/misc/usbtest.c
drivers/usb/misc/uss720.c
drivers/usb/net/Kconfig
drivers/usb/net/Makefile
drivers/usb/net/asix.c
drivers/usb/net/catc.c
drivers/usb/net/cdc_ether.c
drivers/usb/net/gl620a.c
drivers/usb/net/kaweth.c
drivers/usb/net/mcs7830.c [new file with mode: 0644]
drivers/usb/net/net1080.c
drivers/usb/net/pegasus.c
drivers/usb/net/rtl8150.c
drivers/usb/net/usbnet.c
drivers/usb/net/usbnet.h
drivers/usb/serial/Kconfig
drivers/usb/serial/Makefile
drivers/usb/serial/aircable.c
drivers/usb/serial/airprime.c
drivers/usb/serial/belkin_sa.c
drivers/usb/serial/cp2101.c
drivers/usb/serial/cyberjack.c
drivers/usb/serial/cypress_m8.c
drivers/usb/serial/digi_acceleport.c
drivers/usb/serial/empeg.c
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/garmin_gps.c
drivers/usb/serial/generic.c
drivers/usb/serial/io_edgeport.c
drivers/usb/serial/io_ti.c
drivers/usb/serial/ipaq.c
drivers/usb/serial/ipw.c
drivers/usb/serial/ir-usb.c
drivers/usb/serial/keyspan.c
drivers/usb/serial/keyspan_pda.c
drivers/usb/serial/kl5kusb105.c
drivers/usb/serial/kobil_sct.c
drivers/usb/serial/mct_u232.c
drivers/usb/serial/mos7720.c [new file with mode: 0644]
drivers/usb/serial/mos7840.c
drivers/usb/serial/navman.c
drivers/usb/serial/omninet.c
drivers/usb/serial/option.c
drivers/usb/serial/pl2303.c
drivers/usb/serial/safe_serial.c
drivers/usb/serial/sierra.c
drivers/usb/serial/ti_usb_3410_5052.c
drivers/usb/serial/visor.c
drivers/usb/serial/whiteheat.c
drivers/usb/storage/onetouch.c
drivers/usb/storage/transport.c
drivers/usb/storage/unusual_devs.h
drivers/usb/usb-skeleton.c
drivers/video/Kconfig
drivers/video/amifb.c
drivers/video/arcfb.c
drivers/video/atafb.c
drivers/video/aty/atyfb_base.c
drivers/video/au1200fb.c
drivers/video/console/fbcon.c
drivers/video/controlfb.c
drivers/video/hitfb.c
drivers/video/igafb.c
drivers/video/intelfb/intelfbhw.c
drivers/video/matrox/matroxfb_base.c
drivers/video/nvidia/nv_i2c.c
drivers/video/platinumfb.c
drivers/video/pvr2fb.c
drivers/video/pxafb.c
drivers/video/s3c2410fb.c
drivers/video/sa1100fb.c
drivers/video/valkyriefb.c
drivers/w1/Kconfig
fs/Kconfig
fs/Makefile
fs/afs/dir.c
fs/autofs/autofs_i.h
fs/autofs/dirhash.c
fs/autofs/init.c
fs/autofs/inode.c
fs/autofs4/autofs_i.h
fs/autofs4/init.c
fs/autofs4/inode.c
fs/autofs4/waitq.c
fs/befs/befs.h
fs/befs/befs_fs_types.h
fs/befs/btree.c
fs/befs/datastream.c
fs/befs/debug.c
fs/befs/endian.h
fs/befs/inode.c
fs/befs/linuxvfs.c
fs/befs/super.c
fs/binfmt_elf.c
fs/bio.c
fs/buffer.c
fs/cifs/cifsacl.h
fs/cifs/cifsencrypt.h
fs/cifs/cifsfs.c
fs/cifs/cifsfs.h
fs/cifs/cifsglob.h
fs/cifs/cifspdu.h
fs/cifs/cifsproto.h
fs/cifs/cifssmb.c
fs/cifs/connect.c
fs/cifs/inode.c
fs/cifs/link.c
fs/cifs/md5.c
fs/cifs/md5.h
fs/cifs/misc.c
fs/cifs/netmisc.c
fs/cifs/readdir.c
fs/cifs/sess.c
fs/cifs/smbdes.c
fs/cifs/smbencrypt.c
fs/compat.c
fs/compat_ioctl.c
fs/configfs/file.c
fs/dcache.c
fs/dlm/Kconfig
fs/dlm/lowcomms.c
fs/dlm/lowcomms.h
fs/ecryptfs/main.c
fs/eventpoll.c
fs/ext2/super.c
fs/ext3/super.c
fs/ext4/Makefile [new file with mode: 0644]
fs/ext4/acl.c [new file with mode: 0644]
fs/ext4/acl.h [new file with mode: 0644]
fs/ext4/balloc.c [new file with mode: 0644]
fs/ext4/bitmap.c [new file with mode: 0644]
fs/ext4/dir.c [new file with mode: 0644]
fs/ext4/extents.c [new file with mode: 0644]
fs/ext4/file.c [new file with mode: 0644]
fs/ext4/fsync.c [new file with mode: 0644]
fs/ext4/hash.c [new file with mode: 0644]
fs/ext4/ialloc.c [new file with mode: 0644]
fs/ext4/inode.c [new file with mode: 0644]
fs/ext4/ioctl.c [new file with mode: 0644]
fs/ext4/namei.c [new file with mode: 0644]
fs/ext4/namei.h [new file with mode: 0644]
fs/ext4/resize.c [new file with mode: 0644]
fs/ext4/super.c [new file with mode: 0644]
fs/ext4/symlink.c [new file with mode: 0644]
fs/ext4/xattr.c [new file with mode: 0644]
fs/ext4/xattr.h [new file with mode: 0644]
fs/ext4/xattr_security.c [new file with mode: 0644]
fs/ext4/xattr_trusted.c [new file with mode: 0644]
fs/ext4/xattr_user.c [new file with mode: 0644]
fs/fat/file.c
fs/fat/inode.c
fs/fuse/dir.c
fs/fuse/file.c
fs/fuse/fuse_i.h
fs/fuse/inode.c
fs/gfs2/bmap.c
fs/gfs2/bmap.h
fs/gfs2/dir.c
fs/gfs2/locking/dlm/mount.c
fs/gfs2/log.c
fs/gfs2/lops.c
fs/gfs2/ops_address.c
fs/gfs2/ops_fstype.c
fs/gfs2/quota.c
fs/gfs2/recovery.c
fs/gfs2/rgrp.h
fs/hpfs/inode.c
fs/hppfs/hppfs_kern.c
fs/hugetlbfs/inode.c
fs/inode.c
fs/ioprio.c
fs/isofs/joliet.c
fs/jbd/journal.c
fs/jbd/transaction.c
fs/jbd2/Makefile [new file with mode: 0644]
fs/jbd2/checkpoint.c [new file with mode: 0644]
fs/jbd2/commit.c [new file with mode: 0644]
fs/jbd2/journal.c [new file with mode: 0644]
fs/jbd2/recovery.c [new file with mode: 0644]
fs/jbd2/revoke.c [new file with mode: 0644]
fs/jbd2/transaction.c [new file with mode: 0644]
fs/jffs2/super.c
fs/jfs/jfs_imap.c
fs/lockd/clntlock.c
fs/lockd/mon.c
fs/lockd/svc4proc.c
fs/lockd/svclock.c
fs/lockd/svcproc.c
fs/lockd/svcshare.c
fs/lockd/svcsubs.c
fs/lockd/xdr.c
fs/lockd/xdr4.c
fs/minix/inode.c
fs/ncpfs/ioctl.c
fs/nfs/callback.h
fs/nfs/callback_proc.c
fs/nfs/callback_xdr.c
fs/nfs/client.c
fs/nfs/dir.c
fs/nfs/direct.c
fs/nfs/inode.c
fs/nfs/internal.h
fs/nfs/mount_clnt.c
fs/nfs/nfs2xdr.c
fs/nfs/nfs3proc.c
fs/nfs/nfs3xdr.c
fs/nfs/nfs4_fs.h
fs/nfs/nfs4proc.c
fs/nfs/nfs4xdr.c
fs/nfs/super.c
fs/nfs/write.c
fs/nfs_common/nfsacl.c
fs/nfsd/export.c
fs/nfsd/lockd.c
fs/nfsd/nfs2acl.c
fs/nfsd/nfs3acl.c
fs/nfsd/nfs3proc.c
fs/nfsd/nfs3xdr.c
fs/nfsd/nfs4callback.c
fs/nfsd/nfs4proc.c
fs/nfsd/nfs4recover.c
fs/nfsd/nfs4state.c
fs/nfsd/nfs4xdr.c
fs/nfsd/nfscache.c
fs/nfsd/nfsfh.c
fs/nfsd/nfsproc.c
fs/nfsd/nfssvc.c
fs/nfsd/nfsxdr.c
fs/nfsd/vfs.c
fs/ocfs2/cluster/nodemanager.c
fs/ocfs2/file.c
fs/ocfs2/namei.c
fs/ocfs2/super.c
fs/partitions/check.c
fs/partitions/msdos.c
fs/proc/base.c
fs/proc/proc_misc.c
fs/reiserfs/bitmap.c
fs/reiserfs/journal.c
fs/reiserfs/super.c
fs/splice.c
fs/super.c
fs/sysfs/file.c
fs/sysv/super.c
fs/udf/super.c
fs/ufs/util.c
fs/xattr.c
fs/xfs/linux-2.6/kmem.c
fs/xfs/linux-2.6/xfs_buf.c
include/acpi/aclocal.h
include/acpi/pdc_intel.h
include/acpi/processor.h
include/asm-alpha/io.h
include/asm-alpha/irq_regs.h [new file with mode: 0644]
include/asm-alpha/machvec.h
include/asm-arm/arch-clps711x/time.h
include/asm-arm/arch-imx/imx-dma.h
include/asm-arm/arch-l7200/time.h
include/asm-arm/arch-pnx4008/dma.h
include/asm-arm/arch-pxa/dma.h
include/asm-arm/arch-pxa/mmc.h
include/asm-arm/arch-pxa/pxa-regs.h
include/asm-arm/arch-sa1100/jornada720.h
include/asm-arm/arch-versatile/hardware.h
include/asm-arm/hardware/sharpsl_pm.h
include/asm-arm/hw_irq.h
include/asm-arm/io.h
include/asm-arm/irq_regs.h [new file with mode: 0644]
include/asm-arm/mach/irq.h
include/asm-arm/mach/time.h
include/asm-arm/uaccess.h
include/asm-avr32/irq_regs.h [new file with mode: 0644]
include/asm-frv/dma.h
include/asm-frv/highmem.h
include/asm-frv/io.h
include/asm-frv/irq_regs.h [new file with mode: 0644]
include/asm-frv/ptrace.h
include/asm-generic/bitops/sched.h
include/asm-generic/bug.h
include/asm-generic/irq_regs.h [new file with mode: 0644]
include/asm-generic/percpu.h
include/asm-generic/vmlinux.lds.h
include/asm-i386/apic.h
include/asm-i386/arch_hooks.h
include/asm-i386/floppy.h
include/asm-i386/hpet.h
include/asm-i386/hw_irq.h
include/asm-i386/io.h
include/asm-i386/irq_regs.h [new file with mode: 0644]
include/asm-i386/mach-default/do_timer.h
include/asm-i386/mach-visws/do_timer.h
include/asm-i386/mach-voyager/do_timer.h
include/asm-i386/processor.h
include/asm-i386/smp.h
include/asm-i386/uaccess.h
include/asm-i386/unistd.h
include/asm-i386/vic.h
include/asm-i386/voyager.h
include/asm-ia64/io.h
include/asm-ia64/irq_regs.h [new file with mode: 0644]
include/asm-ia64/machvec.h
include/asm-ia64/pal.h
include/asm-ia64/sn/pcibr_provider.h
include/asm-ia64/sn/tioca_provider.h
include/asm-ia64/sn/tioce_provider.h
include/asm-ia64/sn/xpc.h
include/asm-m32r/io.h
include/asm-m32r/irq_regs.h [new file with mode: 0644]
include/asm-m68k/atari_stdma.h
include/asm-m68k/dma-mapping.h
include/asm-m68k/floppy.h
include/asm-m68k/ide.h
include/asm-m68k/irq.h
include/asm-m68k/irq_regs.h [new file with mode: 0644]
include/asm-m68k/mac_iop.h
include/asm-m68k/machdep.h
include/asm-m68k/signal.h
include/asm-m68k/string.h
include/asm-m68k/sun3mmu.h
include/asm-m68k/sun3xflop.h
include/asm-m68k/system.h
include/asm-m68k/uaccess.h
include/asm-m68k/unistd.h
include/asm-m68k/user.h
include/asm-m68knommu/unistd.h
include/asm-mips/cacheflush.h
include/asm-mips/dec/ecc.h
include/asm-mips/dec/kn01.h
include/asm-mips/dec/kn02xa.h
include/asm-mips/fixmap.h
include/asm-mips/fpu.h
include/asm-mips/io.h
include/asm-mips/irq.h
include/asm-mips/irq_regs.h [new file with mode: 0644]
include/asm-mips/jmr3927/irq.h
include/asm-mips/mach-au1x00/au1000_dma.h
include/asm-mips/mach-au1x00/au1000_usbdev.h [deleted file]
include/asm-mips/marvell.h
include/asm-mips/msc01_ic.h
include/asm-mips/stackframe.h
include/asm-mips/termbits.h
include/asm-mips/thread_info.h
include/asm-mips/time.h
include/asm-mips/unistd.h
include/asm-mips/vr41xx/vr41xx.h
include/asm-parisc/irq_regs.h [new file with mode: 0644]
include/asm-parisc/pdc.h
include/asm-powerpc/i8259.h
include/asm-powerpc/ibmebus.h
include/asm-powerpc/io.h
include/asm-powerpc/ipic.h
include/asm-powerpc/irq.h
include/asm-powerpc/irq_regs.h [new file with mode: 0644]
include/asm-powerpc/iseries/hv_lp_event.h
include/asm-powerpc/iseries/it_lp_queue.h
include/asm-powerpc/machdep.h
include/asm-powerpc/mpic.h
include/asm-powerpc/reg.h
include/asm-powerpc/smp.h
include/asm-powerpc/spu.h
include/asm-ppc/commproc.h
include/asm-ppc/floppy.h
include/asm-ppc/gt64260.h
include/asm-ppc/io.h
include/asm-ppc/machdep.h
include/asm-ppc/mpc52xx.h
include/asm-ppc/mv64x60.h
include/asm-ppc/open_pic.h
include/asm-ppc/smp.h
include/asm-s390/cio.h
include/asm-s390/hardirq.h
include/asm-s390/irq_regs.h [new file with mode: 0644]
include/asm-s390/percpu.h
include/asm-s390/pgtable.h
include/asm-s390/s390_ext.h
include/asm-s390/timer.h
include/asm-s390/unistd.h
include/asm-sh/cpu-sh4/ubc.h
include/asm-sh/edosk7705.h [new file with mode: 0644]
include/asm-sh/edosk7705/io.h [deleted file]
include/asm-sh/hp6xx.h [new file with mode: 0644]
include/asm-sh/hp6xx/hp6xx.h [deleted file]
include/asm-sh/hp6xx/ide.h [deleted file]
include/asm-sh/hp6xx/io.h [deleted file]
include/asm-sh/hs7751rvoip.h [new file with mode: 0644]
include/asm-sh/hs7751rvoip/hs7751rvoip.h [deleted file]
include/asm-sh/hs7751rvoip/ide.h [deleted file]
include/asm-sh/hw_irq.h
include/asm-sh/io.h
include/asm-sh/irq-sh7780.h
include/asm-sh/irq.h
include/asm-sh/irq_regs.h [new file with mode: 0644]
include/asm-sh/landisk/ide.h [deleted file]
include/asm-sh/processor.h
include/asm-sh/r7780rp.h [new file with mode: 0644]
include/asm-sh/r7780rp/ide.h [deleted file]
include/asm-sh/r7780rp/r7780rp.h [deleted file]
include/asm-sh/rts7751r2d.h [new file with mode: 0644]
include/asm-sh/rts7751r2d/ide.h [deleted file]
include/asm-sh/rts7751r2d/rts7751r2d.h [deleted file]
include/asm-sh/sh03/ide.h [deleted file]
include/asm-sh/shmin.h [new file with mode: 0644]
include/asm-sh/shmin/shmin.h [deleted file]
include/asm-sh/system.h
include/asm-sh/timer.h
include/asm-sh64/io.h
include/asm-sparc/elf.h
include/asm-sparc/floppy.h
include/asm-sparc/irq.h
include/asm-sparc/irq_regs.h [new file with mode: 0644]
include/asm-sparc/spinlock.h
include/asm-sparc64/compat.h
include/asm-sparc64/floppy.h
include/asm-sparc64/io.h
include/asm-sparc64/irq_regs.h [new file with mode: 0644]
include/asm-um/archparam-ppc.h
include/asm-um/irq_regs.h [new file with mode: 0644]
include/asm-x86_64/apic.h
include/asm-x86_64/floppy.h
include/asm-x86_64/genapic.h
include/asm-x86_64/hw_irq.h
include/asm-x86_64/io.h
include/asm-x86_64/irq_regs.h [new file with mode: 0644]
include/asm-x86_64/mach_apic.h
include/asm-x86_64/percpu.h
include/asm-x86_64/pgtable.h
include/asm-x86_64/processor.h
include/asm-x86_64/proto.h
include/linux/Kbuild
include/linux/acpi.h
include/linux/adb.h
include/linux/arcdevice.h
include/linux/backing-dev.h
include/linux/bitmap.h
include/linux/blkdev.h
include/linux/buffer_head.h
include/linux/carta_random32.h [new file with mode: 0644]
include/linux/cdrom.h
include/linux/compat.h
include/linux/compat_ioctl.h
include/linux/config.h [deleted file]
include/linux/cpumask.h
include/linux/dcache.h
include/linux/dccp.h
include/linux/device.h
include/linux/dmi.h
include/linux/elevator.h
include/linux/ext4_fs.h [new file with mode: 0644]
include/linux/ext4_fs_extents.h [new file with mode: 0644]
include/linux/ext4_fs_i.h [new file with mode: 0644]
include/linux/ext4_fs_sb.h [new file with mode: 0644]
include/linux/ext4_jbd2.h [new file with mode: 0644]
include/linux/fs.h
include/linux/hiddev.h
include/linux/hugetlb.h
include/linux/ide.h
include/linux/if_vlan.h
include/linux/input.h
include/linux/interrupt.h
include/linux/io.h
include/linux/ioc3.h
include/linux/ioc4.h
include/linux/irq.h
include/linux/istallion.h
include/linux/jbd2.h [new file with mode: 0644]
include/linux/libata.h
include/linux/lockd/bind.h
include/linux/lockd/lockd.h
include/linux/lockd/share.h
include/linux/lockd/xdr.h
include/linux/lockd/xdr4.h
include/linux/lockdep.h
include/linux/magic.h
include/linux/mempolicy.h
include/linux/mm.h
include/linux/mmc/protocol.h
include/linux/mmzone.h
include/linux/module.h
include/linux/nbd.h
include/linux/net.h
include/linux/nfs_fs.h
include/linux/nfs_xdr.h
include/linux/nfsd/cache.h
include/linux/nfsd/export.h
include/linux/nfsd/nfsd.h
include/linux/nfsd/nfsfh.h
include/linux/nfsd/state.h
include/linux/nfsd/xdr.h
include/linux/nfsd/xdr3.h
include/linux/nfsd/xdr4.h
include/linux/nodemask.h
include/linux/oom.h [new file with mode: 0644]
include/linux/parport.h
include/linux/pci.h
include/linux/pci_hotplug.h [new file with mode: 0644]
include/linux/pci_ids.h
include/linux/percpu.h
include/linux/personality.h
include/linux/profile.h
include/linux/raid/bitmap.h
include/linux/raid/md_p.h
include/linux/raid_class.h
include/linux/random.h
include/linux/rtc.h
include/linux/sched.h
include/linux/security.h
include/linux/serial_core.h
include/linux/serio.h
include/linux/smb_fs.h
include/linux/sunrpc/msg_prot.h
include/linux/sunrpc/svc.h
include/linux/sunrpc/xdr.h
include/linux/syscalls.h
include/linux/sysrq.h
include/linux/tcp.h
include/linux/tifm.h
include/linux/timex.h
include/linux/tipc.h
include/linux/ufs_fs.h
include/linux/unwind.h
include/linux/usb.h
include/linux/usb/serial.h
include/linux/videodev2.h
include/linux/writeback.h
include/linux/xattr.h
include/net/bluetooth/hci_core.h
include/net/dn.h
include/net/flow.h
include/net/ieee80211softmac.h
include/net/inet_timewait_sock.h
include/net/inetpeer.h
include/net/ip6_route.h
include/net/ip_fib.h
include/net/netlabel.h
include/net/sctp/sctp.h
include/net/sctp/ulpevent.h
include/net/sock.h
include/net/timewait_sock.h
include/net/xfrm.h
include/scsi/sg.h
include/sound/core.h
include/sound/cs4231.h
include/sound/emu10k1.h
include/sound/gus.h
include/sound/initval.h
include/sound/mpu401.h
include/sound/sb.h
include/sound/version.h
include/sound/vx_core.h
init/Kconfig
init/main.c
kernel/audit.c
kernel/cpu.c
kernel/cpuset.c
kernel/fork.c
kernel/futex.c
kernel/futex_compat.c
kernel/irq/chip.c
kernel/irq/handle.c
kernel/irq/manage.c
kernel/irq/proc.c
kernel/irq/resend.c
kernel/irq/spurious.c
kernel/lockdep.c
kernel/module.c
kernel/mutex-debug.c
kernel/nsproxy.c
kernel/posix-cpu-timers.c
kernel/power/disk.c
kernel/power/poweroff.c
kernel/power/swap.c
kernel/power/user.c
kernel/printk.c
kernel/profile.c
kernel/relay.c
kernel/sched.c
kernel/sys_ni.c
kernel/sysctl.c
kernel/time/jiffies.c
kernel/unwind.c
kernel/workqueue.c
lib/Kconfig.debug
lib/Makefile
lib/bitmap.c
lib/cpumask.c
lib/irq_regs.c [new file with mode: 0644]
lib/kobject.c
lib/radix-tree.c
lib/random32.c [new file with mode: 0644]
lib/rwsem-spinlock.c
lib/rwsem.c
lib/spinlock_debug.c
mm/Makefile
mm/backing-dev.c [new file with mode: 0644]
mm/filemap.c
mm/hugetlb.c
mm/memory.c
mm/mempolicy.c
mm/mmap.c
mm/oom_kill.c
mm/page-writeback.c
mm/page_alloc.c
mm/rmap.c
mm/shmem.c
mm/shmem_acl.c
mm/slab.c
mm/truncate.c
mm/vmalloc.c
mm/vmscan.c
net/8021q/vlan_dev.c
net/atm/atm_sysfs.c
net/bluetooth/af_bluetooth.c
net/bluetooth/bnep/core.c
net/bluetooth/bnep/sock.c
net/bluetooth/cmtp/sock.c
net/bluetooth/hci_conn.c
net/bluetooth/hci_event.c
net/bluetooth/hci_sock.c
net/bluetooth/hci_sysfs.c
net/bluetooth/hidp/core.c
net/bluetooth/hidp/sock.c
net/bluetooth/l2cap.c
net/bluetooth/rfcomm/core.c
net/bluetooth/rfcomm/sock.c
net/bluetooth/rfcomm/tty.c
net/bluetooth/sco.c
net/bridge/br_fdb.c
net/bridge/br_if.c
net/bridge/br_private.h
net/bridge/br_stp_if.c
net/compat.c
net/core/dev.c
net/core/flow.c
net/core/netpoll.c
net/core/rtnetlink.c
net/core/scm.c
net/core/sock.c
net/core/utils.c
net/core/wireless.c
net/dccp/ipv4.c
net/dccp/ipv6.c
net/decnet/af_decnet.c
net/decnet/dn_route.c
net/ieee80211/softmac/ieee80211softmac_assoc.c
net/ieee80211/softmac/ieee80211softmac_io.c
net/ieee80211/softmac/ieee80211softmac_module.c
net/ieee80211/softmac/ieee80211softmac_wx.c
net/ipv4/cipso_ipv4.c
net/ipv4/fib_frontend.c
net/ipv4/inetpeer.c
net/ipv4/ip_gre.c
net/ipv4/ipvs/ip_vs_ftp.c
net/ipv4/netfilter/arp_tables.c
net/ipv4/netfilter/ip_conntrack_netlink.c
net/ipv4/netfilter/ip_tables.c
net/ipv4/netfilter/ipt_ECN.c
net/ipv4/netfilter/ipt_TOS.c
net/ipv4/route.c
net/ipv4/tcp_ipv4.c
net/ipv4/tcp_output.c
net/ipv4/xfrm4_policy.c
net/ipv6/Kconfig
net/ipv6/Makefile
net/ipv6/addrconf.c
net/ipv6/af_inet6.c
net/ipv6/fib6_rules.c
net/ipv6/ip6_fib.c
net/ipv6/ndisc.c
net/ipv6/route.c
net/ipv6/sit.c
net/ipv6/tcp_ipv6.c
net/ipv6/xfrm6_policy.c
net/irda/irias_object.c
net/key/af_key.c
net/netfilter/Kconfig
net/netfilter/nf_conntrack_netlink.c
net/netfilter/xt_NFQUEUE.c
net/netfilter/xt_connmark.c
net/netlabel/netlabel_kapi.c
net/sched/sch_htb.c
net/sched/sch_netem.c
net/sctp/ipv6.c
net/sctp/proc.c
net/sctp/socket.c
net/sctp/ulpevent.c
net/sctp/ulpqueue.c
net/sunrpc/auth_gss/svcauth_gss.c
net/sunrpc/pmap_clnt.c
net/sunrpc/svc.c
net/sunrpc/svcsock.c
net/sunrpc/xprtsock.c
net/tipc/bearer.c
net/tipc/config.c
net/tipc/core.c
net/tipc/core.h
net/tipc/dbg.c
net/tipc/dbg.h
net/tipc/discover.c
net/tipc/link.c
net/tipc/name_distr.c
net/tipc/node.c
net/tipc/port.c
net/tipc/socket.c
net/tipc/subscr.c
net/xfrm/xfrm_policy.c
net/xfrm/xfrm_state.c
net/xfrm/xfrm_user.c
scripts/Makefile.headersinst
scripts/Makefile.modpost
scripts/kconfig/lxdialog/dialog.h
scripts/kernel-doc
security/dummy.c
security/selinux/include/xfrm.h
security/selinux/ss/ebitmap.c
security/selinux/ss/mls.c
security/selinux/ss/policydb.c
security/selinux/ss/services.c
security/selinux/xfrm.c
sound/aoa/core/snd-aoa-gpio-feature.c
sound/aoa/soundbus/i2sbus/i2sbus-core.c
sound/aoa/soundbus/i2sbus/i2sbus-pcm.c
sound/aoa/soundbus/i2sbus/i2sbus.h
sound/arm/aaci.c
sound/arm/pxa2xx-ac97.c
sound/arm/pxa2xx-pcm.c
sound/core/control.c
sound/core/hwdep.c
sound/core/hwdep_compat.c
sound/core/info.c
sound/core/init.c
sound/drivers/mpu401/mpu401_uart.c
sound/drivers/mtpav.c
sound/drivers/mts64.c
sound/drivers/serial-u16550.c
sound/drivers/vx/vx_core.c
sound/isa/Kconfig
sound/isa/ad1816a/ad1816a.c
sound/isa/ad1816a/ad1816a_lib.c
sound/isa/ad1848/ad1848_lib.c
sound/isa/cmi8330.c
sound/isa/cs423x/cs4231_lib.c
sound/isa/es1688/es1688_lib.c
sound/isa/es18xx.c
sound/isa/gus/gus_irq.c
sound/isa/gus/gusmax.c
sound/isa/gus/interwave.c
sound/isa/opl3sa2.c
sound/isa/opti9xx/opti92x-ad1848.c
sound/isa/sb/es968.c
sound/isa/sb/sb16_main.c
sound/isa/sb/sb8.c
sound/isa/sb/sb_common.c
sound/isa/sgalaxy.c
sound/isa/wavefront/wavefront.c
sound/mips/au1x00.c
sound/oss/ad1816.c
sound/oss/ad1848.c
sound/oss/ad1889.c
sound/oss/btaudio.c
sound/oss/cs46xx.c
sound/oss/dmasound/dmasound_atari.c
sound/oss/dmasound/dmasound_awacs.c
sound/oss/dmasound/dmasound_paula.c
sound/oss/dmasound/dmasound_q40.c
sound/oss/emu10k1/irqmgr.c
sound/oss/emu10k1/main.c
sound/oss/es1371.c
sound/oss/hal2.c
sound/oss/i810_audio.c
sound/oss/mpu401.c
sound/oss/mpu401.h
sound/oss/msnd_pinnacle.c
sound/oss/nec_vrc5477.c
sound/oss/nm256.h
sound/oss/nm256_audio.c
sound/oss/pas2_card.c
sound/oss/sb_common.c
sound/oss/sh_dac_audio.c
sound/oss/swarm_cs4297a.c
sound/oss/trident.c
sound/oss/uart401.c
sound/oss/uart6850.c
sound/oss/via82cxxx_audio.c
sound/oss/vidc.c
sound/oss/vidc.h
sound/oss/vwsnd.c
sound/oss/waveartist.c
sound/parisc/harmony.c
sound/pci/ac97/ac97_codec.c
sound/pci/ac97/ac97_patch.c
sound/pci/ad1889.c
sound/pci/ali5451/ali5451.c
sound/pci/als300.c
sound/pci/als4000.c
sound/pci/atiixp.c
sound/pci/atiixp_modem.c
sound/pci/au88x0/au88x0.c
sound/pci/au88x0/au88x0.h
sound/pci/au88x0/au88x0_core.c
sound/pci/azt3328.c
sound/pci/bt87x.c
sound/pci/ca0106/ca0106_main.c
sound/pci/cmipci.c
sound/pci/cs4281.c
sound/pci/cs46xx/cs46xx_lib.c
sound/pci/cs5535audio/cs5535audio.c
sound/pci/cs5535audio/cs5535audio_pm.c
sound/pci/echoaudio/echoaudio.c
sound/pci/emu10k1/emu10k1.c
sound/pci/emu10k1/emu10k1_main.c
sound/pci/emu10k1/emu10k1x.c
sound/pci/emu10k1/irq.c
sound/pci/ens1370.c
sound/pci/es1938.c
sound/pci/es1968.c
sound/pci/fm801.c
sound/pci/hda/hda_intel.c
sound/pci/hda/patch_analog.c
sound/pci/hda/patch_atihdmi.c
sound/pci/hda/patch_realtek.c
sound/pci/hda/patch_si3054.c
sound/pci/ice1712/ice1712.c
sound/pci/ice1712/ice1724.c
sound/pci/intel8x0.c
sound/pci/intel8x0m.c
sound/pci/korg1212/korg1212.c
sound/pci/maestro3.c
sound/pci/mixart/mixart_core.c
sound/pci/mixart/mixart_core.h
sound/pci/nm256/nm256.c
sound/pci/pcxhr/pcxhr_core.c
sound/pci/pcxhr/pcxhr_core.h
sound/pci/riptide/riptide.c
sound/pci/rme32.c
sound/pci/rme96.c
sound/pci/rme9652/hdsp.c
sound/pci/rme9652/hdspm.c
sound/pci/rme9652/rme9652.c
sound/pci/sonicvibes.c
sound/pci/trident/trident_main.c
sound/pci/via82xx.c
sound/pci/via82xx_modem.c
sound/pci/vx222/vx222.c
sound/pci/ymfpci/ymfpci_main.c
sound/pcmcia/pdaudiocf/pdaudiocf.h
sound/pcmcia/pdaudiocf/pdaudiocf_irq.c
sound/ppc/pmac.c
sound/ppc/tumbler.c
sound/sparc/amd7930.c
sound/sparc/cs4231.c
sound/sparc/dbri.c
sound/usb/usbaudio.c
sound/usb/usbmidi.c
sound/usb/usbmixer.c
sound/usb/usx2y/usbusx2y.c
sound/usb/usx2y/usbusx2yaudio.c
sound/usb/usx2y/usx2yhwdeppcm.c

index d6f3dd1a3464f0cd6950e1c6dcecc4f7bcb6c84f..8d51c148f72117b707792a65c9c5ad025364a03a 100644 (file)
@@ -395,6 +395,26 @@ bugme-janitor mailing list (every change in the bugzilla is mailed here)
 
 
 
+Managing bug reports
+--------------------
+
+One of the best ways to put into practice your hacking skills is by fixing
+bugs reported by other people. Not only you will help to make the kernel
+more stable, you'll learn to fix real world problems and you will improve
+your skills, and other developers will be aware of your presence. Fixing
+bugs is one of the best ways to get merits among other developers, because
+not many people like wasting time fixing other people's bugs.
+
+To work in the already reported bug reports, go to http://bugzilla.kernel.org.
+If you want to be advised of the future bug reports, you can subscribe to the
+bugme-new mailing list (only new bug reports are mailed here) or to the
+bugme-janitor mailing list (every change in the bugzilla is mailed here)
+
+       http://lists.osdl.org/mailman/listinfo/bugme-new
+       http://lists.osdl.org/mailman/listinfo/bugme-janitors
+
+
+
 Mailing lists
 -------------
 
index c70306abb7b2e2c4fc306bdc70447b47c9e9878e..5c34910665d1d8514fb77c07e310f91b2b7f59bd 100644 (file)
@@ -470,7 +470,68 @@ LOC:     324553     325068
 ERR:          0
 MIS:          0
 
-6. FAQ
+6. MSI quirks
+
+Several PCI chipsets or devices are known to not support MSI.
+The PCI stack provides 3 possible levels of MSI disabling:
+* on a single device
+* on all devices behind a specific bridge
+* globally
+
+6.1. Disabling MSI on a single device
+
+Under some circumstances, it might be required to disable MSI on a
+single device, It may be achived by either not calling pci_enable_msi()
+or all, or setting the pci_dev->no_msi flag before (most of the time
+in a quirk).
+
+6.2. Disabling MSI below a bridge
+
+The vast majority of MSI quirks are required by PCI bridges not
+being able to route MSI between busses. In this case, MSI have to be
+disabled on all devices behind this bridge. It is achieves by setting
+the PCI_BUS_FLAGS_NO_MSI flag in the pci_bus->bus_flags of the bridge
+subordinate bus. There is no need to set the same flag on bridges that
+are below the broken brigde. When pci_enable_msi() is called to enable
+MSI on a device, pci_msi_supported() takes care of checking the NO_MSI
+flag in all parent busses of the device.
+
+Some bridges actually support dynamic MSI support enabling/disabling
+by changing some bits in their PCI configuration space (especially
+the Hypertransport chipsets such as the nVidia nForce and Serverworks
+HT2000). It may then be required to update the NO_MSI flag on the
+corresponding devices in the sysfs hierarchy. To enable MSI support
+on device "0000:00:0e", do:
+
+       echo 1 > /sys/bus/pci/devices/0000:00:0e/msi_bus
+
+To disable MSI support, echo 0 instead of 1. Note that it should be
+used with caution since changing this value might break interrupts.
+
+6.3. Disabling MSI globally
+
+Some extreme cases may require to disable MSI globally on the system.
+For now, the only known case is a Serverworks PCI-X chipsets (MSI are
+not supported on several busses that are not all connected to the
+chipset in the Linux PCI hierarchy). In the vast majority of other
+cases, disabling only behind a specific bridge is enough.
+
+For debugging purpose, the user may also pass pci=nomsi on the kernel
+command-line to explicitly disable MSI globally. But, once the appro-
+priate quirks are added to the kernel, this option should not be
+required anymore.
+
+6.4. Finding why MSI cannot be enabled on a device
+
+Assuming that MSI are not enabled on a device, you should look at
+dmesg to find messages that quirks may output when disabling MSI
+on some devices, some bridges or even globally.
+Then, lspci -t gives the list of bridges above a device. Reading
+/sys/bus/pci/devices/0000:00:0e/msi_bus will tell you whether MSI
+are enabled (1) or disabled (0). In 0 is found in a single bridge
+msi_bus file above the device, MSI cannot be enabled.
+
+7. FAQ
 
 Q1. Are there any limitations on using the MSI?
 
index bc107cb157a8bba060ce65bb9ded734bfbdd15a8..4868c34f75090fe75b4f6bb28f70c7638540c4cd 100644 (file)
@@ -46,7 +46,7 @@ maxcpus=n    Restrict boot time cpus to n. Say if you have 4 cpus, using
              maxcpus=2 will only boot 2. You can choose to bring the
              other cpus later online, read FAQ's for more info.
 
-additional_cpus*=n     Use this to limit hotpluggable cpus. This option sets
+additional_cpus=n (*)  Use this to limit hotpluggable cpus. This option sets
                        cpu_possible_map = cpu_present_map + additional_cpus
 
 (*) Option valid only for following architectures
@@ -101,15 +101,15 @@ cpu_possible_map/for_each_possible_cpu() to iterate.
 
 Never use anything other than cpumask_t to represent bitmap of CPUs.
 
-#include <linux/cpumask.h>
+       #include <linux/cpumask.h>
 
-for_each_possible_cpu     - Iterate over cpu_possible_map
-for_each_online_cpu       - Iterate over cpu_online_map
-for_each_present_cpu      - Iterate over cpu_present_map
-for_each_cpu_mask(x,mask) - Iterate over some random collection of cpu mask.
+       for_each_possible_cpu     - Iterate over cpu_possible_map
+       for_each_online_cpu       - Iterate over cpu_online_map
+       for_each_present_cpu      - Iterate over cpu_present_map
+       for_each_cpu_mask(x,mask) - Iterate over some random collection of cpu mask.
 
-#include <linux/cpu.h>
-lock_cpu_hotplug() and unlock_cpu_hotplug():
+       #include <linux/cpu.h>
+       lock_cpu_hotplug() and unlock_cpu_hotplug():
 
 The above calls are used to inhibit cpu hotplug operations. While holding the
 cpucontrol mutex, cpu_online_map will not change. If you merely need to avoid
@@ -120,7 +120,7 @@ will work as long as stop_machine_run() is used to take a cpu down.
 
 CPU Hotplug - Frequently Asked Questions.
 
-Q: How to enable my kernel to support CPU hotplug?
+Q: How to enable my kernel to support CPU hotplug?
 A: When doing make defconfig, Enable CPU hotplug support
 
    "Processor type and Features" -> Support for Hotpluggable CPUs
@@ -141,39 +141,39 @@ A: You should now notice an entry in sysfs.
 Check if sysfs is mounted, using the "mount" command. You should notice
 an entry as shown below in the output.
 
-....
-none on /sys type sysfs (rw)
-....
+       ....
+       none on /sys type sysfs (rw)
+       ....
 
-if this is not mounted, do the following.
+If this is not mounted, do the following.
 
-#mkdir /sysfs
-#mount -t sysfs sys /sys
+        #mkdir /sysfs
+       #mount -t sysfs sys /sys
 
-now you should see entries for all present cpu, the following is an example
+Now you should see entries for all present cpu, the following is an example
 in a 8-way system.
 
-#pwd
-#/sys/devices/system/cpu
-#ls -l
-total 0
-drwxr-xr-x  10 root root 0 Sep 19 07:44 .
-drwxr-xr-x  13 root root 0 Sep 19 07:45 ..
-drwxr-xr-x   3 root root 0 Sep 19 07:44 cpu0
-drwxr-xr-x   3 root root 0 Sep 19 07:44 cpu1
-drwxr-xr-x   3 root root 0 Sep 19 07:44 cpu2
-drwxr-xr-x   3 root root 0 Sep 19 07:44 cpu3
-drwxr-xr-x   3 root root 0 Sep 19 07:44 cpu4
-drwxr-xr-x   3 root root 0 Sep 19 07:44 cpu5
-drwxr-xr-x   3 root root 0 Sep 19 07:44 cpu6
-drwxr-xr-x   3 root root 0 Sep 19 07:48 cpu7
+       #pwd
+       #/sys/devices/system/cpu
+       #ls -l
+       total 0
+       drwxr-xr-x  10 root root 0 Sep 19 07:44 .
+       drwxr-xr-x  13 root root 0 Sep 19 07:45 ..
+       drwxr-xr-x   3 root root 0 Sep 19 07:44 cpu0
+       drwxr-xr-x   3 root root 0 Sep 19 07:44 cpu1
+       drwxr-xr-x   3 root root 0 Sep 19 07:44 cpu2
+       drwxr-xr-x   3 root root 0 Sep 19 07:44 cpu3
+       drwxr-xr-x   3 root root 0 Sep 19 07:44 cpu4
+       drwxr-xr-x   3 root root 0 Sep 19 07:44 cpu5
+       drwxr-xr-x   3 root root 0 Sep 19 07:44 cpu6
+       drwxr-xr-x   3 root root 0 Sep 19 07:48 cpu7
 
 Under each directory you would find an "online" file which is the control
 file to logically online/offline a processor.
 
 Q: Does hot-add/hot-remove refer to physical add/remove of cpus?
 A: The usage of hot-add/remove may not be very consistently used in the code.
-CONFIG_CPU_HOTPLUG enables logical online/offline capability in the kernel.
+CONFIG_HOTPLUG_CPU enables logical online/offline capability in the kernel.
 To support physical addition/removal, one would need some BIOS hooks and
 the platform should have something like an attention button in PCI hotplug.
 CONFIG_ACPI_HOTPLUG_CPU enables ACPI support for physical add/remove of CPUs.
@@ -181,17 +181,17 @@ CONFIG_ACPI_HOTPLUG_CPU enables ACPI support for physical add/remove of CPUs.
 Q: How do i logically offline a CPU?
 A: Do the following.
 
-#echo 0 > /sys/devices/system/cpu/cpuX/online
+       #echo 0 > /sys/devices/system/cpu/cpuX/online
 
-once the logical offline is successful, check
+Once the logical offline is successful, check
 
-#cat /proc/interrupts
+       #cat /proc/interrupts
 
-you should now not see the CPU that you removed. Also online file will report
+You should now not see the CPU that you removed. Also online file will report
 the state as 0 when a cpu if offline and 1 when its online.
 
-#To display the current cpu state.
-#cat /sys/devices/system/cpu/cpuX/online
+       #To display the current cpu state.
+       #cat /sys/devices/system/cpu/cpuX/online
 
 Q: Why cant i remove CPU0 on some systems?
 A: Some architectures may have some special dependency on a certain CPU.
@@ -234,8 +234,8 @@ Q: If i have some kernel code that needs to be aware of CPU arrival and
    departure, how to i arrange for proper notification?
 A: This is what you would need in your kernel code to receive notifications.
 
-    #include <linux/cpu.h>
-    static int __cpuinit foobar_cpu_callback(struct notifier_block *nfb,
+       #include <linux/cpu.h>
+       static int __cpuinit foobar_cpu_callback(struct notifier_block *nfb,
                                            unsigned long action, void *hcpu)
        {
                unsigned int cpu = (unsigned long)hcpu;
@@ -279,10 +279,10 @@ Q: I don't see my action being called for all CPUs already up and running?
 A: Yes, CPU notifiers are called only when new CPUs are on-lined or offlined.
    If you need to perform some action for each cpu already in the system, then
 
-  for_each_online_cpu(i) {
+       for_each_online_cpu(i) {
                foobar_cpu_callback(&foobar_cpu_notifier, CPU_UP_PREPARE, i);
-               foobar_cpu_callback(&foobar-cpu_notifier, CPU_ONLINE, i);
-  }
+               foobar_cpu_callback(&foobar_cpu_notifier, CPU_ONLINE, i);
+       }
 
 Q: If i would like to develop cpu hotplug support for a new architecture,
    what do i need at a minimum?
@@ -307,38 +307,38 @@ Q: I need to ensure that a particular cpu is not removed when there is some
    work specific to this cpu is in progress.
 A: First switch the current thread context to preferred cpu
 
-   int my_func_on_cpu(int cpu)
-   {
-       cpumask_t saved_mask, new_mask = CPU_MASK_NONE;
-       int curr_cpu, err = 0;
-
-       saved_mask = current->cpus_allowed;
-       cpu_set(cpu, new_mask);
-       err = set_cpus_allowed(current, new_mask);
-
-       if (err)
-           return err;
-
-       /*
-        * If we got scheduled out just after the return from
-        * set_cpus_allowed() before running the work, this ensures
-        * we stay locked.
-        */
-       curr_cpu = get_cpu();
-
-       if (curr_cpu != cpu) {
-          err = -EAGAIN;
-           goto ret;
-       } else {
-                  /*
-           * Do work : But cant sleep, since get_cpu() disables preempt
-           */
-       }
-    ret:
-       put_cpu();
-       set_cpus_allowed(current, saved_mask);
-       return err;
-    }
+       int my_func_on_cpu(int cpu)
+       {
+               cpumask_t saved_mask, new_mask = CPU_MASK_NONE;
+               int curr_cpu, err = 0;
+
+               saved_mask = current->cpus_allowed;
+               cpu_set(cpu, new_mask);
+               err = set_cpus_allowed(current, new_mask);
+
+               if (err)
+                       return err;
+
+               /*
+                * If we got scheduled out just after the return from
+                * set_cpus_allowed() before running the work, this ensures
+                * we stay locked.
+                */
+               curr_cpu = get_cpu();
+
+               if (curr_cpu != cpu) {
+                       err = -EAGAIN;
+                       goto ret;
+               } else {
+                       /*
+                        * Do work : But cant sleep, since get_cpu() disables preempt
+                        */
+               }
+               ret:
+                       put_cpu();
+                       set_cpus_allowed(current, saved_mask);
+                       return err;
+               }
 
 
 Q: How do we determine how many CPUs are available for hotplug.
index 24f3c63b301710ba461e04e9fc353c9f4a5eabcd..1ac3c74646e3fc29fac85e767eaec8ad4e350330 100644 (file)
@@ -255,7 +255,7 @@ Who:        Stephen Hemminger <shemminger@osdl.org>
 
 
 What:  PHYSDEVPATH, PHYSDEVBUS, PHYSDEVDRIVER in the uevent environment
-When:  Oktober 2008
+When:  October 2008
 Why:   The stacking of class devices makes these values misleading and
        inconsistent.
        Class devices should not carry any of these properties, and bus
index 3c384c0cf86e0a6484e121fdc817c4307dcbce21..4dc28cc935037c3b9c8f7cdc4dbb26854fbc2ea8 100644 (file)
@@ -34,6 +34,8 @@ ext2.txt
        - info, mount options and specifications for the Ext2 filesystem.
 ext3.txt
        - info, mount options and specifications for the Ext3 filesystem.
+ext4.txt
+       - info, mount options and specifications for the Ext4 filesystem.
 files.txt
        - info on file management in the Linux kernel.
 fuse.txt
diff --git a/Documentation/filesystems/ext4.txt b/Documentation/filesystems/ext4.txt
new file mode 100644 (file)
index 0000000..6a4adca
--- /dev/null
@@ -0,0 +1,236 @@
+
+Ext4 Filesystem
+===============
+
+This is a development version of the ext4 filesystem, an advanced level
+of the ext3 filesystem which incorporates scalability and reliability
+enhancements for supporting large filesystems (64 bit) in keeping with
+increasing disk capacities and state-of-the-art feature requirements.
+
+Mailing list: linux-ext4@vger.kernel.org
+
+
+1. Quick usage instructions:
+===========================
+
+  - Grab updated e2fsprogs from
+    ftp://ftp.kernel.org/pub/linux/kernel/people/tytso/e2fsprogs-interim/
+    This is a patchset on top of e2fsprogs-1.39, which can be found at
+    ftp://ftp.kernel.org/pub/linux/kernel/people/tytso/e2fsprogs/
+
+  - It's still mke2fs -j /dev/hda1
+
+  - mount /dev/hda1 /wherever -t ext4dev
+
+  - To enable extents,
+
+       mount /dev/hda1 /wherever -t ext4dev -o extents
+
+  - The filesystem is compatible with the ext3 driver until you add a file
+    which has extents (ie: `mount -o extents', then create a file).
+
+    NOTE: The "extents" mount flag is temporary.  It will soon go away and
+    extents will be enabled by the "-o extents" flag to mke2fs or tune2fs
+
+  - When comparing performance with other filesystems, remember that
+    ext3/4 by default offers higher data integrity guarantees than most.  So
+    when comparing with a metadata-only journalling filesystem, use `mount -o
+    data=writeback'.  And you might as well use `mount -o nobh' too along
+    with it.  Making the journal larger than the mke2fs default often helps
+    performance with metadata-intensive workloads.
+
+2. Features
+===========
+
+2.1 Currently available
+
+* ability to use filesystems > 16TB
+* extent format reduces metadata overhead (RAM, IO for access, transactions)
+* extent format more robust in face of on-disk corruption due to magics,
+* internal redunancy in tree
+
+2.1 Previously available, soon to be enabled by default by "mkefs.ext4":
+
+* dir_index and resize inode will be on by default
+* large inodes will be used by default for fast EAs, nsec timestamps, etc
+
+2.2 Candidate features for future inclusion
+
+There are several under discussion, whether they all make it in is
+partly a function of how much time everyone has to work on them:
+
+* improved file allocation (multi-block alloc, delayed alloc; basically done)
+* fix 32000 subdirectory limit (patch exists, needs some e2fsck work)
+* nsec timestamps for mtime, atime, ctime, create time (patch exists,
+  needs some e2fsck work)
+* inode version field on disk (NFSv4, Lustre; prototype exists)
+* reduced mke2fs/e2fsck time via uninitialized groups (prototype exists)
+* journal checksumming for robustness, performance (prototype exists)
+* persistent file preallocation (e.g for streaming media, databases)
+
+Features like metadata checksumming have been discussed and planned for
+a bit but no patches exist yet so I'm not sure they're in the near-term
+roadmap.
+
+The big performance win will come with mballoc and delalloc.  CFS has
+been using mballoc for a few years already with Lustre, and IBM + Bull
+did a lot of benchmarking on it.  The reason it isn't in the first set of
+patches is partly a manageability issue, and partly because it doesn't
+directly affect the on-disk format (outside of much better allocation)
+so it isn't critical to get into the first round of changes.  I believe
+Alex is working on a new set of patches right now.
+
+3. Options
+==========
+
+When mounting an ext4 filesystem, the following option are accepted:
+(*) == default
+
+extents                        ext4 will use extents to address file data.  The
+                       file system will no longer be mountable by ext3.
+
+journal=update         Update the ext4 file system's journal to the current
+                       format.
+
+journal=inum           When a journal already exists, this option is ignored.
+                       Otherwise, it specifies the number of the inode which
+                       will represent the ext4 file system's journal file.
+
+journal_dev=devnum     When the external journal device's major/minor numbers
+                       have changed, this option allows the user to specify
+                       the new journal location.  The journal device is
+                       identified through its new major/minor numbers encoded
+                       in devnum.
+
+noload                 Don't load the journal on mounting.
+
+data=journal           All data are committed into the journal prior to being
+                       written into the main file system.
+
+data=ordered   (*)     All data are forced directly out to the main file
+                       system prior to its metadata being committed to the
+                       journal.
+
+data=writeback         Data ordering is not preserved, data may be written
+                       into the main file system after its metadata has been
+                       committed to the journal.
+
+commit=nrsec   (*)     Ext4 can be told to sync all its data and metadata
+                       every 'nrsec' seconds. The default value is 5 seconds.
+                       This means that if you lose your power, you will lose
+                       as much as the latest 5 seconds of work (your
+                       filesystem will not be damaged though, thanks to the
+                       journaling).  This default value (or any low value)
+                       will hurt performance, but it's good for data-safety.
+                       Setting it to 0 will have the same effect as leaving
+                       it at the default (5 seconds).
+                       Setting it to very large values will improve
+                       performance.
+
+barrier=1              This enables/disables barriers.  barrier=0 disables
+                       it, barrier=1 enables it.
+
+orlov          (*)     This enables the new Orlov block allocator. It is
+                       enabled by default.
+
+oldalloc               This disables the Orlov block allocator and enables
+                       the old block allocator.  Orlov should have better
+                       performance - we'd like to get some feedback if it's
+                       the contrary for you.
+
+user_xattr             Enables Extended User Attributes.  Additionally, you
+                       need to have extended attribute support enabled in the
+                       kernel configuration (CONFIG_EXT4_FS_XATTR).  See the
+                       attr(5) manual page and http://acl.bestbits.at/ to
+                       learn more about extended attributes.
+
+nouser_xattr           Disables Extended User Attributes.
+
+acl                    Enables POSIX Access Control Lists support.
+                       Additionally, you need to have ACL support enabled in
+                       the kernel configuration (CONFIG_EXT4_FS_POSIX_ACL).
+                       See the acl(5) manual page and http://acl.bestbits.at/
+                       for more information.
+
+noacl                  This option disables POSIX Access Control List
+                       support.
+
+reservation
+
+noreservation
+
+bsddf          (*)     Make 'df' act like BSD.
+minixdf                        Make 'df' act like Minix.
+
+check=none             Don't do extra checking of bitmaps on mount.
+nocheck
+
+debug                  Extra debugging information is sent to syslog.
+
+errors=remount-ro(*)   Remount the filesystem read-only on an error.
+errors=continue                Keep going on a filesystem error.
+errors=panic           Panic and halt the machine if an error occurs.
+
+grpid                  Give objects the same group ID as their creator.
+bsdgroups
+
+nogrpid                (*)     New objects have the group ID of their creator.
+sysvgroups
+
+resgid=n               The group ID which may use the reserved blocks.
+
+resuid=n               The user ID which may use the reserved blocks.
+
+sb=n                   Use alternate superblock at this location.
+
+quota
+noquota
+grpquota
+usrquota
+
+bh             (*)     ext4 associates buffer heads to data pages to
+nobh                   (a) cache disk block mapping information
+                       (b) link pages into transaction to provide
+                           ordering guarantees.
+                       "bh" option forces use of buffer heads.
+                       "nobh" option tries to avoid associating buffer
+                       heads (supported only for "writeback" mode).
+
+
+Data Mode
+---------
+There are 3 different data modes:
+
+* writeback mode
+In data=writeback mode, ext4 does not journal data at all.  This mode provides
+a similar level of journaling as that of XFS, JFS, and ReiserFS in its default
+mode - metadata journaling.  A crash+recovery can cause incorrect data to
+appear in files which were written shortly before the crash.  This mode will
+typically provide the best ext4 performance.
+
+* ordered mode
+In data=ordered mode, ext4 only officially journals metadata, but it logically
+groups metadata and data blocks into a single unit called a transaction.  When
+it's time to write the new metadata out to disk, the associated data blocks
+are written first.  In general, this mode performs slightly slower than
+writeback but significantly faster than journal mode.
+
+* journal mode
+data=journal mode provides full data and metadata journaling.  All new data is
+written to the journal first, and then to its final location.
+In the event of a crash, the journal can be replayed, bringing both data and
+metadata into a consistent state.  This mode is the slowest except when data
+needs to be read from and written to disk at the same time where it
+outperforms all others modes.
+
+References
+==========
+
+kernel source: <file:fs/ext4/>
+               <file:fs/jbd2/>
+
+programs:      http://e2fsprogs.sourceforge.net/
+               http://ext2resize.sourceforge.net
+
+useful links:  http://fedoraproject.org/wiki/ext3-devel
+               http://www.bullopensource.org/ext4/
index 35f618f32896c9228c8a32a3c62b5392043237ac..2c6f1fed4618df3949d76173057c9eda3f4f7762 100644 (file)
@@ -24,7 +24,7 @@ Authors:
     Frodo Looijaard <frodol@dds.nl>,
     Philip Edelbrock <phil@netroedge.com>,
     Michiel Rook <michiel@grendelproject.nl>,
-    Grant Coady <gcoady@gmail.com> with guidance
+    Grant Coady <gcoady.lk@gmail.com> with guidance
         from Jean Delvare <khali@linux-fr.org>
 
 Interface
index 28c5b7d1eb90f0ccd8e0307c170f89bd7954dc9c..2ca69df669c3a615601aec996fb8f977aa485180 100644 (file)
@@ -17,7 +17,7 @@ Thanks to Kris Chen from Fintek for answering technical questions and
 providing additional documentation.
 
 Thanks to Chris Lin from Jetway for providing wiring schematics and
-anwsering technical questions.
+answering technical questions.
 
 
 Description
index bab445ab0f523fc627c24aa0c5da11aa11d51523..30d123b8d92022180b4f0cd2ae32cffc47ba4f6e 100644 (file)
@@ -2,7 +2,7 @@ Kernel driver k8temp
 ====================
 
 Supported chips:
-  * AMD K8 CPU
+  * AMD Athlon64/FX or Opteron CPUs
     Prefix: 'k8temp'
     Addresses scanned: PCI space
     Datasheet: http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/32559.pdf
@@ -13,10 +13,13 @@ Contact: Rudolf Marek <r.marek@sh.cvut.cz>
 Description
 -----------
 
-This driver permits reading temperature sensor(s) embedded inside AMD K8 CPUs.
-Official documentation says that it works from revision F of K8 core, but
-in fact it seems to be implemented for all revisions of K8 except the first
-two revisions (SH-B0 and SH-B3).
+This driver permits reading temperature sensor(s) embedded inside AMD K8
+family CPUs (Athlon64/FX, Opteron). Official documentation says that it works
+from revision F of K8 core, but in fact it seems to be implemented for all
+revisions of K8 except the first two revisions (SH-B0 and SH-B3).
+
+Please note that you will need at least lm-sensors 2.10.1 for proper userspace
+support.
 
 There can be up to four temperature sensors inside single CPU. The driver
 will auto-detect the sensors and will display only temperatures from
index c15bbe68264ee514861197726b2dddea2b4bcbbd..04a11124f667756b9a4225b81624d9d9225eb1ae 100644 (file)
@@ -2,12 +2,14 @@ Kernel driver smsc47m1
 ======================
 
 Supported chips:
-  * SMSC LPC47B27x, LPC47M10x, LPC47M13x, LPC47M14x, LPC47M15x and LPC47M192
+  * SMSC LPC47B27x, LPC47M112, LPC47M10x, LPC47M13x, LPC47M14x,
+    LPC47M15x and LPC47M192
     Addresses scanned: none, address read from Super I/O config space
     Prefix: 'smsc47m1'
     Datasheets:
         http://www.smsc.com/main/datasheets/47b27x.pdf
         http://www.smsc.com/main/datasheets/47m10x.pdf
+        http://www.smsc.com/main/datasheets/47m112.pdf
         http://www.smsc.com/main/tools/discontinued/47m13x.pdf
         http://www.smsc.com/main/datasheets/47m14x.pdf
         http://www.smsc.com/main/tools/discontinued/47m15x.pdf
index fae3b781d82d48f6f91a5b261601499ee450e127..caa610a297e8a349f586f15a4b1279903179e47d 100644 (file)
@@ -26,7 +26,7 @@ fan control mode).
 Temperatures are measured in degrees Celsius and measurement resolution is 1
 degC for temp1 and 0.5 degC for temp2 and temp3. An alarm is triggered when
 the temperature gets higher than high limit; it stays on until the temperature
-falls below the Hysteresis value.
+falls below the hysteresis value.
 
 Fan rotation speeds are reported in RPM (rotations per minute). An alarm is
 triggered if the rotation speed has dropped below a programmable limit. Fan
@@ -67,9 +67,9 @@ Thermal Cruise mode
 
 If the temperature is in the range defined by:
 
-pwm[1-4]_target    - set target temperature, unit millidegree Celcius
+pwm[1-4]_target    - set target temperature, unit millidegree Celsius
                     (range 0 - 127000)
-pwm[1-4]_tolerance - tolerance, unit millidegree Celcius (range 0 - 15000)
+pwm[1-4]_tolerance - tolerance, unit millidegree Celsius (range 0 - 15000)
 
 there are no changes to fan speed. Once the temperature leaves the interval,
 fan speed increases (temp is higher) or decreases if lower than desired.
index 71aa403452722348f2a1668db3b6b35699e833df..e50595bfd8ea63e0cfc15c0c4cadd94e01ea1224 100644 (file)
@@ -30,9 +30,10 @@ detailed description):
        - ACPI sounds
        - temperature sensors
        - Experimental: embedded controller register dump
-       - Experimental: LCD brightness control
-       - Experimental: volume control
+       - LCD brightness control
+       - Volume control
        - Experimental: fan speed, fan enable/disable
+       - Experimental: WAN enable and disable
 
 A compatibility table by model and feature is maintained on the web
 site, http://ibm-acpi.sf.net/. I appreciate any success or failure
@@ -52,40 +53,7 @@ Installation
 
 If you are compiling this driver as included in the Linux kernel
 sources, simply enable the CONFIG_ACPI_IBM option (Power Management /
-ACPI / IBM ThinkPad Laptop Extras). The rest of this section describes
-how to install this driver when downloaded from the web site.
-
-First, you need to get a kernel with ACPI support up and running.
-Please refer to http://acpi.sourceforge.net/ for help with this
-step. How successful you will be depends a lot on you ThinkPad model,
-the kernel you are using and any additional patches applied. The
-kernel provided with your distribution may not be good enough. I
-needed to compile a 2.6.7 kernel with the 20040715 ACPI patch to get
-ACPI working reliably on my ThinkPad X40. Old ThinkPad models may not
-be supported at all.
-
-Assuming you have the basic ACPI support working (e.g. you can see the
-/proc/acpi directory), follow the following steps to install this
-driver:
-
-       - unpack the archive:
-
-               tar xzvf ibm-acpi-x.y.tar.gz; cd ibm-acpi-x.y
-
-       - compile the driver:
-
-               make
-
-       - install the module in your kernel modules directory:
-
-               make install
-
-       - load the module:
-
-               modprobe ibm_acpi
-
-After loading the module, check the "dmesg" output for any error messages.
-
+ACPI / IBM ThinkPad Laptop Extras).
 
 Features
 --------
@@ -523,13 +491,8 @@ registers contain the current battery capacity, etc. If you experiment
 with this, do send me your results (including some complete dumps with
 a description of the conditions when they were taken.)
 
-EXPERIMENTAL: LCD brightness control -- /proc/acpi/ibm/brightness
------------------------------------------------------------------
-
-This feature is marked EXPERIMENTAL because the implementation
-directly accesses hardware registers and may not work as expected. USE
-WITH CAUTION! To use this feature, you need to supply the
-experimental=1 parameter when loading the module.
+LCD brightness control -- /proc/acpi/ibm/brightness
+---------------------------------------------------
 
 This feature allows software control of the LCD brightness on ThinkPad
 models which don't have a hardware brightness slider. The available
@@ -542,13 +505,8 @@ commands are:
 The <level> number range is 0 to 7, although not all of them may be
 distinct. The current brightness level is shown in the file.
 
-EXPERIMENTAL: Volume control -- /proc/acpi/ibm/volume
------------------------------------------------------
-
-This feature is marked EXPERIMENTAL because the implementation
-directly accesses hardware registers and may not work as expected. USE
-WITH CAUTION! To use this feature, you need to supply the
-experimental=1 parameter when loading the module.
+Volume control -- /proc/acpi/ibm/volume
+---------------------------------------
 
 This feature allows volume control on ThinkPad models which don't have
 a hardware volume knob. The available commands are:
@@ -611,6 +569,23 @@ with the following command:
 
        echo 'level <level>' > /proc/acpi/ibm/thermal
 
+EXPERIMENTAL: WAN -- /proc/acpi/ibm/wan
+---------------------------------------
+
+This feature is marked EXPERIMENTAL because the implementation
+directly accesses hardware registers and may not work as expected. USE
+WITH CAUTION! To use this feature, you need to supply the
+experimental=1 parameter when loading the module.
+
+This feature shows the presence and current state of a WAN (Sierra
+Wireless EV-DO) device. If WAN is installed, the following commands can
+be used:
+
+       echo enable > /proc/acpi/ibm/wan
+       echo disable > /proc/acpi/ibm/wan
+
+It was tested on a Lenovo Thinkpad X60. It should probably work on other
+Thinkpad models which come with this module installed.
 
 Multiple Commands, Module Parameters
 ------------------------------------
index b9111a703ce0c37a8a3ad59cc442da283629a0b2..5427bdf225ed0392372ff6ce428dd1e68a2aab83 100644 (file)
@@ -3,20 +3,37 @@ xpad - Linux USB driver for X-Box gamepads
 This is the very first release of a driver for X-Box gamepads.
 Basically, this was hacked away in just a few hours, so don't expect
 miracles.
+
 In particular, there is currently NO support for the rumble pack.
 You won't find many ff-aware linux applications anyway.
 
 
-0. Status
----------
+0. Notes
+--------
+
+Driver updated for kernel 2.6.17.11. (Based on a patch for 2.6.11.4.)
 
-For now, this driver has only been tested on just one Linux-Box.
-This one is running a 2.4.18 kernel with usb-uhci on an amd athlon 600.
+The number of buttons/axes reported varies based on 3 things:
+- if you are using a known controller
+- if you are using a known dance pad
+- if using an unknown device (one not listed below), what you set in the
+  module configuration for "Map D-PAD to buttons rather than axes for unknown
+  pads" (module option dpad_to_buttons)
 
-The jstest-program from joystick-1.2.15 (jstest-version 2.1.0) reports
-8 axes and 10 buttons.
+If you set dpad_to_buttons to 0 and you are using an unknown device (one
+not listed below), the driver will map the directional pad to axes (X/Y),
+if you said N it will map the d-pad to buttons, which is needed for dance
+style games to function correctly.  The default is Y.
+
+dpad_to_buttons has no effect for known pads.
+
+0.1 Normal Controllers
+----------------------
+With a normal controller, the directional pad is mapped to its own X/Y axes.
+The jstest-program from joystick-1.2.15 (jstest-version 2.1.0) will report 8
+axes and 10 buttons.
 
-Alls 8 axes work, though they all have the same range (-32768..32767)
+All 8 axes work, though they all have the same range (-32768..32767)
 and the zero-setting is not correct for the triggers (I don't know if that
 is some limitation of jstest, since the input device setup should be fine. I
 didn't have a look at jstest itself yet).
@@ -30,16 +47,50 @@ in game functionality were OK. However, I find it rather difficult to
 play first person shooters with a pad. Your mileage may vary.
 
 
+0.2 Xbox Dance Pads
+-------------------
+When using a known dance pad, jstest will report 6 axes and 14 buttons.
+
+For dance style pads (like the redoctane pad) several changes
+have been made.  The old driver would map the d-pad to axes, resulting
+in the driver being unable to report when the user was pressing both
+left+right or up+down, making DDR style games unplayable.
+
+Known dance pads automatically map the d-pad to buttons and will work
+correctly out of the box.
+
+If your dance pad is recognized by the driver but is using axes instead
+of buttons, see section 0.3 - Unknown Controllers
+
+I've tested this with Stepmania, and it works quite well.
+
+
+0.3 Unkown Controllers
+----------------------
+If you have an unkown xbox controller, it should work just fine with
+the default settings.
+
+HOWEVER if you have an unknown dance pad not listed below, it will not
+work UNLESS you set "dpad_to_buttons" to 1 in the module configuration.
+
+PLEASE if you have an unkown controller, email Dom <binary1230@yahoo.com> with
+a dump from /proc/bus/usb and a description of the pad (manufacturer, country,
+whether it is a dance pad or normal controller) so that we can add your pad
+to the list of supported devices, ensuring that it will work out of the
+box in the future.
+
+
 1. USB adapter
 --------------
 
 Before you can actually use the driver, you need to get yourself an
-adapter cable to connect the X-Box controller to your Linux-Box.
+adapter cable to connect the X-Box controller to your Linux-Box. You
+can buy these online fairly cheap, or build your own.
 
-Such a cable is pretty easy to build. The Controller itself is a USB compound
-device (a hub with three ports for two expansion slots and the controller
-device) with the only difference in a nonstandard connector (5 pins vs. 4 on
-standard USB connector).
+Such a cable is pretty easy to build. The Controller itself is a USB
+compound device (a hub with three ports for two expansion slots and
+the controller device) with the only difference in a nonstandard connector
+(5 pins vs. 4 on standard USB connector).
 
 You just need to solder a USB connector onto the cable and keep the
 yellow wire unconnected. The other pins have the same order on both
@@ -51,36 +102,36 @@ original one. You can buy an extension cable and cut that instead. That way,
 you can still use the controller with your X-Box, if you have one ;)
 
 
-2. driver installation
+2. Driver Installation
 ----------------------
 
 Once you have the adapter cable and the controller is connected, you need
 to load your USB subsystem and should cat /proc/bus/usb/devices.
 There should be an entry like the one at the end [4].
 
-Currently (as of version 0.0.4), the following three devices are included:
+Currently (as of version 0.0.6), the following devices are included:
  original Microsoft XBOX controller (US), vendor=0x045e, product=0x0202
+ smaller  Microsoft XBOX controller (US), vendor=0x045e, product=0x0289
  original Microsoft XBOX controller (Japan), vendor=0x045e, product=0x0285
  InterAct PowerPad Pro (Germany), vendor=0x05fd, product=0x107a
+ RedOctane Xbox Dance Pad (US), vendor=0x0c12, product=0x8809
 
-If you have another controller that is not listed above and is not recognized
-by the driver, please drop me a line with the appropriate info (that is, include
-the name, vendor and product ID, as well as the country where you bought it;
-sending the whole dump out of /proc/bus/usb/devices along would be even better).
+The driver should work with xbox pads not listed above as well, however
+you will need to do something extra for dance pads to work.
 
-In theory, the driver should work with other controllers than mine
-(InterAct PowerPad pro, bought in Germany) just fine, but I cannot test this
-for I only have this one controller.
+If you have a controller not listed above, see 0.3 - Unknown Controllers
 
 If you compiled and installed the driver, test the functionality:
 > modprobe xpad
 > modprobe joydev
 > jstest /dev/js0
 
-There should be a single line showing 18 inputs (8 axes, 10 buttons), and
-it's values should change if you move the sticks and push the buttons.
+If you're using a normal controller, there should be a single line showing
+18 inputs (8 axes, 10 buttons), and its values should change if you move
+the sticks and push the buttons.  If you're using a dance pad, it should
+show 20 inputs (6 axes, 14 buttons).
 
-It works? Voila, your done ;)
+It works? Voila, you're done ;)
 
 
 3. Thanks
@@ -111,6 +162,22 @@ I:  If#= 0 Alt= 0 #EPs= 2 Cls=58(unk. ) Sub=42 Prot=00 Driver=(none)
 E:  Ad=81(I) Atr=03(Int.) MxPS=  32 Ivl= 10ms
 E:  Ad=02(O) Atr=03(Int.) MxPS=  32 Ivl= 10ms
 
+5. /proc/bus/usb/devices - dump from Redoctane Xbox Dance Pad (US):
+
+T:  Bus=01 Lev=02 Prnt=09 Port=00 Cnt=01 Dev#= 10 Spd=12  MxCh= 0
+D:  Ver= 1.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs=  1
+P:  Vendor=0c12 ProdID=8809 Rev= 0.01
+S:  Product=XBOX DDR
+C:* #Ifs= 1 Cfg#= 1 Atr=80 MxPwr=100mA
+I:  If#= 0 Alt= 0 #EPs= 2 Cls=58(unk. ) Sub=42 Prot=00 Driver=xpad
+E:  Ad=82(I) Atr=03(Int.) MxPS=  32 Ivl=4ms
+E:  Ad=02(O) Atr=03(Int.) MxPS=  32 Ivl=4ms
+
 -- 
 Marko Friedemann <mfr@bmx-chemnitz.de>
 2002-07-16
+ - original doc
+
+Dominic Cerquetti <binary1230@yahoo.com>
+2005-03-19
+ - added stuff for dance pads, new d-pad->axes mappings
index ff571f9298e0530bb38d3ffdaabea01f1b4aec17..dd00fd556a60abad15662319d5c46fd0f166b26a 100644 (file)
@@ -1231,6 +1231,11 @@ and is between 256 and 4096 characters. It is defined in the file
                                machine check when some devices' config space
                                is read. But various workarounds are disabled
                                and some IOMMU drivers will not work.
+               bfsort          Sort PCI devices into breadth-first order.
+                               This sorting is done to get a device
+                               order compatible with older (<= 2.4) kernels.
+               nobfsort        Don't sort PCI devices into breadth-first order.
+
        pcmv=           [HW,PCMCIA] BadgePAD 4
 
        pd.             [PARIDE]
index dab123db5a4fed62b324b9ffe2624fc04c0b5846..488773018152056ea159685e732e42452a7ae142 100644 (file)
@@ -50,10 +50,10 @@ The bit position indicates hardirq, softirq, hardirq-read,
 softirq-read respectively, and the character displayed in each
 indicates:
 
-   '.'  acquired while irqs enabled
+   '.'  acquired while irqs disabled
    '+'  acquired in irq context
-   '-'  acquired in process context with irqs disabled
-   '?'  read-acquired both with irqs enabled and in irq context
+   '-'  acquired with irqs enabled
+   '?' read acquired in irq context with irqs enabled.
 
 Unused mutexes cannot be part of the cause of an error.
 
index 994355b0cd19087654d8cab690597944ed633a0a..7f790f66ec68528776852d15a3f60ab60dcd94b6 100644 (file)
@@ -1898,7 +1898,7 @@ queue before processing any further requests:
        smp_wmb();
        <A:modify v=2>  <C:busy>
                        <C:queue v=2>
-       p = &b;         q = p;
+       p = &v;         q = p;
                        <D:request p>
        <B:modify p=&v> <D:commit p=&v>
                        <D:read p>
index 69ddc5c14b7990592a1710957985fd9b6e01369b..e1304b6bc48349d518472ce94e37b581ec03d521 100644 (file)
@@ -63,7 +63,7 @@ the following functions or values:
   a) board_time_init - a function pointer.  Invoked at the beginnig of
      time_init().  It is optional.
        1. (optional) set up RTC routines
-       2. (optional) calibrate and set the mips_counter_frequency
+       2. (optional) calibrate and set the mips_hpt_frequency
 
   b) plat_timer_setup - a function pointer.  Invoked at the end of time_init()
        1. (optional) over-ride any decisions made in time_init()
@@ -72,7 +72,7 @@ the following functions or values:
 
   c) (optional) board-specific RTC routines.
 
-  d) (optional) mips_counter_frequency - It must be definied if the board
+  d) (optional) mips_hpt_frequency - It must be definied if the board
      is using CPU counter for timer interrupt or it is using fixed rate
      gettimeoffset().
 
@@ -104,7 +104,7 @@ Step 1: decide how you like to implement the time services.
      or use an exnternal timer?
 
      In order to use CPU counter register as the timer interrupt source, you
-     must know the counter speed (mips_counter_frequency).  It is usually the
+     must know the counter speed (mips_hpt_frequency).  It is usually the
      same as the CPU speed or an integral divisor of it.
 
   d) decide on whether you want to use high-level or low-level timer
@@ -121,8 +121,8 @@ Step 3: implement rtc routines, board_time_init() and plat_timer_setup()
   if needed.
 
   board_time_init() -
-       a) (optional) set up RTC routines, 
-        b) (optional) calibrate and set the mips_counter_frequency
+       a) (optional) set up RTC routines,
+        b) (optional) calibrate and set the mips_hpt_frequency
            (only needed if you intended to use fixed_rate_gettimeoffset
             or use cpu counter as timer interrupt source)
 
index 59d1166d41eeebc095528a84a24fa584ea0c953d..d684a6ac69a8ec2b8e06016f31e23bef2faf5130 100644 (file)
@@ -66,7 +66,7 @@ Command line parameters
 
   When a device is un-ignored, device recognition and sensing is performed and 
   the device driver will be notified if possible, so the device will become
-  available to the system.
+  available to the system. Note that un-ignoring is performed asynchronously.
 
   You can also add ranges of devices to be ignored by piping to 
   /proc/cio_ignore; "add <device range>, <device range>, ..." will ignore the
index d80e5733827d2ae0ac58a82f166baf08a7a7daef..32a96cc392151abf7e04f505069e5a6499c80860 100644 (file)
@@ -174,14 +174,10 @@ read_dev_chars() - Read Device Characteristics
 
 This routine returns the characteristics for the device specified.
 
-The function is meant to be called with an irq handler in place; that is,
+The function is meant to be called with the device already enabled; that is,
 at earliest during set_online() processing.
 
-While the request is processed synchronously, the device interrupt
-handler is called for final ending status. In case of error situations the
-interrupt handler may recover appropriately. The device irq handler can
-recognize the corresponding interrupts by the interruption parameter be
-0x00524443. The ccw_device must not be locked prior to calling read_dev_chars().
+The ccw_device must not be locked prior to calling read_dev_chars().
 
 The function may be called enabled or disabled.
 
@@ -410,26 +406,7 @@ individual flag meanings.
 
 Usage Notes :
 
-Prior to call ccw_device_start() the device driver must assure disabled state,
-i.e. the I/O mask value in the PSW must be disabled. This can be accomplished
-by calling local_save_flags( flags). The current PSW flags are preserved and
-can be restored by local_irq_restore( flags) at a later time.
-
-If the device driver violates this rule while running in a uni-processor
-environment an interrupt might be presented prior to the ccw_device_start()
-routine returning to the device driver main path. In this case we will end in a
-deadlock situation as the interrupt handler will try to obtain the irq
-lock the device driver still owns (see below) !
-
-The driver must assure to hold the device specific lock. This can be
-accomplished by
-
-(i)  spin_lock(get_ccwdev_lock(cdev)), or
-(ii) spin_lock_irqsave(get_ccwdev_lock(cdev), flags)
-
-Option (i) should be used if the calling routine is running disabled for
-I/O interrupts (see above) already. Option (ii) obtains the device gate und
-puts the CPU into I/O disabled state by preserving the current PSW flags.
+ccw_device_start() must be called disabled and with the ccw device lock held.
 
 The device driver is allowed to issue the next ccw_device_start() call from
 within its interrupt handler already. It is not required to schedule a
@@ -488,7 +465,7 @@ int ccw_device_resume(struct ccw_device *cdev);
 
 cdev - ccw_device the resume operation is requested for
 
-The resume_IO() function returns:
+The ccw_device_resume() function returns:
 
         0  - suspended channel program is resumed
 -EBUSY     - status pending
@@ -507,6 +484,8 @@ a long-running channel program or the device might require to initially issue
 a halt subchannel (HSCH) I/O command. For those purposes the ccw_device_halt()
 command is provided.
 
+ccw_device_halt() must be called disabled and with the ccw device lock held.
+
 int ccw_device_halt(struct ccw_device *cdev,
                     unsigned long intparm);
 
@@ -517,7 +496,7 @@ intparm : interruption parameter; value is only used if no I/O
 
 The ccw_device_halt() function returns :
 
-      0 - successful completion or request successfully initiated
+      0 - request successfully initiated
 -EBUSY  - the device is currently busy, or status pending.
 -ENODEV - cdev invalid.
 -EINVAL - The device is not operational or the ccw device is not online.
@@ -533,6 +512,23 @@ can then perform an appropriate action. Prior to interrupt of an outstanding
 read to a network device (with or without PCI flag) a ccw_device_halt()
 is required to end the pending operation.
 
+ccw_device_clear() - Terminage I/O Request Processing
+
+In order to terminate all I/O processing at the subchannel, the clear subchannel
+(CSCH) command is used. It can be issued via ccw_device_clear().
+
+ccw_device_clear() must be called disabled and with the ccw device lock held.
+
+int ccw_device_clear(struct ccw_device *cdev, unsigned long intparm);
+
+cdev:   ccw_device the clear operation is requested for
+intparm: interruption parameter (see ccw_device_halt())
+
+The ccw_device_clear() function returns:
+
+      0 - request successfully initiated
+-ENODEV - cdev invalid
+-EINVAL - The device is not operational or the ccw device is not online.
 
 Miscellaneous Support Routines
 
index 62c082387aea294ca627f9e0f9cd6514fb4c6983..77bf450ec39be579ae422916c569e2f31bf344a9 100644 (file)
@@ -239,6 +239,9 @@ status - Can be 'online' or 'offline'.
 
 type - The physical type of the channel path.
 
+shared - Whether the channel path is shared.
+
+cmg - The channel measurement group.
 
 3. System devices
 -----------------
index d9e5960dafd5b2fee860552edac5f92b4e3bec42..5eb92754499098eaddaec839cb5d913157837fd1 100644 (file)
@@ -1,4 +1,49 @@
 
+1 Release Date    : Mon Oct 02 11:21:32 PDT 2006 - Sumant Patro <Sumant.Patro@lsil.com>
+2 Current Version : 00.00.03.05
+3 Older Version   : 00.00.03.04
+
+i.     PCI_DEVICE macro used
+
+       Convert the pci_device_id-table of the megaraid_sas-driver to the PCI_DEVICE-macro, to safe some lines.
+
+               - Henrik Kretzschmar <henne@nachtwindheim.de>
+ii.    All compiler warnings removed
+iii.   megasas_ctrl_info struct reverted to 3.02 release
+iv.    Default value of megasas_dbg_lvl set to 0
+v.     Removing in megasas_exit the sysfs entry created for megasas_dbg_lvl
+vi.    In megasas_teardown_frame_pool(), cmd->frame was passed instead of
+       cmd->sense to pci_pool_free. Fixed. Bug was pointed out by
+       Eric Sesterhenn
+
+1 Release Date    : Wed Sep 13 14:22:51 PDT 2006 - Sumant Patro <Sumant.Patro@lsil.com>
+2 Current Version : 00.00.03.04
+3 Older Version   : 00.00.03.03
+
+i.     Added Reboot notify
+ii.    Reduced by 1 max cmds sent to FW from Driver to make the reply_q_sz same
+       as Max Cmds FW can support
+
+1 Release Date    : Tue Aug 22 16:33:14 PDT 2006 - Sumant Patro <Sumant.Patro@lsil.com>
+2 Current Version : 00.00.03.03
+3 Older Version   : 00.00.03.02
+
+i.     Send stop adapter to FW & Dump pending FW cmds before declaring adapter dead.
+       New varible added to set dbg level.
+ii.    Disable interrupt made as fn pointer as they are different for 1068 / 1078
+iii.   Frame count optimization. Main frame can contain 2 SGE for 64 bit SGLs and
+       3 SGE for 32 bit SGL
+iv.    Tasklet added for cmd completion
+v.     If FW in operational state before firing INIT, now we send RESET Flag to FW instead of just READY. This is used to do soft reset.
+vi.    megasas_ctrl_prop structure updated (based on FW struct)
+vii.   Added print : FW now in Ready State during initialization
+
+1 Release Date    : Sun Aug 06 22:49:52 PDT 2006 - Sumant Patro <Sumant.Patro@lsil.com>
+2 Current Version : 00.00.03.02
+3 Older Version   : 00.00.03.01
+
+i.     Added FW tranistion state for Hotplug scenario
+
 1 Release Date    : Sun May 14 22:49:52 PDT 2006 - Sumant Patro <Sumant.Patro@lsil.com>
 2 Current Version : 00.00.03.01
 3 Older Version   : 00.00.02.04
index 89bf8c20a5860787bc27fc2a5836fd5e0833a051..0bc7f1e3c9e6aa2e340bec8f512684351630fc9f 100644 (file)
@@ -86,7 +86,7 @@ valid for 30 seconds.
 core_pattern:
 
 core_pattern is used to specify a core dumpfile pattern name.
-. max length 64 characters; default value is "core"
+. max length 128 characters; default value is "core"
 . core_pattern is used as a pattern template for the output filename;
   certain string patterns (beginning with '%') are substituted with
   their actual values.
@@ -105,6 +105,9 @@ core_pattern is used to specify a core dumpfile pattern name.
        %h      hostname
        %e      executable filename
        %<OTHER> both are dropped
+. If the first character of the pattern is a '|', the kernel will treat
+  the rest of the pattern as a command to run.  The core dump will be
+  written to the standard input of that program instead of to a file.
 
 ==============================================================
 
index 126e59d935cd2348f162fc06aefe2538478584c4..8755b3e7b09e500446d99800e8abc90df96c2b85 100644 (file)
@@ -51,7 +51,7 @@
  50 -> NPG Tech Real TV FM Top 10                          [14f1:0842]
  51 -> WinFast DTV2000 H                                   [107d:665e]
  52 -> Geniatech DVB-S                                     [14f1:0084]
- 53 -> Hauppauge WinTV-HVR3000 TriMode Analog/DVB-S/DVB-T  [0070:1404]
+ 53 -> Hauppauge WinTV-HVR3000 TriMode Analog/DVB-S/DVB-T  [0070:1404,0070:1400,0070:1401,0070:1402]
  54 -> Norwood Micro TV Tuner
  55 -> Shenzhen Tungsten Ages Tech TE-DTV-250 / Swann OEM  [c180:c980]
  56 -> Hauppauge WinTV-HVR1300 DVB-T/Hybrid MPEG Encoder   [0070:9600,0070:9601,0070:9602]
index 17becb9b1a96b5ea066f8caa82e34914bd188051..d708702aba2f292b83bc62fb20274d18f3389716 100644 (file)
@@ -641,7 +641,7 @@ CALGARY x86-64 IOMMU
 P:     Muli Ben-Yehuda
 M:     muli@il.ibm.com
 P:     Jon D. Mason
-M:     jdmason@us.ibm.com
+M:     jdmason@kudzu.us
 L:     linux-kernel@vger.kernel.org
 L:     discuss@x86-64.org
 S:     Maintained
@@ -905,7 +905,8 @@ P:  David Teigland
 M:     teigland@redhat.com
 L:     cluster-devel@redhat.com
 W:     http://sources.redhat.com/cluster/
-T:     git kernel.org:/pub/scm/linux/kernel/git/steve/gfs-2.6.git
+T:     git kernel.org:/pub/scm/linux/kernel/git/steve/gfs2-2.6-fixes.git
+T:     git kernel.org:/pub/scm/linux/kernel/git/steve/gfs2-2.6-nmw.git
 S:     Supported
 
 DAVICOM FAST ETHERNET (DMFE) NETWORK DRIVER
@@ -1188,7 +1189,8 @@ P:        Steven Whitehouse
 M:     swhiteho@redhat.com
 L:     cluster-devel@redhat.com
 W:     http://sources.redhat.com/cluster/
-T:     git kernel.org:/pub/scm/linux/kernel/git/steve/gfs-2.6.git
+T:     git kernel.org:/pub/scm/linux/kernel/git/steve/gfs2-2.6-fixes.git
+T:     git kernel.org:/pub/scm/linux/kernel/git/steve/gfs2-2.6-nmw.git
 S:     Supported
 
 GIGASET ISDN DRIVERS
@@ -1666,6 +1668,12 @@ M:       sct@redhat.com, akpm@osdl.org
 L:     ext2-devel@lists.sourceforge.net
 S:     Maintained
 
+K8TEMP HARDWARE MONITORING DRIVER
+P:     Rudolf Marek
+M:     r.marek@assembler.cz
+L:     lm-sensors@lm-sensors.org
+S:     Maintained
+
 KCONFIG
 P:     Roman Zippel
 M:     zippel@linux-m68k.org
@@ -1996,6 +2004,13 @@ M:       rubini@ipvvis.unipv.it
 L:     linux-kernel@vger.kernel.org
 S:     Maintained
 
+MSI LAPTOP SUPPORT
+P:     Lennart Poettering
+M:     mzxreary@0pointer.de
+L:     https://tango.0pointer.de/mailman/listinfo/s270-linux
+W:     http://0pointer.de/lennart/tchibo.html
+S:     Maintained
+
 MTRR AND SIMILAR SUPPORT [i386]
 P:     Richard Gooch
 M:     rgooch@atnf.csiro.au
@@ -2003,8 +2018,11 @@ L:       linux-kernel@vger.kernel.org
 W:     http://www.atnf.csiro.au/~rgooch/linux/kernel-patches.html
 S:     Maintained
 
-MULTIMEDIA CARD (MMC) SUBSYSTEM
-S:     Orphan
+MULTIMEDIA CARD (MMC) AND SECURE DIGITAL (SD) SUBSYSTEM
+P:     Pierre Ossman
+M:     drzeus-mmc@drzeus.cx
+L:     linux-kernel@vger.kernel.org
+S:     Maintained
 
 MULTISOUND SOUND DRIVER
 P:     Andrew Veliath
@@ -2040,11 +2058,13 @@ P:      Marc Boucher
 P:     James Morris
 P:     Harald Welte
 P:     Jozsef Kadlecsik
-M:     coreteam@netfilter.org
+P:     Patrick McHardy
+M:     kaber@trash.net
+L:     netfilter-devel@lists.netfilter.org
+L:     netfilter@lists.netfilter.org
+L:     coreteam@netfilter.org
 W:     http://www.netfilter.org/
 W:     http://www.iptables.org/
-L:     netfilter@lists.netfilter.org
-L:     netfilter-devel@lists.netfilter.org
 S:     Supported
 
 NETLABEL
@@ -2261,6 +2281,17 @@ T:       git kernel.org:/pub/scm/linux/kernel/git/kyle/parisc-2.6.git
 T:     cvs cvs.parisc-linux.org:/var/cvs/linux-2.6
 S:     Maintained
 
+PC87360 HARDWARE MONITORING DRIVER
+P:     Jim Cromie
+M:     jim.cromie@gmail.com
+L:     lm-sensors@lm-sensors.org
+S:     Maintained
+
+PC8736x GPIO DRIVER
+P:     Jim Cromie
+M:     jim.cromie@gmail.com
+S:     Maintained
+
 PCI ERROR RECOVERY
 P:     Linas Vepstas
 M:     linas@austin.ibm.com
@@ -2284,8 +2315,8 @@ T:        quilt kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/
 S:     Supported
 
 PCI HOTPLUG CORE
-P:     Greg Kroah-Hartman
-M:     gregkh@suse.de
+P:     Kristen Carlson Accardi
+M:     kristen.c.accardi@intel.com
 S:     Supported
 
 PCI HOTPLUG COMPAQ DRIVER
@@ -2592,10 +2623,19 @@ L: lksctp-developers@lists.sourceforge.net
 S: Supported
 
 SCx200 CPU SUPPORT
-P:     Christer Weinigel
-M:     christer@weinigel.se
-W:     http://www.weinigel.se
-S:     Supported
+P:     Jim Cromie
+M:     jim.cromie@gmail.com
+S:     Odd Fixes
+
+SCx200 GPIO DRIVER
+P:     Jim Cromie
+M:     jim.cromie@gmail.com
+S:     Maintained
+
+SCx200 HRT CLOCKSOURCE DRIVER
+P:     Jim Cromie
+M:     jim.cromie@gmail.com
+S:     Maintained
 
 SECURITY CONTACT
 P:     Security Officers
@@ -2760,14 +2800,7 @@ S:       Maintained
 UltraSPARC (sparc64):
 P:     David S. Miller
 M:     davem@davemloft.net
-P:     Eddie C. Dost
-M:     ecd@brainaid.de
-P:     Jakub Jelinek
-M:     jj@sunsite.ms.mff.cuni.cz
-P:     Anton Blanchard
-M:     anton@samba.org
 L:     sparclinux@vger.kernel.org
-L:     ultralinux@vger.kernel.org
 T:     git kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6.git
 S:     Maintained
 
index adb2c748e105609e2f37b91318e87c90bb189961..389ff0cca9a7f3e0f3a5c8dba0c8f6539e79763c 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 6
-SUBLEVEL = 18
-EXTRAVERSION =
+SUBLEVEL = 19
+EXTRAVERSION =-rc2
 NAME=Avast! A bilge rat!
 
 # *DOCUMENTATION*
@@ -499,6 +499,7 @@ endif
 
 ifdef CONFIG_UNWIND_INFO
 CFLAGS         += -fasynchronous-unwind-tables
+LDFLAGS_vmlinux        += --eh-frame-hdr
 endif
 
 ifdef CONFIG_DEBUG_INFO
@@ -741,6 +742,9 @@ endif # ifdef CONFIG_KALLSYMS
 
 # vmlinux image - including updated kernel symbols
 vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) $(kallsyms.o) FORCE
+ifdef CONFIG_HEADERS_CHECK
+       $(Q)$(MAKE) -f $(srctree)/Makefile headers_check
+endif
        $(call if_changed_rule,vmlinux__)
        $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost $@
        $(Q)rm -f .old_version
@@ -932,7 +936,7 @@ headers_install_all: include/linux/version.h scripts_basic FORCE
 
 PHONY += headers_install
 headers_install: include/linux/version.h scripts_basic FORCE
-       @if [ ! -r include/asm-$(ARCH)/Kbuild ]; then \
+       @if [ ! -r $(srctree)/include/asm-$(ARCH)/Kbuild ]; then \
          echo '*** Error: Headers not exportable for this architecture ($(ARCH))'; \
          exit 1 ; fi
        $(Q)$(MAKE) $(build)=scripts scripts/unifdef
@@ -1316,7 +1320,8 @@ define xtags
            $(all-sources) | xargs $1 -a \
                -I __initdata,__exitdata,__acquires,__releases \
                -I EXPORT_SYMBOL,EXPORT_SYMBOL_GPL \
-               --extra=+f --c-kinds=+px; \
+               --extra=+f --c-kinds=+px \
+               --regex-asm='/ENTRY\(([^)]*)\).*/\1/'; \
            $(all-kconfigs) | xargs $1 -a \
                --langdef=kconfig \
                --language-force=kconfig \
index 8b02420f732eb8e1df10db233b2444d9881470b7..e9762a33b0439b3d70d451954f3bc790c40cb0f2 100644 (file)
@@ -6,40 +6,13 @@
  */
 
 #include <linux/module.h>
-#include <linux/string.h>
-#include <linux/user.h>
-#include <linux/elfcore.h>
-#include <linux/socket.h>
-#include <linux/syscalls.h>
-#include <linux/in.h>
-#include <linux/in6.h>
-#include <linux/pci.h>
-#include <linux/screen_info.h>
-#include <linux/tty.h>
-#include <linux/mm.h>
-#include <linux/delay.h>
-#include <linux/dma-mapping.h>
-
-#include <asm/io.h>
 #include <asm/console.h>
-#include <asm/hwrpb.h>
 #include <asm/uaccess.h>
-#include <asm/processor.h>
 #include <asm/checksum.h>
-#include <linux/interrupt.h>
 #include <asm/fpu.h>
-#include <asm/irq.h>
 #include <asm/machvec.h>
-#include <asm/pgalloc.h>
-#include <asm/semaphore.h>
-#include <asm/tlbflush.h>
-#include <asm/cacheflush.h>
-#include <asm/vga.h>
 
-#include <asm/unistd.h>
-
-extern struct hwrpb_struct *hwrpb;
-extern spinlock_t rtc_lock;
+#include <linux/syscalls.h>
 
 /* these are C runtime functions with special calling conventions: */
 extern void __divl (void);
@@ -52,14 +25,9 @@ extern void __divqu (void);
 extern void __remqu (void);
 
 EXPORT_SYMBOL(alpha_mv);
-EXPORT_SYMBOL(screen_info);
-EXPORT_SYMBOL(perf_irq);
 EXPORT_SYMBOL(callback_getenv);
 EXPORT_SYMBOL(callback_setenv);
 EXPORT_SYMBOL(callback_save_env);
-#ifdef CONFIG_ALPHA_GENERIC
-EXPORT_SYMBOL(alpha_using_srm);
-#endif /* CONFIG_ALPHA_GENERIC */
 
 /* platform dependent support */
 EXPORT_SYMBOL(strcat);
@@ -77,47 +45,14 @@ EXPORT_SYMBOL(__constant_c_memset);
 EXPORT_SYMBOL(copy_page);
 EXPORT_SYMBOL(clear_page);
 
-EXPORT_SYMBOL(__direct_map_base);
-EXPORT_SYMBOL(__direct_map_size);
-
-#ifdef CONFIG_PCI
-EXPORT_SYMBOL(pci_alloc_consistent);
-EXPORT_SYMBOL(pci_free_consistent);
-EXPORT_SYMBOL(pci_map_single);
-EXPORT_SYMBOL(pci_map_page);
-EXPORT_SYMBOL(pci_unmap_single);
-EXPORT_SYMBOL(pci_unmap_page);
-EXPORT_SYMBOL(pci_map_sg);
-EXPORT_SYMBOL(pci_unmap_sg);
-EXPORT_SYMBOL(pci_dma_supported);
-EXPORT_SYMBOL(pci_dac_dma_supported);
-EXPORT_SYMBOL(pci_dac_page_to_dma);
-EXPORT_SYMBOL(pci_dac_dma_to_page);
-EXPORT_SYMBOL(pci_dac_dma_to_offset);
-EXPORT_SYMBOL(alpha_gendev_to_pci);
-#endif
-EXPORT_SYMBOL(dma_set_mask);
-
-EXPORT_SYMBOL(dump_thread);
-EXPORT_SYMBOL(dump_elf_thread);
-EXPORT_SYMBOL(dump_elf_task);
-EXPORT_SYMBOL(dump_elf_task_fp);
-EXPORT_SYMBOL(hwrpb);
-EXPORT_SYMBOL(start_thread);
 EXPORT_SYMBOL(alpha_read_fp_reg);
 EXPORT_SYMBOL(alpha_read_fp_reg_s);
 EXPORT_SYMBOL(alpha_write_fp_reg);
 EXPORT_SYMBOL(alpha_write_fp_reg_s);
 
-/* In-kernel system calls.  */
+/* entry.S */
 EXPORT_SYMBOL(kernel_thread);
-EXPORT_SYMBOL(sys_dup);
-EXPORT_SYMBOL(sys_exit);
-EXPORT_SYMBOL(sys_write);
-EXPORT_SYMBOL(sys_lseek);
 EXPORT_SYMBOL(kernel_execve);
-EXPORT_SYMBOL(sys_setsid);
-EXPORT_SYMBOL(sys_wait4);
 
 /* Networking helper routines. */
 EXPORT_SYMBOL(csum_tcpudp_magic);
@@ -134,10 +69,6 @@ EXPORT_SYMBOL(alpha_fp_emul_imprecise);
 EXPORT_SYMBOL(alpha_fp_emul);
 #endif
 
-#ifdef CONFIG_ALPHA_BROKEN_IRQ_MASK
-EXPORT_SYMBOL(__min_ipl);
-#endif
-
 /*
  * The following are specially called from the uaccess assembly stubs.
  */
@@ -160,26 +91,9 @@ EXPORT_SYMBOL(up);
  */
 
 #ifdef CONFIG_SMP
-EXPORT_SYMBOL(flush_tlb_mm);
-EXPORT_SYMBOL(flush_tlb_range);
-EXPORT_SYMBOL(flush_tlb_page);
-EXPORT_SYMBOL(smp_imb);
-EXPORT_SYMBOL(cpu_data);
-EXPORT_SYMBOL(smp_num_cpus);
-EXPORT_SYMBOL(smp_call_function);
-EXPORT_SYMBOL(smp_call_function_on_cpu);
 EXPORT_SYMBOL(_atomic_dec_and_lock);
 #endif /* CONFIG_SMP */
 
-/*
- * NUMA specific symbols
- */
-#ifdef CONFIG_DISCONTIGMEM
-EXPORT_SYMBOL(node_data);
-#endif /* CONFIG_DISCONTIGMEM */
-
-EXPORT_SYMBOL(rtc_lock);
-
 /*
  * The following are special because they're not called
  * explicitly (the C compiler or assembler generates them in
@@ -200,8 +114,3 @@ EXPORT_SYMBOL(__remqu);
 EXPORT_SYMBOL(memcpy);
 EXPORT_SYMBOL(memset);
 EXPORT_SYMBOL(memchr);
-
-#ifdef CONFIG_ALPHA_IRONGATE
-EXPORT_SYMBOL(irongate_ioremap);
-EXPORT_SYMBOL(irongate_iounmap);
-#endif
index a27ba12ba35ec6b935d8974320d1f4c2e7067391..ca46b2c2445756bfc84cfd87ee5fe58226c6bec0 100644 (file)
@@ -387,8 +387,7 @@ apecs_pci_clr_err(void)
 }
 
 void
-apecs_machine_check(unsigned long vector, unsigned long la_ptr,
-                   struct pt_regs * regs)
+apecs_machine_check(unsigned long vector, unsigned long la_ptr)
 {
        struct el_common *mchk_header;
        struct el_apecs_procdata *mchk_procdata;
@@ -412,7 +411,7 @@ apecs_machine_check(unsigned long vector, unsigned long la_ptr,
        wrmces(0x7);            /* reset machine check pending flag */
        mb();
 
-       process_mcheck_info(vector, la_ptr, regs, "APECS",
+       process_mcheck_info(vector, la_ptr, "APECS",
                            (mcheck_expected(0)
                             && (mchk_sysdata->epic_dcsr & 0x0c00UL)));
 }
index fd563064363c43b3c56168efeee595320f438e08..1d6ee6c985f940992db550fdb5595945c6597611 100644 (file)
@@ -1192,8 +1192,7 @@ cia_decode_mchk(unsigned long la_ptr)
 }
 
 void
-cia_machine_check(unsigned long vector, unsigned long la_ptr,
-                 struct pt_regs * regs)
+cia_machine_check(unsigned long vector, unsigned long la_ptr)
 {
        int expected;
 
@@ -1208,5 +1207,5 @@ cia_machine_check(unsigned long vector, unsigned long la_ptr,
        expected = mcheck_expected(0);
        if (!expected && vector == 0x660)
                expected = cia_decode_mchk(la_ptr);
-       process_mcheck_info(vector, la_ptr, regs, "CIA", expected);
+       process_mcheck_info(vector, la_ptr, "CIA", expected);
 }
index 138d497d1cca8b37e4b043776cf28d784cff0ce4..e4a0bcf1d28b6834492808c0cf52b4681e3b0182 100644 (file)
@@ -404,6 +404,7 @@ irongate_ioremap(unsigned long addr, unsigned long size)
 #endif
        return (void __iomem *)vaddr;
 }
+EXPORT_SYMBOL(irongate_ioremap);
 
 void
 irongate_iounmap(volatile void __iomem *xaddr)
@@ -414,3 +415,4 @@ irongate_iounmap(volatile void __iomem *xaddr)
        if (addr)
                return vfree((void *)(PAGE_MASK & addr)); 
 }
+EXPORT_SYMBOL(irongate_iounmap);
index 6a5a9145c676023950701041f92fbbc2b14f0cad..4843f6ec9f3a1c1f92ac83a31ef89f3a90d0a1b1 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/tty.h>
 
 #include <asm/ptrace.h>
+#include <asm/irq_regs.h>
 #include <asm/smp.h>
 
 #include "proto.h"
@@ -386,8 +387,7 @@ ioc_error(__u32 stat0, __u32 stat1)
 }
 
 void
-lca_machine_check(unsigned long vector, unsigned long la_ptr,
-                 struct pt_regs *regs)
+lca_machine_check(unsigned long vector, unsigned long la_ptr)
 {
        const char * reason;
        union el_lca el;
@@ -397,7 +397,7 @@ lca_machine_check(unsigned long vector, unsigned long la_ptr,
        wrmces(rdmces());       /* reset machine check pending flag */
 
        printk(KERN_CRIT "LCA machine check: vector=%#lx pc=%#lx code=%#x\n",
-              vector, regs->pc, (unsigned int) el.c->code);
+              vector, get_irq_regs()->pc, (unsigned int) el.c->code);
 
        /*
         * The first quadword after the common header always seems to
index 28849c8941539d9b555ecdb4a8d19c0dec472c99..8d019071190a4bf45ecd42397a0afc38ee2be45f 100644 (file)
@@ -572,8 +572,7 @@ mcpcia_print_system_area(unsigned long la_ptr)
 }
 
 void
-mcpcia_machine_check(unsigned long vector, unsigned long la_ptr,
-                    struct pt_regs * regs)
+mcpcia_machine_check(unsigned long vector, unsigned long la_ptr)
 {
        struct el_common *mchk_header;
        struct el_MCPCIA_uncorrected_frame_mcheck *mchk_logout;
@@ -610,7 +609,7 @@ mcpcia_machine_check(unsigned long vector, unsigned long la_ptr,
        wrmces(0x7);
        mb();
 
-       process_mcheck_info(vector, la_ptr, regs, "MCPCIA", expected != 0);
+       process_mcheck_info(vector, la_ptr, "MCPCIA", expected != 0);
        if (!expected && vector != 0x620 && vector != 0x630) {
                mcpcia_print_uncorrectable(mchk_logout);
                mcpcia_print_system_area(la_ptr);
index 277674a500ff448ee3e5be999fbc1b055313f307..c5a271d37abd734b248e669b506d886844ab1791 100644 (file)
@@ -187,8 +187,7 @@ polaris_pci_clr_err(void)
 }
 
 void
-polaris_machine_check(unsigned long vector, unsigned long la_ptr,
-                     struct pt_regs * regs)
+polaris_machine_check(unsigned long vector, unsigned long la_ptr)
 {
        /* Clear the error before any reporting.  */
        mb();
@@ -198,6 +197,6 @@ polaris_machine_check(unsigned long vector, unsigned long la_ptr,
        wrmces(0x7);
        mb();
 
-       process_mcheck_info(vector, la_ptr, regs, "POLARIS",
+       process_mcheck_info(vector, la_ptr, "POLARIS",
                            mcheck_expected(0));
 }
index ecce09e3626a190c8511748b4cf6be7093b699ff..f5ca5255eb060ad822fff8358b4557ced9e11d2e 100644 (file)
@@ -551,8 +551,7 @@ t2_clear_errors(int cpu)
  * Hence all the taken/expected/any_expected/last_taken stuff...
  */
 void
-t2_machine_check(unsigned long vector, unsigned long la_ptr,
-                struct pt_regs * regs)
+t2_machine_check(unsigned long vector, unsigned long la_ptr)
 {
        int cpu = smp_processor_id();
 #ifdef CONFIG_VERBOSE_MCHECK
@@ -618,5 +617,5 @@ t2_machine_check(unsigned long vector, unsigned long la_ptr,
        }
 #endif
 
-       process_mcheck_info(vector, la_ptr, regs, "T2", mcheck_expected(cpu));
+       process_mcheck_info(vector, la_ptr, "T2", mcheck_expected(cpu));
 }
index 8aa305bd6a2c88896da40027e19316546370ea66..ce623c6e55e1c9c30d1521a95309496273a2889f 100644 (file)
@@ -443,8 +443,7 @@ tsunami_pci_clr_err(void)
 }
 
 void
-tsunami_machine_check(unsigned long vector, unsigned long la_ptr,
-                     struct pt_regs * regs)
+tsunami_machine_check(unsigned long vector, unsigned long la_ptr)
 {
        /* Clear error before any reporting.  */
        mb();
@@ -454,6 +453,6 @@ tsunami_machine_check(unsigned long vector, unsigned long la_ptr,
        wrmces(0x7);
        mb();
 
-       process_mcheck_info(vector, la_ptr, regs, "TSUNAMI",
+       process_mcheck_info(vector, la_ptr, "TSUNAMI",
                            mcheck_expected(smp_processor_id()));
 }
index 2b767a1bad962774def0b111553ed67bfd719a80..7e072443d7fdecdf9e8adc0eb85be4c1f1b24dee 100644 (file)
@@ -322,8 +322,7 @@ wildfire_init_arch(void)
 }
 
 void
-wildfire_machine_check(unsigned long vector, unsigned long la_ptr,
-                      struct pt_regs * regs)
+wildfire_machine_check(unsigned long vector, unsigned long la_ptr)
 {
        mb();
        mb();  /* magic */
@@ -332,7 +331,7 @@ wildfire_machine_check(unsigned long vector, unsigned long la_ptr,
        wrmces(0x7);
        mb();
 
-       process_mcheck_info(vector, la_ptr, regs, "WILDFIRE",
+       process_mcheck_info(vector, la_ptr, "WILDFIRE",
                            mcheck_expected(smp_processor_id()));
 }
 
index 64f59f2fcf5cc8aa8f5659158e77f9efb6281c64..69b5f4ea735531903f2af37d747361f00a6356df 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/sched.h>
 
 #include <asm/io.h>
+#include <asm/irq_regs.h>
 #include <asm/hwrpb.h>
 #include <asm/smp.h>
 #include <asm/err_common.h>
@@ -229,7 +230,7 @@ ev6_process_logout_frame(struct el_common *mchk_header, int print)
 }
 
 void
-ev6_machine_check(u64 vector, u64 la_ptr, struct pt_regs *regs)
+ev6_machine_check(u64 vector, u64 la_ptr)
 {
        struct el_common *mchk_header = (struct el_common *)la_ptr;
 
@@ -260,7 +261,7 @@ ev6_machine_check(u64 vector, u64 la_ptr, struct pt_regs *regs)
                       (unsigned int)vector, (int)smp_processor_id());
                
                ev6_process_logout_frame(mchk_header, 1);
-               dik_show_regs(regs, NULL);
+               dik_show_regs(get_irq_regs(), NULL);
 
                err_print_prefix = saved_err_prefix;
        }
index fed6b3d1b80364675b65c3b8220a834801868828..95463ab1cf358aebd5df0b9a4f5839ee79cbb182 100644 (file)
@@ -118,7 +118,7 @@ ev7_collect_logout_frame_subpackets(struct el_subpacket *el_ptr,
 }
 
 void
-ev7_machine_check(u64 vector, u64 la_ptr, struct pt_regs *regs)
+ev7_machine_check(u64 vector, u64 la_ptr)
 {
        struct el_subpacket *el_ptr = (struct el_subpacket *)la_ptr;
        char *saved_err_prefix = err_print_prefix;
index 64e9b73809fa5a2627a72cd86d3833ecafda78f8..3c12258158e67f0f8b4afdd8ecdb5d1139c59e30 100644 (file)
@@ -60,26 +60,26 @@ extern struct ev7_lf_subpackets *
 ev7_collect_logout_frame_subpackets(struct el_subpacket *,
                                    struct ev7_lf_subpackets *);
 extern void ev7_register_error_handlers(void);
-extern void ev7_machine_check(u64, u64, struct pt_regs *);
+extern void ev7_machine_check(u64, u64);
 
 /*
  * err_ev6.c
  */
 extern void ev6_register_error_handlers(void);
 extern int ev6_process_logout_frame(struct el_common *, int);
-extern void ev6_machine_check(u64, u64, struct pt_regs *);
+extern void ev6_machine_check(u64, u64);
 
 /*
  * err_marvel.c
  */
-extern void marvel_machine_check(u64, u64, struct pt_regs *);
+extern void marvel_machine_check(u64, u64);
 extern void marvel_register_error_handlers(void);
 
 /*
  * err_titan.c
  */
 extern int titan_process_logout_frame(struct el_common *, int);
-extern void titan_machine_check(u64, u64, struct pt_regs *);
+extern void titan_machine_check(u64, u64);
 extern void titan_register_error_handlers(void);
 extern int privateer_process_logout_frame(struct el_common *, int);
-extern void privateer_machine_check(u64, u64, struct pt_regs *);
+extern void privateer_machine_check(u64, u64);
index 70b38b1d2af3b3005036cc9b60403bd42c7b7768..f2956ac8dccc775f60f866a24eadae130333e5fe 100644 (file)
@@ -1042,7 +1042,7 @@ marvel_process_logout_frame(struct ev7_lf_subpackets *lf_subpackets, int print)
 }
 
 void
-marvel_machine_check(u64 vector, u64 la_ptr, struct pt_regs *regs)
+marvel_machine_check(u64 vector, u64 la_ptr)
 {
        struct el_subpacket *el_ptr = (struct el_subpacket *)la_ptr;
        int (*process_frame)(struct ev7_lf_subpackets *, int) = NULL;
@@ -1077,7 +1077,7 @@ marvel_machine_check(u64 vector, u64 la_ptr, struct pt_regs *regs)
 
        default:
                /* Don't know it - pass it up.  */
-               ev7_machine_check(vector, la_ptr, regs);
+               ev7_machine_check(vector, la_ptr);
                return;
        }       
 
index 7e6720d45f027cb5a62e7d0dcb3632197f56e54d..febe71c6869fae5b8f7baea4751611c026d596c4 100644 (file)
@@ -379,7 +379,7 @@ titan_process_logout_frame(struct el_common *mchk_header, int print)
 }
 
 void
-titan_machine_check(u64 vector, u64 la_ptr, struct pt_regs *regs)
+titan_machine_check(u64 vector, u64 la_ptr)
 {
        struct el_common *mchk_header = (struct el_common *)la_ptr;
        struct el_TITAN_sysdata_mcheck *tmchk =
@@ -408,7 +408,7 @@ titan_machine_check(u64 vector, u64 la_ptr, struct pt_regs *regs)
         * Only handle system errors here 
         */
        if ((vector != SCB_Q_SYSMCHK) && (vector != SCB_Q_SYSERR)) {
-               ev6_machine_check(vector, la_ptr, regs);
+               ev6_machine_check(vector, la_ptr);
                return;
        }
 
@@ -442,7 +442,7 @@ titan_machine_check(u64 vector, u64 la_ptr, struct pt_regs *regs)
 #ifdef CONFIG_VERBOSE_MCHECK
                titan_process_logout_frame(mchk_header, alpha_verbose_mcheck);
                if (alpha_verbose_mcheck)
-                       dik_show_regs(regs, NULL);
+                       dik_show_regs(get_irq_regs(), NULL);
 #endif /* CONFIG_VERBOSE_MCHECK */
 
                err_print_prefix = saved_err_prefix;
@@ -452,7 +452,7 @@ titan_machine_check(u64 vector, u64 la_ptr, struct pt_regs *regs)
                 * machine checks to interrupts
                 */
                irqmask = tmchk->c_dirx & TITAN_MCHECK_INTERRUPT_MASK;
-               titan_dispatch_irqs(irqmask, regs);
+               titan_dispatch_irqs(irqmask);
        }       
 
 
@@ -701,7 +701,7 @@ privateer_process_logout_frame(struct el_common *mchk_header, int print)
 }
 
 void
-privateer_machine_check(u64 vector, u64 la_ptr, struct pt_regs *regs)
+privateer_machine_check(u64 vector, u64 la_ptr)
 {
        struct el_common *mchk_header = (struct el_common *)la_ptr;
        struct el_TITAN_sysdata_mcheck *tmchk =
@@ -723,7 +723,7 @@ privateer_machine_check(u64 vector, u64 la_ptr, struct pt_regs *regs)
         * Only handle system events here.
         */
        if (vector != SCB_Q_SYSEVENT) 
-               return titan_machine_check(vector, la_ptr, regs);
+               return titan_machine_check(vector, la_ptr);
 
        /*
         * Report the event - System Events should be reported even if no
@@ -746,7 +746,7 @@ privateer_machine_check(u64 vector, u64 la_ptr, struct pt_regs *regs)
        /*
         * Dispatch the interrupt(s).
         */
-       titan_dispatch_irqs(irqmask, regs);
+       titan_dispatch_irqs(irqmask);
 
        /* 
         * Release the logout frame.
index 729c475d2269a3f1f302e746168949d3aee89966..facf82a5499a84ce83e72e4d4a70324d0ea224d5 100644 (file)
@@ -127,7 +127,7 @@ unlock:
 #define MAX_ILLEGAL_IRQS 16
 
 void
-handle_irq(int irq, struct pt_regs * regs)
+handle_irq(int irq)
 {      
        /* 
         * We ack quickly, we don't want the irq controller
@@ -157,6 +157,6 @@ handle_irq(int irq, struct pt_regs * regs)
         * at IPL 0.
         */
        local_irq_disable();
-       __do_IRQ(irq, regs);
+       __do_IRQ(irq);
        irq_exit();
 }
index ddf5cf8dcb0bcefe44994ad9c10751f8caa5b09e..e16aeb6e79ef8cd62955f27d7fd623cacfd79cca 100644 (file)
@@ -6,6 +6,7 @@
 #include <linux/sched.h>
 #include <linux/irq.h>
 #include <linux/kernel_stat.h>
+#include <linux/module.h>
 
 #include <asm/machvec.h>
 #include <asm/dma.h>
@@ -16,6 +17,7 @@
 /* Hack minimum IPL during interrupt processing for broken hardware.  */
 #ifdef CONFIG_ALPHA_BROKEN_IRQ_MASK
 int __min_ipl;
+EXPORT_SYMBOL(__min_ipl);
 #endif
 
 /*
@@ -30,6 +32,7 @@ dummy_perf(unsigned long vector, struct pt_regs *regs)
 }
 
 void (*perf_irq)(unsigned long, struct pt_regs *) = dummy_perf;
+EXPORT_SYMBOL(perf_irq);
 
 /*
  * The main interrupt entry point.
@@ -39,6 +42,7 @@ asmlinkage void
 do_entInt(unsigned long type, unsigned long vector,
          unsigned long la_ptr, struct pt_regs *regs)
 {
+       struct pt_regs *old_regs;
        switch (type) {
        case 0:
 #ifdef CONFIG_SMP
@@ -51,6 +55,7 @@ do_entInt(unsigned long type, unsigned long vector,
 #endif
                break;
        case 1:
+               old_regs = set_irq_regs(regs);
 #ifdef CONFIG_SMP
          {
                long cpu;
@@ -61,18 +66,23 @@ do_entInt(unsigned long type, unsigned long vector,
                if (cpu != boot_cpuid) {
                        kstat_cpu(cpu).irqs[RTC_IRQ]++;
                } else {
-                       handle_irq(RTC_IRQ, regs);
+                       handle_irq(RTC_IRQ);
                }
          }
 #else
-               handle_irq(RTC_IRQ, regs);
+               handle_irq(RTC_IRQ);
 #endif
+               set_irq_regs(old_regs);
                return;
        case 2:
-               alpha_mv.machine_check(vector, la_ptr, regs);
+               old_regs = set_irq_regs(regs);
+               alpha_mv.machine_check(vector, la_ptr);
+               set_irq_regs(old_regs);
                return;
        case 3:
-               alpha_mv.device_interrupt(vector, regs);
+               old_regs = set_irq_regs(regs);
+               alpha_mv.device_interrupt(vector);
+               set_irq_regs(old_regs);
                return;
        case 4:
                perf_irq(la_ptr, regs);
@@ -120,8 +130,7 @@ struct mcheck_info __mcheck_info;
 
 void
 process_mcheck_info(unsigned long vector, unsigned long la_ptr,
-                   struct pt_regs *regs, const char *machine,
-                   int expected)
+                   const char *machine, int expected)
 {
        struct el_common *mchk_header;
        const char *reason;
@@ -148,7 +157,7 @@ process_mcheck_info(unsigned long vector, unsigned long la_ptr,
        mchk_header = (struct el_common *)la_ptr;
 
        printk(KERN_CRIT "%s machine check: vector=0x%lx pc=0x%lx code=0x%x\n",
-              machine, vector, regs->pc, mchk_header->code);
+              machine, vector, get_irq_regs()->pc, mchk_header->code);
 
        switch (mchk_header->code) {
        /* Machine check reasons.  Defined according to PALcode sources.  */
@@ -189,7 +198,7 @@ process_mcheck_info(unsigned long vector, unsigned long la_ptr,
        printk(KERN_CRIT "machine check type: %s%s\n",
               reason, mchk_header->retry ? " (retryable)" : "");
 
-       dik_show_regs(regs, NULL);
+       dik_show_regs(get_irq_regs(), NULL);
 
 #ifdef CONFIG_VERBOSE_MCHECK
        if (alpha_verbose_mcheck > 1) {
index ebbadbc0c36a3fd98769db496983c76cb58f146f..9405bee9894e9c4febd62efb2e2487dc63e5bf13 100644 (file)
@@ -137,7 +137,7 @@ init_i8259a_irqs(void)
 
 #if defined(IACK_SC)
 void
-isa_device_interrupt(unsigned long vector, struct pt_regs *regs)
+isa_device_interrupt(unsigned long vector)
 {
        /*
         * Generate a PCI interrupt acknowledge cycle.  The PIC will
@@ -147,13 +147,13 @@ isa_device_interrupt(unsigned long vector, struct pt_regs *regs)
         */
        int j = *(vuip) IACK_SC;
        j &= 0xff;
-       handle_irq(j, regs);
+       handle_irq(j);
 }
 #endif
 
 #if defined(CONFIG_ALPHA_GENERIC) || !defined(IACK_SC)
 void
-isa_no_iack_sc_device_interrupt(unsigned long vector, struct pt_regs *regs)
+isa_no_iack_sc_device_interrupt(unsigned long vector)
 {
        unsigned long pic;
 
@@ -176,7 +176,7 @@ isa_no_iack_sc_device_interrupt(unsigned long vector, struct pt_regs *regs)
        while (pic) {
                int j = ffz(~pic);
                pic &= pic - 1;
-               handle_irq(j, regs);
+               handle_irq(j);
        }
 }
 #endif
index f201d8ffc0d9d36853b80b4b903dff06efaaf387..cc9a8a7aa279e05b5a16876f52f563467611eb2f 100644 (file)
 
 #define RTC_IRQ    8
 
-extern void isa_device_interrupt(unsigned long, struct pt_regs *);
-extern void isa_no_iack_sc_device_interrupt(unsigned long, struct pt_regs *);
-extern void srm_device_interrupt(unsigned long, struct pt_regs *);
-extern void pyxis_device_interrupt(unsigned long, struct pt_regs *);
+extern void isa_device_interrupt(unsigned long);
+extern void isa_no_iack_sc_device_interrupt(unsigned long);
+extern void srm_device_interrupt(unsigned long);
+extern void pyxis_device_interrupt(unsigned long);
 
 extern struct irqaction timer_irqaction;
 extern struct irqaction isa_cascade_irqaction;
@@ -39,4 +39,4 @@ extern void i8259a_end_irq(unsigned int);
 extern struct hw_interrupt_type i8259a_irq_type;
 extern void init_i8259a_irqs(void);
 
-extern void handle_irq(int irq, struct pt_regs * regs);
+extern void handle_irq(int irq);
index 3b581415bab0bdaa5e9607cb14faf4dc7debed10..d53edbccbfe5d88653c59433be2d29147800c33f 100644 (file)
@@ -81,7 +81,7 @@ static struct hw_interrupt_type pyxis_irq_type = {
 };
 
 void 
-pyxis_device_interrupt(unsigned long vector, struct pt_regs *regs)
+pyxis_device_interrupt(unsigned long vector)
 {
        unsigned long pld;
        unsigned int i;
@@ -98,9 +98,9 @@ pyxis_device_interrupt(unsigned long vector, struct pt_regs *regs)
                i = ffz(~pld);
                pld &= pld - 1; /* clear least bit set */
                if (i == 7)
-                       isa_device_interrupt(vector, regs);
+                       isa_device_interrupt(vector);
                else
-                       handle_irq(16+i, regs);
+                       handle_irq(16+i);
        }
 }
 
index 8e4d121f84ccf87745aa6149e0a1a26e53649211..32212014fbe91632e9bb80b5307725d16e758d1a 100644 (file)
@@ -72,8 +72,8 @@ init_srm_irqs(long max, unsigned long ignore_mask)
 }
 
 void 
-srm_device_interrupt(unsigned long vector, struct pt_regs * regs)
+srm_device_interrupt(unsigned long vector)
 {
        int irq = (vector - 0x800) >> 4;
-       handle_irq(irq, regs);
+       handle_irq(irq);
 }
index fff5cf93e8164a6a465f5c538d16350d271307e0..174b729c504b274084c10bd78ff9e4465f3a9cda 100644 (file)
@@ -201,6 +201,7 @@ dma_set_mask(struct device *dev, u64 mask)
 
        return 0;
 }
+EXPORT_SYMBOL(dma_set_mask);
 
 void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
 {
index c468e312e5f815bd67b19c7354bf65422ea51d4b..6e7d1fe6e93532daa923ae6d6b69839e639954b6 100644 (file)
@@ -300,6 +300,7 @@ pci_map_single(struct pci_dev *pdev, void *cpu_addr, size_t size, int dir)
        dac_allowed = pdev ? pci_dac_dma_supported(pdev, pdev->dma_mask) : 0; 
        return pci_map_single_1(pdev, cpu_addr, size, dac_allowed);
 }
+EXPORT_SYMBOL(pci_map_single);
 
 dma_addr_t
 pci_map_page(struct pci_dev *pdev, struct page *page, unsigned long offset,
@@ -314,6 +315,7 @@ pci_map_page(struct pci_dev *pdev, struct page *page, unsigned long offset,
        return pci_map_single_1(pdev, (char *)page_address(page) + offset, 
                                size, dac_allowed);
 }
+EXPORT_SYMBOL(pci_map_page);
 
 /* Unmap a single streaming mode DMA translation.  The DMA_ADDR and
    SIZE must match what was provided for in a previous pci_map_single
@@ -379,6 +381,7 @@ pci_unmap_single(struct pci_dev *pdev, dma_addr_t dma_addr, size_t size,
        DBGA2("pci_unmap_single: sg [%lx,%lx] np %ld from %p\n",
              dma_addr, size, npages, __builtin_return_address(0));
 }
+EXPORT_SYMBOL(pci_unmap_single);
 
 void
 pci_unmap_page(struct pci_dev *pdev, dma_addr_t dma_addr,
@@ -386,6 +389,7 @@ pci_unmap_page(struct pci_dev *pdev, dma_addr_t dma_addr,
 {
        pci_unmap_single(pdev, dma_addr, size, direction);
 }
+EXPORT_SYMBOL(pci_unmap_page);
 
 /* Allocate and map kernel buffer using consistent mode DMA for PCI
    device.  Returns non-NULL cpu-view pointer to the buffer if
@@ -427,6 +431,7 @@ try_again:
 
        return cpu_addr;
 }
+EXPORT_SYMBOL(pci_alloc_consistent);
 
 /* Free and unmap a consistent DMA buffer.  CPU_ADDR and DMA_ADDR must
    be values that were returned from pci_alloc_consistent.  SIZE must
@@ -444,7 +449,7 @@ pci_free_consistent(struct pci_dev *pdev, size_t size, void *cpu_addr,
        DBGA2("pci_free_consistent: [%x,%lx] from %p\n",
              dma_addr, size, __builtin_return_address(0));
 }
-
+EXPORT_SYMBOL(pci_free_consistent);
 
 /* Classify the elements of the scatterlist.  Write dma_address
    of each element with:
@@ -672,6 +677,7 @@ pci_map_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents,
                pci_unmap_sg(pdev, start, out - start, direction);
        return 0;
 }
+EXPORT_SYMBOL(pci_map_sg);
 
 /* Unmap a set of streaming mode DMA translations.  Again, cpu read
    rules concerning calls here are the same as for pci_unmap_single()
@@ -752,6 +758,7 @@ pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents,
 
        DBGA("pci_unmap_sg: %ld entries\n", nents - (end - sg));
 }
+EXPORT_SYMBOL(pci_unmap_sg);
 
 
 /* Return whether the given PCI device DMA address mask can be
@@ -786,6 +793,7 @@ pci_dma_supported(struct pci_dev *pdev, u64 mask)
 
        return 0;
 }
+EXPORT_SYMBOL(pci_dma_supported);
 
 \f
 /*
@@ -908,6 +916,7 @@ pci_dac_dma_supported(struct pci_dev *dev, u64 mask)
 
        return ok;
 }
+EXPORT_SYMBOL(pci_dac_dma_supported);
 
 dma64_addr_t
 pci_dac_page_to_dma(struct pci_dev *pdev, struct page *page,
@@ -917,6 +926,7 @@ pci_dac_page_to_dma(struct pci_dev *pdev, struct page *page,
                + __pa(page_address(page)) 
                + (dma64_addr_t) offset);
 }
+EXPORT_SYMBOL(pci_dac_page_to_dma);
 
 struct page *
 pci_dac_dma_to_page(struct pci_dev *pdev, dma64_addr_t dma_addr)
@@ -924,13 +934,14 @@ pci_dac_dma_to_page(struct pci_dev *pdev, dma64_addr_t dma_addr)
        unsigned long paddr = (dma_addr & PAGE_MASK) - alpha_mv.pci_dac_offset;
        return virt_to_page(__va(paddr));
 }
+EXPORT_SYMBOL(pci_dac_dma_to_page);
 
 unsigned long
 pci_dac_dma_to_offset(struct pci_dev *pdev, dma64_addr_t dma_addr)
 {
        return (dma_addr & ~PAGE_MASK);
 }
-
+EXPORT_SYMBOL(pci_dac_dma_to_offset);
 
 /* Helper for generic DMA-mapping functions. */
 
@@ -957,6 +968,7 @@ alpha_gendev_to_pci(struct device *dev)
        /* This assumes ISA bus master with dma_mask 0xffffff. */
        return NULL;
 }
+EXPORT_SYMBOL(alpha_gendev_to_pci);
 
 int
 dma_set_mask(struct device *dev, u64 mask)
@@ -969,3 +981,4 @@ dma_set_mask(struct device *dev, u64 mask)
 
        return 0;
 }
+EXPORT_SYMBOL(dma_set_mask);
index b3a8a29803654eab232f478d7a1c58a9a483c1ee..3370e6faeae022d5209e1bb05188959823e0a944 100644 (file)
@@ -205,6 +205,7 @@ start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp)
        regs->ps = 8;
        wrusp(sp);
 }
+EXPORT_SYMBOL(start_thread);
 
 /*
  * Free current thread data structures etc..
@@ -376,6 +377,7 @@ dump_thread(struct pt_regs * pt, struct user * dump)
        dump->regs[EF_A2]  = pt->r18;
        memcpy((char *)dump->regs + EF_SIZE, sw->fp, 32 * 8);
 }
+EXPORT_SYMBOL(dump_thread);
 
 /*
  * Fill in the user structure for a ELF core dump.
@@ -424,6 +426,7 @@ dump_elf_thread(elf_greg_t *dest, struct pt_regs *pt, struct thread_info *ti)
           useful value of the thread's UNIQUE field.  */
        dest[32] = ti->pcb.unique;
 }
+EXPORT_SYMBOL(dump_elf_thread);
 
 int
 dump_elf_task(elf_greg_t *dest, struct task_struct *task)
@@ -431,6 +434,7 @@ dump_elf_task(elf_greg_t *dest, struct task_struct *task)
        dump_elf_thread(dest, task_pt_regs(task), task_thread_info(task));
        return 1;
 }
+EXPORT_SYMBOL(dump_elf_task);
 
 int
 dump_elf_task_fp(elf_fpreg_t *dest, struct task_struct *task)
@@ -439,6 +443,7 @@ dump_elf_task_fp(elf_fpreg_t *dest, struct task_struct *task)
        memcpy(dest, sw->fp, 32 * 8);
        return 1;
 }
+EXPORT_SYMBOL(dump_elf_task_fp);
 
 /*
  * sys_execve() executes a new program.
index 21f71287b6f5f11b511a939d54222d4f4b5e7087..95912ecc65e1bb63af2f6991c08f485bfe938e40 100644 (file)
@@ -20,7 +20,7 @@ struct pci_controller;
 extern struct pci_ops apecs_pci_ops;
 extern void apecs_init_arch(void);
 extern void apecs_pci_clr_err(void);
-extern void apecs_machine_check(u64, u64, struct pt_regs *);
+extern void apecs_machine_check(u64, u64);
 extern void apecs_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
 
 /* core_cia.c */
@@ -29,27 +29,27 @@ extern void cia_init_pci(void);
 extern void cia_init_arch(void);
 extern void pyxis_init_arch(void);
 extern void cia_kill_arch(int);
-extern void cia_machine_check(u64, u64, struct pt_regs *);
+extern void cia_machine_check(u64, u64);
 extern void cia_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
 
 /* core_irongate.c */
 extern struct pci_ops irongate_pci_ops;
 extern int irongate_pci_clr_err(void);
 extern void irongate_init_arch(void);
-extern void irongate_machine_check(u64, u64, struct pt_regs *);
+extern void irongate_machine_check(u64, u64);
 #define irongate_pci_tbi ((void *)0)
 
 /* core_lca.c */
 extern struct pci_ops lca_pci_ops;
 extern void lca_init_arch(void);
-extern void lca_machine_check(u64, u64, struct pt_regs *);
+extern void lca_machine_check(u64, u64);
 extern void lca_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
 
 /* core_marvel.c */
 extern struct pci_ops marvel_pci_ops;
 extern void marvel_init_arch(void);
 extern void marvel_kill_arch(int);
-extern void marvel_machine_check(u64, u64, struct pt_regs *);
+extern void marvel_machine_check(u64, u64);
 extern void marvel_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
 extern int marvel_pa_to_nid(unsigned long);
 extern int marvel_cpuid_to_nid(int);
@@ -64,7 +64,7 @@ void io7_clear_errors(struct io7 *io7);
 extern struct pci_ops mcpcia_pci_ops;
 extern void mcpcia_init_arch(void);
 extern void mcpcia_init_hoses(void);
-extern void mcpcia_machine_check(u64, u64, struct pt_regs *);
+extern void mcpcia_machine_check(u64, u64);
 extern void mcpcia_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
 
 /* core_polaris.c */
@@ -72,21 +72,21 @@ extern struct pci_ops polaris_pci_ops;
 extern int polaris_read_config_dword(struct pci_dev *, int, u32 *);
 extern int polaris_write_config_dword(struct pci_dev *, int, u32);
 extern void polaris_init_arch(void);
-extern void polaris_machine_check(u64, u64, struct pt_regs *);
+extern void polaris_machine_check(u64, u64);
 #define polaris_pci_tbi ((void *)0)
 
 /* core_t2.c */
 extern struct pci_ops t2_pci_ops;
 extern void t2_init_arch(void);
 extern void t2_kill_arch(int);
-extern void t2_machine_check(u64, u64, struct pt_regs *);
+extern void t2_machine_check(u64, u64);
 extern void t2_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
 
 /* core_titan.c */
 extern struct pci_ops titan_pci_ops;
 extern void titan_init_arch(void);
 extern void titan_kill_arch(int);
-extern void titan_machine_check(u64, u64, struct pt_regs *);
+extern void titan_machine_check(u64, u64);
 extern void titan_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
 extern struct _alpha_agp_info *titan_agp_info(void);
 
@@ -94,14 +94,14 @@ extern struct _alpha_agp_info *titan_agp_info(void);
 extern struct pci_ops tsunami_pci_ops;
 extern void tsunami_init_arch(void);
 extern void tsunami_kill_arch(int);
-extern void tsunami_machine_check(u64, u64, struct pt_regs *);
+extern void tsunami_machine_check(u64, u64);
 extern void tsunami_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
 
 /* core_wildfire.c */
 extern struct pci_ops wildfire_pci_ops;
 extern void wildfire_init_arch(void);
 extern void wildfire_kill_arch(int);
-extern void wildfire_machine_check(u64, u64, struct pt_regs *);
+extern void wildfire_machine_check(u64, u64);
 extern void wildfire_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
 extern int wildfire_pa_to_nid(unsigned long);
 extern int wildfire_cpuid_to_nid(int);
@@ -133,7 +133,7 @@ extern void smp_percpu_timer_interrupt(struct pt_regs *);
 /* extern void reset_for_srm(void); */
 
 /* time.c */
-extern irqreturn_t timer_interrupt(int irq, void *dev, struct pt_regs * regs);
+extern irqreturn_t timer_interrupt(int irq, void *dev);
 extern void common_init_rtc(void);
 extern unsigned long est_cycle_freq;
 
@@ -177,7 +177,7 @@ extern void dik_show_regs(struct pt_regs *regs, unsigned long *r9_15);
 extern void die_if_kernel(char *, struct pt_regs *, long, unsigned long *);
 
 /* sys_titan.c */
-extern void titan_dispatch_irqs(u64, struct pt_regs *);
+extern void titan_dispatch_irqs(u64);
 
 /* ../mm/init.c */
 extern void switch_to_system_map(void);
@@ -214,5 +214,4 @@ extern struct mcheck_info
 #endif
 
 extern void process_mcheck_info(unsigned long vector, unsigned long la_ptr,
-                               struct pt_regs *regs, const char *machine,
-                               int expected);
+                               const char *machine, int expected);
index a94e6d93e2eedb695f83e718a2fd3eba1b674807..1aea7c7c683cddb0d5b7e065f1e08f720d70a8e0 100644 (file)
@@ -66,6 +66,7 @@ static struct notifier_block alpha_panic_block = {
 
 
 struct hwrpb_struct *hwrpb;
+EXPORT_SYMBOL(hwrpb);
 unsigned long srm_hae;
 
 int alpha_l1i_cacheshape;
@@ -111,6 +112,7 @@ unsigned long alpha_agpgart_size = DEFAULT_AGP_APER_SIZE;
 #ifdef CONFIG_ALPHA_GENERIC
 struct alpha_machine_vector alpha_mv;
 int alpha_using_srm;
+EXPORT_SYMBOL(alpha_using_srm);
 #endif
 
 static struct alpha_machine_vector *get_sysvec(unsigned long, unsigned long,
@@ -137,6 +139,8 @@ struct screen_info screen_info = {
        .orig_video_points = 16
 };
 
+EXPORT_SYMBOL(screen_info);
+
 /*
  * The direct map I/O window, if any.  This should be the same
  * for all busses, since it's used by virt_to_bus.
@@ -144,6 +148,8 @@ struct screen_info screen_info = {
 
 unsigned long __direct_map_base;
 unsigned long __direct_map_size;
+EXPORT_SYMBOL(__direct_map_base);
+EXPORT_SYMBOL(__direct_map_size);
 
 /*
  * Declare all of the machine vectors.
index 4dc273e537fdd38830deb0ede8a3b560827a8ab0..d1ec4f51df1aae6c3678dc85d393edb2d33ee321 100644 (file)
@@ -52,6 +52,7 @@
 
 /* A collection of per-processor data.  */
 struct cpuinfo_alpha cpu_data[NR_CPUS];
+EXPORT_SYMBOL(cpu_data);
 
 /* A collection of single bit ipi messages.  */
 static struct {
@@ -74,6 +75,7 @@ EXPORT_SYMBOL(cpu_online_map);
 
 int smp_num_probed;            /* Internal processor count */
 int smp_num_cpus = 1;          /* Number that came online.  */
+EXPORT_SYMBOL(smp_num_cpus);
 
 extern void calibrate_delay(void);
 
@@ -515,12 +517,15 @@ smp_cpus_done(unsigned int max_cpus)
 void
 smp_percpu_timer_interrupt(struct pt_regs *regs)
 {
+       struct pt_regs *old_regs;
        int cpu = smp_processor_id();
        unsigned long user = user_mode(regs);
        struct cpuinfo_alpha *data = &cpu_data[cpu];
 
+       old_regs = set_irq_regs(regs);
+
        /* Record kernel PC.  */
-       profile_tick(CPU_PROFILING, regs);
+       profile_tick(CPU_PROFILING);
 
        if (!--data->prof_counter) {
                /* We need to make like a normal interrupt -- otherwise
@@ -534,6 +539,7 @@ smp_percpu_timer_interrupt(struct pt_regs *regs)
 
                irq_exit();
        }
+       set_irq_regs(old_regs);
 }
 
 int __init
@@ -786,6 +792,7 @@ smp_call_function_on_cpu (void (*func) (void *info), void *info, int retry,
 
        return 0;
 }
+EXPORT_SYMBOL(smp_call_function_on_cpu);
 
 int
 smp_call_function (void (*func) (void *info), void *info, int retry, int wait)
@@ -793,6 +800,7 @@ smp_call_function (void (*func) (void *info), void *info, int retry, int wait)
        return smp_call_function_on_cpu (func, info, retry, wait,
                                         cpu_online_map);
 }
+EXPORT_SYMBOL(smp_call_function);
 
 static void
 ipi_imb(void *ignored)
@@ -807,6 +815,7 @@ smp_imb(void)
        if (on_each_cpu(ipi_imb, NULL, 1, 1))
                printk(KERN_CRIT "smp_imb: timed out\n");
 }
+EXPORT_SYMBOL(smp_imb);
 
 static void
 ipi_flush_tlb_all(void *ignored)
@@ -862,6 +871,7 @@ flush_tlb_mm(struct mm_struct *mm)
 
        preempt_enable();
 }
+EXPORT_SYMBOL(flush_tlb_mm);
 
 struct flush_tlb_page_struct {
        struct vm_area_struct *vma;
@@ -914,6 +924,7 @@ flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
 
        preempt_enable();
 }
+EXPORT_SYMBOL(flush_tlb_page);
 
 void
 flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end)
@@ -921,6 +932,7 @@ flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long e
        /* On the Alpha we always flush the whole user tlb.  */
        flush_tlb_mm(vma->vm_mm);
 }
+EXPORT_SYMBOL(flush_tlb_range);
 
 static void
 ipi_flush_icache_page(void *x)
index d6926b7b1e994b3dde36c9f7c77991ea55102227..49bedfbbd31bedc7986f31b6182356d8d2690959 100644 (file)
@@ -100,7 +100,7 @@ static struct hw_interrupt_type alcor_irq_type = {
 };
 
 static void
-alcor_device_interrupt(unsigned long vector, struct pt_regs *regs)
+alcor_device_interrupt(unsigned long vector)
 {
        unsigned long pld;
        unsigned int i;
@@ -116,9 +116,9 @@ alcor_device_interrupt(unsigned long vector, struct pt_regs *regs)
                i = ffz(~pld);
                pld &= pld - 1; /* clear least bit set */
                if (i == 31) {
-                       isa_device_interrupt(vector, regs);
+                       isa_device_interrupt(vector);
                } else {
-                       handle_irq(16 + i, regs);
+                       handle_irq(16 + i);
                }
        }
 }
index 25a215067da8a55111a55ca8ec83e8eaa8e5f9a6..ace475c124f69d9d2e248268e8ef3436c4262f1e 100644 (file)
@@ -82,7 +82,7 @@ static struct hw_interrupt_type cabriolet_irq_type = {
 };
 
 static void 
-cabriolet_device_interrupt(unsigned long v, struct pt_regs *r)
+cabriolet_device_interrupt(unsigned long v)
 {
        unsigned long pld;
        unsigned int i;
@@ -98,15 +98,15 @@ cabriolet_device_interrupt(unsigned long v, struct pt_regs *r)
                i = ffz(~pld);
                pld &= pld - 1; /* clear least bit set */
                if (i == 4) {
-                       isa_device_interrupt(v, r);
+                       isa_device_interrupt(v);
                } else {
-                       handle_irq(16 + i, r);
+                       handle_irq(16 + i);
                }
        }
 }
 
 static void __init
-common_init_irq(void (*srm_dev_int)(unsigned long v, struct pt_regs *r))
+common_init_irq(void (*srm_dev_int)(unsigned long v))
 {
        init_i8259a_irqs();
 
@@ -154,18 +154,18 @@ cabriolet_init_irq(void)
    too invasive though.  */
 
 static void
-pc164_srm_device_interrupt(unsigned long v, struct pt_regs *r)
+pc164_srm_device_interrupt(unsigned long v)
 {
        __min_ipl = getipl();
-       srm_device_interrupt(v, r);
+       srm_device_interrupt(v);
        __min_ipl = 0;
 }
 
 static void
-pc164_device_interrupt(unsigned long v, struct pt_regs *r)
+pc164_device_interrupt(unsigned long v)
 {
        __min_ipl = getipl();
-       cabriolet_device_interrupt(v, r);
+       cabriolet_device_interrupt(v);
        __min_ipl = 0;
 }
 
index dd6103b867e778e062e932fb8a26cbf5f527be67..85d2f933dd07b0b8d9ca88f13646e302d13e1328 100644 (file)
@@ -217,7 +217,7 @@ static struct hw_interrupt_type clipper_irq_type = {
 };
 
 static void
-dp264_device_interrupt(unsigned long vector, struct pt_regs * regs)
+dp264_device_interrupt(unsigned long vector)
 {
 #if 1
        printk("dp264_device_interrupt: NOT IMPLEMENTED YET!! \n");
@@ -236,9 +236,9 @@ dp264_device_interrupt(unsigned long vector, struct pt_regs * regs)
                i = ffz(~pld);
                pld &= pld - 1; /* clear least bit set */
                if (i == 55)
-                       isa_device_interrupt(vector, regs);
+                       isa_device_interrupt(vector);
                else
-                       handle_irq(16 + i, 16 + i, regs);
+                       handle_irq(16 + i);
 #if 0
                TSUNAMI_cchip->dir0.csr = 1UL << i; mb();
                tmp = TSUNAMI_cchip->dir0.csr;
@@ -248,7 +248,7 @@ dp264_device_interrupt(unsigned long vector, struct pt_regs * regs)
 }
 
 static void 
-dp264_srm_device_interrupt(unsigned long vector, struct pt_regs * regs)
+dp264_srm_device_interrupt(unsigned long vector)
 {
        int irq;
 
@@ -268,11 +268,11 @@ dp264_srm_device_interrupt(unsigned long vector, struct pt_regs * regs)
        if (irq >= 32)
                irq -= 16;
 
-       handle_irq(irq, regs);
+       handle_irq(irq);
 }
 
 static void 
-clipper_srm_device_interrupt(unsigned long vector, struct pt_regs * regs)
+clipper_srm_device_interrupt(unsigned long vector)
 {
        int irq;
 
@@ -290,7 +290,7 @@ clipper_srm_device_interrupt(unsigned long vector, struct pt_regs * regs)
         *
         * Eg IRQ 24 is DRIR bit 8, etc, etc
         */
-       handle_irq(irq, regs);
+       handle_irq(irq);
 }
 
 static void __init
index ed108b66ec09842b0ab9af2aeb7bbc23c0812305..9c5a306dc0ee825a47d3d8c0bd27e2d091069086 100644 (file)
@@ -80,7 +80,7 @@ static struct hw_interrupt_type eb64p_irq_type = {
 };
 
 static void 
-eb64p_device_interrupt(unsigned long vector, struct pt_regs *regs)
+eb64p_device_interrupt(unsigned long vector)
 {
        unsigned long pld;
        unsigned int i;
@@ -97,9 +97,9 @@ eb64p_device_interrupt(unsigned long vector, struct pt_regs *regs)
                pld &= pld - 1; /* clear least bit set */
 
                if (i == 5) {
-                       isa_device_interrupt(vector, regs);
+                       isa_device_interrupt(vector);
                } else {
-                       handle_irq(16 + i, regs);
+                       handle_irq(16 + i);
                }
        }
 }
index 64a785baf53a0f1ffac8ebfcb904a4ec4c01c0d6..7ef3b6fb3700c877309e3100c0d9991de7659b44 100644 (file)
@@ -91,7 +91,7 @@ static struct hw_interrupt_type eiger_irq_type = {
 };
 
 static void
-eiger_device_interrupt(unsigned long vector, struct pt_regs * regs)
+eiger_device_interrupt(unsigned long vector)
 {
        unsigned intstatus;
 
@@ -118,20 +118,20 @@ eiger_device_interrupt(unsigned long vector, struct pt_regs * regs)
                 * despatch an interrupt if it's set.
                 */
 
-               if (intstatus & 8) handle_irq(16+3, regs);
-               if (intstatus & 4) handle_irq(16+2, regs);
-               if (intstatus & 2) handle_irq(16+1, regs);
-               if (intstatus & 1) handle_irq(16+0, regs);
+               if (intstatus & 8) handle_irq(16+3);
+               if (intstatus & 4) handle_irq(16+2);
+               if (intstatus & 2) handle_irq(16+1);
+               if (intstatus & 1) handle_irq(16+0);
        } else {
-               isa_device_interrupt(vector, regs);
+               isa_device_interrupt(vector);
        }
 }
 
 static void
-eiger_srm_device_interrupt(unsigned long vector, struct pt_regs * regs)
+eiger_srm_device_interrupt(unsigned long vector)
 {
        int irq = (vector - 0x800) >> 4;
-       handle_irq(irq, regs);
+       handle_irq(irq);
 }
 
 static void __init
index 4ac2b328b8de32e8cd60294d0bb2925a327f1327..2c3de97de46ca54416b7f52f6fc50bbac7684f6b 100644 (file)
@@ -129,7 +129,7 @@ static struct hw_interrupt_type jensen_local_irq_type = {
 };
 
 static void 
-jensen_device_interrupt(unsigned long vector, struct pt_regs * regs)
+jensen_device_interrupt(unsigned long vector)
 {
        int irq;
 
@@ -189,7 +189,7 @@ jensen_device_interrupt(unsigned long vector, struct pt_regs * regs)
           if (cc - last_msg > ((JENSEN_CYCLES_PER_SEC) * 3) ||
              irq != last_irq) {
                 printk(KERN_CRIT " irq %d count %d cc %u @ %lx\n",
-                       irq, count, cc-last_cc, regs->pc);
+                       irq, count, cc-last_cc, get_irq_regs()->pc);
                 count = 0;
                 last_msg = cc;
                 last_irq = irq;
@@ -198,7 +198,7 @@ jensen_device_interrupt(unsigned long vector, struct pt_regs * regs)
         }
 #endif
 
-       handle_irq(irq, regs);
+       handle_irq(irq);
 }
 
 static void __init
@@ -244,7 +244,7 @@ jensen_init_arch(void)
 }
 
 static void
-jensen_machine_check (u64 vector, u64 la, struct pt_regs *regs)
+jensen_machine_check (u64 vector, u64 la)
 {
        printk(KERN_CRIT "Machine check\n");
 }
index 36d2159543769758904fe8125b7c037b4984efcc..e349f03b830e9c96826646877006e640dcf0edad 100644 (file)
@@ -38,7 +38,7 @@
  * Interrupt handling.
  */
 static void 
-io7_device_interrupt(unsigned long vector, struct pt_regs * regs)
+io7_device_interrupt(unsigned long vector)
 {
        unsigned int pid;
        unsigned int irq;
@@ -64,7 +64,7 @@ io7_device_interrupt(unsigned long vector, struct pt_regs * regs)
        irq &= MARVEL_IRQ_VEC_IRQ_MASK;         /* not too many bits */
        irq |= pid << MARVEL_IRQ_VEC_PE_SHIFT;  /* merge the pid     */
 
-       handle_irq(irq, regs);
+       handle_irq(irq);
 }
 
 static volatile unsigned long *
index 61ac56f8eeea9675c1a87f6d27d23a6fb4a43e5c..b8b817feb1eedb8db7be5baa8df5639cb02a4b0f 100644 (file)
@@ -33,7 +33,7 @@
 
 
 static void 
-miata_srm_device_interrupt(unsigned long vector, struct pt_regs * regs)
+miata_srm_device_interrupt(unsigned long vector)
 {
        int irq;
 
@@ -56,7 +56,7 @@ miata_srm_device_interrupt(unsigned long vector, struct pt_regs * regs)
        if (irq >= 16)
                irq = irq + 8;
 
-       handle_irq(irq, regs);
+       handle_irq(irq);
 }
 
 static void __init
index cc4c58111366b54fccd67789262e92a681ca75b9..8d3e9429c5ee60c17d9a015ebff09a40feabe9e0 100644 (file)
@@ -79,7 +79,7 @@ static struct hw_interrupt_type mikasa_irq_type = {
 };
 
 static void 
-mikasa_device_interrupt(unsigned long vector, struct pt_regs *regs)
+mikasa_device_interrupt(unsigned long vector)
 {
        unsigned long pld;
        unsigned int i;
@@ -97,9 +97,9 @@ mikasa_device_interrupt(unsigned long vector, struct pt_regs *regs)
                i = ffz(~pld);
                pld &= pld - 1; /* clear least bit set */
                if (i < 16) {
-                       isa_device_interrupt(vector, regs);
+                       isa_device_interrupt(vector);
                } else {
-                       handle_irq(i, regs);
+                       handle_irq(i);
                }
        }
 }
@@ -182,8 +182,7 @@ mikasa_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
 
 #if defined(CONFIG_ALPHA_GENERIC) || !defined(CONFIG_ALPHA_PRIMO)
 static void
-mikasa_apecs_machine_check(unsigned long vector, unsigned long la_ptr,
-                          struct pt_regs * regs)
+mikasa_apecs_machine_check(unsigned long vector, unsigned long la_ptr)
 {
 #define MCHK_NO_DEVSEL 0x205U
 #define MCHK_NO_TABT 0x204U
@@ -202,7 +201,7 @@ mikasa_apecs_machine_check(unsigned long vector, unsigned long la_ptr,
        mb();
 
        code = mchk_header->code;
-       process_mcheck_info(vector, la_ptr, regs, "MIKASA APECS",
+       process_mcheck_info(vector, la_ptr, "MIKASA APECS",
                            (mcheck_expected(0)
                             && (code == MCHK_NO_DEVSEL
                                 || code == MCHK_NO_TABT)));
index c0d696efec5bafc2537e6b6dc2bb36c83058957c..93744bab73fb24ac63d6ba9406a4a3c4d0a294fb 100644 (file)
@@ -124,8 +124,7 @@ naut_sys_machine_check(unsigned long vector, unsigned long la_ptr,
    in the system.  They are analysed separately but all starts here.  */
 
 void
-nautilus_machine_check(unsigned long vector, unsigned long la_ptr,
-                      struct pt_regs *regs)
+nautilus_machine_check(unsigned long vector, unsigned long la_ptr)
 {
        char *mchk_class;
 
@@ -165,7 +164,7 @@ nautilus_machine_check(unsigned long vector, unsigned long la_ptr,
        else if (vector == SCB_Q_SYSMCHK)
                mchk_class = "Fatal";
        else {
-               ev6_machine_check(vector, la_ptr, regs);
+               ev6_machine_check(vector, la_ptr);
                return;
        }
 
@@ -173,7 +172,7 @@ nautilus_machine_check(unsigned long vector, unsigned long la_ptr,
                         "[%s System Machine Check (NMI)]\n",
               vector, mchk_class);
 
-       naut_sys_machine_check(vector, la_ptr, regs);
+       naut_sys_machine_check(vector, la_ptr, get_irq_regs());
 
        /* Tell the PALcode to clear the machine check */
        draina();
index 2d3cff7e8c5f83723576d8b0d54ca004d80af53e..de6ba3432e8ad191a0c7d13cf4b8dc6435489930 100644 (file)
@@ -77,7 +77,7 @@ static struct hw_interrupt_type noritake_irq_type = {
 };
 
 static void 
-noritake_device_interrupt(unsigned long vector, struct pt_regs *regs)
+noritake_device_interrupt(unsigned long vector)
 {
        unsigned long pld;
        unsigned int i;
@@ -96,15 +96,15 @@ noritake_device_interrupt(unsigned long vector, struct pt_regs *regs)
                i = ffz(~pld);
                pld &= pld - 1; /* clear least bit set */
                if (i < 16) {
-                       isa_device_interrupt(vector, regs);
+                       isa_device_interrupt(vector);
                } else {
-                       handle_irq(i, regs);
+                       handle_irq(i);
                }
        }
 }
 
 static void 
-noritake_srm_device_interrupt(unsigned long vector, struct pt_regs * regs)
+noritake_srm_device_interrupt(unsigned long vector)
 {
        int irq;
 
@@ -122,7 +122,7 @@ noritake_srm_device_interrupt(unsigned long vector, struct pt_regs * regs)
        if (irq >= 16)
                irq = irq + 1;
 
-       handle_irq(irq, regs);
+       handle_irq(irq);
 }
 
 static void __init
@@ -264,8 +264,7 @@ noritake_swizzle(struct pci_dev *dev, u8 *pinp)
 
 #if defined(CONFIG_ALPHA_GENERIC) || !defined(CONFIG_ALPHA_PRIMO)
 static void
-noritake_apecs_machine_check(unsigned long vector, unsigned long la_ptr,
-                            struct pt_regs * regs)
+noritake_apecs_machine_check(unsigned long vector, unsigned long la_ptr)
 {
 #define MCHK_NO_DEVSEL 0x205U
 #define MCHK_NO_TABT 0x204U
@@ -284,7 +283,7 @@ noritake_apecs_machine_check(unsigned long vector, unsigned long la_ptr,
         mb();
 
         code = mchk_header->code;
-        process_mcheck_info(vector, la_ptr, regs, "NORITAKE APECS",
+        process_mcheck_info(vector, la_ptr, "NORITAKE APECS",
                             (mcheck_expected(0)
                              && (code == MCHK_NO_DEVSEL
                                  || code == MCHK_NO_TABT)));
index 949607e3d6fbe82395c641b1f94ecb3d99ef1b12..581d08c70b9234302cb65126756659a2d8b25839 100644 (file)
@@ -134,7 +134,7 @@ static struct hw_interrupt_type rawhide_irq_type = {
 };
 
 static void 
-rawhide_srm_device_interrupt(unsigned long vector, struct pt_regs * regs)
+rawhide_srm_device_interrupt(unsigned long vector)
 {
        int irq;
 
@@ -158,7 +158,7 @@ rawhide_srm_device_interrupt(unsigned long vector, struct pt_regs * regs)
        /* Adjust by which hose it is from.  */
        irq -= ((irq + 16) >> 2) & 0x38;
 
-       handle_irq(irq, regs);
+       handle_irq(irq);
 }
 
 static void __init
index 6ae50605263592061869345ecfe1856a1c33467e..ce1faa6f1df1f4e1aba6ac57f3f8001f75bdf2f4 100644 (file)
@@ -83,7 +83,7 @@ static struct hw_interrupt_type rx164_irq_type = {
 };
 
 static void 
-rx164_device_interrupt(unsigned long vector, struct pt_regs *regs)
+rx164_device_interrupt(unsigned long vector)
 {
        unsigned long pld;
        volatile unsigned int *dirr;
@@ -102,9 +102,9 @@ rx164_device_interrupt(unsigned long vector, struct pt_regs *regs)
                i = ffz(~pld);
                pld &= pld - 1; /* clear least bit set */
                if (i == 20) {
-                       isa_no_iack_sc_device_interrupt(vector, regs);
+                       isa_no_iack_sc_device_interrupt(vector);
                } else {
-                       handle_irq(16+i, regs);
+                       handle_irq(16+i);
                }
        }
 }
index a7a14647b50e01cf2f7725192b76e0d5c7b270a3..906019cfa6815ff8d6c00d6a299313090398b7bc 100644 (file)
@@ -512,7 +512,7 @@ static struct hw_interrupt_type sable_lynx_irq_type = {
 };
 
 static void 
-sable_lynx_srm_device_interrupt(unsigned long vector, struct pt_regs * regs)
+sable_lynx_srm_device_interrupt(unsigned long vector)
 {
        /* Note that the vector reported by the SRM PALcode corresponds
           to the interrupt mask bits, but we have to manage via the
@@ -526,7 +526,7 @@ sable_lynx_srm_device_interrupt(unsigned long vector, struct pt_regs * regs)
        printk("%s: vector 0x%lx bit 0x%x irq 0x%x\n",
               __FUNCTION__, vector, bit, irq);
 #endif
-       handle_irq(irq, regs);
+       handle_irq(irq);
 }
 
 static void __init
index 2c75cd1fd81aab537e6b93615011baba52b98e2c..9bd9a31450c64a414ba08cc137ae349a535b0497 100644 (file)
@@ -85,7 +85,7 @@ static struct hw_interrupt_type takara_irq_type = {
 };
 
 static void
-takara_device_interrupt(unsigned long vector, struct pt_regs *regs)
+takara_device_interrupt(unsigned long vector)
 {
        unsigned intstatus;
 
@@ -112,20 +112,20 @@ takara_device_interrupt(unsigned long vector, struct pt_regs *regs)
                 * despatch an interrupt if it's set.
                 */
 
-               if (intstatus & 8) handle_irq(16+3, regs);
-               if (intstatus & 4) handle_irq(16+2, regs);
-               if (intstatus & 2) handle_irq(16+1, regs);
-               if (intstatus & 1) handle_irq(16+0, regs);
+               if (intstatus & 8) handle_irq(16+3);
+               if (intstatus & 4) handle_irq(16+2);
+               if (intstatus & 2) handle_irq(16+1);
+               if (intstatus & 1) handle_irq(16+0);
        } else {
-               isa_device_interrupt (vector, regs);
+               isa_device_interrupt (vector);
        }
 }
 
 static void 
-takara_srm_device_interrupt(unsigned long vector, struct pt_regs * regs)
+takara_srm_device_interrupt(unsigned long vector)
 {
        int irq = (vector - 0x800) >> 4;
-       handle_irq(irq, regs);
+       handle_irq(irq);
 }
 
 static void __init
index 302aab38d95f6ce902bce1c5737506fc9a58f05c..29ab7db81c30983cc113fcf5c51bea39375749f9 100644 (file)
@@ -167,18 +167,18 @@ titan_set_irq_affinity(unsigned int irq, cpumask_t affinity)
 }
 
 static void
-titan_device_interrupt(unsigned long vector, struct pt_regs * regs)
+titan_device_interrupt(unsigned long vector)
 {
        printk("titan_device_interrupt: NOT IMPLEMENTED YET!! \n");
 }
 
 static void 
-titan_srm_device_interrupt(unsigned long vector, struct pt_regs * regs)
+titan_srm_device_interrupt(unsigned long vector)
 {
        int irq;
 
        irq = (vector - 0x800) >> 4;
-       handle_irq(irq, regs);
+       handle_irq(irq);
 }
 
 
@@ -204,7 +204,7 @@ static struct hw_interrupt_type titan_irq_type = {
 };
 
 static irqreturn_t
-titan_intr_nop(int irq, void *dev_id, struct pt_regs *regs)                    
+titan_intr_nop(int irq, void *dev_id)
 {
       /*
        * This is a NOP interrupt handler for the purposes of
@@ -243,7 +243,7 @@ titan_legacy_init_irq(void)
 }
 
 void
-titan_dispatch_irqs(u64 mask, struct pt_regs *regs)
+titan_dispatch_irqs(u64 mask)
 {
        unsigned long vector;
 
@@ -263,7 +263,7 @@ titan_dispatch_irqs(u64 mask, struct pt_regs *regs)
                vector = 0x900 + (vector << 4); /* convert to SRM vector */
                
                /* dispatch it */
-               alpha_mv.device_interrupt(vector, regs);
+               alpha_mv.device_interrupt(vector);
        }
 }
   
index 22c5798fe083ba03cf16e88ec6fe4088fce61ce3..42c3eede4d099a3a970f9d78e25f42f3f8eeb8b1 100644 (file)
@@ -234,7 +234,7 @@ wildfire_init_irq(void)
 }
 
 static void 
-wildfire_device_interrupt(unsigned long vector, struct pt_regs * regs)
+wildfire_device_interrupt(unsigned long vector)
 {
        int irq;
 
@@ -246,7 +246,7 @@ wildfire_device_interrupt(unsigned long vector, struct pt_regs * regs)
         * bits 5-0:    irq in PCA
         */
 
-       handle_irq(irq, regs);
+       handle_irq(irq);
        return;
 }
 
index 581ddcc22fc58e13eca80f75446e04c4c866ef09..d7053eb4ffcfd93623d58aabda82d30cf9118dee 100644 (file)
@@ -57,6 +57,7 @@
 static int set_rtc_mmss(unsigned long);
 
 DEFINE_SPINLOCK(rtc_lock);
+EXPORT_SYMBOL(rtc_lock);
 
 #define TICK_SIZE (tick_nsec / 1000)
 
@@ -104,7 +105,7 @@ unsigned long long sched_clock(void)
  * timer_interrupt() needs to keep up the real-time clock,
  * as well as call the "do_timer()" routine every clocktick
  */
-irqreturn_t timer_interrupt(int irq, void *dev, struct pt_regs * regs)
+irqreturn_t timer_interrupt(int irq, void *dev)
 {
        unsigned long delta;
        __u32 now;
@@ -112,7 +113,7 @@ irqreturn_t timer_interrupt(int irq, void *dev, struct pt_regs * regs)
 
 #ifndef CONFIG_SMP
        /* Not SMP, do kernel PC profiling here.  */
-       profile_tick(CPU_PROFILING, regs);
+       profile_tick(CPU_PROFILING);
 #endif
 
        write_seqlock(&xtime_lock);
@@ -132,7 +133,7 @@ irqreturn_t timer_interrupt(int irq, void *dev, struct pt_regs * regs)
        while (nticks > 0) {
                do_timer(1);
 #ifndef CONFIG_SMP
-               update_process_times(user_mode(regs));
+               update_process_times(user_mode(get_irq_regs()));
 #endif
                nticks--;
        }
index b826f58c6e7247e5f73a45039a1493c9b7c90f60..e3e3806a6f254f02b3cec0d1a02fba5fc05639c2 100644 (file)
 #include <linux/swap.h>
 #include <linux/initrd.h>
 #include <linux/pfn.h>
+#include <linux/module.h>
 
 #include <asm/hwrpb.h>
 #include <asm/pgalloc.h>
 
 pg_data_t node_data[MAX_NUMNODES];
 bootmem_data_t node_bdata[MAX_NUMNODES];
+EXPORT_SYMBOL(node_data);
 
 #undef DEBUG_DISCONTIG
 #ifdef DEBUG_DISCONTIG
index 181ef1ead5b8362e1bef5fabe94f2659befceced..80a72c75214f65956e5ce1872d190fcb3a4cceae 100644 (file)
@@ -163,8 +163,7 @@ static struct locomo_dev_info locomo_devices[] = {
 #define        LOCOMO_IRQ_LT_START     (IRQ_LOCOMO_LT)
 #define        LOCOMO_IRQ_SPI_START    (IRQ_LOCOMO_SPI_RFR)
 
-static void locomo_handler(unsigned int irq, struct irqdesc *desc,
-                       struct pt_regs *regs)
+static void locomo_handler(unsigned int irq, struct irqdesc *desc)
 {
        int req, i;
        struct irqdesc *d;
@@ -182,7 +181,7 @@ static void locomo_handler(unsigned int irq, struct irqdesc *desc,
                d = irq_desc + irq;
                for (i = 0; i <= 3; i++, d++, irq++) {
                        if (req & (0x0100 << i)) {
-                               desc_handle_irq(irq, d, regs);
+                               desc_handle_irq(irq, d);
                        }
 
                }
@@ -218,15 +217,14 @@ static struct irq_chip locomo_chip = {
        .unmask = locomo_unmask_irq,
 };
 
-static void locomo_key_handler(unsigned int irq, struct irqdesc *desc,
-                           struct pt_regs *regs)
+static void locomo_key_handler(unsigned int irq, struct irqdesc *desc)
 {
        struct irqdesc *d;
        void __iomem *mapbase = get_irq_chipdata(irq);
 
        if (locomo_readl(mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC) & 0x0001) {
                d = irq_desc + LOCOMO_IRQ_KEY_START;
-               desc_handle_irq(LOCOMO_IRQ_KEY_START, d, regs);
+               desc_handle_irq(LOCOMO_IRQ_KEY_START, d);
        }
 }
 
@@ -264,8 +262,7 @@ static struct irq_chip locomo_key_chip = {
        .unmask = locomo_key_unmask_irq,
 };
 
-static void locomo_gpio_handler(unsigned int irq, struct irqdesc *desc,
-                            struct pt_regs *regs)
+static void locomo_gpio_handler(unsigned int irq, struct irqdesc *desc)
 {
        int req, i;
        struct irqdesc *d;
@@ -280,7 +277,7 @@ static void locomo_gpio_handler(unsigned int irq, struct irqdesc *desc,
                d = irq_desc + LOCOMO_IRQ_GPIO_START;
                for (i = 0; i <= 15; i++, irq++, d++) {
                        if (req & (0x0001 << i)) {
-                               desc_handle_irq(irq, d, regs);
+                               desc_handle_irq(irq, d);
                        }
                }
        }
@@ -328,15 +325,14 @@ static struct irq_chip locomo_gpio_chip = {
        .unmask = locomo_gpio_unmask_irq,
 };
 
-static void locomo_lt_handler(unsigned int irq, struct irqdesc *desc,
-                          struct pt_regs *regs)
+static void locomo_lt_handler(unsigned int irq, struct irqdesc *desc)
 {
        struct irqdesc *d;
        void __iomem *mapbase = get_irq_chipdata(irq);
 
        if (locomo_readl(mapbase + LOCOMO_LTINT) & 0x0001) {
                d = irq_desc + LOCOMO_IRQ_LT_START;
-               desc_handle_irq(LOCOMO_IRQ_LT_START, d, regs);
+               desc_handle_irq(LOCOMO_IRQ_LT_START, d);
        }
 }
 
@@ -374,8 +370,7 @@ static struct irq_chip locomo_lt_chip = {
        .unmask = locomo_lt_unmask_irq,
 };
 
-static void locomo_spi_handler(unsigned int irq, struct irqdesc *desc,
-                           struct pt_regs *regs)
+static void locomo_spi_handler(unsigned int irq, struct irqdesc *desc)
 {
        int req, i;
        struct irqdesc *d;
@@ -388,7 +383,7 @@ static void locomo_spi_handler(unsigned int irq, struct irqdesc *desc,
 
                for (i = 0; i <= 3; i++, irq++, d++) {
                        if (req & (0x0001 << i)) {
-                               desc_handle_irq(irq, d, regs);
+                               desc_handle_irq(irq, d);
                        }
                }
        }
index 30046ad41cedd52fd3884deced4a242f1a5186d1..d5f72010a6f315c122fb50f211690eec45ed39b6 100644 (file)
@@ -147,7 +147,7 @@ void __init sa1111_adjust_zones(int node, unsigned long *size, unsigned long *ho
  * will call us again if there are more interrupts to process.
  */
 static void
-sa1111_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
+sa1111_irq_handler(unsigned int irq, struct irqdesc *desc)
 {
        unsigned int stat0, stat1, i;
        void __iomem *base = get_irq_data(irq);
@@ -162,17 +162,17 @@ sa1111_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
        sa1111_writel(stat1, base + SA1111_INTSTATCLR1);
 
        if (stat0 == 0 && stat1 == 0) {
-               do_bad_IRQ(irq, desc, regs);
+               do_bad_IRQ(irq, desc);
                return;
        }
 
        for (i = IRQ_SA1111_START; stat0; i++, stat0 >>= 1)
                if (stat0 & 1)
-                       handle_edge_irq(i, irq_desc + i, regs);
+                       handle_edge_irq(i, irq_desc + i);
 
        for (i = IRQ_SA1111_START + 32; stat1; i++, stat1 >>= 1)
                if (stat1 & 1)
-                       handle_edge_irq(i, irq_desc + i, regs);
+                       handle_edge_irq(i, irq_desc + i);
 
        /* For level-based interrupts */
        desc->chip->unmask(irq);
index f412dedda68412b2c6ac239826e1adc14f03931a..605dedf967907cf3f360f194e467ff5b0b5b7375 100644 (file)
@@ -258,7 +258,7 @@ static void sharpsl_ac_timer(unsigned long data)
 }
 
 
-irqreturn_t sharpsl_ac_isr(int irq, void *dev_id, struct pt_regs *fp)
+irqreturn_t sharpsl_ac_isr(int irq, void *dev_id)
 {
        /* Delay the event slightly to debounce */
        /* Must be a smaller delay than the chrg_full_isr below */
@@ -293,7 +293,7 @@ static void sharpsl_chrg_full_timer(unsigned long data)
 /* Charging Finished Interrupt (Not present on Corgi) */
 /* Can trigger at the same time as an AC staus change so
    delay until after that has been processed */
-irqreturn_t sharpsl_chrg_full_isr(int irq, void *dev_id, struct pt_regs *fp)
+irqreturn_t sharpsl_chrg_full_isr(int irq, void *dev_id)
 {
        if (sharpsl_pm.flags & SHARPSL_SUSPENDED)
                return IRQ_HANDLED;
@@ -304,7 +304,7 @@ irqreturn_t sharpsl_chrg_full_isr(int irq, void *dev_id, struct pt_regs *fp)
        return IRQ_HANDLED;
 }
 
-irqreturn_t sharpsl_fatal_isr(int irq, void *dev_id, struct pt_regs *fp)
+irqreturn_t sharpsl_fatal_isr(int irq, void *dev_id)
 {
        int is_fatal = 0;
 
index 3f60dd9aca80bfb7961329d8dfc39004d5ef7be1..34038eccbba9e478b3bfb75ec283e289fee63cb2 100644 (file)
@@ -67,10 +67,10 @@ void __init ioctime_init(void)
 }
 
 static irqreturn_t
-ioc_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+ioc_timer_interrupt(int irq, void *dev_id)
 {
        write_seqlock(&xtime_lock);
-       timer_tick(regs);
+       timer_tick();
        write_sequnlock(&xtime_lock);
        return IRQ_HANDLED;
 }
index da69e660574bf1510f8f1457d07c7368b7de12e2..4779f474f9113ac0a87aa0ae41ac332b02033484 100644 (file)
@@ -178,9 +178,3 @@ EXPORT_SYMBOL(_find_next_zero_bit_be);
 EXPORT_SYMBOL(_find_first_bit_be);
 EXPORT_SYMBOL(_find_next_bit_be);
 #endif
-
-       /* syscalls */
-EXPORT_SYMBOL(sys_write);
-EXPORT_SYMBOL(sys_lseek);
-EXPORT_SYMBOL(sys_exit);
-EXPORT_SYMBOL(sys_wait4);
index 3e14b1348c0b715d77c77390bdd12e95668c5e0a..b27513a0f11ee292502ce47152c21e10154e1de4 100644 (file)
@@ -567,7 +567,7 @@ static void ecard_check_lockup(struct irqdesc *desc)
 }
 
 static void
-ecard_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
+ecard_irq_handler(unsigned int irq, struct irqdesc *desc)
 {
        ecard_t *ec;
        int called = 0;
@@ -586,7 +586,7 @@ ecard_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
 
                if (pending) {
                        struct irqdesc *d = irq_desc + ec->irq;
-                       desc_handle_irq(ec->irq, d, regs);
+                       desc_handle_irq(ec->irq, d);
                        called ++;
                }
        }
@@ -609,7 +609,7 @@ static unsigned char first_set[] =
 };
 
 static void
-ecard_irqexp_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
+ecard_irqexp_handler(unsigned int irq, struct irqdesc *desc)
 {
        const unsigned int statusmask = 15;
        unsigned int status;
@@ -633,7 +633,7 @@ ecard_irqexp_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *reg
                         * Serial cards should go in 0/1, ethernet/scsi in 2/3
                         * otherwise you will lose serial data at high speeds!
                         */
-                       desc_handle_irq(ec->irq, d, regs);
+                       desc_handle_irq(ec->irq, d);
                } else {
                        printk(KERN_WARNING "card%d: interrupt from unclaimed "
                               "card???\n", slot);
index 2e1bf830fe11bf0523b2e37cbefaa32d50db4d55..2c4ff1cbe33490df3d4c37e08817eae074ae68ad 100644 (file)
@@ -111,6 +111,7 @@ static struct irq_desc bad_irq_desc = {
  */
 asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
 {
+       struct pt_regs *old_regs = set_irq_regs(regs);
        struct irqdesc *desc = irq_desc + irq;
 
        /*
@@ -122,12 +123,13 @@ asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
 
        irq_enter();
 
-       desc_handle_irq(irq, desc, regs);
+       desc_handle_irq(irq, desc);
 
        /* AT91 specific workaround */
        irq_finish(irq);
 
        irq_exit();
+       set_irq_regs(old_regs);
 }
 
 void set_irq_flags(unsigned int irq, unsigned int iflags)
index b030320b17c7eef06e1a66ddd084b67867aa235f..c03cab5c4c798e763108480de6382312f41ba5ca 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/profile.h>
 #include <linux/sysdev.h>
 #include <linux/timer.h>
+#include <linux/irq.h>
 
 #include <asm/leds.h>
 #include <asm/thread_info.h>
@@ -324,9 +325,10 @@ EXPORT_SYMBOL(restore_time_delta);
 /*
  * Kernel system timer support.
  */
-void timer_tick(struct pt_regs *regs)
+void timer_tick(void)
 {
-       profile_tick(CPU_PROFILING, regs);
+       struct pt_regs *regs = get_irq_regs();
+       profile_tick(CPU_PROFILING);
        do_leds();
        do_set_rtc();
        do_timer(1);
index baa997c857dc938afd3353cd1616a57fdc622451..fe3d297d682d2ba19fd224f9c7cf9ce3ad63eeef 100644 (file)
@@ -127,12 +127,12 @@ static unsigned long aaec2000_gettimeoffset(void)
 
 /* We enter here with IRQs enabled */
 static irqreturn_t
-aaec2000_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+aaec2000_timer_interrupt(int irq, void *dev_id)
 {
        /* TODO: Check timer accuracy */
        write_seqlock(&xtime_lock);
 
-       timer_tick(regs);
+       timer_tick();
        TIMER1_CLEAR = 1;
 
        write_sequnlock(&xtime_lock);
index a92a8622c78a04857712b34fc661cc7dd617c8ea..07c9cea8961d745742d83490802f2a4a05888120 100644 (file)
@@ -65,13 +65,13 @@ static unsigned long at91rm9200_gettimeoffset(void)
 /*
  * IRQ handler for the timer.
  */
-static irqreturn_t at91rm9200_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t at91rm9200_timer_interrupt(int irq, void *dev_id)
 {
        if (at91_sys_read(AT91_ST_SR) & AT91_ST_PITS) { /* This is a shared interrupt */
                write_seqlock(&xtime_lock);
 
                while (((read_CRTR() - last_crtr) & AT91_ST_ALMV) >= LATCH) {
-                       timer_tick(regs);
+                       timer_tick();
                        last_crtr = (last_crtr + LATCH) & AT91_ST_ALMV;
                }
 
index 58c9bf5e95205f1e4ecbed09d85b175f284a5a22..7467d644f0a3406c7ccc939d4f19e0f9ff8ab2aa 100644 (file)
@@ -332,7 +332,7 @@ static struct irq_chip gpio_irqchip = {
        .set_wake       = gpio_irq_set_wake,
 };
 
-static void gpio_irq_handler(unsigned irq, struct irqdesc *desc, struct pt_regs *regs)
+static void gpio_irq_handler(unsigned irq, struct irqdesc *desc)
 {
        unsigned        pin;
        struct irqdesc  *gpio;
@@ -363,7 +363,7 @@ static void gpio_irq_handler(unsigned irq, struct irqdesc *desc, struct pt_regs
                                        gpio_irq_mask(pin);
                                }
                                else
-                                       desc_handle_irq(pin, gpio, regs);
+                                       desc_handle_irq(pin, gpio);
                        }
                        pin++;
                        gpio++;
index a071eac4a30a3cd5617b914a34b87bae00b54b09..428493dd4687a73c6512ba1a3ec4ed2716e8407a 100644 (file)
@@ -48,10 +48,10 @@ static unsigned long clps711x_gettimeoffset(void)
  * IRQ handler for the timer
  */
 static irqreturn_t
-p720t_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+p720t_timer_interrupt(int irq, void *dev_id)
 {
        write_seqlock(&xtime_lock);
-       timer_tick(regs);
+       timer_tick();
        write_sequnlock(&xtime_lock);
        return IRQ_HANDLED;
 }
index 92eaebdd56061455fdfbb812e6b5cc3f4d861f57..fb10cf252588ac1174304095b3b1cf82d6aec710 100644 (file)
@@ -292,11 +292,11 @@ extern void ioctime_init(void);
 extern unsigned long ioc_timer_gettimeoffset(void);
 
 static irqreturn_t
-clps7500_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+clps7500_timer_interrupt(int irq, void *dev_id)
 {
        write_seqlock(&xtime_lock);
 
-       timer_tick(regs);
+       timer_tick();
 
        /* Why not using do_leds interface?? */
        {
index 70dd12ef3c40da46521d35a8bc527e8c546716b8..90103ab373a6ae8fbe830f5e96767ecbe197787c 100644 (file)
@@ -174,7 +174,7 @@ static unsigned long ebsa110_gettimeoffset(void)
 }
 
 static irqreturn_t
-ebsa110_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+ebsa110_timer_interrupt(int irq, void *dev_id)
 {
        u32 count;
 
@@ -190,7 +190,7 @@ ebsa110_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        __raw_writeb(count & 0xff, PIT_T1);
        __raw_writeb(count >> 8, PIT_T1);
 
-       timer_tick(regs);
+       timer_tick();
 
        write_sequnlock(&xtime_lock);
 
index a87a784b9201519db7e5138b68aa34b305c08f0b..e3fd1ab6adccfa4ca051a76a5a31a675b75c11a7 100644 (file)
@@ -97,7 +97,7 @@ static unsigned int last_jiffy_time;
 
 #define TIMER4_TICKS_PER_JIFFY         ((CLOCK_TICK_RATE + (HZ/2)) / HZ)
 
-static int ep93xx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static int ep93xx_timer_interrupt(int irq, void *dev_id)
 {
        write_seqlock(&xtime_lock);
 
@@ -106,7 +106,7 @@ static int ep93xx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                (__raw_readl(EP93XX_TIMER4_VALUE_LOW) - last_jiffy_time)
                                                >= TIMER4_TICKS_PER_JIFFY) {
                last_jiffy_time += TIMER4_TICKS_PER_JIFFY;
-               timer_tick(regs);
+               timer_tick();
        }
 
        write_sequnlock(&xtime_lock);
@@ -245,7 +245,7 @@ EXPORT_SYMBOL(gpio_line_set);
  * EP93xx IRQ handling
  *************************************************************************/
 static void ep93xx_gpio_ab_irq_handler(unsigned int irq,
-               struct irqdesc *desc, struct pt_regs *regs)
+               struct irqdesc *desc)
 {
        unsigned char status;
        int i;
@@ -254,7 +254,7 @@ static void ep93xx_gpio_ab_irq_handler(unsigned int irq,
        for (i = 0; i < 8; i++) {
                if (status & (1 << i)) {
                        desc = irq_desc + IRQ_EP93XX_GPIO(0) + i;
-                       desc_handle_irq(IRQ_EP93XX_GPIO(0) + i, desc, regs);
+                       desc_handle_irq(IRQ_EP93XX_GPIO(0) + i, desc);
                }
        }
 
@@ -262,7 +262,7 @@ static void ep93xx_gpio_ab_irq_handler(unsigned int irq,
        for (i = 0; i < 8; i++) {
                if (status & (1 << i)) {
                        desc = irq_desc + IRQ_EP93XX_GPIO(8) + i;
-                       desc_handle_irq(IRQ_EP93XX_GPIO(8) + i, desc, regs);
+                       desc_handle_irq(IRQ_EP93XX_GPIO(8) + i, desc);
                }
        }
 }
index 2af610811ca4247bda63c9a885163ba4891911e4..fa6be870c6c20cac3896bacfda7f52cbd93d6b85 100644 (file)
@@ -28,13 +28,13 @@ static unsigned long timer1_gettimeoffset (void)
 }
 
 static irqreturn_t
-timer1_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+timer1_interrupt(int irq, void *dev_id)
 {
        write_seqlock(&xtime_lock);
 
        *CSR_TIMER1_CLR = 0;
 
-       timer_tick(regs);
+       timer_tick();
 
        write_sequnlock(&xtime_lock);
 
index a1ae49df5c3be95c6ba23070a7369ee56b173a4c..1463330ed8ee6b441991f9ca801194f644499edf 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
+#include <linux/irq.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
@@ -154,7 +155,7 @@ static void dc21285_enable_error(unsigned long __data)
 /*
  * Warn on PCI errors.
  */
-static irqreturn_t dc21285_abort_irq(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t dc21285_abort_irq(int irq, void *dev_id)
 {
        unsigned int cmd;
        unsigned int status;
@@ -165,7 +166,7 @@ static irqreturn_t dc21285_abort_irq(int irq, void *dev_id, struct pt_regs *regs
 
        if (status & PCI_STATUS_REC_MASTER_ABORT) {
                printk(KERN_DEBUG "PCI: master abort, pc=0x%08lx\n",
-                       instruction_pointer(regs));
+                       instruction_pointer(get_irq_regs()));
                cmd |= PCI_STATUS_REC_MASTER_ABORT << 16;
        }
 
@@ -184,7 +185,7 @@ static irqreturn_t dc21285_abort_irq(int irq, void *dev_id, struct pt_regs *regs
        return IRQ_HANDLED;
 }
 
-static irqreturn_t dc21285_serr_irq(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t dc21285_serr_irq(int irq, void *dev_id)
 {
        struct timer_list *timer = dev_id;
        unsigned int cntl;
@@ -206,7 +207,7 @@ static irqreturn_t dc21285_serr_irq(int irq, void *dev_id, struct pt_regs *regs)
        return IRQ_HANDLED;
 }
 
-static irqreturn_t dc21285_discard_irq(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t dc21285_discard_irq(int irq, void *dev_id)
 {
        printk(KERN_DEBUG "PCI: discard timer expired\n");
        *CSR_SA110_CNTL &= 0xffffde07;
@@ -214,7 +215,7 @@ static irqreturn_t dc21285_discard_irq(int irq, void *dev_id, struct pt_regs *re
        return IRQ_HANDLED;
 }
 
-static irqreturn_t dc21285_dparity_irq(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t dc21285_dparity_irq(int irq, void *dev_id)
 {
        unsigned int cmd;
 
@@ -228,7 +229,7 @@ static irqreturn_t dc21285_dparity_irq(int irq, void *dev_id, struct pt_regs *re
        return IRQ_HANDLED;
 }
 
-static irqreturn_t dc21285_parity_irq(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t dc21285_parity_irq(int irq, void *dev_id)
 {
        struct timer_list *timer = dev_id;
        unsigned int cmd;
index 87448c2d6baa192fb621047ee47d1b0e3e1133d4..888dedd501b9b94ce4a7bef35e98b9f9868a28fa 100644 (file)
@@ -85,17 +85,17 @@ static struct irqchip isa_hi_chip = {
 };
 
 static void
-isa_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
+isa_irq_handler(unsigned int irq, struct irqdesc *desc)
 {
        unsigned int isa_irq = *(unsigned char *)PCIIACK_BASE;
 
        if (isa_irq < _ISA_IRQ(0) || isa_irq >= _ISA_IRQ(16)) {
-               do_bad_IRQ(isa_irq, desc, regs);
+               do_bad_IRQ(isa_irq, desc);
                return;
        }
 
        desc = irq_desc + isa_irq;
-       desc_handle_irq(isa_irq, desc, regs);
+       desc_handle_irq(isa_irq, desc);
 }
 
 static struct irqaction irq_cascade = {
index c4810a40c8e1275e9d63e1670d4db71d7876beb2..d884a3954fb4c843290e3cb08375adf24eea680e 100644 (file)
@@ -62,10 +62,10 @@ static unsigned long isa_gettimeoffset(void)
 }
 
 static irqreturn_t
-isa_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+isa_timer_interrupt(int irq, void *dev_id)
 {
        write_seqlock(&xtime_lock);
-       timer_tick(regs);
+       timer_tick();
        write_sequnlock(&xtime_lock);
        return IRQ_HANDLED;
 }
index c096b45693084f4bbab9a15ed3c20dadb32ce0c2..4719229a1a78555d1b61dbfe4b746f3e4b41fbc3 100644 (file)
@@ -101,14 +101,14 @@ static void inline unmask_gpio_irq(u32 irq)
 
 static void
 h720x_gpio_handler(unsigned int mask, unsigned int irq,
-                 struct irqdesc *desc, struct pt_regs *regs)
+                 struct irqdesc *desc)
 {
        IRQDBG("%s irq: %d\n",__FUNCTION__,irq);
        desc = irq_desc + irq;
        while (mask) {
                if (mask & 1) {
                        IRQDBG("handling irq %d\n", irq);
-                       desc_handle_irq(irq, desc, regs);
+                       desc_handle_irq(irq, desc);
                }
                irq++;
                desc++;
@@ -117,63 +117,58 @@ h720x_gpio_handler(unsigned int mask, unsigned int irq,
 }
 
 static void
-h720x_gpioa_demux_handler(unsigned int irq_unused, struct irqdesc *desc,
-                       struct pt_regs *regs)
+h720x_gpioa_demux_handler(unsigned int irq_unused, struct irqdesc *desc)
 {
        unsigned int mask, irq;
 
        mask = CPU_REG(GPIO_A_VIRT,GPIO_STAT);
        irq = IRQ_CHAINED_GPIOA(0);
        IRQDBG("%s mask: 0x%08x irq: %d\n",__FUNCTION__,mask,irq);
-       h720x_gpio_handler(mask, irq, desc, regs);
+       h720x_gpio_handler(mask, irq, desc);
 }
 
 static void
-h720x_gpiob_demux_handler(unsigned int irq_unused, struct irqdesc *desc,
-                       struct pt_regs *regs)
+h720x_gpiob_demux_handler(unsigned int irq_unused, struct irqdesc *desc)
 {
        unsigned int mask, irq;
        mask = CPU_REG(GPIO_B_VIRT,GPIO_STAT);
        irq = IRQ_CHAINED_GPIOB(0);
        IRQDBG("%s mask: 0x%08x irq: %d\n",__FUNCTION__,mask,irq);
-       h720x_gpio_handler(mask, irq, desc, regs);
+       h720x_gpio_handler(mask, irq, desc);
 }
 
 static void
-h720x_gpioc_demux_handler(unsigned int irq_unused, struct irqdesc *desc,
-                       struct pt_regs *regs)
+h720x_gpioc_demux_handler(unsigned int irq_unused, struct irqdesc *desc)
 {
        unsigned int mask, irq;
 
        mask = CPU_REG(GPIO_C_VIRT,GPIO_STAT);
        irq = IRQ_CHAINED_GPIOC(0);
        IRQDBG("%s mask: 0x%08x irq: %d\n",__FUNCTION__,mask,irq);
-       h720x_gpio_handler(mask, irq, desc, regs);
+       h720x_gpio_handler(mask, irq, desc);
 }
 
 static void
-h720x_gpiod_demux_handler(unsigned int irq_unused, struct irqdesc *desc,
-                       struct pt_regs *regs)
+h720x_gpiod_demux_handler(unsigned int irq_unused, struct irqdesc *desc)
 {
        unsigned int mask, irq;
 
        mask = CPU_REG(GPIO_D_VIRT,GPIO_STAT);
        irq = IRQ_CHAINED_GPIOD(0);
        IRQDBG("%s mask: 0x%08x irq: %d\n",__FUNCTION__,mask,irq);
-       h720x_gpio_handler(mask, irq, desc, regs);
+       h720x_gpio_handler(mask, irq, desc);
 }
 
 #ifdef CONFIG_CPU_H7202
 static void
-h720x_gpioe_demux_handler(unsigned int irq_unused, struct irqdesc *desc,
-                       struct pt_regs *regs)
+h720x_gpioe_demux_handler(unsigned int irq_unused, struct irqdesc *desc)
 {
        unsigned int mask, irq;
 
        mask = CPU_REG(GPIO_E_VIRT,GPIO_STAT);
        irq = IRQ_CHAINED_GPIOE(0);
        IRQDBG("%s mask: 0x%08x irq: %d\n",__FUNCTION__,mask,irq);
-       h720x_gpio_handler(mask, irq, desc, regs);
+       h720x_gpio_handler(mask, irq, desc);
 }
 #endif
 
index a9a8255a3a0397deaf698d46e5f4587ea0931db8..13f76bdb3d9d6ebacd029eb53d69dd8989de835a 100644 (file)
  * Timer interrupt handler
  */
 static irqreturn_t
-h7201_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+h7201_timer_interrupt(int irq, void *dev_id)
 {
        write_seqlock(&xtime_lock);
 
        CPU_REG (TIMER_VIRT, TIMER_TOPSTAT);
-       timer_tick(regs);
+       timer_tick();
 
        write_sequnlock(&xtime_lock);
 
index da678d163fd992487ba97ef48a1c6bb3247ac4dd..06fecaefd8dcaf249e1ba48bbc03aa672aed3a27 100644 (file)
@@ -106,8 +106,7 @@ static struct platform_device *devices[] __initdata = {
  * we have to handle all timer interrupts in one place.
  */
 static void
-h7202_timerx_demux_handler(unsigned int irq_unused, struct irqdesc *desc,
-                       struct pt_regs *regs)
+h7202_timerx_demux_handler(unsigned int irq_unused, struct irqdesc *desc)
 {
        unsigned int mask, irq;
 
@@ -115,7 +114,7 @@ h7202_timerx_demux_handler(unsigned int irq_unused, struct irqdesc *desc,
 
        if ( mask & TSTAT_T0INT ) {
                write_seqlock(&xtime_lock);
-               timer_tick(regs);
+               timer_tick();
                write_sequnlock(&xtime_lock);
                if( mask == TSTAT_T0INT )
                        return;
@@ -126,7 +125,7 @@ h7202_timerx_demux_handler(unsigned int irq_unused, struct irqdesc *desc,
        desc = irq_desc + irq;
        while (mask) {
                if (mask & 1)
-                       desc_handle_irq(irq, desc, regs);
+                       desc_handle_irq(irq, desc);
                irq++;
                desc++;
                mask >>= 1;
@@ -137,9 +136,9 @@ h7202_timerx_demux_handler(unsigned int irq_unused, struct irqdesc *desc,
  * Timer interrupt handler
  */
 static irqreturn_t
-h7202_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+h7202_timer_interrupt(int irq, void *dev_id)
 {
-       h7202_timerx_demux_handler(0, NULL, regs);
+       h7202_timerx_demux_handler(0, NULL);
        return IRQ_HANDLED;
 }
 
index 36578871ecc870de68eca19e96c4afce4bd21b99..6d50d85a618ca397b410ad1264a6485a43020de7 100644 (file)
@@ -279,8 +279,8 @@ imx_dma_setup_sg(imx_dmach_t dma_ch,
  */
 int
 imx_dma_setup_handlers(imx_dmach_t dma_ch,
-                      void (*irq_handler) (int, void *, struct pt_regs *),
-                      void (*err_handler) (int, void *, struct pt_regs *, int),
+                      void (*irq_handler) (int, void *),
+                      void (*err_handler) (int, void *, int),
                       void *data)
 {
        struct imx_dma_channel *imxdma = &imx_dma_channels[dma_ch];
@@ -461,7 +461,7 @@ imx_dma_request_by_prio(imx_dmach_t * pdma_ch, const char *name,
        return -ENODEV;
 }
 
-static irqreturn_t dma_err_handler(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t dma_err_handler(int irq, void *dev_id)
 {
        int i, disr = DISR;
        struct imx_dma_channel *channel;
@@ -500,7 +500,7 @@ static irqreturn_t dma_err_handler(int irq, void *dev_id, struct pt_regs *regs)
                /*imx_dma_channels[i].sg = NULL;*/
 
                if (channel->name && channel->err_handler) {
-                       channel->err_handler(i, channel->data, regs, errcode);
+                       channel->err_handler(i, channel->data, errcode);
                        continue;
                }
 
@@ -517,7 +517,7 @@ static irqreturn_t dma_err_handler(int irq, void *dev_id, struct pt_regs *regs)
        return IRQ_HANDLED;
 }
 
-static irqreturn_t dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t dma_irq_handler(int irq, void *dev_id)
 {
        int i, disr = DISR;
 
@@ -536,7 +536,7 @@ static irqreturn_t dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
                                } else {
                                        if (channel->irq_handler)
                                                channel->irq_handler(i,
-                                                       channel->data, regs);
+                                                       channel->data);
                                }
                        } else {
                                /*
index 2688bd82c2a242addcc62822b90b461d509ec0f3..368b13b058ab1c8e3e852e45be97c59faf9faa51 100644 (file)
@@ -146,13 +146,13 @@ imx_gpio_unmask_irq(unsigned int irq)
 
 static void
 imx_gpio_handler(unsigned int mask, unsigned int irq,
-                 struct irqdesc *desc, struct pt_regs *regs)
+                 struct irqdesc *desc)
 {
        desc = irq_desc + irq;
        while (mask) {
                if (mask & 1) {
                        DEBUG_IRQ("handling irq %d\n", irq);
-                       desc_handle_irq(irq, desc, regs);
+                       desc_handle_irq(irq, desc);
                }
                irq++;
                desc++;
@@ -161,47 +161,43 @@ imx_gpio_handler(unsigned int mask, unsigned int irq,
 }
 
 static void
-imx_gpioa_demux_handler(unsigned int irq_unused, struct irqdesc *desc,
-                       struct pt_regs *regs)
+imx_gpioa_demux_handler(unsigned int irq_unused, struct irqdesc *desc)
 {
        unsigned int mask, irq;
 
        mask = ISR(0);
        irq = IRQ_GPIOA(0);
-       imx_gpio_handler(mask, irq, desc, regs);
+       imx_gpio_handler(mask, irq, desc);
 }
 
 static void
-imx_gpiob_demux_handler(unsigned int irq_unused, struct irqdesc *desc,
-                       struct pt_regs *regs)
+imx_gpiob_demux_handler(unsigned int irq_unused, struct irqdesc *desc)
 {
        unsigned int mask, irq;
 
        mask = ISR(1);
        irq = IRQ_GPIOB(0);
-       imx_gpio_handler(mask, irq, desc, regs);
+       imx_gpio_handler(mask, irq, desc);
 }
 
 static void
-imx_gpioc_demux_handler(unsigned int irq_unused, struct irqdesc *desc,
-                       struct pt_regs *regs)
+imx_gpioc_demux_handler(unsigned int irq_unused, struct irqdesc *desc)
 {
        unsigned int mask, irq;
 
        mask = ISR(2);
        irq = IRQ_GPIOC(0);
-       imx_gpio_handler(mask, irq, desc, regs);
+       imx_gpio_handler(mask, irq, desc);
 }
 
 static void
-imx_gpiod_demux_handler(unsigned int irq_unused, struct irqdesc *desc,
-                       struct pt_regs *regs)
+imx_gpiod_demux_handler(unsigned int irq_unused, struct irqdesc *desc)
 {
        unsigned int mask, irq;
 
        mask = ISR(3);
        irq = IRQ_GPIOD(0);
-       imx_gpio_handler(mask, irq, desc, regs);
+       imx_gpio_handler(mask, irq, desc);
 }
 
 static struct irq_chip imx_internal_chip = {
index 6ed7523c65bb6f8bf51bb1de03afb398395ffa16..8ae4a2c5066fc2a55e7bec5c46377162aa119cc6 100644 (file)
@@ -56,7 +56,7 @@ static unsigned long imx_gettimeoffset(void)
  * IRQ handler for the timer
  */
 static irqreturn_t
-imx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+imx_timer_interrupt(int irq, void *dev_id)
 {
        write_seqlock(&xtime_lock);
 
@@ -64,7 +64,7 @@ imx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        if (IMX_TSTAT(TIMER_BASE))
                IMX_TSTAT(TIMER_BASE) = 0;
 
-       timer_tick(regs);
+       timer_tick();
        write_sequnlock(&xtime_lock);
 
        return IRQ_HANDLED;
index 42021fdfa0c67790634c22eac3df24a47c1b5b13..8d880cb9ba39f4795166274d961f7763b87a7083 100644 (file)
@@ -248,7 +248,7 @@ unsigned long integrator_gettimeoffset(void)
  * IRQ handler for the timer
  */
 static irqreturn_t
-integrator_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+integrator_timer_interrupt(int irq, void *dev_id)
 {
        write_seqlock(&xtime_lock);
 
@@ -262,7 +262,7 @@ integrator_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
         * primary CPU
         */
        if (hard_smp_processor_id() == 0) {
-               timer_tick(regs);
+               timer_tick();
 #ifdef CONFIG_SMP
                smp_send_timer();
 #endif
@@ -272,7 +272,7 @@ integrator_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        /*
         * this is the ARM equivalent of the APIC timer interrupt
         */
-       update_process_times(user_mode(regs));
+       update_process_times(user_mode(get_irq_regs()));
 #endif /* CONFIG_SMP */
 
        write_sequnlock(&xtime_lock);
index 678b6ba2b463ac020c9f9fc0edbd20dde4fcf7f3..771b65bffe69edd206f0e1de6bc1f34692c56e51 100644 (file)
@@ -202,12 +202,12 @@ static struct irq_chip sic_chip = {
 };
 
 static void
-sic_handle_irq(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
+sic_handle_irq(unsigned int irq, struct irqdesc *desc)
 {
        unsigned long status = sic_readl(INTCP_VA_SIC_BASE + IRQ_STATUS);
 
        if (status == 0) {
-               do_bad_IRQ(irq, desc, regs);
+               do_bad_IRQ(irq, desc);
                return;
        }
 
@@ -218,7 +218,7 @@ sic_handle_irq(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
                irq += IRQ_SIC_START;
 
                desc = irq_desc + irq;
-               desc_handle_irq(irq, desc, regs);
+               desc_handle_irq(irq, desc);
        } while (status);
 }
 
index 4418f6d7572d015310b23626450a4b8cf88ba1d5..fb8c6d97b22b3c4975d3403606828331fb5ad13a 100644 (file)
@@ -440,9 +440,10 @@ v3_pci_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
        return 1;
 }
 
-static irqreturn_t v3_irq(int irq, void *devid, struct pt_regs *regs)
+static irqreturn_t v3_irq(int irq, void *devid)
 {
 #ifdef CONFIG_DEBUG_LL
+       struct pt_regs *regs = get_irq_regs();
        unsigned long pc = instruction_pointer(regs);
        unsigned long instr = *(unsigned long *)pc;
        char buf[128];
index ee49cf790dab5f2570366fa7b4cf789ffb770628..5278f589fcee29ea4204bc44be9adc9a8b41835b 100644 (file)
@@ -96,8 +96,7 @@ static struct rtc_ops rtc_ops = {
        .set_alarm      = integrator_rtc_set_alarm,
 };
 
-static irqreturn_t arm_rtc_interrupt(int irq, void *dev_id,
-                                    struct pt_regs *regs)
+static irqreturn_t arm_rtc_interrupt(int irq, void *dev_id)
 {
        writel(0, rtc_base + RTC_EOI);
        return IRQ_HANDLED;
index 7f91f689a04106c47cac822756d50dc946c5f185..22c98e9dad280aff426b4070a24a0a9ec5971ffd 100644 (file)
@@ -204,7 +204,7 @@ unsigned long ixp2000_gettimeoffset (void)
        return offset / ticks_per_usec;
 }
 
-static int ixp2000_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static int ixp2000_timer_interrupt(int irq, void *dev_id)
 {
        write_seqlock(&xtime_lock);
 
@@ -213,7 +213,7 @@ static int ixp2000_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 
        while ((signed long)(next_jiffy_time - *missing_jiffy_timer_csr)
                                                        >= ticks_per_jiffy) {
-               timer_tick(regs);
+               timer_tick();
                next_jiffy_time -= ticks_per_jiffy;
        }
 
@@ -308,7 +308,7 @@ EXPORT_SYMBOL(gpio_line_config);
 /*************************************************************************
  * IRQ handling IXP2000
  *************************************************************************/
-static void ixp2000_GPIO_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
+static void ixp2000_GPIO_irq_handler(unsigned int irq, struct irqdesc *desc)
 {                               
        int i;
        unsigned long status = *IXP2000_GPIO_INST;
@@ -316,7 +316,7 @@ static void ixp2000_GPIO_irq_handler(unsigned int irq, struct irqdesc *desc, str
        for (i = 0; i <= 7; i++) {
                if (status & (1<<i)) {
                        desc = irq_desc + i + IRQ_IXP2000_GPIO0;
-                       desc_handle_irq(i + IRQ_IXP2000_GPIO0, desc, regs);
+                       desc_handle_irq(i + IRQ_IXP2000_GPIO0, desc);
                }
        }
 }
@@ -401,7 +401,7 @@ static void ixp2000_pci_irq_unmask(unsigned int irq)
 /*
  * Error interrupts. These are used extensively by the microengine drivers
  */
-static void ixp2000_err_irq_handler(unsigned int irq, struct irqdesc *desc,  struct pt_regs *regs)
+static void ixp2000_err_irq_handler(unsigned int irq, struct irqdesc *desc)
 {
        int i;
        unsigned long status = *IXP2000_IRQ_ERR_STATUS;
@@ -409,7 +409,7 @@ static void ixp2000_err_irq_handler(unsigned int irq, struct irqdesc *desc,  str
        for(i = 31; i >= 0; i--) {
                if(status & (1 << i)) {
                        desc = irq_desc + IRQ_IXP2000_DRAM0_MIN_ERR + i;
-                       desc_handle_irq(IRQ_IXP2000_DRAM0_MIN_ERR + i, desc, regs);
+                       desc_handle_irq(IRQ_IXP2000_DRAM0_MIN_ERR + i, desc);
                }
        }
 }
index a6f14801872d3aa73f75b26dd2d4bb31d45f4f7b..9ee63834e6031839a7776492adaa734d5a27347b 100644 (file)
@@ -133,11 +133,13 @@ static void ixdp2400_pci_postinit(void)
        struct pci_dev *dev;
 
        if (ixdp2x00_master_npu()) {
-               dev = pci_find_slot(1, IXDP2400_SLAVE_ENET_DEVFN);
+               dev = pci_get_bus_and_slot(1, IXDP2400_SLAVE_ENET_DEVFN);
                pci_remove_bus_device(dev);
+               pci_dev_put(dev)
        } else {
-               dev = pci_find_slot(1, IXDP2400_MASTER_ENET_DEVFN);
+               dev = pci_get_bus_and_slot(1, IXDP2400_MASTER_ENET_DEVFN);
                pci_remove_bus_device(dev);
+               pci_dev_put(dev)
 
                ixdp2x00_slave_pci_postinit();
        }
index 91d36d91dac03f501a4a3c4377a9802ac13d7082..70d247f09a7ecebe5451f4290efdea4c362b0bbb 100644 (file)
@@ -261,14 +261,16 @@ int __init ixdp2800_pci_init(void)
 
                pci_common_init(&ixdp2800_pci);
                if (ixdp2x00_master_npu()) {
-                       dev = pci_find_slot(1, IXDP2800_SLAVE_ENET_DEVFN);
+                       dev = pci_get_bus_and_slot(1, IXDP2800_SLAVE_ENET_DEVFN);
                        pci_remove_bus_device(dev);
+                       pci_dev_put(dev);
 
                        ixdp2800_master_enable_slave();
                        ixdp2800_master_wait_for_slave_bus_scan();
                } else {
-                       dev = pci_find_slot(1, IXDP2800_MASTER_ENET_DEVFN);
+                       dev = pci_get_bus_and_slot(1, IXDP2800_MASTER_ENET_DEVFN);
                        pci_remove_bus_device(dev);
+                       pci_dev_put(dev);
                }
        }
 
index 40eef8b367407dd0a6ab61cb46d0484d8c54db60..aa2655092d2dc728805609969a7bbf43331e4ef8 100644 (file)
@@ -106,7 +106,7 @@ static void ixdp2x00_irq_unmask(unsigned int irq)
                ixp2000_release_slowport(&old_cfg);
 }
 
-static void ixdp2x00_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
+static void ixdp2x00_irq_handler(unsigned int irq, struct irqdesc *desc)
 {
         volatile u32 ex_interrupt = 0;
        static struct slowport_cfg old_cfg;
@@ -132,7 +132,7 @@ static void ixdp2x00_irq_handler(unsigned int irq, struct irqdesc *desc, struct
                        struct irqdesc *cpld_desc;
                        int cpld_irq = IXP2000_BOARD_IRQ(0) + i;
                        cpld_desc = irq_desc + cpld_irq;
-                       desc_handle_irq(cpld_irq, cpld_desc, regs);
+                       desc_handle_irq(cpld_irq, cpld_desc);
                }
        }
 
@@ -241,11 +241,14 @@ void ixdp2x00_slave_pci_postinit(void)
        /*
         * Remove PMC device is there is one
         */
-       if((dev = pci_find_slot(1, IXDP2X00_PMC_DEVFN)))
+       if((dev = pci_get_bus_and_slot(1, IXDP2X00_PMC_DEVFN))) {
                pci_remove_bus_device(dev);
+               pci_dev_put(dev);
+       }
 
-       dev = pci_find_slot(0, IXDP2X00_21555_DEVFN);
+       dev = pci_get_bus_and_slot(0, IXDP2X00_21555_DEVFN);
        pci_remove_bus_device(dev);
+       pci_dev_put(dev);
 }
 
 /**************************************************************************
index 7f42366f60d165d11666666bf8593b8efa4f49ca..9ccae9e63f70deacdffc5fde976abd4d86677799 100644 (file)
@@ -63,7 +63,7 @@ static void ixdp2x01_irq_unmask(unsigned int irq)
 
 static u32 valid_irq_mask;
 
-static void ixdp2x01_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
+static void ixdp2x01_irq_handler(unsigned int irq, struct irqdesc *desc)
 {
        u32 ex_interrupt;
        int i;
@@ -82,7 +82,7 @@ static void ixdp2x01_irq_handler(unsigned int irq, struct irqdesc *desc, struct
                        struct irqdesc *cpld_desc;
                        int cpld_irq = IXP2000_BOARD_IRQ(0) + i;
                        cpld_desc = irq_desc + cpld_irq;
-                       desc_handle_irq(cpld_irq, cpld_desc, regs);
+                       desc_handle_irq(cpld_irq, cpld_desc);
                }
        }
 
index 566a07821c77a939ea638677971c5f9a471e1bb5..a704a1820048404e8f6ef7e8fc8be68f7a18c5a3 100644 (file)
@@ -251,7 +251,7 @@ static void ixp23xx_pci_irq_unmask(unsigned int irq)
 /*
  * TODO: Should this just be done at ASM level?
  */
-static void pci_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
+static void pci_handler(unsigned int irq, struct irqdesc *desc)
 {
        u32 pci_interrupt;
        unsigned int irqno;
@@ -271,7 +271,7 @@ static void pci_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *
        }
 
        int_desc = irq_desc + irqno;
-       desc_handle_irq(irqno, int_desc, regs);
+       desc_handle_irq(irqno, int_desc);
 
        desc->chip->unmask(irq);
 }
@@ -348,12 +348,12 @@ ixp23xx_gettimeoffset(void)
 }
 
 static irqreturn_t
-ixp23xx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+ixp23xx_timer_interrupt(int irq, void *dev_id)
 {
        /* Clear Pending Interrupt by writing '1' to it */
        *IXP23XX_TIMER_STATUS = IXP23XX_TIMER1_INT_PEND;
        while ((signed long)(*IXP23XX_TIMER_CONT - next_jiffy_time) >= LATCH) {
-               timer_tick(regs);
+               timer_tick();
                next_jiffy_time += LATCH;
        }
 
index 37a32e6bcca2d1e52cb88128f091cd5858efdc57..b6ab0e8bb5e826c2ae861bb4781cde3d052579ee 100644 (file)
@@ -60,7 +60,7 @@ static void ixdp2351_inta_unmask(unsigned int irq)
        *IXDP2351_CPLD_INTA_MASK_CLR_REG = IXDP2351_INTA_IRQ_MASK(irq);
 }
 
-static void ixdp2351_inta_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
+static void ixdp2351_inta_handler(unsigned int irq, struct irqdesc *desc)
 {
        u16 ex_interrupt =
                *IXDP2351_CPLD_INTA_STAT_REG & IXDP2351_INTA_IRQ_VALID;
@@ -74,7 +74,7 @@ static void ixdp2351_inta_handler(unsigned int irq, struct irqdesc *desc, struct
                        int cpld_irq =
                                IXP23XX_MACH_IRQ(IXDP2351_INTA_IRQ_BASE + i);
                        cpld_desc = irq_desc + cpld_irq;
-                       desc_handle_irq(cpld_irq, cpld_desc, regs);
+                       desc_handle_irq(cpld_irq, cpld_desc);
                }
        }
 
@@ -97,7 +97,7 @@ static void ixdp2351_intb_unmask(unsigned int irq)
        *IXDP2351_CPLD_INTB_MASK_CLR_REG = IXDP2351_INTB_IRQ_MASK(irq);
 }
 
-static void ixdp2351_intb_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
+static void ixdp2351_intb_handler(unsigned int irq, struct irqdesc *desc)
 {
        u16 ex_interrupt =
                *IXDP2351_CPLD_INTB_STAT_REG & IXDP2351_INTB_IRQ_VALID;
@@ -111,7 +111,7 @@ static void ixdp2351_intb_handler(unsigned int irq, struct irqdesc *desc, struct
                        int cpld_irq =
                                IXP23XX_MACH_IRQ(IXDP2351_INTB_IRQ_BASE + i);
                        cpld_desc = irq_desc + cpld_irq;
-                       desc_handle_irq(cpld_irq, cpld_desc, regs);
+                       desc_handle_irq(cpld_irq, cpld_desc);
                }
        }
 
index 35dd8b3824b0301a5d8fc9ecc4b849408c21324f..c7513f6eb50c3640e8e9562a72cd9163d1bfd276 100644 (file)
@@ -256,7 +256,7 @@ static unsigned volatile last_jiffy_time;
 
 #define CLOCK_TICKS_PER_USEC   ((CLOCK_TICK_RATE + USEC_PER_SEC/2) / USEC_PER_SEC)
 
-static irqreturn_t ixp4xx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t ixp4xx_timer_interrupt(int irq, void *dev_id)
 {
        write_seqlock(&xtime_lock);
 
@@ -267,7 +267,7 @@ static irqreturn_t ixp4xx_timer_interrupt(int irq, void *dev_id, struct pt_regs
         * Catch up with the real idea of time
         */
        while ((signed long)(*IXP4XX_OSTS - last_jiffy_time) >= LATCH) {
-               timer_tick(regs);
+               timer_tick();
                last_jiffy_time += LATCH;
        }
 
index 81ffcae1f56ea4cdcff61191e367ed51f01c745a..29aa98d3a7faeb4993213e29aee093fe0f389f88 100644 (file)
@@ -24,7 +24,7 @@
 
 #include <asm/mach-types.h>
 
-static irqreturn_t nas100d_reset_handler(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t nas100d_reset_handler(int irq, void *dev_id)
 {
        /* Signal init to do the ctrlaltdel action, this will bypass init if
         * it hasn't started and do a kernel_restart.
index a29b3b2b61b63cfb085ff54d2af53c1251fe316a..acd71e9c38a703792cc08d739ba1f0db81a2909b 100644 (file)
@@ -25,7 +25,7 @@
 
 #include <asm/mach-types.h>
 
-static irqreturn_t nslu2_power_handler(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t nslu2_power_handler(int irq, void *dev_id)
 {
        /* Signal init to do the ctrlaltdel action, this will bypass init if
         * it hasn't started and do a kernel_restart.
@@ -35,7 +35,7 @@ static irqreturn_t nslu2_power_handler(int irq, void *dev_id, struct pt_regs *re
        return IRQ_HANDLED;
 }
 
-static irqreturn_t nslu2_reset_handler(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t nslu2_reset_handler(int irq, void *dev_id)
 {
        /* This is the paper-clip reset, it shuts the machine down directly.
         */
index 4f2ab48800a50eb6ba15f8c1a2e6b4c72af5bcd2..15fbcc911fe76da4fa97a3bb1f68fbd2fc189b06 100644 (file)
@@ -71,14 +71,13 @@ static struct irq_chip kev7a400_cpld_chip = {
 };
 
 
-static void kev7a400_cpld_handler (unsigned int irq, struct irqdesc *desc,
-                                 struct pt_regs *regs)
+static void kev7a400_cpld_handler (unsigned int irq, struct irqdesc *desc)
 {
        u32 mask = CPLD_LATCHED_INTS;
        irq = IRQ_KEV7A400_CPLD;
        for (; mask; mask >>= 1, ++irq) {
                if (mask & 1)
-                       desc[irq].handle (irq, desc, regs);
+                       desc[irq].handle (irq, desc);
        }
 }
 
index a21b12f06c6b3aa2be8bf6ed66809212b036d6a4..8441e0a156cb2f28555c4eab291d6bd0af2c74c6 100644 (file)
@@ -207,8 +207,7 @@ static struct irq_chip lpd7a40x_cpld_chip = {
        .unmask = lh7a40x_unmask_cpld_irq,
 };
 
-static void lpd7a40x_cpld_handler (unsigned int irq, struct irqdesc *desc,
-                                 struct pt_regs *regs)
+static void lpd7a40x_cpld_handler (unsigned int irq, struct irqdesc *desc)
 {
        unsigned int mask = CPLD_INTERRUPTS;
 
index 18e8bb4eb202280446f251f20dc7f5f006a20d35..0ca20c6c83b7be253e4ae897f6ba2b01af90f496 100644 (file)
@@ -15,4 +15,4 @@ extern void lh7a404_init_irq (void);
 extern void lh7a40x_clcd_init (void);
 extern void lh7a40x_init_board_irq (void);
 
-#define IRQ_DISPATCH(irq) desc_handle_irq((irq),(irq_desc + irq), regs)
+#define IRQ_DISPATCH(irq) desc_handle_irq((irq),(irq_desc + irq))
index f9b3fe9174a5e1dadcd82f91e626f8d22270053f..646071334b8f107a2ee0b72620cefd33e02ff06c 100644 (file)
@@ -51,14 +51,13 @@ irq_chip lh7a400_cpld_chip = {
 };
 
 static void
-lh7a400_cpld_handler (unsigned int irq, struct irqdesc *desc,
-                     struct pt_regs *regs)
+lh7a400_cpld_handler (unsigned int irq, struct irqdesc *desc)
 {
        u32 mask = CPLD_LATCHED_INTS;
        irq = IRQ_KEV_7A400_CPLD;
        for (; mask; mask >>= 1, ++irq) {
                if (mask & 1)
-                       desc[irq].handle (irq, desc, regs);
+                       desc[irq].handle (irq, desc);
        }
 }
 
index d6055dde646877a1d304827863ec2b06482d421a..b20376804bbb19849bafdb7348143f6f3a4a60f1 100644 (file)
@@ -57,8 +57,7 @@ static struct irq_chip lh7a40x_cpld_chip = {
        .unmask = lh7a40x_unmask_cpld_irq,
 };
 
-static void lh7a40x_cpld_handler (unsigned int irq, struct irqdesc *desc,
-                                 struct pt_regs *regs)
+static void lh7a40x_cpld_handler (unsigned int irq, struct irqdesc *desc)
 {
        unsigned int mask = CPLD_INTERRUPTS;
 
index ad5652e0150719e7776a81c1b90afbdea5e6142f..bef3c4b68d3bb3e028521f3c140fb91e4f80f1eb 100644 (file)
 #endif
 
 static irqreturn_t
-lh7a40x_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+lh7a40x_timer_interrupt(int irq, void *dev_id)
 {
        write_seqlock(&xtime_lock);
 
        TIMER_EOI = 0;
-       timer_tick(regs);
+       timer_tick();
 
        write_sequnlock(&xtime_lock);
 
index af0b13534cfd5521430d02d158f8683e0c407cb9..edbbbdc3b06be2b50e0c40a46f92cc7b10bfdb64 100644 (file)
@@ -69,8 +69,7 @@ static struct platform_device *devices[] __initdata = {
 #endif
 
 static void
-netx_hif_demux_handler(unsigned int irq_unused, struct irqdesc *desc,
-                       struct pt_regs *regs)
+netx_hif_demux_handler(unsigned int irq_unused, struct irqdesc *desc)
 {
        unsigned int irq = NETX_IRQ_HIF_CHAINED(0);
        unsigned int stat;
@@ -83,7 +82,7 @@ netx_hif_demux_handler(unsigned int irq_unused, struct irqdesc *desc,
        while (stat) {
                if (stat & 1) {
                        DEBUG_IRQ("handling irq %d\n", irq);
-                       desc_handle_irq(irq, desc, regs);
+                       desc_handle_irq(irq, desc);
                }
                irq++;
                desc++;
index 6d72c81b7d9f3c67ea9a696559fa683b0a5e78f9..0993336c0b556aa837cdc8cb35989fc888b3268e 100644 (file)
@@ -38,11 +38,11 @@ static unsigned long netx_gettimeoffset(void)
  * IRQ handler for the timer
  */
 static irqreturn_t
-netx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+netx_timer_interrupt(int irq, void *dev_id)
 {
        write_seqlock(&xtime_lock);
 
-       timer_tick(regs);
+       timer_tick();
        write_sequnlock(&xtime_lock);
 
        /* acknowledge interrupt */
index 6b05647a6c01743504650c1021013b19dc367f51..3a622801d7b0f1548a98056250860a5cea4bac37 100644 (file)
@@ -327,7 +327,7 @@ static struct spi_board_info __initdata mistral_boardinfo[] = { {
 
 #ifdef CONFIG_PM
 static irqreturn_t
-osk_mistral_wake_interrupt(int irq, void *ignored, struct pt_regs *regs)
+osk_mistral_wake_interrupt(int irq, void *ignored)
 {
        return IRQ_HANDLED;
 }
index efe9bfc6e55f694c7c40921e0037e09be0e663be..8e40208b10bbf6f0c61f0c451ac92a3d51a800ab 100644 (file)
@@ -84,8 +84,7 @@ static void fpga_mask_ack_irq(unsigned int irq)
        fpga_ack_irq(irq);
 }
 
-void innovator_fpga_IRQ_demux(unsigned int irq, struct irqdesc *desc,
-                             struct pt_regs *regs)
+void innovator_fpga_IRQ_demux(unsigned int irq, struct irqdesc *desc)
 {
        struct irqdesc *d;
        u32 stat;
@@ -101,7 +100,7 @@ void innovator_fpga_IRQ_demux(unsigned int irq, struct irqdesc *desc,
             fpga_irq++, stat >>= 1) {
                if (stat & 1) {
                        d = irq_desc + fpga_irq;
-                       desc_handle_irq(fpga_irq, d, regs);
+                       desc_handle_irq(fpga_irq, d);
                }
        }
 }
index cd76185bab7478a03eeb08a572a64fc006adbb38..4834758d340c60a9bdec5b349a780443d9893e52 100644 (file)
@@ -682,8 +682,7 @@ static int omap_pm_finish(suspend_state_t state)
 }
 
 
-static irqreturn_t  omap_wakeup_interrupt(int  irq, void *  dev,
-                                    struct pt_regs *  regs)
+static irqreturn_t  omap_wakeup_interrupt(int irq, void *dev)
 {
        return IRQ_HANDLED;
 }
index c4b790217a5b0ab259ac8289d4a415ef578e81ed..4cc98a578e4bf5ed98ac048f702f2c519ae7a22d 100644 (file)
@@ -204,8 +204,7 @@ void __init omap_serial_init(void)
 
 #ifdef CONFIG_OMAP_SERIAL_WAKE
 
-static irqreturn_t omap_serial_wake_interrupt(int irq, void *dev_id,
-                                             struct pt_regs *regs)
+static irqreturn_t omap_serial_wake_interrupt(int irq, void *dev_id)
 {
        /* Need to do something with serial port right after wake-up? */
        return IRQ_HANDLED;
index 4d91b9f510843fa1ce45b441d30387637075df10..1b7e4a506c2646e66788aaa47f8056147ba4da4a 100644 (file)
@@ -160,8 +160,7 @@ static unsigned long omap_mpu_timer_gettimeoffset(void)
  * Latency during the interrupt is calculated using timer1.
  * Both timer0 and timer1 are counting at 6MHz (P2 6.5MHz).
  */
-static irqreturn_t omap_mpu_timer_interrupt(int irq, void *dev_id,
-                                       struct pt_regs *regs)
+static irqreturn_t omap_mpu_timer_interrupt(int irq, void *dev_id)
 {
        unsigned long now, latency;
 
@@ -169,7 +168,7 @@ static irqreturn_t omap_mpu_timer_interrupt(int irq, void *dev_id,
        now = 0 - omap_mpu_timer_read(0);
        latency = MPU_TICKS_PER_SEC / HZ - omap_mpu_timer_read(1);
        omap_mpu_timer_last = now - latency;
-       timer_tick(regs);
+       timer_tick();
        write_sequnlock(&xtime_lock);
 
        return IRQ_HANDLED;
@@ -182,8 +181,7 @@ static struct irqaction omap_mpu_timer_irq = {
 };
 
 static unsigned long omap_mpu_timer1_overflows;
-static irqreturn_t omap_mpu_timer1_interrupt(int irq, void *dev_id,
-                                            struct pt_regs *regs)
+static irqreturn_t omap_mpu_timer1_interrupt(int irq, void *dev_id)
 {
        omap_mpu_timer1_overflows++;
        return IRQ_HANDLED;
index c37b0e6d12481388335b96992845132dc7f32925..03d6905ba490ce1ac7e93e3e146f4ac5ecf30e16 100644 (file)
@@ -203,7 +203,7 @@ static void __init apollon_led_init(void)
        omap_set_gpio_dataout(LED2_GPIO15, 0);
 }
 
-static irqreturn_t apollon_sw_interrupt(int irq, void *ignored, struct pt_regs *regs)
+static irqreturn_t apollon_sw_interrupt(int irq, void *ignored)
 {
        static unsigned int led0, led1, led2;
 
index fe5fd6d42dea8def5e4c8a8a0e93919830263e26..973189cd97665c7aee22f2a51439e5745eb4a630 100644 (file)
@@ -37,13 +37,12 @@ static inline void omap2_gp_timer_start(unsigned long load_val)
        omap_dm_timer_start(gptimer);
 }
 
-static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id,
-                                           struct pt_regs *regs)
+static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id)
 {
        write_seqlock(&xtime_lock);
 
        omap_dm_timer_write_status(gptimer, OMAP_TIMER_INT_OVERFLOW);
-       timer_tick(regs);
+       timer_tick();
 
        write_sequnlock(&xtime_lock);
 
index ec01574f88ac995e5a72b19be62baf5e6e2eb2e7..d6a279e4b52416213281fbb6bdd8f73ad8f7208e 100644 (file)
@@ -32,7 +32,7 @@
 
 static struct dma_channel {
        char *name;
-       void (*irq_handler) (int, int, void *, struct pt_regs *);
+       void (*irq_handler) (int, int, void *);
        void *data;
        struct pnx4008_dma_ll *ll;
        u32 ll_dma;
@@ -150,8 +150,7 @@ static inline void pnx4008_dma_unlock(void)
 #define VALID_CHANNEL(c)       (((c) >= 0) && ((c) < MAX_DMA_CHANNELS))
 
 int pnx4008_request_channel(char *name, int ch,
-                           void (*irq_handler) (int, int, void *,
-                                                struct pt_regs *), void *data)
+                           void (*irq_handler) (int, int, void *), void *data)
 {
        int i, found = 0;
 
@@ -1033,7 +1032,7 @@ int pnx4008_dma_ch_enabled(int ch)
 
 EXPORT_SYMBOL_GPL(pnx4008_dma_ch_enabled);
 
-static irqreturn_t dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t dma_irq_handler(int irq, void *dev_id)
 {
        int i;
        unsigned long dint = __raw_readl(DMAC_INT_STAT);
@@ -1053,8 +1052,7 @@ static irqreturn_t dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
                                        cause |= DMA_ERR_INT;
                                if (tcint & i_bit)
                                        cause |= DMA_TC_INT;
-                               channel->irq_handler(i, cause, channel->data,
-                                                    regs);
+                               channel->irq_handler(i, cause, channel->data);
                        } else {
                                /*
                                 * IRQ for an unregistered DMA channel
index b986065cd0f33c1f920aa534d9a499d78f031bf5..8621c206ac846d5ca6e61b07eea3efab060108b0 100644 (file)
@@ -47,15 +47,14 @@ static unsigned long pnx4008_gettimeoffset(void)
 /*!
  * IRQ handler for the timer
  */
-static irqreturn_t pnx4008_timer_interrupt(int irq, void *dev_id,
-                                          struct pt_regs *regs)
+static irqreturn_t pnx4008_timer_interrupt(int irq, void *dev_id)
 {
        if (__raw_readl(HSTIM_INT) & MATCH0_INT) {
 
                write_seqlock(&xtime_lock);
 
                do {
-                       timer_tick(regs);
+                       timer_tick();
 
                        /*
                         * this algorithm takes care of possible delay
index 337c01c4ac37194860c45f845a503686ecc0e6c4..a1a900d16665fc8f58d6431306d1d4df0011dbee 100644 (file)
@@ -212,7 +212,7 @@ static struct platform_device corgits_device = {
  */
 static struct pxamci_platform_data corgi_mci_platform_data;
 
-static int corgi_mci_init(struct device *dev, irqreturn_t (*corgi_detect_int)(int, void *, struct pt_regs *), void *data)
+static int corgi_mci_init(struct device *dev, irq_handler_t corgi_detect_int, void *data)
 {
        int err;
 
index 7d8c85486c669065554d1857b4359ce94ee9b6c8..4440babe7b97595dabe3330082ffd8aad9b6d674 100644 (file)
 
 static struct dma_channel {
        char *name;
-       void (*irq_handler)(int, void *, struct pt_regs *);
+       void (*irq_handler)(int, void *);
        void *data;
 } dma_channels[PXA_DMA_CHANNELS];
 
 
 int pxa_request_dma (char *name, pxa_dma_prio prio,
-                        void (*irq_handler)(int, void *, struct pt_regs *),
+                        void (*irq_handler)(int, void *),
                         void *data)
 {
        unsigned long flags;
@@ -87,7 +87,7 @@ void pxa_free_dma (int dma_ch)
        local_irq_restore(flags);
 }
 
-static irqreturn_t dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t dma_irq_handler(int irq, void *dev_id)
 {
        int i, dint = DINT;
 
@@ -95,7 +95,7 @@ static irqreturn_t dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
                if (dint & (1 << i)) {
                        struct dma_channel *channel = &dma_channels[i];
                        if (channel->name && channel->irq_handler) {
-                               channel->irq_handler(i, channel->data, regs);
+                               channel->irq_handler(i, channel->data);
                        } else {
                                /*
                                 * IRQ for an unregistered DMA channel:
index 3e4b0ab71c66bbe40530ef03935d29126b3942e8..64df44043a654f88826edd7e2e65470d41bdf455 100644 (file)
@@ -125,7 +125,7 @@ static struct pxafb_mach_info sharp_lm8v31 = {
        .pxafb_lcd_power = &idp_lcd_power
 };
 
-static int idp_mci_init(struct device *dev, irqreturn_t (*idp_detect_int)(int, void *, struct pt_regs *), void *data)
+static int idp_mci_init(struct device *dev, irq_handler_t idp_detect_int, void *data)
 {
        /* setup GPIO for PXA25x MMC controller */
        pxa_gpio_mode(GPIO6_MMCCLK_MD);
index 12141e2a50cc35e1368f05b8fc10b93cb854f5bc..ab1a16025d51ccb1ec98db0d0eba019d20d5d894 100644 (file)
@@ -143,8 +143,7 @@ static struct irq_chip pxa_low_gpio_chip = {
  * Demux handler for GPIO>=2 edge detect interrupts
  */
 
-static void pxa_gpio_demux_handler(unsigned int irq, struct irqdesc *desc,
-                                  struct pt_regs *regs)
+static void pxa_gpio_demux_handler(unsigned int irq, struct irqdesc *desc)
 {
        unsigned int mask;
        int loop;
@@ -160,7 +159,7 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irqdesc *desc,
                        mask >>= 2;
                        do {
                                if (mask & 1)
-                                       desc_handle_irq(irq, desc, regs);
+                                       desc_handle_irq(irq, desc);
                                irq++;
                                desc++;
                                mask >>= 1;
@@ -175,7 +174,7 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irqdesc *desc,
                        desc = irq_desc + irq;
                        do {
                                if (mask & 1)
-                                       desc_handle_irq(irq, desc, regs);
+                                       desc_handle_irq(irq, desc);
                                irq++;
                                desc++;
                                mask >>= 1;
@@ -190,7 +189,7 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irqdesc *desc,
                        desc = irq_desc + irq;
                        do {
                                if (mask & 1)
-                                       desc_handle_irq(irq, desc, regs);
+                                       desc_handle_irq(irq, desc);
                                irq++;
                                desc++;
                                mask >>= 1;
@@ -206,7 +205,7 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irqdesc *desc,
                        desc = irq_desc + irq;
                        do {
                                if (mask & 1)
-                                       desc_handle_irq(irq, desc, regs);
+                                       desc_handle_irq(irq, desc);
                                irq++;
                                desc++;
                                mask >>= 1;
index eff2a91b2565ee8b46d3673c6bbe5d12759e2c1f..5749f6b72e12646d733a447a9c4bb90e8198adae 100644 (file)
@@ -75,8 +75,7 @@ static struct irq_chip lpd270_irq_chip = {
        .unmask         = lpd270_unmask_irq,
 };
 
-static void lpd270_irq_handler(unsigned int irq, struct irqdesc *desc,
-                                 struct pt_regs *regs)
+static void lpd270_irq_handler(unsigned int irq, struct irqdesc *desc)
 {
        unsigned long pending;
 
@@ -86,7 +85,7 @@ static void lpd270_irq_handler(unsigned int irq, struct irqdesc *desc,
                if (likely(pending)) {
                        irq = LPD270_IRQ(0) + __ffs(pending);
                        desc = irq_desc + irq;
-                       desc_handle_irq(irq, desc, regs);
+                       desc_handle_irq(irq, desc);
 
                        pending = __raw_readw(LPD270_INT_STATUS) &
                                                lpd270_irq_enabled;
index 157cf47cbe6655e239cb7a0c78abe15b4df88788..142c33c3dff57ab4233ef0b4db002c12906c33a3 100644 (file)
@@ -85,8 +85,7 @@ static struct irq_chip lubbock_irq_chip = {
        .unmask         = lubbock_unmask_irq,
 };
 
-static void lubbock_irq_handler(unsigned int irq, struct irqdesc *desc,
-                               struct pt_regs *regs)
+static void lubbock_irq_handler(unsigned int irq, struct irqdesc *desc)
 {
        unsigned long pending = LUB_IRQ_SET_CLR & lubbock_irq_enabled;
        do {
@@ -94,7 +93,7 @@ static void lubbock_irq_handler(unsigned int irq, struct irqdesc *desc,
                if (likely(pending)) {
                        irq = LUBBOCK_IRQ(0) + __ffs(pending);
                        desc = irq_desc + irq;
-                       desc_handle_irq(irq, desc, regs);
+                       desc_handle_irq(irq, desc);
                }
                pending = LUB_IRQ_SET_CLR & lubbock_irq_enabled;
        } while (pending);
@@ -379,7 +378,7 @@ static struct pxafb_mach_info sharp_lm8v31 = {
 #define        MMC_POLL_RATE           msecs_to_jiffies(1000)
 
 static void lubbock_mmc_poll(unsigned long);
-static irqreturn_t (*mmc_detect_int)(int, void *, struct pt_regs *);
+static irq_handler_t mmc_detect_int;
 
 static struct timer_list mmc_timer = {
        .function       = lubbock_mmc_poll,
@@ -398,22 +397,22 @@ static void lubbock_mmc_poll(unsigned long data)
        if (LUB_IRQ_SET_CLR & (1 << 0))
                mod_timer(&mmc_timer, jiffies + MMC_POLL_RATE);
        else {
-               (void) mmc_detect_int(LUBBOCK_SD_IRQ, (void *)data, NULL);
+               (void) mmc_detect_int(LUBBOCK_SD_IRQ, (void *)data);
                enable_irq(LUBBOCK_SD_IRQ);
        }
 }
 
-static irqreturn_t lubbock_detect_int(int irq, void *data, struct pt_regs *regs)
+static irqreturn_t lubbock_detect_int(int irq, void *data)
 {
        /* IRQ is level triggered; disable, and poll for removal */
        disable_irq(irq);
        mod_timer(&mmc_timer, jiffies + MMC_POLL_RATE);
 
-       return mmc_detect_int(irq, data, regs);
+       return mmc_detect_int(irq, data);
 }
 
 static int lubbock_mci_init(struct device *dev,
-               irqreturn_t (*detect_int)(int, void *, struct pt_regs *),
+               irq_handler_t detect_int,
                void *data)
 {
        /* setup GPIO for PXA25x MMC controller */
index 7ba0447d6fa3dfbbb160f3c98e88daa97565dba9..49c34d94a9fee6d489b11f19346586e5d5091525 100644 (file)
@@ -71,8 +71,7 @@ static struct irq_chip mainstone_irq_chip = {
        .unmask         = mainstone_unmask_irq,
 };
 
-static void mainstone_irq_handler(unsigned int irq, struct irqdesc *desc,
-                                 struct pt_regs *regs)
+static void mainstone_irq_handler(unsigned int irq, struct irqdesc *desc)
 {
        unsigned long pending = MST_INTSETCLR & mainstone_irq_enabled;
        do {
@@ -80,7 +79,7 @@ static void mainstone_irq_handler(unsigned int irq, struct irqdesc *desc,
                if (likely(pending)) {
                        irq = MAINSTONE_IRQ(0) + __ffs(pending);
                        desc = irq_desc + irq;
-                       desc_handle_irq(irq, desc, regs);
+                       desc_handle_irq(irq, desc);
                }
                pending = MST_INTSETCLR & mainstone_irq_enabled;
        } while (pending);
@@ -314,7 +313,7 @@ static struct pxafb_mach_info mainstone_pxafb_info = {
        .pxafb_backlight_power  = mainstone_backlight_power,
 };
 
-static int mainstone_mci_init(struct device *dev, irqreturn_t (*mstone_detect_int)(int, void *, struct pt_regs *), void *data)
+static int mainstone_mci_init(struct device *dev, irq_handler_t mstone_detect_int, void *data)
 {
        int err;
 
index 5e8c098ca13986125b15927bc9b8d2dc0eff1c52..34fb80b37023090147e43c1870591f6a829f6758 100644 (file)
@@ -197,7 +197,7 @@ static struct platform_device poodle_ts_device = {
  */
 static struct pxamci_platform_data poodle_mci_platform_data;
 
-static int poodle_mci_init(struct device *dev, irqreturn_t (*poodle_detect_int)(int, void *, struct pt_regs *), void *data)
+static int poodle_mci_init(struct device *dev, irq_handler_t poodle_detect_int, void *data)
 {
        int err;
 
index 401cdb850fbc2f014eec92a2a307290b99425eca..3cbac63bed3c0b952db4c2af7149da2f6926c07d 100644 (file)
@@ -291,7 +291,7 @@ static struct platform_device spitzts_device = {
 
 static struct pxamci_platform_data spitz_mci_platform_data;
 
-static int spitz_mci_init(struct device *dev, irqreturn_t (*spitz_detect_int)(int, void *, struct pt_regs *), void *data)
+static int spitz_mci_init(struct device *dev, irq_handler_t spitz_detect_int, void *data)
 {
        int err;
 
index 1fddfeaa630def3f09dfde30108605b82711b5bd..6cc202755fb46c6ded53a8fe16512687ceb57f49 100644 (file)
@@ -65,7 +65,7 @@ static const struct ssp_info_ ssp_info[PXA_SSP_PORTS] = {
 static DEFINE_MUTEX(mutex);
 static int use_count[PXA_SSP_PORTS] = {0, 0, 0};
 
-static irqreturn_t ssp_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t ssp_interrupt(int irq, void *dev_id)
 {
        struct ssp_dev *dev = (struct ssp_dev*) dev_id;
        unsigned int status = SSSR_P(dev->port);
index 5dbd191c57c4e6980073ea58099282000b06d616..3ac268fa419b68ce81c04af8e5b369d7f1aae1ca 100644 (file)
@@ -75,7 +75,7 @@ static int match_posponed;
 #endif
 
 static irqreturn_t
-pxa_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+pxa_timer_interrupt(int irq, void *dev_id)
 {
        int next_match;
 
@@ -105,7 +105,7 @@ pxa_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
         * exactly one tick period which should be a pretty rare event.
         */
        do {
-               timer_tick(regs);
+               timer_tick();
                OSSR = OSSR_M0;  /* Clear match on timer 0 */
                next_match = (OSMR0 += LATCH);
        } while( (signed long)(next_match - OSCR) <= 8 );
@@ -157,13 +157,13 @@ static void pxa_dyn_tick_reprogram(unsigned long ticks)
 }
 
 static irqreturn_t
-pxa_dyn_tick_handler(int irq, void *dev_id, struct pt_regs *regs)
+pxa_dyn_tick_handler(int irq, void *dev_id)
 {
        if (match_posponed) {
                match_posponed = 0;
                OSMR0 = initial_match;
                if ( (signed long)(initial_match - OSCR) <= 8 )
-                       return pxa_timer_interrupt(irq, dev_id, regs);
+                       return pxa_timer_interrupt(irq, dev_id);
        }
        return IRQ_NONE;
 }
index 249353616aba519ecefbc3868c27aaab58f5d14d..7915a5a228657bafe8d83aae928f32d796c82ec5 100644 (file)
@@ -174,7 +174,7 @@ static struct pxa2xx_udc_mach_info udc_info __initdata = {
  */
 static struct pxamci_platform_data tosa_mci_platform_data;
 
-static int tosa_mci_init(struct device *dev, irqreturn_t (*tosa_detect_int)(int, void *, struct pt_regs *), void *data)
+static int tosa_mci_init(struct device *dev, irq_handler_t tosa_detect_int, void *data)
 {
        int err;
 
index 910571e9a190cba0597219ce523c7c97a7525e7d..c1827d021ba825c4b01b0a7379a23e32b5070b18 100644 (file)
@@ -270,7 +270,7 @@ void board_pcmcia_power(int power)  {;}
 #endif         /* CONFIG_MACH_TRIZEPS4_CONXS */
 EXPORT_SYMBOL(board_pcmcia_power);
 
-static int trizeps4_mci_init(struct device *dev, irqreturn_t (*mci_detect_int)(int, void *, struct pt_regs *), void *data)
+static int trizeps4_mci_init(struct device *dev, irq_handler_t mci_detect_int, void *data)
 {
        int err;
        /* setup GPIO for PXA27x MMC controller */
index da0286973823a0be4f7431a38adfdd4294ed186f..68c67053f47990b4477ba4f4328d870920123ad3 100644 (file)
@@ -515,18 +515,18 @@ static unsigned long realview_gettimeoffset(void)
 /*
  * IRQ handler for the timer
  */
-static irqreturn_t realview_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t realview_timer_interrupt(int irq, void *dev_id)
 {
        write_seqlock(&xtime_lock);
 
        // ...clear the interrupt
        writel(1, TIMER0_VA_BASE + TIMER_INTCLR);
 
-       timer_tick(regs);
+       timer_tick();
 
 #if defined(CONFIG_SMP) && !defined(CONFIG_LOCAL_TIMERS)
        smp_send_timer();
-       update_process_times(user_mode(regs));
+       update_process_times(user_mode(get_irq_regs()));
 #endif
 
        write_sequnlock(&xtime_lock);
index ac511d41d4d75d5a0f078a4c53caac9654e20185..596379a4cf82826fab9bd2f47bf05984ba8ef801 100644 (file)
@@ -83,7 +83,7 @@ static void iomd_get_next_sg(struct scatterlist *sg, dma_t *dma)
        sg->length |= flags;
 }
 
-static irqreturn_t iomd_dma_handle(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t iomd_dma_handle(int irq, void *dev_id)
 {
        dma_t *dma = (dma_t *)dev_id;
        unsigned long base = dma->dma_base;
index 440e9aa0211abafad0585c93cc26e86463d72210..23d5beea55680bc04dc45a726945bb85b6f567c8 100644 (file)
@@ -112,8 +112,7 @@ static struct irqchip  bast_pc104_chip = {
 
 static void
 bast_irq_pc104_demux(unsigned int irq,
-                    struct irqdesc *desc,
-                    struct pt_regs *regs)
+                    struct irqdesc *desc)
 {
        unsigned int stat;
        unsigned int irqno;
@@ -133,7 +132,7 @@ bast_irq_pc104_demux(unsigned int irq,
                        if (stat & 1) {
                                irqno = bast_pc104_irqs[i];
                                desc = irq_desc + irqno;
-                               desc_handle_irq(irqno, desc, regs);
+                               desc_handle_irq(irqno, desc);
                        }
                }
        }
index d264bbbd8bef893fa660255fafbb88876f290b52..3d211dc2f2f90923136b55a8e814e842463e49d0 100644 (file)
@@ -595,7 +595,7 @@ s3c2410_dma_lastxfer(struct s3c2410_dma_chan *chan)
 #define dmadbg2(x...)
 
 static irqreturn_t
-s3c2410_dma_irq(int irq, void *devpw, struct pt_regs *regs)
+s3c2410_dma_irq(int irq, void *devpw)
 {
        struct s3c2410_dma_chan *chan = (struct s3c2410_dma_chan *)devpw;
        struct s3c2410_dma_buf  *buf;
index 3e9f3462c61b13f012eb5479228196e1f7405ad3..683b3491ba3c4ae4634aed2e7a217363dc03f45b 100644 (file)
@@ -480,8 +480,7 @@ static struct irqchip s3c_irq_adc = {
 
 /* irq demux for adc */
 static void s3c_irq_demux_adc(unsigned int irq,
-                             struct irqdesc *desc,
-                             struct pt_regs *regs)
+                             struct irqdesc *desc)
 {
        unsigned int subsrc, submsk;
        unsigned int offset = 9;
@@ -500,17 +499,16 @@ static void s3c_irq_demux_adc(unsigned int irq,
        if (subsrc != 0) {
                if (subsrc & 1) {
                        mydesc = irq_desc + IRQ_TC;
-                       desc_handle_irq(IRQ_TC, mydesc, regs);
+                       desc_handle_irq(IRQ_TC, mydesc);
                }
                if (subsrc & 2) {
                        mydesc = irq_desc + IRQ_ADC;
-                       desc_handle_irq(IRQ_ADC, mydesc, regs);
+                       desc_handle_irq(IRQ_ADC, mydesc);
                }
        }
 }
 
-static void s3c_irq_demux_uart(unsigned int start,
-                              struct pt_regs *regs)
+static void s3c_irq_demux_uart(unsigned int start)
 {
        unsigned int subsrc, submsk;
        unsigned int offset = start - IRQ_S3CUART_RX0;
@@ -533,17 +531,17 @@ static void s3c_irq_demux_uart(unsigned int start,
                desc = irq_desc + start;
 
                if (subsrc & 1)
-                       desc_handle_irq(start, desc, regs);
+                       desc_handle_irq(start, desc);
 
                desc++;
 
                if (subsrc & 2)
-                       desc_handle_irq(start+1, desc, regs);
+                       desc_handle_irq(start+1, desc);
 
                desc++;
 
                if (subsrc & 4)
-                       desc_handle_irq(start+2, desc, regs);
+                       desc_handle_irq(start+2, desc);
        }
 }
 
@@ -551,35 +549,31 @@ static void s3c_irq_demux_uart(unsigned int start,
 
 static void
 s3c_irq_demux_uart0(unsigned int irq,
-                   struct irqdesc *desc,
-                   struct pt_regs *regs)
+                   struct irqdesc *desc)
 {
        irq = irq;
-       s3c_irq_demux_uart(IRQ_S3CUART_RX0, regs);
+       s3c_irq_demux_uart(IRQ_S3CUART_RX0);
 }
 
 static void
 s3c_irq_demux_uart1(unsigned int irq,
-                   struct irqdesc *desc,
-                   struct pt_regs *regs)
+                   struct irqdesc *desc)
 {
        irq = irq;
-       s3c_irq_demux_uart(IRQ_S3CUART_RX1, regs);
+       s3c_irq_demux_uart(IRQ_S3CUART_RX1);
 }
 
 static void
 s3c_irq_demux_uart2(unsigned int irq,
-                   struct irqdesc *desc,
-                   struct pt_regs *regs)
+                   struct irqdesc *desc)
 {
        irq = irq;
-       s3c_irq_demux_uart(IRQ_S3CUART_RX2, regs);
+       s3c_irq_demux_uart(IRQ_S3CUART_RX2);
 }
 
 static void
 s3c_irq_demux_extint8(unsigned int irq,
-                     struct irqdesc *desc,
-                     struct pt_regs *regs)
+                     struct irqdesc *desc)
 {
        unsigned long eintpnd = __raw_readl(S3C24XX_EINTPEND);
        unsigned long eintmsk = __raw_readl(S3C24XX_EINTMASK);
@@ -594,15 +588,14 @@ s3c_irq_demux_extint8(unsigned int irq,
                eintpnd &= ~(1<<irq);
 
                irq += (IRQ_EINT4 - 4);
-               desc_handle_irq(irq, irq_desc + irq, regs);
+               desc_handle_irq(irq, irq_desc + irq);
        }
 
 }
 
 static void
 s3c_irq_demux_extint4t7(unsigned int irq,
-                       struct irqdesc *desc,
-                       struct pt_regs *regs)
+                       struct irqdesc *desc)
 {
        unsigned long eintpnd = __raw_readl(S3C24XX_EINTPEND);
        unsigned long eintmsk = __raw_readl(S3C24XX_EINTMASK);
@@ -618,7 +611,7 @@ s3c_irq_demux_extint4t7(unsigned int irq,
 
                irq += (IRQ_EINT4 - 4);
 
-               desc_handle_irq(irq, irq_desc + irq, regs);
+               desc_handle_irq(irq, irq_desc + irq);
        }
 }
 
index ba5109af40b4d407fbccd0d5f6c99b8e9ccea752..817e2c684410bce25eeae0d383f296bad14cb644 100644 (file)
@@ -226,7 +226,7 @@ static struct s3c2410fb_mach_info __initdata amlm5900_lcd_info = {
 #endif
 
 static irqreturn_t
-amlm5900_wake_interrupt(int irq, void *ignored, struct pt_regs *regs)
+amlm5900_wake_interrupt(int irq, void *ignored)
 {
        return IRQ_HANDLED;
 }
index fc08febe2e543891cd2b0599a0dcb403e8f32cdf..39db0752d53b1b67573dcb4f227a06411b312b80 100644 (file)
@@ -42,8 +42,7 @@
 /* WDT/AC97 */
 
 static void s3c_irq_demux_wdtac97(unsigned int irq,
-                                 struct irqdesc *desc,
-                                 struct pt_regs *regs)
+                                 struct irqdesc *desc)
 {
        unsigned int subsrc, submsk;
        struct irqdesc *mydesc;
@@ -61,11 +60,11 @@ static void s3c_irq_demux_wdtac97(unsigned int irq,
        if (subsrc != 0) {
                if (subsrc & 1) {
                        mydesc = irq_desc + IRQ_S3C2440_WDT;
-                       desc_handle_irq(IRQ_S3C2440_WDT, mydesc, regs);
+                       desc_handle_irq(IRQ_S3C2440_WDT, mydesc);
                }
                if (subsrc & 2) {
                        mydesc = irq_desc + IRQ_S3C2440_AC97;
-                       desc_handle_irq(IRQ_S3C2440_AC97, mydesc, regs);
+                       desc_handle_irq(IRQ_S3C2440_AC97, mydesc);
                }
        }
 }
index ec702f88b299f051f65e87d7d3f3f7011455bca2..146f2109dd905bcff124151fea8573428a8a68a3 100644 (file)
@@ -42,8 +42,7 @@
 /* camera irq */
 
 static void s3c_irq_demux_cam(unsigned int irq,
-                             struct irqdesc *desc,
-                             struct pt_regs *regs)
+                             struct irqdesc *desc)
 {
        unsigned int subsrc, submsk;
        struct irqdesc *mydesc;
@@ -61,11 +60,11 @@ static void s3c_irq_demux_cam(unsigned int irq,
        if (subsrc != 0) {
                if (subsrc & 1) {
                        mydesc = irq_desc + IRQ_S3C2440_CAM_C;
-                       desc_handle_irq(IRQ_S3C2440_CAM_C, mydesc, regs);
+                       desc_handle_irq(IRQ_S3C2440_CAM_C, mydesc);
                }
                if (subsrc & 2) {
                        mydesc = irq_desc + IRQ_S3C2440_CAM_P;
-                       desc_handle_irq(IRQ_S3C2440_CAM_P, mydesc, regs);
+                       desc_handle_irq(IRQ_S3C2440_CAM_P, mydesc);
                }
        }
 }
index 00d1cfca971287f175bc27ed60ff76a121fe6153..9910bf0f2cea63c3fab5e53e79a9a6398762b418 100644 (file)
@@ -128,10 +128,10 @@ static unsigned long s3c2410_gettimeoffset (void)
  * IRQ handler for the timer
  */
 static irqreturn_t
-s3c2410_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+s3c2410_timer_interrupt(int irq, void *dev_id)
 {
        write_seqlock(&xtime_lock);
-       timer_tick(regs);
+       timer_tick();
        write_sequnlock(&xtime_lock);
        return IRQ_HANDLED;
 }
index c635efa7cd3189cf97f1ec4550d4b987d6a2b870..22b0e1cdd4bf3d4e584588b4399c54646c673847 100644 (file)
@@ -58,7 +58,7 @@ usb_simtec_powercontrol(int port, int to)
 }
 
 static irqreturn_t
-usb_simtec_ocirq(int irq, void *pw, struct pt_regs *regs)
+usb_simtec_ocirq(int irq, void *pw)
 {
        struct s3c2410_hcd_info *info = (struct s3c2410_hcd_info *)pw;
 
index 639597729932e5ce821569f03fcd19184b4515fc..90a4130114a61dcc555139359a3848e1d845f288 100644 (file)
@@ -82,6 +82,14 @@ static struct sdram_params sdram_tbl[] __initdata = {
                .twr            = 9,
                .refresh        = 64000,
                .cas_latency    = 3,
+       }, {    /* Samsung K4S281632B-1H */
+               .name           = "K4S281632b-1H",
+               .rows           = 12,
+               .tck            = 10,
+               .trp            = 20,
+               .twr            = 10,
+               .refresh        = 64000,
+               .cas_latency    = 3,
        }, {    /* Samsung KM416S4030CT */
                .name           = "KM416S4030CT",
                .rows           = 13,
@@ -366,6 +374,8 @@ static int __init sa1110_clk_init(void)
 
                if (machine_is_h3100())
                        name = "KM416S4030CT";
+               if (machine_is_jornada720())
+                       name = "K4S281632B-1H";
        }
 
        sdram = sa1110_find_sdram(name);
index 2ea2a657a0346c06a2bf293814cf7e7ef95079bb..1fbe053e8b5998cd46216d9ba445fb26849a3a4e 100644 (file)
@@ -42,7 +42,7 @@ static sa1100_dma_t dma_chan[SA1100_DMA_CHANNELS];
 static spinlock_t dma_list_lock;
 
 
-static irqreturn_t dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t dma_irq_handler(int irq, void *dev_id)
 {
        dma_regs_t *dma_regs = dev_id;
        sa1100_dma_t *dma = dma_chan + (((u_int)dma_regs >> 5) & 7);
index 7364478cec12167425d5b9a1953b7b44232446bc..fa6dc71bd6ad053bef39fffde07261f190ee5f50 100644 (file)
@@ -702,7 +702,7 @@ static u32 gpio_irq_mask[] = {
        GPIO2_SD_CON_SLT,
 };
 
-static void h3800_IRQ_demux(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
+static void h3800_IRQ_demux(unsigned int irq, struct irqdesc *desc)
 {
        int i;
 
@@ -719,14 +719,14 @@ static void h3800_IRQ_demux(unsigned int irq, struct irqdesc *desc, struct pt_re
                if (0) printk("%s KPIO 0x%08X\n", __FUNCTION__, irq);
                for (j = 0; j < H3800_KPIO_IRQ_COUNT; j++)
                        if (irq & kpio_irq_mask[j])
-                               do_edge_IRQ(H3800_KPIO_IRQ_COUNT + j, irq_desc + H3800_KPIO_IRQ_COUNT + j, regs);
+                               do_edge_IRQ(H3800_KPIO_IRQ_COUNT + j, irq_desc + H3800_KPIO_IRQ_COUNT + j);
 
                /* GPIO2 */
                irq = H3800_ASIC2_GPIINTFLAG;
                if (0) printk("%s GPIO 0x%08X\n", __FUNCTION__, irq);
                for (j = 0; j < H3800_GPIO_IRQ_COUNT; j++)
                        if (irq & gpio_irq_mask[j])
-                               do_edge_IRQ(H3800_GPIO_IRQ_COUNT + j, irq_desc + H3800_GPIO_IRQ_COUNT + j , regs);
+                               do_edge_IRQ(H3800_GPIO_IRQ_COUNT + j, irq_desc + H3800_GPIO_IRQ_COUNT + j);
        }
 
        if (i >= MAX_ASIC_ISR_LOOPS)
index b55b90a2e8fe975faba29388a517b36cfcb400cd..f4c6322ca33eec90c58aab15ee990f9712c30eed 100644 (file)
@@ -110,8 +110,7 @@ static struct irq_chip sa1100_low_gpio_chip = {
  * and call the handler.
  */
 static void
-sa1100_high_gpio_handler(unsigned int irq, struct irqdesc *desc,
-                        struct pt_regs *regs)
+sa1100_high_gpio_handler(unsigned int irq, struct irqdesc *desc)
 {
        unsigned int mask;
 
@@ -128,7 +127,7 @@ sa1100_high_gpio_handler(unsigned int irq, struct irqdesc *desc,
                mask >>= 11;
                do {
                        if (mask & 1)
-                               desc_handle_irq(irq, desc, regs);
+                               desc_handle_irq(irq, desc);
                        mask >>= 1;
                        irq++;
                        desc++;
index af6d2775cf8237e34aecd21f8039083acbabc5db..354d5e91da599f72a03750ac9b14c29a873cc573 100644 (file)
@@ -29,7 +29,7 @@
  * is rather unfortunate.
  */
 static void
-neponset_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
+neponset_irq_handler(unsigned int irq, struct irqdesc *desc)
 {
        unsigned int irr;
 
@@ -69,12 +69,12 @@ neponset_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *reg
 
                        if (irr & IRR_ETHERNET) {
                                d = irq_desc + IRQ_NEPONSET_SMC9196;
-                               desc_handle_irq(IRQ_NEPONSET_SMC9196, d, regs);
+                               desc_handle_irq(IRQ_NEPONSET_SMC9196, d);
                        }
 
                        if (irr & IRR_USAR) {
                                d = irq_desc + IRQ_NEPONSET_USAR;
-                               desc_handle_irq(IRQ_NEPONSET_USAR, d, regs);
+                               desc_handle_irq(IRQ_NEPONSET_USAR, d);
                        }
 
                        desc->chip->unmask(irq);
@@ -82,7 +82,7 @@ neponset_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *reg
 
                if (irr & IRR_SA1111) {
                        d = irq_desc + IRQ_NEPONSET_SA1111;
-                       desc_handle_irq(IRQ_NEPONSET_SA1111, d, regs);
+                       desc_handle_irq(IRQ_NEPONSET_SA1111, d);
                }
        }
 }
index 5eba5fbbb561757ceb6a267b05eceade86d6b865..59703c6fb29bc514a83a5d4135989758ad801db9 100644 (file)
@@ -25,7 +25,7 @@
 
 #define TIMEOUT 100000
 
-static irqreturn_t ssp_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t ssp_interrupt(int irq, void *dev_id)
 {
        unsigned int status = Ser4SSSR;
 
index 49ae716e16c2ad1a12fd7e0336e5f2826519442f..4284bd6f7a1f583c2af51cc98be24f7e6f638e87 100644 (file)
@@ -77,7 +77,7 @@ static int match_posponed;
 #endif
 
 static irqreturn_t
-sa1100_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+sa1100_timer_interrupt(int irq, void *dev_id)
 {
        unsigned int next_match;
 
@@ -99,7 +99,7 @@ sa1100_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
         * handlers.
         */
        do {
-               timer_tick(regs);
+               timer_tick();
                OSSR = OSSR_M0;  /* Clear match on timer 0 */
                next_match = (OSMR0 += LATCH);
        } while ((signed long)(next_match - OSCR) <= 0);
@@ -151,13 +151,13 @@ static void sa1100_dyn_tick_reprogram(unsigned long ticks)
 }
 
 static irqreturn_t
-sa1100_dyn_tick_handler(int irq, void *dev_id, struct pt_regs *regs)
+sa1100_dyn_tick_handler(int irq, void *dev_id)
 {
        if (match_posponed) {
                match_posponed = 0;
                OSMR0 = initial_match;
                if ((signed long)(initial_match - OSCR) <= 0)
-                       return sa1100_timer_interrupt(irq, dev_id, regs);
+                       return sa1100_timer_interrupt(irq, dev_id);
        }
        return IRQ_NONE;
 }
index 1095df34fec072cfd76ab5ba77841e71f96174c3..0e480fae8ec51e0c4ca07706373681ce8c90448e 100644 (file)
@@ -80,10 +80,10 @@ static void __init shark_map_io(void)
 #define HZ_TIME ((1193180 + HZ/2) / HZ)
 
 static irqreturn_t
-shark_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+shark_timer_interrupt(int irq, void *dev_id)
 {
        write_seqlock(&xtime_lock);
-       timer_tick(regs);
+       timer_tick();
        write_sequnlock(&xtime_lock);
        return IRQ_HANDLED;
 }
index b227052296cff2be019ed69e8b5b4d2c0d2931e9..297ecf130650bae3916b6cd97e029af9d9c8bb88 100644 (file)
@@ -61,7 +61,7 @@ static void shark_enable_8259A_irq(unsigned int irq)
 
 static void shark_ack_8259A_irq(unsigned int irq){}
 
-static irqreturn_t bogus_int(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t bogus_int(int irq, void *dev_id)
 {
        printk("Got interrupt %i!\n",irq);
        return IRQ_NONE;
index f2bbef07b1e408e8a82b8f85c794ff59ee4fb672..3b8576111c16db0a8a9e425cacfa89e2fd5ac572 100644 (file)
@@ -77,12 +77,12 @@ static struct irq_chip sic_chip = {
 };
 
 static void
-sic_handle_irq(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
+sic_handle_irq(unsigned int irq, struct irqdesc *desc)
 {
        unsigned long status = readl(VA_SIC_BASE + SIC_IRQ_STATUS);
 
        if (status == 0) {
-               do_bad_IRQ(irq, desc, regs);
+               do_bad_IRQ(irq, desc);
                return;
        }
 
@@ -93,7 +93,7 @@ sic_handle_irq(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
                irq += IRQ_SIC_START;
 
                desc = irq_desc + irq;
-               desc_handle_irq(irq, desc, regs);
+               desc_handle_irq(irq, desc);
        } while (status);
 }
 
@@ -188,12 +188,12 @@ static struct map_desc versatile_io_desc[] __initdata = {
                .length         = SZ_4K,
                .type           = MT_DEVICE
        }, {
-               .virtual        =  VERSATILE_PCI_VIRT_BASE,
+               .virtual        =  (unsigned long)VERSATILE_PCI_VIRT_BASE,
                .pfn            = __phys_to_pfn(VERSATILE_PCI_BASE),
                .length         = VERSATILE_PCI_BASE_SIZE,
                .type           = MT_DEVICE
        }, {
-               .virtual        =  VERSATILE_PCI_CFG_VIRT_BASE,
+               .virtual        =  (unsigned long)VERSATILE_PCI_CFG_VIRT_BASE,
                .pfn            = __phys_to_pfn(VERSATILE_PCI_CFG_BASE),
                .length         = VERSATILE_PCI_CFG_BASE_SIZE,
                .type           = MT_DEVICE
@@ -851,14 +851,14 @@ static unsigned long versatile_gettimeoffset(void)
 /*
  * IRQ handler for the timer
  */
-static irqreturn_t versatile_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t versatile_timer_interrupt(int irq, void *dev_id)
 {
        write_seqlock(&xtime_lock);
 
        // ...clear the interrupt
        writel(1, TIMER0_VA_BASE + TIMER_INTCLR);
 
-       timer_tick(regs);
+       timer_tick();
 
        write_sequnlock(&xtime_lock);
 
index 13bbd08ff841d2c006bd99646488193a7a7c619b..5cd0b5d9e7ebbf9e8935bb996c1748ab4d2722ce 100644 (file)
  * Cfg   42000000 - 42FFFFFF     PCI config
  *
  */
-#define SYS_PCICTL                     IO_ADDRESS(VERSATILE_SYS_PCICTL)
-#define PCI_IMAP0                      IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x0)
-#define PCI_IMAP1                      IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x4)
-#define PCI_IMAP2                      IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x8)
-#define PCI_SMAP0                      IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x10)
-#define PCI_SMAP1                      IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x14)
-#define PCI_SMAP2                      IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x18)
-#define PCI_SELFID                     IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0xc)
+#define __IO_ADDRESS(n) ((void __iomem *)(unsigned long)IO_ADDRESS(n))
+#define SYS_PCICTL             __IO_ADDRESS(VERSATILE_SYS_PCICTL)
+#define PCI_IMAP0              __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x0)
+#define PCI_IMAP1              __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x4)
+#define PCI_IMAP2              __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x8)
+#define PCI_SMAP0              __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x10)
+#define PCI_SMAP1              __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x14)
+#define PCI_SMAP2              __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x18)
+#define PCI_SELFID             __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0xc)
 
 #define DEVICE_ID_OFFSET               0x00
 #define CSR_OFFSET                     0x04
@@ -76,7 +77,7 @@ static int __init versatile_pci_slot_ignore(char *str)
 __setup("pci_slot_ignore=", versatile_pci_slot_ignore);
 
 
-static unsigned long __pci_addr(struct pci_bus *bus,
+static void __iomem *__pci_addr(struct pci_bus *bus,
                                unsigned int devfn, int offset)
 {
        unsigned int busnr = bus->number;
@@ -91,14 +92,14 @@ static unsigned long __pci_addr(struct pci_bus *bus,
        if (devfn > 255)
                BUG();
 
-       return (VERSATILE_PCI_CFG_VIRT_BASE | (busnr << 16) |
+       return VERSATILE_PCI_CFG_VIRT_BASE + ((busnr << 16) |
                (PCI_SLOT(devfn) << 11) | (PCI_FUNC(devfn) << 8) | offset);
 }
 
 static int versatile_read_config(struct pci_bus *bus, unsigned int devfn, int where,
                                 int size, u32 *val)
 {
-       unsigned long addr = __pci_addr(bus, devfn, where);
+       void __iomem *addr = __pci_addr(bus, devfn, where & ~3);
        u32 v;
        int slot = PCI_SLOT(devfn);
 
@@ -121,13 +122,12 @@ static int versatile_read_config(struct pci_bus *bus, unsigned int devfn, int wh
                        break;
 
                case 2:
-                       v = __raw_readl(addr & ~3);
-                       if (addr & 2) v >>= 16;
+                       v = __raw_readl(addr);
+                       if (where & 2) v >>= 16;
                        v &= 0xffff;
                        break;
 
                default:
-                       addr &= ~3;
                        v = __raw_readl(addr);
                        break;
                }
@@ -140,7 +140,7 @@ static int versatile_read_config(struct pci_bus *bus, unsigned int devfn, int wh
 static int versatile_write_config(struct pci_bus *bus, unsigned int devfn, int where,
                                  int size, u32 val)
 {
-       unsigned long addr = __pci_addr(bus, devfn, where);
+       void __iomem *addr = __pci_addr(bus, devfn, where);
        int slot = PCI_SLOT(devfn);
 
        if (pci_slot_ignore & (1 << slot)) {
@@ -279,7 +279,7 @@ int __init pci_versatile_setup(int nr, struct pci_sys_data *sys)
        printk("PCI core found (slot %d)\n",myslot);
 
        __raw_writel(myslot, PCI_SELFID);
-       local_pci_cfg_base = (void *) VERSATILE_PCI_CFG_VIRT_BASE + (myslot << 11);
+       local_pci_cfg_base = VERSATILE_PCI_CFG_VIRT_BASE + (myslot << 11);
 
        val = __raw_readl(local_pci_cfg_base + CSR_OFFSET);
        val |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE;
index 591fc3187c7fc8edcde66091ed855647b250a56d..46544059279132efb3b3112f95929912f700f004 100644 (file)
@@ -361,14 +361,14 @@ __ioremap(unsigned long phys_addr, size_t size, unsigned long flags)
 }
 EXPORT_SYMBOL(__ioremap);
 
-void __iounmap(void __iomem *addr)
+void __iounmap(volatile void __iomem *addr)
 {
 #ifndef CONFIG_SMP
        struct vm_struct **p, *tmp;
 #endif
        unsigned int section_mapping = 0;
 
-       addr = (void __iomem *)(PAGE_MASK & (unsigned long)addr);
+       addr = (volatile void __iomem *)(PAGE_MASK & (unsigned long)addr);
 
 #ifndef CONFIG_SMP
        /*
@@ -395,6 +395,6 @@ void __iounmap(void __iomem *addr)
 #endif
 
        if (!section_mapping)
-               vunmap(addr);
+               vunmap((void __force *)addr);
 }
 EXPORT_SYMBOL(__iounmap);
index 726ad2b3b435f25740790840f431988ea0f3ec99..7c3289c2acd7d4b2add8364c502b368ac9e88d9e 100644 (file)
@@ -20,7 +20,8 @@
 #include <linux/sched.h>
 #include <linux/oprofile.h>
 #include <linux/interrupt.h>
-#include <asm/irq.h>
+#include <linux/irq.h>
+
 #include <asm/system.h>
 
 #include "op_counter.h"
@@ -341,7 +342,7 @@ static void inline __xsc2_check_ctrs(void)
        __asm__ __volatile__ ("mcr p14, 0, %0, c5, c1, 0" : : "r" (flag));
 }
 
-static irqreturn_t xscale_pmu_interrupt(int irq, void *arg, struct pt_regs *regs)
+static irqreturn_t xscale_pmu_interrupt(int irq, void *arg)
 {
        int i;
        u32 pmnc;
@@ -356,7 +357,7 @@ static irqreturn_t xscale_pmu_interrupt(int irq, void *arg, struct pt_regs *regs
                        continue;
 
                write_counter(i, -(u32)results[i].reset_counter);
-               oprofile_add_sample(regs, i);
+               oprofile_add_sample(get_irq_regs(), i);
                results[i].ovf--;
        }
 
index 06282dffbdc62c4eacff041c84131b86b857da46..f530abdaa7a1e7fb5bd16ea5e5a49263d39f8cad 100644 (file)
@@ -47,7 +47,7 @@ unsigned long iop3xx_gettimeoffset(void)
 }
 
 static irqreturn_t
-iop3xx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+iop3xx_timer_interrupt(int irq, void *dev_id)
 {
        write_seqlock(&xtime_lock);
 
@@ -57,7 +57,7 @@ iop3xx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 
        while ((signed long)(next_jiffy_time - *IOP3XX_TU_TCR1)
                                                        >= ticks_per_jiffy) {
-               timer_tick(regs);
+               timer_tick();
                next_jiffy_time -= ticks_per_jiffy;
        }
 
index 1bbb431843ce056ced668044bd5d71a43036a14e..bb045e5ddbd837e3906a90415e5800b383c6dd08 100644 (file)
@@ -899,8 +899,7 @@ static int omap1_dma_handle_ch(int ch)
        return 1;
 }
 
-static irqreturn_t omap1_dma_irq_handler(int irq, void *dev_id,
-                                        struct pt_regs *regs)
+static irqreturn_t omap1_dma_irq_handler(int irq, void *dev_id)
 {
        int ch = ((int) dev_id) - 1;
        int handled = 0;
@@ -962,8 +961,7 @@ static int omap2_dma_handle_ch(int ch)
 }
 
 /* STATUS register count is from 1-32 while our is 0-31 */
-static irqreturn_t omap2_dma_irq_handler(int irq, void *dev_id,
-                                        struct pt_regs *regs)
+static irqreturn_t omap2_dma_irq_handler(int irq, void *dev_id)
 {
        u32 val;
        int i;
@@ -1220,8 +1218,7 @@ static void set_b1_regs(void)
        omap_writew(fi, OMAP1610_DMA_LCD_SRC_FI_B1_L);
 }
 
-static irqreturn_t lcd_dma_irq_handler(int irq, void *dev_id,
-                                      struct pt_regs *regs)
+static irqreturn_t lcd_dma_irq_handler(int irq, void *dev_id)
 {
        u16 w;
 
index f55f99ae58aea6ab07402c2562ab00b84ff8c38e..8162eed8b500e697938fbc78e90bbb99392cfd24 100644 (file)
@@ -783,8 +783,7 @@ void omap_free_gpio(int gpio)
  * line's interrupt handler has been run, we may miss some nested
  * interrupts.
  */
-static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc,
-                            struct pt_regs *regs)
+static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc)
 {
        void __iomem *isr_reg = NULL;
        u32 isr;
@@ -882,7 +881,7 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc,
                                continue;
                        }
 
-                       desc_handle_irq(gpio_irq, d, regs);
+                       desc_handle_irq(gpio_irq, d);
 
                        if (unlikely((d->status & IRQ_PENDING) && !d->depth)) {
                                irq_mask = 1 <<
index ade9a0fa6ef678033ff2f17f6dd8446389e7ae21..ec50008a2df6421e46275d0ec022231bdf9a3b8f 100644 (file)
@@ -96,7 +96,7 @@ static void omap_mcbsp_dump_reg(u8 id)
        DBG("***********************\n");
 }
 
-static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id)
 {
        struct omap_mcbsp * mcbsp_tx = (struct omap_mcbsp *)(dev_id);
 
@@ -106,7 +106,7 @@ static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id, struct pt_re
        return IRQ_HANDLED;
 }
 
-static irqreturn_t omap_mcbsp_rx_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t omap_mcbsp_rx_irq_handler(int irq, void *dev_id)
 {
        struct omap_mcbsp * mcbsp_rx = (struct omap_mcbsp *)(dev_id);
 
index cf6df3378d3786d3bcaa2876f770b70db46cc6ca..2653106011618b2a2279eb894298b8390ff2c1ed 100644 (file)
@@ -194,8 +194,7 @@ unsigned long long sched_clock(void)
  * issues with dynamic tick. In the dynamic tick case, we need to lock
  * with irqsave.
  */
-static inline irqreturn_t _omap_32k_timer_interrupt(int irq, void *dev_id,
-                                       struct pt_regs *regs)
+static inline irqreturn_t _omap_32k_timer_interrupt(int irq, void *dev_id)
 {
        unsigned long now;
 
@@ -205,7 +204,7 @@ static inline irqreturn_t _omap_32k_timer_interrupt(int irq, void *dev_id,
        while ((signed long)(now - omap_32k_last_tick)
                                                >= OMAP_32K_TICKS_PER_HZ) {
                omap_32k_last_tick += OMAP_32K_TICKS_PER_HZ;
-               timer_tick(regs);
+               timer_tick();
        }
 
        /* Restart timer so we don't drift off due to modulo or dynamic tick.
@@ -218,19 +217,17 @@ static inline irqreturn_t _omap_32k_timer_interrupt(int irq, void *dev_id,
        return IRQ_HANDLED;
 }
 
-static irqreturn_t omap_32k_timer_handler(int irq, void *dev_id,
-                                       struct pt_regs *regs)
+static irqreturn_t omap_32k_timer_handler(int irq, void *dev_id)
 {
-       return _omap_32k_timer_interrupt(irq, dev_id, regs);
+       return _omap_32k_timer_interrupt(irq, dev_id);
 }
 
-static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id,
-                                           struct pt_regs *regs)
+static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id)
 {
        unsigned long flags;
 
        write_seqlock_irqsave(&xtime_lock, flags);
-       _omap_32k_timer_interrupt(irq, dev_id, regs);
+       _omap_32k_timer_interrupt(irq, dev_id);
        write_sequnlock_irqrestore(&xtime_lock, flags);
 
        return IRQ_HANDLED;
index b02af1d740fab56b1f28c7525f7ac97f3006829f..579c69ae9ff78ac47d3b2e01b2830f6da88d80c2 100644 (file)
@@ -4,7 +4,7 @@
 #
 # Up to date versions of this file can be obtained from:
 #
-#   http://www.arm.linux.org.uk/developer/machines/?action=download
+#   http://www.arm.linux.org.uk/developer/machines/download.php
 #
 # Please do not send patches to this file; it is automatically generated!
 # To add an entry into this database, please see Documentation/arm/README,
@@ -12,7 +12,7 @@
 #
 #   http://www.arm.linux.org.uk/developer/machines/?action=new
 #
-# Last update: Sat Sep 23 13:20:43 2006
+# Last update: Mon Oct 16 21:13:36 2006
 #
 # machine_is_xxx       CONFIG_xxxx             MACH_TYPE_xxx           number
 #
@@ -1157,3 +1157,17 @@ adsturboxb               MACH_ADSTURBOXB         ADSTURBOXB              1143
 oti4110                        MACH_OTI4110            OTI4110                 1144
 hme_pxa                        MACH_HME_PXA            HME_PXA                 1145
 deisterdca             MACH_DEISTERDCA         DEISTERDCA              1146
+ces_ssem2              MACH_CES_SSEM2          CES_SSEM2               1147
+ces_mtr                        MACH_CES_MTR            CES_MTR                 1148
+tds_avng_sbc           MACH_TDS_AVNG_SBC       TDS_AVNG_SBC            1149
+everest                        MACH_EVEREST            EVEREST                 1150
+pnx4010                        MACH_PNX4010            PNX4010                 1151
+oxnas                  MACH_OXNAS              OXNAS                   1152
+fiori                  MACH_FIORI              FIORI                   1153
+ml1200                 MACH_ML1200             ML1200                  1154
+cactus                 MACH_CACTUS             CACTUS                  1155
+nb2xxx                 MACH_NB2XXX             NB2XXX                  1156
+hw6900                 MACH_HW6900             HW6900                  1157
+cdcs_quoll             MACH_CDCS_QUOLL         CDCS_QUOLL              1158
+quicksilver            MACH_QUICKSILVER        QUICKSILVER             1159
+uplat926               MACH_UPLAT926           UPLAT926                1160
index dedbb449632edc1f65a40d39e06650df14831a98..a657a28f08dbbbf701acfe16e18a6b4350430948 100644 (file)
@@ -90,7 +90,7 @@ void vfp_raise_sigfpe(unsigned int sicode, struct pt_regs *regs)
 
        info.si_signo = SIGFPE;
        info.si_code = sicode;
-       info.si_addr = (void *)(instruction_pointer(regs) - 4);
+       info.si_addr = (void __user *)(instruction_pointer(regs) - 4);
 
        /*
         * This is the same as NWFPE, because it's not clear what
index 07907b6ecb634126b116236e3a92fcba632d4ec1..93293d04b3032c47f1181fb0576d34521e454e7b 100644 (file)
@@ -202,14 +202,6 @@ EXPORT_SYMBOL(_find_next_zero_bit_le);
 EXPORT_SYMBOL(elf_platform);
 EXPORT_SYMBOL(elf_hwcap);
 
-       /* syscalls */
-EXPORT_SYMBOL(sys_write);
-EXPORT_SYMBOL(sys_read);
-EXPORT_SYMBOL(sys_lseek);
-EXPORT_SYMBOL(sys_open);
-EXPORT_SYMBOL(sys_exit);
-EXPORT_SYMBOL(sys_wait4);
-
 #ifdef CONFIG_PREEMPT
 EXPORT_SYMBOL(kernel_flag);
 #endif
index 3e56b9f4358af4a3728c96ed2815eb033a0fc841..5a247ba71a72e1bdfcd036e3ca8840eb35fbfe08 100644 (file)
@@ -124,15 +124,15 @@ unsigned long long sched_clock(void)
  *
  * In UP mode, it is invoked from the (global) timer_interrupt.
  */
-static void local_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static void local_timer_interrupt(int irq, void *dev_id)
 {
        if (current->pid)
-               profile_tick(CPU_PROFILING, regs);
-       update_process_times(user_mode(regs));
+               profile_tick(CPU_PROFILING);
+       update_process_times(user_mode(get_irq_regs()));
 }
 
 static irqreturn_t
-timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+timer_interrupt(int irq, void *dev_id)
 {
        unsigned int count;
 
@@ -157,7 +157,7 @@ timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
         *
         * SMP is not supported yet.
         */
-       local_timer_interrupt(irq, dev_id, regs);
+       local_timer_interrupt(irq, dev_id);
 
        return IRQ_HANDLED;
 }
index 7da9c5f7a0eb8cfd14419c0ff57b9ddcfd28b7b0..4dff1f98890039f0d96fcbc54e27c76322e3e383 100644 (file)
@@ -102,8 +102,7 @@ struct irq_chip eim_chip = {
        .set_type       = eim_set_irq_type,
 };
 
-static void demux_eim_irq(unsigned int irq, struct irq_desc *desc,
-                         struct pt_regs *regs)
+static void demux_eim_irq(unsigned int irq, struct irq_desc *desc)
 {
        struct at32_sm *sm = desc->handler_data;
        struct irq_desc *ext_desc;
@@ -121,7 +120,7 @@ static void demux_eim_irq(unsigned int irq, struct irq_desc *desc,
 
                ext_irq = i + sm->eim_first_irq;
                ext_desc = irq_desc + ext_irq;
-               ext_desc->handle_irq(ext_irq, ext_desc, regs);
+               ext_desc->handle_irq(ext_irq, ext_desc);
        }
 
        spin_unlock(&sm->lock);
index 74f8c9f2f03d20b0829c8155ba18d5cceb024186..eb87a18ad7b2f70c6a49a7595efeca4ac23706b1 100644 (file)
@@ -52,16 +52,19 @@ static struct intc intc0 = {
 asmlinkage void do_IRQ(int level, struct pt_regs *regs)
 {
        struct irq_desc *desc;
+       struct pt_regs *old_regs;
        unsigned int irq;
        unsigned long status_reg;
 
        local_irq_disable();
 
+       old_regs = set_irq_regs(regs);
+
        irq_enter();
 
        irq = intc_readl(&intc0, INTCAUSE0 - 4 * level);
        desc = irq_desc + irq;
-       desc->handle_irq(irq, desc, regs);
+       desc->handle_irq(irq, desc);
 
        /*
         * Clear all interrupt level masks so that we may handle
@@ -75,6 +78,8 @@ asmlinkage void do_IRQ(int level, struct pt_regs *regs)
        sysreg_write(SR, status_reg);
 
        irq_exit();
+
+       set_irq_regs(old_regs);
 }
 
 void __init init_IRQ(void)
index f5de6cf7df4e751be20f5c2b1714a3a3e1db0024..156184e17e57d0b74483b6c47b30e8cde814a92a 100644 (file)
@@ -121,15 +121,14 @@ unsigned long frv_dma_inprogress;
 /*
  * DMA irq handler - determine channel involved, grab status and call real handler
  */
-static irqreturn_t dma_irq_handler(int irq, void *_channel, struct pt_regs *regs)
+static irqreturn_t dma_irq_handler(int irq, void *_channel)
 {
        struct frv_dma_channel *channel = _channel;
 
        frv_clear_dma_inprogress(channel - frv_dma_channels);
        return channel->handler(channel - frv_dma_channels,
                                __get_DMAC(channel->ioaddr, CSTR),
-                               channel->data,
-                               regs);
+                               channel->data);
 
 } /* end dma_irq_handler() */
 
index 369bc0a7443df36987ffaba1e846177ca4e3f0a2..ad753c1e9b8fffa652e4e682f107f42ec400c5fc 100644 (file)
@@ -80,7 +80,7 @@ static struct irq_chip frv_fpga_pic = {
 /*
  * FPGA PIC interrupt handler
  */
-static irqreturn_t fpga_interrupt(int irq, void *_mask, struct pt_regs *regs)
+static irqreturn_t fpga_interrupt(int irq, void *_mask)
 {
        uint16_t imr, mask = (unsigned long) _mask;
 
@@ -95,7 +95,7 @@ static irqreturn_t fpga_interrupt(int irq, void *_mask, struct pt_regs *regs)
                irq = 31 - irq;
                mask &= ~(1 << irq);
 
-               generic_handle_irq(IRQ_BASE_FPGA + irq, regs);
+               generic_handle_irq(IRQ_BASE_FPGA + irq);
        }
 
        return IRQ_HANDLED;
index a43a22158956d625763904ecd88edeaa4f5f9f71..e0983f6926ed77be5b8874a7624051c258b63bc4 100644 (file)
@@ -79,7 +79,7 @@ static struct irq_chip frv_fpga_pic = {
 /*
  * FPGA PIC interrupt handler
  */
-static irqreturn_t fpga_interrupt(int irq, void *_mask, struct pt_regs *regs)
+static irqreturn_t fpga_interrupt(int irq, void *_mask)
 {
        uint16_t imr, mask = (unsigned long) _mask;
 
@@ -94,7 +94,7 @@ static irqreturn_t fpga_interrupt(int irq, void *_mask, struct pt_regs *regs)
                irq = 31 - irq;
                mask &= ~(1 << irq);
 
-               generic_irq_handle(IRQ_BASE_FPGA + irq, regs);
+               generic_irq_handle(IRQ_BASE_FPGA + irq);
        }
 
        return IRQ_HANDLED;
index 39c0188a3498e0337e33c3e5bff3962cb42298f2..c157eeff871d218348e12bcb48f2c3b951e1eaef 100644 (file)
@@ -90,7 +90,7 @@ static struct irq_chip frv_mb93493_pic = {
 /*
  * MB93493 PIC interrupt handler
  */
-static irqreturn_t mb93493_interrupt(int irq, void *_piqsr, struct pt_regs *regs)
+static irqreturn_t mb93493_interrupt(int irq, void *_piqsr)
 {
        volatile void *piqsr = _piqsr;
        uint32_t iqsr;
@@ -106,7 +106,7 @@ static irqreturn_t mb93493_interrupt(int irq, void *_piqsr, struct pt_regs *regs
                irq = 31 - irq;
                iqsr &= ~(1 << irq);
 
-               generic_handle_irq(IRQ_BASE_MB93493 + irq, regs);
+               generic_handle_irq(IRQ_BASE_MB93493 + irq);
        }
 
        return IRQ_HANDLED;
index 5ac041c7c0a4749b72cf95e7daf6862b55761fee..87f360a4ea27165059971e76001a0e818a0178e9 100644 (file)
@@ -143,7 +143,7 @@ static struct irq_chip frv_cpu_pic = {
 asmlinkage void do_IRQ(void)
 {
        irq_enter();
-       generic_handle_irq(__get_IRL(), __frame);
+       generic_handle_irq(__get_IRL());
        irq_exit();
 }
 
index 44a9aebc4f5a1637d1076510c1900c3aae33fa2c..ed588d73d7d8528bb93f4909affca45403270d87 100644 (file)
@@ -40,7 +40,7 @@ unsigned long __nongprelbss __dsu_clock_speed_HZ;
 unsigned long __nongprelbss __serial_clock_speed_HZ;
 unsigned long __delay_loops_MHz;
 
-static irqreturn_t timer_interrupt(int irq, void *dummy, struct pt_regs *regs);
+static irqreturn_t timer_interrupt(int irq, void *dummy);
 
 static struct irqaction timer_irq  = {
        timer_interrupt, IRQF_DISABLED, CPU_MASK_NONE, "timer", NULL, NULL
@@ -55,7 +55,7 @@ static inline int set_rtc_mmss(unsigned long nowtime)
  * timer_interrupt() needs to keep up the real-time clock,
  * as well as call the "do_timer()" routine every clocktick
  */
-static irqreturn_t timer_interrupt(int irq, void *dummy, struct pt_regs * regs)
+static irqreturn_t timer_interrupt(int irq, void *dummy)
 {
        /* last time the cmos clock got updated */
        static long last_rtc_update = 0;
@@ -70,8 +70,8 @@ static irqreturn_t timer_interrupt(int irq, void *dummy, struct pt_regs * regs)
        write_seqlock(&xtime_lock);
 
        do_timer(1);
-       update_process_times(user_mode(regs));
-       profile_tick(CPU_PROFILING, regs);
+       update_process_times(user_mode(get_irq_regs()));
+       profile_tick(CPU_PROFILING);
 
        /*
         * If we have an externally synchronized Linux clock, then update
index 21c9a4e71104356d7c83a98ca7a92eb8c08f5216..fc4f2abccf06fdfd426b20b8195f1ae25d873c53 100644 (file)
@@ -7,6 +7,7 @@ choice
 
 config M386
        bool "386"
+       depends on !UML
        ---help---
          This is the processor type of your CPU. This information is used for
          optimizing purposes. In order to compile a kernel that can run on
@@ -301,7 +302,7 @@ config X86_USE_PPRO_CHECKSUM
 
 config X86_USE_3DNOW
        bool
-       depends on MCYRIXIII || MK7 || MGEODE_LX
+       depends on (MCYRIXIII || MK7 || MGEODE_LX) && !UML
        default y
 
 config X86_OOSTORE
index 7cc0b189b82baa80d83d813a11ec256243a6cb0c..0677908dfa0600dd3f5cf9e315d4ad62154aca3f 100644 (file)
@@ -42,6 +42,10 @@ cflags-$(CONFIG_REGPARM) += -mregparm=3
 # temporary until string.h is fixed
 cflags-y += -ffreestanding
 
+# this works around some issues with generating unwind tables in older gccs
+# newer gccs do it by default
+cflags-y += -maccumulate-outgoing-args
+
 # Disable unit-at-a-time mode on pre-gcc-4.0 compilers, it makes gcc use
 # a lot more stack due to the lack of sharing of stacklots:
 CFLAGS                         += $(shell if [ $(call cc-version) -lt 0400 ] ; then echo $(call cc-option,-fno-unit-at-a-time); fi ;)
@@ -51,8 +55,8 @@ cflags-y += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
 AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
 
 # is .cfi_signal_frame supported too?
-cflags-y += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
-AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
+cflags-y += $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1,)
+AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1,)
 
 CFLAGS += $(cflags-y)
 
index ee2d79bd8af7933dcd4250756c719496dca5502c..97aacd6bd7d810a85c15f9d96811167b5b680165 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-git7
-# Wed Sep 27 21:53:10 2006
+# Linux kernel version: 2.6.19-rc2-git4
+# Sat Oct 21 03:38:56 2006
 #
 CONFIG_X86_32=y
 CONFIG_GENERIC_TIME=y
@@ -31,9 +31,11 @@ CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
 CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
@@ -41,9 +43,10 @@ CONFIG_IKCONFIG_PROC=y
 # CONFIG_RELAY is not set
 CONFIG_INITRAMFS_SOURCE=""
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
 # CONFIG_EMBEDDED is not set
 CONFIG_UID16=y
-CONFIG_SYSCTL=y
+# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -76,6 +79,7 @@ CONFIG_STOP_MACHINE=y
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 CONFIG_LBD=y
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
@@ -163,6 +167,7 @@ CONFIG_VM86=y
 # CONFIG_I8K is not set
 # CONFIG_X86_REBOOTFIXUPS is not set
 CONFIG_MICROCODE=y
+CONFIG_MICROCODE_OLD_INTERFACE=y
 CONFIG_X86_MSR=y
 CONFIG_X86_CPUID=y
 
@@ -177,6 +182,7 @@ CONFIG_HIGHMEM4G=y
 # CONFIG_HIGHMEM64G is not set
 CONFIG_PAGE_OFFSET=0xC0000000
 CONFIG_HIGHMEM=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_FLATMEM_MANUAL=y
 # CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -295,6 +301,7 @@ CONFIG_PCI_MMCONFIG=y
 CONFIG_PCI_MSI=y
 # CONFIG_PCI_MULTITHREAD_PROBE is not set
 # CONFIG_PCI_DEBUG is not set
+# CONFIG_HT_IRQ is not set
 CONFIG_ISA_DMA_API=y
 # CONFIG_ISA is not set
 # CONFIG_MCA is not set
@@ -354,6 +361,7 @@ CONFIG_IP_PNP_DHCP=y
 # CONFIG_INET_TUNNEL is not set
 CONFIG_INET_XFRM_MODE_TRANSPORT=y
 CONFIG_INET_XFRM_MODE_TUNNEL=y
+# CONFIG_INET_XFRM_MODE_BEET is not set
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
@@ -370,9 +378,10 @@ CONFIG_IPV6=y
 # CONFIG_INET6_TUNNEL is not set
 CONFIG_INET6_XFRM_MODE_TRANSPORT=y
 CONFIG_INET6_XFRM_MODE_TUNNEL=y
+# CONFIG_INET6_XFRM_MODE_BEET is not set
 # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=y
 # CONFIG_IPV6_TUNNEL is not set
-# CONFIG_IPV6_SUBTREES is not set
 # CONFIG_IPV6_MULTIPLE_TABLES is not set
 # CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
@@ -473,6 +482,13 @@ CONFIG_BLK_DEV_INITRD=y
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
 
+#
+# Misc devices
+#
+# CONFIG_IBM_ASM is not set
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+
 #
 # ATA/ATAPI/MFM/RLL support
 #
@@ -519,6 +535,7 @@ CONFIG_BLK_DEV_AMD74XX=y
 # CONFIG_BLK_DEV_CS5535 is not set
 # CONFIG_BLK_DEV_HPT34X is not set
 # CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_JMICRON is not set
 # CONFIG_BLK_DEV_SC1200 is not set
 CONFIG_BLK_DEV_PIIX=y
 # CONFIG_BLK_DEV_IT821X is not set
@@ -615,6 +632,7 @@ CONFIG_AIC79XX_DEBUG_MASK=0
 # CONFIG_SCSI_IPR is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
 # CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
 # CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
@@ -658,7 +676,6 @@ CONFIG_SATA_INTEL_COMBINED=y
 # CONFIG_PATA_HPT3X3 is not set
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_JMICRON is not set
-# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MPIIX is not set
 # CONFIG_PATA_OLDPIIX is not set
@@ -667,7 +684,6 @@ CONFIG_SATA_INTEL_COMBINED=y
 # CONFIG_PATA_OPTI is not set
 # CONFIG_PATA_OPTIDMA is not set
 # CONFIG_PATA_PDC_OLD is not set
-# CONFIG_PATA_QDI is not set
 # CONFIG_PATA_RADISYS is not set
 # CONFIG_PATA_RZ1000 is not set
 # CONFIG_PATA_SC1200 is not set
@@ -684,6 +700,7 @@ CONFIG_SATA_INTEL_COMBINED=y
 CONFIG_MD=y
 # CONFIG_BLK_DEV_MD is not set
 CONFIG_BLK_DEV_DM=y
+# CONFIG_DM_DEBUG is not set
 # CONFIG_DM_CRYPT is not set
 # CONFIG_DM_SNAPSHOT is not set
 # CONFIG_DM_MIRROR is not set
@@ -874,6 +891,7 @@ CONFIG_NET_POLL_CONTROLLER=y
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -896,6 +914,7 @@ CONFIG_KEYBOARD_ATKBD=y
 # CONFIG_KEYBOARD_LKKBD is not set
 # CONFIG_KEYBOARD_XTKBD is not set
 # CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
 CONFIG_INPUT_MOUSE=y
 CONFIG_MOUSE_PS2=y
 # CONFIG_MOUSE_SERIAL is not set
@@ -1012,6 +1031,7 @@ CONFIG_HANGCHECK_TIMER=y
 #
 # Dallas's 1-wire bus
 #
+# CONFIG_W1 is not set
 
 #
 # Hardware Monitoring support
@@ -1019,16 +1039,10 @@ CONFIG_HANGCHECK_TIMER=y
 # CONFIG_HWMON is not set
 # CONFIG_HWMON_VID is not set
 
-#
-# Misc devices
-#
-# CONFIG_IBM_ASM is not set
-
 #
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -1134,6 +1148,7 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_STORAGE_SDDR55 is not set
 # CONFIG_USB_STORAGE_JUMPSHOT is not set
 # CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_KARMA is not set
 # CONFIG_USB_LIBUSUAL is not set
 
 #
@@ -1187,6 +1202,7 @@ CONFIG_USB_MON=y
 #
 # CONFIG_USB_EMI62 is not set
 # CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
 # CONFIG_USB_AUERSWALD is not set
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
@@ -1194,12 +1210,13 @@ CONFIG_USB_MON=y
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGETKIT is not set
-# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_PHIDGET is not set
 # CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
 # CONFIG_USB_APPLEDISPLAY is not set
 # CONFIG_USB_SISUSBVGA is not set
 # CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
 # CONFIG_USB_TEST is not set
 
 #
@@ -1269,6 +1286,7 @@ CONFIG_EXT3_FS=y
 CONFIG_EXT3_FS_XATTR=y
 CONFIG_EXT3_FS_POSIX_ACL=y
 # CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4DEV_FS is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 CONFIG_FS_MBCACHE=y
@@ -1281,6 +1299,7 @@ CONFIG_REISERFS_FS_POSIX_ACL=y
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -1291,6 +1310,7 @@ CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
 CONFIG_AUTOFS4_FS=y
 # CONFIG_FUSE_FS is not set
+CONFIG_GENERIC_ACL=y
 
 #
 # CD-ROM/DVD Filesystems
@@ -1315,8 +1335,10 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
 CONFIG_HUGETLBFS=y
 CONFIG_HUGETLB_PAGE=y
 CONFIG_RAMFS=y
@@ -1452,11 +1474,14 @@ CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
 # CONFIG_DEBUG_FS is not set
 # CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
 # CONFIG_FRAME_POINTER is not set
 CONFIG_UNWIND_INFO=y
 CONFIG_STACK_UNWIND=y
 # CONFIG_FORCED_INLINING is not set
+# CONFIG_HEADERS_CHECK is not set
 # CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_LKDTM is not set
 CONFIG_EARLY_PRINTK=y
 CONFIG_DEBUG_STACKOVERFLOW=y
 # CONFIG_DEBUG_STACK_USAGE is not set
index 92f79cdd9a48c97aebb8a207a211cf28e421707a..ab974ff970730ec48300a2db994d1c9628f07d00 100644 (file)
@@ -332,7 +332,7 @@ acpi_parse_ioapic(acpi_table_entry_header * header, const unsigned long end)
 /*
  * Parse Interrupt Source Override for the ACPI SCI
  */
-static void acpi_sci_ioapic_setup(u32 gsi, u16 polarity, u16 trigger)
+static void acpi_sci_ioapic_setup(u32 bus_irq, u32 gsi, u16 polarity, u16 trigger)
 {
        if (trigger == 0)       /* compatible SCI trigger is level */
                trigger = 3;
@@ -352,13 +352,13 @@ static void acpi_sci_ioapic_setup(u32 gsi, u16 polarity, u16 trigger)
         * If GSI is < 16, this will update its flags,
         * else it will create a new mp_irqs[] entry.
         */
-       mp_override_legacy_irq(gsi, polarity, trigger, gsi);
+       mp_override_legacy_irq(bus_irq, polarity, trigger, gsi);
 
        /*
         * stash over-ride to indicate we've been here
         * and for later update of acpi_fadt
         */
-       acpi_sci_override_gsi = gsi;
+       acpi_sci_override_gsi = bus_irq;
        return;
 }
 
@@ -376,7 +376,7 @@ acpi_parse_int_src_ovr(acpi_table_entry_header * header,
        acpi_table_print_madt_entry(header);
 
        if (intsrc->bus_irq == acpi_fadt.sci_int) {
-               acpi_sci_ioapic_setup(intsrc->global_irq,
+               acpi_sci_ioapic_setup(intsrc->bus_irq, intsrc->global_irq,
                                      intsrc->flags.polarity,
                                      intsrc->flags.trigger);
                return 0;
@@ -879,7 +879,7 @@ static int __init acpi_parse_madt_ioapic_entries(void)
         * pretend we got one so we can set the SCI flags.
         */
        if (!acpi_sci_override_gsi)
-               acpi_sci_ioapic_setup(acpi_fadt.sci_int, 0, 0);
+               acpi_sci_ioapic_setup(acpi_fadt.sci_int, acpi_fadt.sci_int, 0, 0);
 
        /* Fill in identity legacy mapings where no override */
        mp_config_acpi_legacy_irqs();
index 25db49ef1770aa11ce148f1d35789e85bc125151..20563e52c62248853e9d4fbc9af48461c27696bd 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/acpi.h>
+#include <linux/cpu.h>
 
 #include <acpi/processor.h>
 #include <asm/acpi.h>
@@ -41,5 +42,124 @@ void acpi_processor_power_init_bm_check(struct acpi_processor_flags *flags,
                flags->bm_check = 1;
        }
 }
-
 EXPORT_SYMBOL(acpi_processor_power_init_bm_check);
+
+/* The code below handles cstate entry with monitor-mwait pair on Intel*/
+
+struct cstate_entry_s {
+       struct {
+               unsigned int eax;
+               unsigned int ecx;
+       } states[ACPI_PROCESSOR_MAX_POWER];
+};
+static struct cstate_entry_s *cpu_cstate_entry;        /* per CPU ptr */
+
+static short mwait_supported[ACPI_PROCESSOR_MAX_POWER];
+
+#define MWAIT_SUBSTATE_MASK    (0xf)
+#define MWAIT_SUBSTATE_SIZE    (4)
+
+#define CPUID_MWAIT_LEAF (5)
+#define CPUID5_ECX_EXTENSIONS_SUPPORTED (0x1)
+#define CPUID5_ECX_INTERRUPT_BREAK     (0x2)
+
+#define MWAIT_ECX_INTERRUPT_BREAK      (0x1)
+
+#define NATIVE_CSTATE_BEYOND_HALT      (2)
+
+int acpi_processor_ffh_cstate_probe(unsigned int cpu,
+               struct acpi_processor_cx *cx, struct acpi_power_register *reg)
+{
+       struct cstate_entry_s *percpu_entry;
+       struct cpuinfo_x86 *c = cpu_data + cpu;
+
+       cpumask_t saved_mask;
+       int retval;
+       unsigned int eax, ebx, ecx, edx;
+       unsigned int edx_part;
+       unsigned int cstate_type; /* C-state type and not ACPI C-state type */
+       unsigned int num_cstate_subtype;
+
+       if (!cpu_cstate_entry || c->cpuid_level < CPUID_MWAIT_LEAF )
+               return -1;
+
+       if (reg->bit_offset != NATIVE_CSTATE_BEYOND_HALT)
+               return -1;
+
+       percpu_entry = per_cpu_ptr(cpu_cstate_entry, cpu);
+       percpu_entry->states[cx->index].eax = 0;
+       percpu_entry->states[cx->index].ecx = 0;
+
+       /* Make sure we are running on right CPU */
+       saved_mask = current->cpus_allowed;
+       retval = set_cpus_allowed(current, cpumask_of_cpu(cpu));
+       if (retval)
+               return -1;
+
+       cpuid(CPUID_MWAIT_LEAF, &eax, &ebx, &ecx, &edx);
+
+       /* Check whether this particular cx_type (in CST) is supported or not */
+       cstate_type = (cx->address >> MWAIT_SUBSTATE_SIZE) + 1;
+       edx_part = edx >> (cstate_type * MWAIT_SUBSTATE_SIZE);
+       num_cstate_subtype = edx_part & MWAIT_SUBSTATE_MASK;
+
+       retval = 0;
+       if (num_cstate_subtype < (cx->address & MWAIT_SUBSTATE_MASK)) {
+               retval = -1;
+               goto out;
+       }
+
+       /* mwait ecx extensions INTERRUPT_BREAK should be supported for C2/C3 */
+       if (!(ecx & CPUID5_ECX_EXTENSIONS_SUPPORTED) ||
+           !(ecx & CPUID5_ECX_INTERRUPT_BREAK)) {
+               retval = -1;
+               goto out;
+       }
+       percpu_entry->states[cx->index].ecx = MWAIT_ECX_INTERRUPT_BREAK;
+
+       /* Use the hint in CST */
+       percpu_entry->states[cx->index].eax = cx->address;
+
+       if (!mwait_supported[cstate_type]) {
+               mwait_supported[cstate_type] = 1;
+               printk(KERN_DEBUG "Monitor-Mwait will be used to enter C-%d "
+                      "state\n", cx->type);
+       }
+
+out:
+       set_cpus_allowed(current, saved_mask);
+       return retval;
+}
+EXPORT_SYMBOL_GPL(acpi_processor_ffh_cstate_probe);
+
+void acpi_processor_ffh_cstate_enter(struct acpi_processor_cx *cx)
+{
+       unsigned int cpu = smp_processor_id();
+       struct cstate_entry_s *percpu_entry;
+
+       percpu_entry = per_cpu_ptr(cpu_cstate_entry, cpu);
+       mwait_idle_with_hints(percpu_entry->states[cx->index].eax,
+                             percpu_entry->states[cx->index].ecx);
+}
+EXPORT_SYMBOL_GPL(acpi_processor_ffh_cstate_enter);
+
+static int __init ffh_cstate_init(void)
+{
+       struct cpuinfo_x86 *c = &boot_cpu_data;
+       if (c->x86_vendor != X86_VENDOR_INTEL)
+               return -1;
+
+       cpu_cstate_entry = alloc_percpu(struct cstate_entry_s);
+       return 0;
+}
+
+static void __exit ffh_cstate_exit(void)
+{
+       if (cpu_cstate_entry) {
+               free_percpu(cpu_cstate_entry);
+               cpu_cstate_entry = NULL;
+       }
+}
+
+arch_initcall(ffh_cstate_init);
+__exitcall(ffh_cstate_exit);
index 28ab8064976421ffab42ed3ba07b3063f8fee86b..583c238e17fb2e9550fbbcb490ba1a41288b97dc 100644 (file)
@@ -344,6 +344,7 @@ void alternatives_smp_switch(int smp)
 
 void __init alternative_instructions(void)
 {
+       unsigned long flags;
        if (no_replacement) {
                printk(KERN_INFO "(SMP-)alternatives turned off\n");
                free_init_pages("SMP alternatives",
@@ -351,6 +352,8 @@ void __init alternative_instructions(void)
                                (unsigned long)__smp_alt_end);
                return;
        }
+
+       local_irq_save(flags);
        apply_alternatives(__alt_instructions, __alt_instructions_end);
 
        /* switch to patch-once-at-boottime-only mode and free the
@@ -386,4 +389,5 @@ void __init alternative_instructions(void)
                alternatives_smp_switch(0);
        }
 #endif
+       local_irq_restore(flags);
 }
index 90faae5c5d30a5451ce1e70e743eaca62424598c..2fd4b7d927c24f5578b437b7a183da4c24537488 100644 (file)
@@ -1193,11 +1193,11 @@ EXPORT_SYMBOL(switch_ipi_to_APIC_timer);
  * value into /proc/profile.
  */
 
-inline void smp_local_timer_interrupt(struct pt_regs * regs)
+inline void smp_local_timer_interrupt(void)
 {
-       profile_tick(CPU_PROFILING, regs);
+       profile_tick(CPU_PROFILING);
 #ifdef CONFIG_SMP
-       update_process_times(user_mode_vm(regs));
+       update_process_times(user_mode_vm(get_irq_regs()));
 #endif
 
        /*
@@ -1223,6 +1223,7 @@ inline void smp_local_timer_interrupt(struct pt_regs * regs)
 
 fastcall void smp_apic_timer_interrupt(struct pt_regs *regs)
 {
+       struct pt_regs *old_regs = set_irq_regs(regs);
        int cpu = smp_processor_id();
 
        /*
@@ -1241,12 +1242,13 @@ fastcall void smp_apic_timer_interrupt(struct pt_regs *regs)
         * interrupt lock, which is the WrongThing (tm) to do.
         */
        irq_enter();
-       smp_local_timer_interrupt(regs);
+       smp_local_timer_interrupt();
        irq_exit();
+       set_irq_regs(old_regs);
 }
 
 #ifndef CONFIG_SMP
-static void up_apic_timer_interrupt_call(struct pt_regs *regs)
+static void up_apic_timer_interrupt_call(void)
 {
        int cpu = smp_processor_id();
 
@@ -1255,11 +1257,11 @@ static void up_apic_timer_interrupt_call(struct pt_regs *regs)
         */
        per_cpu(irq_stat, cpu).apic_timer_irqs++;
 
-       smp_local_timer_interrupt(regs);
+       smp_local_timer_interrupt();
 }
 #endif
 
-void smp_send_timer_broadcast_ipi(struct pt_regs *regs)
+void smp_send_timer_broadcast_ipi(void)
 {
        cpumask_t mask;
 
@@ -1272,7 +1274,7 @@ void smp_send_timer_broadcast_ipi(struct pt_regs *regs)
                 * We can directly call the apic timer interrupt handler
                 * in UP case. Minus all irq related functions
                 */
-               up_apic_timer_interrupt_call(regs);
+               up_apic_timer_interrupt_call();
 #endif
        }
 }
index b42f2d914af3bb15eada724c854bc92581f47169..2af65858d3229b29cad60a7d25dc88a5a927bb5c 100644 (file)
@@ -540,11 +540,30 @@ static inline void apm_restore_cpus(cpumask_t mask)
  * Also, we KNOW that for the non error case of apm_bios_call, there
  * is no useful data returned in the low order 8 bits of eax.
  */
-#define APM_DO_CLI     \
-       if (apm_info.allow_ints) \
-               local_irq_enable(); \
-       else \
+
+static inline unsigned long __apm_irq_save(void)
+{
+       unsigned long flags;
+       local_save_flags(flags);
+       if (apm_info.allow_ints) {
+               if (irqs_disabled_flags(flags))
+                       local_irq_enable();
+       } else
+               local_irq_disable();
+
+       return flags;
+}
+
+#define apm_irq_save(flags) \
+       do { flags = __apm_irq_save(); } while (0)
+
+static inline void apm_irq_restore(unsigned long flags)
+{
+       if (irqs_disabled_flags(flags))
                local_irq_disable();
+       else if (irqs_disabled())
+               local_irq_enable();
+}
 
 #ifdef APM_ZERO_SEGS
 #      define APM_DECL_SEGS \
@@ -596,12 +615,11 @@ static u8 apm_bios_call(u32 func, u32 ebx_in, u32 ecx_in,
        save_desc_40 = gdt[0x40 / 8];
        gdt[0x40 / 8] = bad_bios_desc;
 
-       local_save_flags(flags);
-       APM_DO_CLI;
+       apm_irq_save(flags);
        APM_DO_SAVE_SEGS;
        apm_bios_call_asm(func, ebx_in, ecx_in, eax, ebx, ecx, edx, esi);
        APM_DO_RESTORE_SEGS;
-       local_irq_restore(flags);
+       apm_irq_restore(flags);
        gdt[0x40 / 8] = save_desc_40;
        put_cpu();
        apm_restore_cpus(cpus);
@@ -640,12 +658,11 @@ static u8 apm_bios_call_simple(u32 func, u32 ebx_in, u32 ecx_in, u32 *eax)
        save_desc_40 = gdt[0x40 / 8];
        gdt[0x40 / 8] = bad_bios_desc;
 
-       local_save_flags(flags);
-       APM_DO_CLI;
+       apm_irq_save(flags);
        APM_DO_SAVE_SEGS;
        error = apm_bios_call_simple_asm(func, ebx_in, ecx_in, eax);
        APM_DO_RESTORE_SEGS;
-       local_irq_restore(flags);
+       apm_irq_restore(flags);
        gdt[0x40 / 8] = save_desc_40;
        put_cpu();
        apm_restore_cpus(cpus);
index 4f43047de40625ffabaf6125000eb5c59e535547..2d8703b7ce65ead94dc3d6d26cf37421ad87d236 100644 (file)
@@ -110,17 +110,15 @@ int therm_throt_process(int curr)
 
 #ifdef CONFIG_SYSFS
 /* Add/Remove thermal_throttle interface for CPU device */
-static __cpuinit int thermal_throttle_add_dev(struct sys_device * sys_dev)
+static __cpuinit int thermal_throttle_add_dev(struct sys_device *sys_dev)
 {
-       sysfs_create_group(&sys_dev->kobj, &thermal_throttle_attr_group);
-       return 0;
+       return sysfs_create_group(&sys_dev->kobj, &thermal_throttle_attr_group);
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
-static __cpuinit int thermal_throttle_remove_dev(struct sys_device * sys_dev)
+static __cpuinit void thermal_throttle_remove_dev(struct sys_device *sys_dev)
 {
-       sysfs_remove_group(&sys_dev->kobj, &thermal_throttle_attr_group);
-       return 0;
+       return sysfs_remove_group(&sys_dev->kobj, &thermal_throttle_attr_group);
 }
 
 /* Mutex protecting device creation against CPU hotplug */
@@ -133,12 +131,14 @@ static __cpuinit int thermal_throttle_cpu_callback(struct notifier_block *nfb,
 {
        unsigned int cpu = (unsigned long)hcpu;
        struct sys_device *sys_dev;
+       int err;
 
        sys_dev = get_cpu_sysdev(cpu);
        mutex_lock(&therm_cpu_lock);
        switch (action) {
        case CPU_ONLINE:
-               thermal_throttle_add_dev(sys_dev);
+               err = thermal_throttle_add_dev(sys_dev);
+               WARN_ON(err);
                break;
        case CPU_DEAD:
                thermal_throttle_remove_dev(sys_dev);
@@ -157,6 +157,7 @@ static struct notifier_block thermal_throttle_cpu_notifier =
 static __init int thermal_throttle_init_device(void)
 {
        unsigned int cpu = 0;
+       int err;
 
        if (!atomic_read(&therm_throt_en))
                return 0;
@@ -167,8 +168,10 @@ static __init int thermal_throttle_init_device(void)
        mutex_lock(&therm_cpu_lock);
 #endif
        /* connect live CPUs to sysfs */
-       for_each_online_cpu(cpu)
-               thermal_throttle_add_dev(get_cpu_sysdev(cpu));
+       for_each_online_cpu(cpu) {
+               err = thermal_throttle_add_dev(get_cpu_sysdev(cpu));
+               WARN_ON(err);
+       }
 #ifdef CONFIG_HOTPLUG_CPU
        mutex_unlock(&therm_cpu_lock);
 #endif
index be9d883c62ce0302995b56c830530670902a7fe6..ca31f18d277c5487e3afab809783f9d79beb4fbe 100644 (file)
@@ -317,7 +317,7 @@ is386:      movl $2,%ecx            # set MP
        movl %eax,%gs
        lldt %ax
        cld                     # gcc2 wants the direction flag cleared at all times
-       pushl %eax              # fake return address
+       pushl $0                # fake return address for unwinder
 #ifdef CONFIG_SMP
        movb ready, %cl
        movb $1, ready
index 477b24daff539bf3d5a1ab6be6e10f6f10dedc22..9a0060b92e32ace2911ae839a9d8b710e7458ec4 100644 (file)
@@ -109,7 +109,7 @@ static struct clocksource clocksource_pit = {
 
 static int __init init_pit_clocksource(void)
 {
-       if (num_possible_cpus() > 4) /* PIT does not scale! */
+       if (num_possible_cpus() > 1) /* PIT does not scale! */
                return 0;
 
        clocksource_pit.mult = clocksource_hz2mult(CLOCK_TICK_RATE, 20);
index d07ed31f11e3269aed95d97c7cb8784c00cd3c11..62996cd17084245dafd53bcfab9555c20cc38c60 100644 (file)
@@ -113,7 +113,8 @@ void make_8259A_irq(unsigned int irq)
 {
        disable_irq_nosync(irq);
        io_apic_irqs &= ~(1<<irq);
-       set_irq_chip_and_handler(irq, &i8259A_chip, handle_level_irq);
+       set_irq_chip_and_handler_name(irq, &i8259A_chip, handle_level_irq,
+                                     "XT");
        enable_irq(irq);
 }
 
@@ -335,13 +336,13 @@ void init_8259A(int auto_eoi)
  */
  
 
-static irqreturn_t math_error_irq(int cpl, void *dev_id, struct pt_regs *regs)
+static irqreturn_t math_error_irq(int cpl, void *dev_id)
 {
        extern void math_error(void __user *);
        outb(0,0xF0);
        if (ignore_fpu_irq || !boot_cpu_data.hard_math)
                return IRQ_NONE;
-       math_error((void __user *)regs->eip);
+       math_error((void __user *)get_irq_regs()->eip);
        return IRQ_HANDLED;
 }
 
@@ -369,8 +370,8 @@ void __init init_ISA_irqs (void)
                        /*
                         * 16 old-style INTA-cycle interrupts:
                         */
-                       set_irq_chip_and_handler(i, &i8259A_chip,
-                                                handle_level_irq);
+                       set_irq_chip_and_handler_name(i, &i8259A_chip,
+                                                     handle_level_irq, "XT");
                } else {
                        /*
                         * 'high' PCI IRQs filled in on demand
index b7287fb499f3f0537b1afd2111e3788976f94aa7..350192d6ab986f70314abb98e7e2a68a04d0b9e7 100644 (file)
@@ -1184,8 +1184,8 @@ static int __assign_irq_vector(int irq)
 
        BUG_ON((unsigned)irq >= NR_IRQ_VECTORS);
 
-       if (IO_APIC_VECTOR(irq) > 0)
-               return IO_APIC_VECTOR(irq);
+       if (irq_vector[irq] > 0)
+               return irq_vector[irq];
 
        current_vector += 8;
        if (current_vector == SYSCALL_VECTOR)
@@ -1199,7 +1199,7 @@ static int __assign_irq_vector(int irq)
        }
 
        vector = current_vector;
-       IO_APIC_VECTOR(irq) = vector;
+       irq_vector[irq] = vector;
 
        return vector;
 }
@@ -1225,11 +1225,11 @@ static void ioapic_register_intr(int irq, int vector, unsigned long trigger)
 {
        if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) ||
                        trigger == IOAPIC_LEVEL)
-               set_irq_chip_and_handler(irq, &ioapic_chip,
-                                        handle_fasteoi_irq);
+               set_irq_chip_and_handler_name(irq, &ioapic_chip,
+                                        handle_fasteoi_irq, "fasteoi");
        else
-               set_irq_chip_and_handler(irq, &ioapic_chip,
-                                        handle_edge_irq);
+               set_irq_chip_and_handler_name(irq, &ioapic_chip,
+                                        handle_edge_irq, "edge");
        set_intr_gate(vector, interrupt[irq]);
 }
 
@@ -1967,7 +1967,7 @@ static void ack_ioapic_quirk_irq(unsigned int irq)
  * operation to prevent an edge-triggered interrupt escaping meanwhile.
  * The idea is from Manfred Spraul.  --macro
  */
-       i = IO_APIC_VECTOR(irq);
+       i = irq_vector[irq];
 
        v = apic_read(APIC_TMR + ((i & ~0x1f) >> 1));
 
@@ -1984,7 +1984,7 @@ static void ack_ioapic_quirk_irq(unsigned int irq)
 
 static int ioapic_retrigger_irq(unsigned int irq)
 {
-       send_IPI_self(IO_APIC_VECTOR(irq));
+       send_IPI_self(irq_vector[irq]);
 
        return 1;
 }
@@ -2020,7 +2020,7 @@ static inline void init_IO_APIC_traps(void)
         */
        for (irq = 0; irq < NR_IRQS ; irq++) {
                int tmp = irq;
-               if (IO_APIC_IRQ(tmp) && !IO_APIC_VECTOR(tmp)) {
+               if (IO_APIC_IRQ(tmp) && !irq_vector[tmp]) {
                        /*
                         * Hmm.. We don't have an entry for this,
                         * so default to an old-fashioned 8259
@@ -2235,7 +2235,8 @@ static inline void check_timer(void)
        printk(KERN_INFO "...trying to set up timer as Virtual Wire IRQ...");
 
        disable_8259A_irq(0);
-       set_irq_chip_and_handler(0, &lapic_chip, handle_fasteoi_irq);
+       set_irq_chip_and_handler_name(0, &lapic_chip, handle_fasteoi_irq,
+                                     "fasteio");
        apic_write_around(APIC_LVT0, APIC_DM_FIXED | vector);   /* Fixed mode */
        enable_8259A_irq(0);
 
@@ -2541,7 +2542,8 @@ int arch_setup_msi_irq(unsigned int irq, struct pci_dev *dev)
 
        write_msi_msg(irq, &msg);
 
-       set_irq_chip_and_handler(irq, &msi_chip, handle_edge_irq);
+       set_irq_chip_and_handler_name(irq, &msi_chip, handle_edge_irq,
+                                     "edge");
 
        return 0;
 }
@@ -2594,7 +2596,7 @@ static void set_ht_irq_affinity(unsigned int irq, cpumask_t mask)
 }
 #endif
 
-static struct hw_interrupt_type ht_irq_chip = {
+static struct irq_chip ht_irq_chip = {
        .name           = "PCI-HT",
        .mask           = mask_ht_irq,
        .unmask         = unmask_ht_irq,
@@ -2636,7 +2638,8 @@ int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev)
                write_ht_irq_low(irq, low);
                write_ht_irq_high(irq, high);
 
-               set_irq_chip_and_handler(irq, &ht_irq_chip, handle_edge_irq);
+               set_irq_chip_and_handler_name(irq, &ht_irq_chip,
+                                             handle_edge_irq, "edge");
        }
        return vector;
 }
index 3dd2e180151bcc868c80be75875d9c054b316a26..3201d421090a0d2cf5237f4d55ef070d41bc48b9 100644 (file)
@@ -53,6 +53,7 @@ static union irq_ctx *softirq_ctx[NR_CPUS] __read_mostly;
  */
 fastcall unsigned int do_IRQ(struct pt_regs *regs)
 {      
+       struct pt_regs *old_regs;
        /* high bit used in ret_from_ code */
        int irq = ~regs->orig_eax;
        struct irq_desc *desc = irq_desc + irq;
@@ -67,6 +68,7 @@ fastcall unsigned int do_IRQ(struct pt_regs *regs)
                BUG();
        }
 
+       old_regs = set_irq_regs(regs);
        irq_enter();
 #ifdef CONFIG_DEBUG_STACKOVERFLOW
        /* Debugging check for stack overflow: is there less than 1KB free? */
@@ -95,7 +97,7 @@ fastcall unsigned int do_IRQ(struct pt_regs *regs)
         * current stack (which is the irq stack already after all)
         */
        if (curctx != irqctx) {
-               int arg1, arg2, arg3, ebx;
+               int arg1, arg2, ebx;
 
                /* build the stack frame on the IRQ stack */
                isp = (u32*) ((char*)irqctx + sizeof(*irqctx));
@@ -114,17 +116,17 @@ fastcall unsigned int do_IRQ(struct pt_regs *regs)
                        "       xchgl  %%ebx,%%esp      \n"
                        "       call   *%%edi           \n"
                        "       movl   %%ebx,%%esp      \n"
-                       : "=a" (arg1), "=d" (arg2), "=c" (arg3), "=b" (ebx)
-                       :  "0" (irq),   "1" (desc),  "2" (regs),  "3" (isp),
+                       : "=a" (arg1), "=d" (arg2), "=b" (ebx)
+                       :  "0" (irq),   "1" (desc),  "2" (isp),
                           "D" (desc->handle_irq)
                        : "memory", "cc"
                );
        } else
 #endif
-               desc->handle_irq(irq, desc, regs);
+               desc->handle_irq(irq, desc);
 
        irq_exit();
-
+       set_irq_regs(old_regs);
        return 1;
 }
 
@@ -256,7 +258,7 @@ int show_interrupts(struct seq_file *p, void *v)
                        seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
 #endif
                seq_printf(p, " %8s", irq_desc[i].chip->name);
-               seq_printf(p, "-%s", handle_irq_name(irq_desc[i].handle_irq));
+               seq_printf(p, "-%-8s", irq_desc[i].name);
                seq_printf(p, "  %s", action->name);
 
                for (action=action->next; action; action = action->next)
index 9b9479768d5ebcda920044781234b8aa2d4183d3..c4d0291b519f836db7cfaccdfb8f375ffb0751ea 100644 (file)
@@ -656,14 +656,18 @@ static struct attribute_group mc_attr_group = {
 
 static int mc_sysdev_add(struct sys_device *sys_dev)
 {
-       int cpu = sys_dev->id;
+       int err, cpu = sys_dev->id;
        struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
 
        if (!cpu_online(cpu))
                return 0;
+
        pr_debug("Microcode:CPU %d added\n", cpu);
        memset(uci, 0, sizeof(*uci));
-       sysfs_create_group(&sys_dev->kobj, &mc_attr_group);
+
+       err = sysfs_create_group(&sys_dev->kobj, &mc_attr_group);
+       if (err)
+               return err;
 
        microcode_init_cpu(cpu);
        return 0;
index 3e8e3adb04896243323922cc0dadf3b94429c0c1..eaafe233a5da83f4abbb2c17e670b8a46fa4edaa 100644 (file)
@@ -219,11 +219,11 @@ static int __init check_nmi_watchdog(void)
        int cpu;
 
        /* Enable NMI watchdog for newer systems.
-           Actually it should be safe for most systems before 2004 too except
-          for some IBM systems that corrupt registers when NMI happens
-          during SMM. Unfortunately we don't have more exact information
-          on these and use this coarse check. */
-       if (nmi_watchdog == NMI_DEFAULT && dmi_get_year(DMI_BIOS_DATE) >= 2004)
+          Probably safe on most older systems too, but let's be careful.
+          IBM ThinkPads use INT10 inside SMM and that allows early NMI inside SMM
+          which hangs the system. Disable watchdog for all thinkpads */
+       if (nmi_watchdog == NMI_DEFAULT && dmi_get_year(DMI_BIOS_DATE) >= 2004 &&
+               !dmi_name_in_vendors("ThinkPad"))
                nmi_watchdog = NMI_LOCAL_APIC;
 
        if ((nmi_watchdog == NMI_NONE) || (nmi_watchdog == NMI_DEFAULT))
index dad02a960e03572046c2e9ced98186c64e7ca5a5..1e1fa3e391a3889ec822c869c19bd9feb76e5e36 100644 (file)
@@ -236,20 +236,28 @@ EXPORT_SYMBOL_GPL(cpu_idle_wait);
  * We execute MONITOR against need_resched and enter optimized wait state
  * through MWAIT. Whenever someone changes need_resched, we would be woken
  * up from MWAIT (without an IPI).
+ *
+ * New with Core Duo processors, MWAIT can take some hints based on CPU
+ * capability.
  */
-static void mwait_idle(void)
+void mwait_idle_with_hints(unsigned long eax, unsigned long ecx)
 {
-       local_irq_enable();
-
-       while (!need_resched()) {
+       if (!need_resched()) {
                __monitor((void *)&current_thread_info()->flags, 0, 0);
                smp_mb();
-               if (need_resched())
-                       break;
-               __mwait(0, 0);
+               if (!need_resched())
+                       __mwait(eax, ecx);
        }
 }
 
+/* Default MONITOR/MWAIT with no hints, used for default C1 state */
+static void mwait_idle(void)
+{
+       local_irq_enable();
+       while (!need_resched())
+               mwait_idle_with_hints(0, 0);
+}
+
 void __devinit select_idle_routine(const struct cpuinfo_x86 *c)
 {
        if (cpu_has(c, X86_FEATURE_MWAIT)) {
index 000cf03751fe9fd88280ea6938837c3f49126cac..519e63c3c1306abb1a59b31e017d76e4e671b01d 100644 (file)
@@ -1083,16 +1083,15 @@ static unsigned long __init setup_memory(void)
 
 void __init zone_sizes_init(void)
 {
+       unsigned long max_zone_pfns[MAX_NR_ZONES];
+       memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
+       max_zone_pfns[ZONE_DMA] =
+               virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
+       max_zone_pfns[ZONE_NORMAL] = max_low_pfn;
 #ifdef CONFIG_HIGHMEM
-       unsigned long max_zone_pfns[MAX_NR_ZONES] = {
-                       virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT,
-                       max_low_pfn,
-                       highend_pfn};
+       max_zone_pfns[ZONE_HIGHMEM] = highend_pfn;
        add_active_range(0, 0, highend_pfn);
 #else
-       unsigned long max_zone_pfns[MAX_NR_ZONES] = {
-                       virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT,
-                       max_low_pfn};
        add_active_range(0, 0, max_low_pfn);
 #endif
 
index 1b080ab8a49fad87d600b397d12748393d46ed6e..31e5c6573aae450b3a1f94fe7129de94fc4ea26e 100644 (file)
@@ -321,6 +321,7 @@ static inline void leave_mm (unsigned long cpu)
 
 fastcall void smp_invalidate_interrupt(struct pt_regs *regs)
 {
+       struct pt_regs *old_regs = set_irq_regs(regs);
        unsigned long cpu;
 
        cpu = get_cpu();
@@ -351,6 +352,7 @@ fastcall void smp_invalidate_interrupt(struct pt_regs *regs)
        smp_mb__after_clear_bit();
 out:
        put_cpu_no_resched();
+       set_irq_regs(old_regs);
 }
 
 static void flush_tlb_others(cpumask_t cpumask, struct mm_struct *mm,
@@ -605,11 +607,14 @@ void smp_send_stop(void)
  */
 fastcall void smp_reschedule_interrupt(struct pt_regs *regs)
 {
+       struct pt_regs *old_regs = set_irq_regs(regs);
        ack_APIC_irq();
+       set_irq_regs(old_regs);
 }
 
 fastcall void smp_call_function_interrupt(struct pt_regs *regs)
 {
+       struct pt_regs *old_regs = set_irq_regs(regs);
        void (*func) (void *info) = call_data->func;
        void *info = call_data->info;
        int wait = call_data->wait;
@@ -632,6 +637,7 @@ fastcall void smp_call_function_interrupt(struct pt_regs *regs)
                mb();
                atomic_inc(&call_data->finished);
        }
+       set_irq_regs(old_regs);
 }
 
 /*
index 7e639f78b0b9f274ea055ef42275506b262a769c..2697e9210e92773a28d5b2e9ea7174433465acef 100644 (file)
@@ -318,3 +318,4 @@ ENTRY(sys_call_table)
        .long sys_vmsplice
        .long sys_move_pages
        .long sys_getcpu
+       .long sys_epoll_pwait
index 58a2d5582419d2051f3e8c7db7082ecaea496f40..78af572fd17c3e4a903aaf59062744455808e77a 100644 (file)
@@ -161,7 +161,7 @@ EXPORT_SYMBOL(profile_pc);
  * Time Stamp Counter value at the time of the timer interrupt, so that
  * we later on can estimate the time of day more exactly.
  */
-irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t timer_interrupt(int irq, void *dev_id)
 {
        /*
         * Here we are in the timer irq handler. We just have irqs locally
@@ -188,7 +188,7 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        }
 #endif
 
-       do_timer_interrupt_hook(regs);
+       do_timer_interrupt_hook();
 
 
        if (MCA_bus) {
@@ -201,15 +201,15 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                high bit of the PPI port B (0x61).  Note that some PS/2s,
                notably the 55SX, work fine if this is removed.  */
 
-               irq = inb_p( 0x61 );    /* read the current state */
-               outb_p( irq|0x80, 0x61 );       /* reset the IRQ */
+               u8 irq_v = inb_p( 0x61 );       /* read the current state */
+               outb_p( irq_v|0x80, 0x61 );     /* reset the IRQ */
        }
 
        write_sequnlock(&xtime_lock);
 
 #ifdef CONFIG_X86_LOCAL_APIC
        if (using_apic_timer)
-               smp_send_timer_broadcast_ipi(regs);
+               smp_send_timer_broadcast_ipi();
 #endif
 
        return IRQ_HANDLED;
index 6bf14a4e995ec86af8dcc312e7ed52320658d5f2..1a2a979cf6a344f1603b33605a319831ee667a95 100644 (file)
@@ -441,7 +441,7 @@ int hpet_rtc_dropped_irq(void)
        return 1;
 }
 
-irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id)
 {
        struct rtc_time curr_time;
        unsigned long rtc_int_flag = 0;
@@ -480,7 +480,7 @@ irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        }
        if (call_rtc_interrupt) {
                rtc_int_flag |= (RTC_IRQF | (RTC_NUM_INTS << 8));
-               rtc_interrupt(rtc_int_flag, dev_id, regs);
+               rtc_interrupt(rtc_int_flag, dev_id);
        }
        return IRQ_HANDLED;
 }
index b8fa0a8b2e4733170d0b72cff576d7ddb8c750cd..fbc95828cd7493082aeeedc0396a762db056097b 100644 (file)
@@ -349,8 +349,8 @@ static int tsc_update_callback(void)
        int change = 0;
 
        /* check to see if we should switch to the safe clocksource: */
-       if (clocksource_tsc.rating != 50 && check_tsc_unstable()) {
-               clocksource_tsc.rating = 50;
+       if (clocksource_tsc.rating != 0 && check_tsc_unstable()) {
+               clocksource_tsc.rating = 0;
                clocksource_reselect();
                change = 1;
        }
@@ -461,7 +461,7 @@ static int __init init_tsc_clocksource(void)
                                                        clocksource_tsc.shift);
                /* lower the rating if we already know its unstable: */
                if (check_tsc_unstable())
-                       clocksource_tsc.rating = 50;
+                       clocksource_tsc.rating = 0;
 
                init_timer(&verify_tsc_freq_timer);
                verify_tsc_freq_timer.function = verify_tsc_freq;
index 8355d8d87d183d8b81f78e04c053508fa46c7553..cbcd61d6120b2fdf13b1f59a46721eb8c3c89b10 100644 (file)
@@ -714,7 +714,7 @@ static int irqbits;
        | (1 << SIGUSR1) | (1 << SIGUSR2) | (1 << SIGIO)  | (1 << SIGURG) \
        | (1 << SIGUNUSED) )
        
-static irqreturn_t irq_handler(int intno, void *dev_id, struct pt_regs * regs)
+static irqreturn_t irq_handler(int intno, void *dev_id)
 {
        int irq_bit;
        unsigned long flags;
index ef6ad9e1a609d85d751268b4c8911706476b723b..c01eb39c0b43160738fd0cba92fa9e9c38f1629d 100644 (file)
@@ -152,6 +152,8 @@ ENTRY(__read_lock_failed)
 
 #endif
 
+#ifdef CONFIG_RWSEM_XCHGADD_ALGORITHM
+
 /* Fix up special calling conventions */
 ENTRY(call_rwsem_down_read_failed)
        CFI_STARTPROC
@@ -214,3 +216,4 @@ ENTRY(call_rwsem_downgrade_wake)
        CFI_ENDPROC
        END(call_rwsem_downgrade_wake)
 
+#endif
index 08502fc6d0cb8d0fc819682d26b499e5aab08efb..d22cfc9d656ca39317d68a1a2a0f6ec6b13bf2df 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/highmem.h>
 #include <linux/blkdev.h>
 #include <linux/module.h>
+#include <linux/backing-dev.h>
 #include <asm/uaccess.h>
 #include <asm/mmx.h>
 
@@ -179,7 +180,7 @@ __clear_user(void __user *to, unsigned long n)
 EXPORT_SYMBOL(__clear_user);
 
 /**
- * strlen_user: - Get the size of a string in user space.
+ * strnlen_user: - Get the size of a string in user space.
  * @s: The string to measure.
  * @n: The maximum valid length
  *
@@ -741,7 +742,7 @@ survive:
 
                        if (retval == -ENOMEM && is_init(current)) {
                                up_read(&current->mm->mmap_sem);
-                               blk_congestion_wait(WRITE, HZ/50);
+                               congestion_wait(WRITE, HZ/50);
                                goto survive;
                        }
 
index 5929f884d79b666c344643dbb8d5c1b59026d154..07097ed48890d64762e61b9f84e8b264d63c885c 100644 (file)
@@ -191,7 +191,7 @@ static struct hw_interrupt_type piix4_virtual_irq_type = {
  * enable_irq gets the right irq. This 'master' irq is never directly
  * manipulated by any driver.
  */
-static irqreturn_t piix4_master_intr(int irq, void *dev_id, struct pt_regs * regs)
+static irqreturn_t piix4_master_intr(int irq, void *dev_id)
 {
        int realirq;
        irq_desc_t *desc;
@@ -244,7 +244,7 @@ static irqreturn_t piix4_master_intr(int irq, void *dev_id, struct pt_regs * reg
        kstat_cpu(smp_processor_id()).irqs[realirq]++;
 
        if (likely(desc->action != NULL))
-               handle_IRQ_event(realirq, regs, desc->action);
+               handle_IRQ_event(realirq, desc->action);
 
        if (!(desc->status & IRQ_DISABLED))
                enable_8259A_irq(realirq);
index 80b7f2fc4f46ac9038128f852ad11d3e67ad3b03..8fe7e4593d5fe7aca75b81d35bbb70863427bcb2 100644 (file)
@@ -44,7 +44,7 @@ struct voyager_SUS *voyager_SUS = NULL;
 
 #ifdef CONFIG_SMP
 static void
-voyager_dump(int dummy1, struct pt_regs *dummy2, struct tty_struct *dummy3)
+voyager_dump(int dummy1, struct tty_struct *dummy3)
 {
        /* get here via a sysrq */
        voyager_smp_dump();
@@ -87,7 +87,7 @@ voyager_detect(struct voyager_bios_info *bios)
 }
 
 void
-voyager_system_interrupt(int cpl, void *dev_id, struct pt_regs *regs)
+voyager_system_interrupt(int cpl, void *dev_id)
 {
        printk("Voyager: detected system interrupt\n");
 }
@@ -166,7 +166,7 @@ voyager_memory_detect(int region, __u32 *start, __u32 *length)
  * off the timer tick to the SMP code, since the VIC doesn't have an
  * internal timer (The QIC does, but that's another story). */
 void
-voyager_timer_interrupt(struct pt_regs *regs)
+voyager_timer_interrupt(void)
 {
        if((jiffies & 0x3ff) == 0) {
 
@@ -202,7 +202,7 @@ voyager_timer_interrupt(struct pt_regs *regs)
                }
        }
 #ifdef CONFIG_SMP
-       smp_vic_timer_interrupt(regs);
+       smp_vic_timer_interrupt();
 #endif
 }
 
index 856c73fcb7e76b0fcc27aa7956ce1ed0258384df..f3fea2ad50fea81c5a4a3decfcdfc52d041b5f61 100644 (file)
@@ -85,8 +85,8 @@ static int ack_QIC_CPI(__u8 cpi);
 static void ack_special_QIC_CPI(__u8 cpi);
 static void ack_VIC_CPI(__u8 cpi);
 static void send_CPI_allbutself(__u8 cpi);
-static void enable_vic_irq(unsigned int irq);
-static void disable_vic_irq(unsigned int irq);
+static void mask_vic_irq(unsigned int irq);
+static void unmask_vic_irq(unsigned int irq);
 static unsigned int startup_vic_irq(unsigned int irq);
 static void enable_local_vic_irq(unsigned int irq);
 static void disable_local_vic_irq(unsigned int irq);
@@ -126,10 +126,10 @@ send_QIC_CPI(__u32 cpuset, __u8 cpi)
 }
 
 static inline void
-wrapper_smp_local_timer_interrupt(struct pt_regs *regs)
+wrapper_smp_local_timer_interrupt(void)
 {
        irq_enter();
-       smp_local_timer_interrupt(regs);
+       smp_local_timer_interrupt();
        irq_exit();
 }
 
@@ -205,15 +205,12 @@ ack_CPI(__u8 cpi)
 /* The VIC IRQ descriptors -- these look almost identical to the
  * 8259 IRQs except that masks and things must be kept per processor
  */
-static struct hw_interrupt_type vic_irq_type = {
-       .typename = "VIC-level",
-       .startup = startup_vic_irq,
-       .shutdown = disable_vic_irq,
-       .enable = enable_vic_irq,
-       .disable = disable_vic_irq,
-       .ack = before_handle_vic_irq,
-       .end = after_handle_vic_irq,
-       .set_affinity = set_vic_irq_affinity,
+static struct irq_chip vic_chip = {
+       .name           = "VIC",
+       .startup        = startup_vic_irq,
+       .mask           = mask_vic_irq,
+       .unmask         = unmask_vic_irq,
+       .set_affinity   = set_vic_irq_affinity,
 };
 
 /* used to count up as CPUs are brought on line (starts at 0) */
@@ -786,7 +783,7 @@ fastcall void
 smp_vic_sys_interrupt(struct pt_regs *regs)
 {
        ack_CPI(VIC_SYS_INT);
-       printk("Voyager SYSTEM INTERRUPT\n");
+       printk("Voyager SYSTEM INTERRUPT\n");   
 }
 
 /* Handle a voyager CMN_INT; These interrupts occur either because of
@@ -1135,15 +1132,19 @@ EXPORT_SYMBOL(smp_call_function);
 fastcall void 
 smp_apic_timer_interrupt(struct pt_regs *regs)
 {
-       wrapper_smp_local_timer_interrupt(regs);
+       struct pt_regs *old_regs = set_irq_regs(regs);
+       wrapper_smp_local_timer_interrupt();
+       set_irq_regs(old_regs);
 }
 
 /* All of the QUAD interrupt GATES */
 fastcall void
 smp_qic_timer_interrupt(struct pt_regs *regs)
 {
+       struct pt_regs *old_regs = set_irq_regs(regs);
        ack_QIC_CPI(QIC_TIMER_CPI);
-       wrapper_smp_local_timer_interrupt(regs);
+       wrapper_smp_local_timer_interrupt();
+       set_irq_regs(old_regs);
 }
 
 fastcall void
@@ -1177,6 +1178,7 @@ smp_qic_call_function_interrupt(struct pt_regs *regs)
 fastcall void
 smp_vic_cpi_interrupt(struct pt_regs *regs)
 {
+       struct pt_regs *old_regs = set_irq_regs(regs);
        __u8 cpu = smp_processor_id();
 
        if(is_cpu_quad())
@@ -1185,7 +1187,7 @@ smp_vic_cpi_interrupt(struct pt_regs *regs)
                ack_VIC_CPI(VIC_CPI_LEVEL0);
 
        if(test_and_clear_bit(VIC_TIMER_CPI, &vic_cpi_mailbox[cpu]))
-               wrapper_smp_local_timer_interrupt(regs);
+               wrapper_smp_local_timer_interrupt();
        if(test_and_clear_bit(VIC_INVALIDATE_CPI, &vic_cpi_mailbox[cpu]))
                smp_invalidate_interrupt();
        if(test_and_clear_bit(VIC_RESCHEDULE_CPI, &vic_cpi_mailbox[cpu]))
@@ -1194,6 +1196,7 @@ smp_vic_cpi_interrupt(struct pt_regs *regs)
                smp_enable_irq_interrupt();
        if(test_and_clear_bit(VIC_CALL_FUNCTION_CPI, &vic_cpi_mailbox[cpu]))
                smp_call_function_interrupt();
+       set_irq_regs(old_regs);
 }
 
 static void
@@ -1264,10 +1267,10 @@ smp_send_stop(void)
 /* this function is triggered in time.c when a clock tick fires
  * we need to re-broadcast the tick to all CPUs */
 void
-smp_vic_timer_interrupt(struct pt_regs *regs)
+smp_vic_timer_interrupt(void)
 {
        send_CPI_allbutself(VIC_TIMER_CPI);
-       smp_local_timer_interrupt(regs);
+       smp_local_timer_interrupt();
 }
 
 /* local (per CPU) timer interrupt.  It does both profiling and
@@ -1279,12 +1282,12 @@ smp_vic_timer_interrupt(struct pt_regs *regs)
  * value into /proc/profile.
  */
 void
-smp_local_timer_interrupt(struct pt_regs * regs)
+smp_local_timer_interrupt(void)
 {
        int cpu = smp_processor_id();
        long weight;
 
-       profile_tick(CPU_PROFILING, regs);
+       profile_tick(CPU_PROFILING);
        if (--per_cpu(prof_counter, cpu) <= 0) {
                /*
                 * The multiplier may have changed since the last time we got
@@ -1302,7 +1305,7 @@ smp_local_timer_interrupt(struct pt_regs * regs)
                                                per_cpu(prof_counter, cpu);
                }
 
-               update_process_times(user_mode_vm(regs));
+               update_process_times(user_mode_vm(get_irq_regs()));
        }
 
        if( ((1<<cpu) & voyager_extended_vic_processors) == 0)
@@ -1389,6 +1392,17 @@ setup_profiling_timer(unsigned int multiplier)
        return 0;
 }
 
+/* This is a bit of a mess, but forced on us by the genirq changes
+ * there's no genirq handler that really does what voyager wants
+ * so hack it up with the simple IRQ handler */
+static void fastcall
+handle_vic_irq(unsigned int irq, struct irq_desc *desc)
+{
+       before_handle_vic_irq(irq);
+       handle_simple_irq(irq, desc);
+       after_handle_vic_irq(irq);
+}
+
 
 /*  The CPIs are handled in the per cpu 8259s, so they must be
  *  enabled to be received: FIX: enabling the CPIs in the early
@@ -1425,7 +1439,7 @@ smp_intr_init(void)
         * This is for later: first 16 correspond to PC IRQs; next 16
         * are Primary MC IRQs and final 16 are Secondary MC IRQs */
        for(i = 0; i < 48; i++)
-               irq_desc[i].chip = &vic_irq_type;
+               set_irq_chip_and_handler(i, &vic_chip, handle_vic_irq);
 }
 
 /* send a CPI at level cpi to a set of cpus in cpuset (set 1 bit per
@@ -1523,7 +1537,7 @@ ack_VIC_CPI(__u8 cpi)
 static unsigned int
 startup_vic_irq(unsigned int irq)
 {
-       enable_vic_irq(irq);
+       unmask_vic_irq(irq);
 
        return 0;
 }
@@ -1550,7 +1564,7 @@ startup_vic_irq(unsigned int irq)
  *    adjust their masks accordingly.  */
 
 static void
-enable_vic_irq(unsigned int irq)
+unmask_vic_irq(unsigned int irq)
 {
        /* linux doesn't to processor-irq affinity, so enable on
         * all CPUs we know about */
@@ -1559,7 +1573,7 @@ enable_vic_irq(unsigned int irq)
        __u32 processorList = 0;
        unsigned long flags;
 
-       VDEBUG(("VOYAGER: enable_vic_irq(%d) CPU%d affinity 0x%lx\n",
+       VDEBUG(("VOYAGER: unmask_vic_irq(%d) CPU%d affinity 0x%lx\n",
                irq, cpu, cpu_irq_affinity[cpu]));
        spin_lock_irqsave(&vic_irq_lock, flags);
        for_each_online_cpu(real_cpu) {
@@ -1583,7 +1597,7 @@ enable_vic_irq(unsigned int irq)
 }
 
 static void
-disable_vic_irq(unsigned int irq)
+mask_vic_irq(unsigned int irq)
 {
        /* lazy disable, do nothing */
 }
@@ -1811,7 +1825,7 @@ set_vic_irq_affinity(unsigned int irq, cpumask_t mask)
         * disabled again as it comes in (voyager lazy disable).  If
         * the affinity map is tightened to disable the interrupt on a
         * cpu, it will be pushed off when it comes in */
-       enable_vic_irq(irq);
+       unmask_vic_irq(irq);
 }
 
 static void
index 455597db84dffe2d078db1011d21653a8568650c..ddbdb0336f28f1c6d4d303d11055a929b7daf286 100644 (file)
@@ -356,11 +356,12 @@ void __init numa_kva_reserve(void)
 void __init zone_sizes_init(void)
 {
        int nid;
-       unsigned long max_zone_pfns[MAX_NR_ZONES] = {
-               virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT,
-               max_low_pfn,
-               highend_pfn
-       };
+       unsigned long max_zone_pfns[MAX_NR_ZONES];
+       memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
+       max_zone_pfns[ZONE_DMA] =
+               virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
+       max_zone_pfns[ZONE_NORMAL] = max_low_pfn;
+       max_zone_pfns[ZONE_HIGHMEM] = highend_pfn;
 
        /* If SRAT has not registered memory, register it now */
        if (find_max_pfn_with_active_regions() == 0) {
index 68bce194e688a1903480425b3db8dc37802127f0..6d5ace845e445b2eca6a25452e100e380e0467b4 100644 (file)
@@ -20,6 +20,7 @@
 unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 |
                                PCI_PROBE_MMCONF;
 
+int pci_bf_sort;
 int pci_routeirq;
 int pcibios_last_bus = -1;
 unsigned long pirq_table_addr;
@@ -117,6 +118,20 @@ void __devinit  pcibios_fixup_bus(struct pci_bus *b)
        pci_read_bridge_bases(b);
 }
 
+/*
+ * Only use DMI information to set this if nothing was passed
+ * on the kernel command line (which was parsed earlier).
+ */
+
+static int __devinit set_bf_sort(struct dmi_system_id *d)
+{
+       if (pci_bf_sort == pci_bf_sort_default) {
+               pci_bf_sort = pci_dmi_bf;
+               printk(KERN_INFO "PCI: %s detected, enabling pci=bfsort.\n", d->ident);
+       }
+       return 0;
+}
+
 /*
  * Enable renumbering of PCI bus# ranges to reach all PCI busses (Cardbus)
  */
@@ -130,11 +145,11 @@ static int __devinit assign_all_busses(struct dmi_system_id *d)
 }
 #endif
 
+static struct dmi_system_id __devinitdata pciprobe_dmi_table[] = {
+#ifdef __i386__
 /*
  * Laptops which need pci=assign-busses to see Cardbus cards
  */
-static struct dmi_system_id __devinitdata pciprobe_dmi_table[] = {
-#ifdef __i386__
        {
                .callback = assign_all_busses,
                .ident = "Samsung X20 Laptop",
@@ -144,6 +159,38 @@ static struct dmi_system_id __devinitdata pciprobe_dmi_table[] = {
                },
        },
 #endif         /* __i386__ */
+       {
+               .callback = set_bf_sort,
+               .ident = "Dell PowerEdge 1950",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Dell"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 1950"),
+               },
+       },
+       {
+               .callback = set_bf_sort,
+               .ident = "Dell PowerEdge 1955",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Dell"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 1955"),
+               },
+       },
+       {
+               .callback = set_bf_sort,
+               .ident = "Dell PowerEdge 2900",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Dell"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 2900"),
+               },
+       },
+       {
+               .callback = set_bf_sort,
+               .ident = "Dell PowerEdge 2950",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Dell"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 2950"),
+               },
+       },
        {}
 };
 
@@ -189,6 +236,8 @@ static int __init pcibios_init(void)
 
        pcibios_resource_survey();
 
+       if (pci_bf_sort >= pci_force_bf)
+               pci_sort_breadthfirst();
 #ifdef CONFIG_PCI_BIOS
        if ((pci_probe & PCI_BIOS_SORT) && !(pci_probe & PCI_NO_SORT))
                pcibios_sort();
@@ -203,6 +252,12 @@ char * __devinit  pcibios_setup(char *str)
        if (!strcmp(str, "off")) {
                pci_probe = 0;
                return NULL;
+       } else if (!strcmp(str, "bfsort")) {
+               pci_bf_sort = pci_force_bf;
+               return NULL;
+       } else if (!strcmp(str, "nobfsort")) {
+               pci_bf_sort = pci_force_nobf;
+               return NULL;
        }
 #ifdef CONFIG_PCI_BIOS
        else if (!strcmp(str, "bios")) {
index 5acf0b4743cfc74ba1cc04e34e708449a3d03ecc..431c9a51b1578bbaf39de3bcefc95d2087a73a38 100644 (file)
@@ -256,6 +256,8 @@ static int __init pci_check_type2(void)
 
 void __init pci_direct_init(int type)
 {
+       if (type == 0)
+               return;
        printk(KERN_INFO "PCI: Using configuration type %d\n", type);
        if (type == 1)
                raw_pci_ops = &pci_direct_conf1;
index b60d7e8689ede9fcb6d1ca4d0fb055d1750603f3..908b410f4c931c1ac62e562d2828ccd68714600f 100644 (file)
@@ -342,51 +342,6 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,       PCI_DEVICE_ID_INTEL_MCH_PB1,    pcie_r
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_MCH_PC,     pcie_rootport_aspm_quirk );
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_MCH_PC1,    pcie_rootport_aspm_quirk );
 
-/*
- * Fixup to mark boot BIOS video selected by BIOS before it changes
- *
- * From information provided by "Jon Smirl" <jonsmirl@gmail.com>
- *
- * The standard boot ROM sequence for an x86 machine uses the BIOS
- * to select an initial video card for boot display. This boot video 
- * card will have it's BIOS copied to C0000 in system RAM. 
- * IORESOURCE_ROM_SHADOW is used to associate the boot video
- * card with this copy. On laptops this copy has to be used since
- * the main ROM may be compressed or combined with another image.
- * See pci_map_rom() for use of this flag. IORESOURCE_ROM_SHADOW
- * is marked here since the boot video device will be the only enabled
- * video device at this point.
- */
-
-static void __devinit pci_fixup_video(struct pci_dev *pdev)
-{
-       struct pci_dev *bridge;
-       struct pci_bus *bus;
-       u16 config;
-
-       if ((pdev->class >> 8) != PCI_CLASS_DISPLAY_VGA)
-               return;
-
-       /* Is VGA routed to us? */
-       bus = pdev->bus;
-       while (bus) {
-               bridge = bus->self;
-               if (bridge) {
-                       pci_read_config_word(bridge, PCI_BRIDGE_CONTROL,
-                                               &config);
-                       if (!(config & PCI_BRIDGE_CTL_VGA))
-                               return;
-               }
-               bus = bus->parent;
-       }
-       pci_read_config_word(pdev, PCI_COMMAND, &config);
-       if (config & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) {
-               pdev->resource[PCI_ROM_RESOURCE].flags |= IORESOURCE_ROM_SHADOW;
-               printk(KERN_DEBUG "Boot video device is %s\n", pci_name(pdev));
-       }
-}
-DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_video);
-
 /*
  * Some Toshiba laptops need extra code to enable their TI TSB43AB22/A.
  *
index d028e1b05c3697e56e64631b0863cb3d90819fd3..b21b6da8ab1dc6915258a4ec211e43cb6c39c61c 100644 (file)
@@ -28,6 +28,10 @@ static __init int pci_access_init(void)
 #ifdef CONFIG_PCI_DIRECT
        pci_direct_init(type);
 #endif
+       if (!raw_pci_ops)
+               printk(KERN_ERR
+               "PCI: Fatal: No config space access function found\n");
+
        return 0;
 }
 arch_initcall(pci_access_init);
index 47f02af74be3735b66d0cdb1830e2fb527c1f8d0..dbc4aae919592b926255d73ce7ebdeec675164cd 100644 (file)
@@ -1141,10 +1141,6 @@ static int pirq_enable_irq(struct pci_dev *dev)
                        }
                        dev = temp_dev;
                        if (irq >= 0) {
-#ifdef CONFIG_PCI_MSI
-                               if (!platform_legacy_irq(irq))
-                                       irq = IO_APIC_VECTOR(irq);
-#endif
                                printk(KERN_INFO "PCI->APIC IRQ transform: %s[%c] -> IRQ %d\n",
                                        pci_name(dev), 'A' + pin, irq);
                                dev->irq = irq;
index 1814f74569c63efd415bdfa4393a9471107a3742..ad065cebd7b9e1d94fb665c147d01cc90f36412d 100644 (file)
 extern unsigned int pci_probe;
 extern unsigned long pirq_table_addr;
 
+enum pci_bf_sort_state {
+       pci_bf_sort_default,
+       pci_force_nobf,
+       pci_force_bf,
+       pci_dmi_bf,
+};
+
 /* pci-i386.c */
 
 extern unsigned int pcibios_max_latency;
index 0f14a82b856e500b72aa4277ddea084ae242a8f7..64e951de4e5749b64ca721601f0bddfd4dd7a886 100644 (file)
@@ -1,8 +1,9 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.17-rc3
-# Thu Apr 27 11:48:23 2006
+# Linux kernel version: 2.6.19-rc1
+# Mon Oct  9 10:53:59 2006
 #
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
 # Code maturity level options
@@ -18,16 +19,22 @@ CONFIG_LOCALVERSION=""
 # CONFIG_LOCALVERSION_AUTO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
 CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+CONFIG_TASKSTATS=y
+# CONFIG_TASK_DELAY_ACCT is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_CPUSETS=y
 CONFIG_RELAY=y
 CONFIG_INITRAMFS_SOURCE=""
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_TASK_XACCT=y
+CONFIG_SYSCTL=y
 # CONFIG_EMBEDDED is not set
+# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -40,6 +47,8 @@ CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
 CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -58,6 +67,7 @@ CONFIG_STOP_MACHINE=y
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_BLK_DEV_IO_TRACE is not set
 
 #
@@ -89,7 +99,7 @@ CONFIG_EFI=y
 CONFIG_GENERIC_IOMAP=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
 CONFIG_IA64_UNCACHED_ALLOCATOR=y
-CONFIG_DMA_IS_DMA32=y
+CONFIG_AUDIT_ARCH=y
 # CONFIG_IA64_GENERIC is not set
 # CONFIG_IA64_DIG is not set
 # CONFIG_IA64_HP_ZX1 is not set
@@ -116,6 +126,7 @@ CONFIG_FORCE_MAX_ZONEORDER=17
 CONFIG_SMP=y
 CONFIG_NR_CPUS=1024
 # CONFIG_HOTPLUG_CPU is not set
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_SCHED_SMT=y
 CONFIG_PREEMPT=y
 CONFIG_SELECT_MEMORY_MODEL=y
@@ -128,6 +139,7 @@ CONFIG_NEED_MULTIPLE_NODES=y
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_MIGRATION=y
+CONFIG_RESOURCES_64BIT=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
 CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
 CONFIG_ARCH_FLATMEM_ENABLE=y
@@ -135,15 +147,24 @@ CONFIG_ARCH_SPARSEMEM_ENABLE=y
 CONFIG_ARCH_DISCONTIGMEM_DEFAULT=y
 CONFIG_NUMA=y
 CONFIG_NODES_SHIFT=10
+CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_VIRTUAL_MEM_MAP=y
 CONFIG_HOLES_IN_ZONE=y
 CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y
+CONFIG_HAVE_ARCH_NODEDATA_EXTENSION=y
 CONFIG_IA32_SUPPORT=y
 CONFIG_COMPAT=y
 CONFIG_IA64_MCA_RECOVERY=y
 CONFIG_PERFMON=y
 CONFIG_IA64_PALINFO=y
 CONFIG_SGI_SN=y
+# CONFIG_IA64_ESI is not set
+
+#
+# SN Devices
+#
+CONFIG_SGI_IOC4=y
+CONFIG_SGI_IOC3=y
 
 #
 # Firmware Drivers
@@ -159,6 +180,7 @@ CONFIG_BINFMT_ELF=y
 CONFIG_PM=y
 # CONFIG_PM_LEGACY is not set
 # CONFIG_PM_DEBUG is not set
+# CONFIG_PM_SYSFS_DEPRECATED is not set
 
 #
 # ACPI (Advanced Configuration and Power Interface) Support
@@ -166,6 +188,7 @@ CONFIG_PM=y
 CONFIG_ACPI=y
 # CONFIG_ACPI_BUTTON is not set
 # CONFIG_ACPI_FAN is not set
+# CONFIG_ACPI_DOCK is not set
 # CONFIG_ACPI_PROCESSOR is not set
 CONFIG_ACPI_NUMA=y
 CONFIG_ACPI_BLACKLIST_YEAR=0
@@ -185,7 +208,12 @@ CONFIG_ACPI_SYSTEM=y
 #
 CONFIG_PCI=y
 CONFIG_PCI_DOMAINS=y
+CONFIG_PCIEPORTBUS=y
+CONFIG_HOTPLUG_PCI_PCIE=y
+# CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE is not set
+CONFIG_PCIEAER=y
 # CONFIG_PCI_MSI is not set
+# CONFIG_PCI_MULTITHREAD_PROBE is not set
 # CONFIG_PCI_DEBUG is not set
 
 #
@@ -215,6 +243,9 @@ CONFIG_NET=y
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
@@ -231,19 +262,31 @@ CONFIG_SYN_COOKIES=y
 # CONFIG_INET_IPCOMP is not set
 # CONFIG_INET_XFRM_TUNNEL is not set
 # CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
 CONFIG_INET_DIAG=m
 CONFIG_INET_TCP_DIAG=m
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
 CONFIG_IPV6=m
 # CONFIG_IPV6_PRIVACY is not set
 # CONFIG_IPV6_ROUTER_PREF is not set
 # CONFIG_INET6_AH is not set
 # CONFIG_INET6_ESP is not set
 # CONFIG_INET6_IPCOMP is not set
+# CONFIG_IPV6_MIP6 is not set
 # CONFIG_INET6_XFRM_TUNNEL is not set
 # CONFIG_INET6_TUNNEL is not set
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
 # CONFIG_IPV6_TUNNEL is not set
+# CONFIG_IPV6_SUBTREES is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
 
 #
@@ -269,7 +312,6 @@ CONFIG_IPV6=m
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -298,6 +340,7 @@ CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=y
 # CONFIG_DEBUG_DRIVER is not set
+# CONFIG_SYS_HYPERVISOR is not set
 
 #
 # Connector - unified userspace <-> kernelspace linker
@@ -335,6 +378,7 @@ CONFIG_BLK_DEV_NBD=m
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 CONFIG_BLK_DEV_INITRD=y
 # CONFIG_CDROM_PKTCDVD is not set
 CONFIG_ATA_OVER_ETH=m
@@ -381,6 +425,7 @@ CONFIG_IDEDMA_PCI_AUTO=y
 # CONFIG_BLK_DEV_CS5530 is not set
 # CONFIG_BLK_DEV_HPT34X is not set
 # CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_JMICRON is not set
 # CONFIG_BLK_DEV_SC1200 is not set
 # CONFIG_BLK_DEV_PIIX is not set
 # CONFIG_BLK_DEV_IT821X is not set
@@ -404,6 +449,7 @@ CONFIG_IDEDMA_AUTO=y
 #
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
+CONFIG_SCSI_NETLINK=y
 CONFIG_SCSI_PROC_FS=y
 
 #
@@ -425,12 +471,14 @@ CONFIG_SCSI_CONSTANTS=y
 # CONFIG_SCSI_LOGGING is not set
 
 #
-# SCSI Transport Attributes
+# SCSI Transports
 #
 CONFIG_SCSI_SPI_ATTRS=y
 CONFIG_SCSI_FC_ATTRS=y
 CONFIG_SCSI_ISCSI_ATTRS=m
 CONFIG_SCSI_SAS_ATTRS=y
+CONFIG_SCSI_SAS_LIBSAS=y
+# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set
 
 #
 # SCSI low-level drivers
@@ -443,45 +491,81 @@ CONFIG_ISCSI_TCP=m
 # CONFIG_SCSI_AIC7XXX is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
+# CONFIG_SCSI_ARCMSR is not set
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
-CONFIG_SCSI_SATA=y
-# CONFIG_SCSI_SATA_AHCI is not set
-# CONFIG_SCSI_SATA_SVW is not set
-# CONFIG_SCSI_ATA_PIIX is not set
-# CONFIG_SCSI_SATA_MV is not set
-# CONFIG_SCSI_SATA_NV is not set
-# CONFIG_SCSI_PDC_ADMA is not set
-# CONFIG_SCSI_SATA_QSTOR is not set
-# CONFIG_SCSI_SATA_PROMISE is not set
-# CONFIG_SCSI_SATA_SX4 is not set
-# CONFIG_SCSI_SATA_SIL is not set
-# CONFIG_SCSI_SATA_SIL24 is not set
-# CONFIG_SCSI_SATA_SIS is not set
-# CONFIG_SCSI_SATA_ULI is not set
-# CONFIG_SCSI_SATA_VIA is not set
-CONFIG_SCSI_SATA_VITESSE=y
+# CONFIG_SCSI_HPTIOP is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
 # CONFIG_SCSI_IPS is not set
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
 # CONFIG_SCSI_SYM53C8XX_2 is not set
 # CONFIG_SCSI_IPR is not set
 CONFIG_SCSI_QLOGIC_1280=y
 CONFIG_SCSI_QLA_FC=y
-CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE=y
-# CONFIG_SCSI_QLA21XX is not set
-CONFIG_SCSI_QLA22XX=y
-CONFIG_SCSI_QLA2300=y
-CONFIG_SCSI_QLA2322=y
-# CONFIG_SCSI_QLA24XX is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
 # CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_DEBUG is not set
 
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+CONFIG_ATA=y
+# CONFIG_SATA_AHCI is not set
+# CONFIG_SATA_SVW is not set
+# CONFIG_ATA_PIIX is not set
+# CONFIG_SATA_MV is not set
+# CONFIG_SATA_NV is not set
+# CONFIG_PDC_ADMA is not set
+# CONFIG_SATA_QSTOR is not set
+# CONFIG_SATA_PROMISE is not set
+# CONFIG_SATA_SX4 is not set
+# CONFIG_SATA_SIL is not set
+# CONFIG_SATA_SIL24 is not set
+# CONFIG_SATA_SIS is not set
+# CONFIG_SATA_ULI is not set
+# CONFIG_SATA_VIA is not set
+CONFIG_SATA_VITESSE=y
+# CONFIG_PATA_ALI is not set
+# CONFIG_PATA_AMD is not set
+# CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATIIXP is not set
+# CONFIG_PATA_CMD64X is not set
+# CONFIG_PATA_CS5520 is not set
+# CONFIG_PATA_CS5530 is not set
+# CONFIG_PATA_CYPRESS is not set
+# CONFIG_PATA_EFAR is not set
+# CONFIG_ATA_GENERIC is not set
+# CONFIG_PATA_HPT366 is not set
+# CONFIG_PATA_HPT37X is not set
+# CONFIG_PATA_HPT3X2N is not set
+# CONFIG_PATA_HPT3X3 is not set
+# CONFIG_PATA_IT821X is not set
+# CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_TRIFLEX is not set
+# CONFIG_PATA_MPIIX is not set
+# CONFIG_PATA_OLDPIIX is not set
+# CONFIG_PATA_NETCELL is not set
+# CONFIG_PATA_NS87410 is not set
+# CONFIG_PATA_OPTI is not set
+# CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC_OLD is not set
+# CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RZ1000 is not set
+# CONFIG_PATA_SC1200 is not set
+# CONFIG_PATA_SERVERWORKS is not set
+# CONFIG_PATA_PDC2027X is not set
+# CONFIG_PATA_SIL680 is not set
+# CONFIG_PATA_SIS is not set
+# CONFIG_PATA_VIA is not set
+# CONFIG_PATA_WINBOND is not set
+
 #
 # Multi-device support (RAID and LVM)
 #
@@ -491,12 +575,12 @@ CONFIG_MD_LINEAR=y
 CONFIG_MD_RAID0=y
 CONFIG_MD_RAID1=y
 # CONFIG_MD_RAID10 is not set
-CONFIG_MD_RAID5=y
+CONFIG_MD_RAID456=y
 # CONFIG_MD_RAID5_RESHAPE is not set
-# CONFIG_MD_RAID6 is not set
 CONFIG_MD_MULTIPATH=y
 # CONFIG_MD_FAULTY is not set
 CONFIG_BLK_DEV_DM=y
+# CONFIG_DM_DEBUG is not set
 CONFIG_DM_CRYPT=m
 CONFIG_DM_SNAPSHOT=m
 CONFIG_DM_MIRROR=m
@@ -563,6 +647,7 @@ CONFIG_NETDEVICES=y
 # CONFIG_SK98LIN is not set
 CONFIG_TIGON3=y
 # CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -571,6 +656,7 @@ CONFIG_CHELSIO_T1=m
 # CONFIG_IXGB is not set
 CONFIG_S2IO=m
 # CONFIG_S2IO_NAPI is not set
+# CONFIG_MYRI10GE is not set
 
 #
 # Token Ring devices
@@ -612,6 +698,7 @@ CONFIG_NET_POLL_CONTROLLER=y
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -646,6 +733,7 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 CONFIG_VT=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
 CONFIG_SERIAL_NONSTANDARD=y
 # CONFIG_COMPUTONE is not set
 # CONFIG_ROCKETPORT is not set
@@ -659,10 +747,12 @@ CONFIG_SERIAL_NONSTANDARD=y
 # CONFIG_N_HDLC is not set
 # CONFIG_SPECIALIX is not set
 # CONFIG_SX is not set
+# CONFIG_RIO is not set
 # CONFIG_STALDRV is not set
 CONFIG_SGI_SNSC=y
 CONFIG_SGI_TIOCX=y
 CONFIG_SGI_MBCS=m
+CONFIG_MSPEC=y
 
 #
 # Serial drivers
@@ -701,6 +791,7 @@ CONFIG_EFI_RTC=y
 # Ftape, the floppy tape device driver
 #
 CONFIG_AGP=y
+# CONFIG_AGP_SIS is not set
 # CONFIG_AGP_VIA is not set
 CONFIG_AGP_SGI_TIOCA=y
 # CONFIG_DRM is not set
@@ -730,7 +821,6 @@ CONFIG_MMTIMER=y
 #
 # Dallas's 1-wire bus
 #
-# CONFIG_W1 is not set
 
 #
 # Hardware Monitoring support
@@ -741,6 +831,7 @@ CONFIG_MMTIMER=y
 #
 # Misc devices
 #
+# CONFIG_TIFM_CORE is not set
 
 #
 # Multimedia devices
@@ -756,6 +847,7 @@ CONFIG_MMTIMER=y
 #
 # Graphics support
 #
+CONFIG_FIRMWARE_EDID=y
 # CONFIG_FB is not set
 
 #
@@ -764,6 +856,7 @@ CONFIG_MMTIMER=y
 CONFIG_VGA_CONSOLE=y
 # CONFIG_VGACON_SOFT_SCROLLBACK is not set
 CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -794,6 +887,7 @@ CONFIG_USB=m
 CONFIG_USB_EHCI_HCD=m
 # CONFIG_USB_EHCI_SPLIT_ISO is not set
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
 # CONFIG_USB_ISP116X_HCD is not set
 CONFIG_USB_OHCI_HCD=m
 # CONFIG_USB_OHCI_BIG_ENDIAN is not set
@@ -843,6 +937,7 @@ CONFIG_USB_HIDINPUT=y
 # CONFIG_USB_ATI_REMOTE2 is not set
 # CONFIG_USB_KEYSPAN_REMOTE is not set
 # CONFIG_USB_APPLETOUCH is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
 
 #
 # USB Imaging devices
@@ -874,15 +969,18 @@ CONFIG_USB_MON=y
 #
 # CONFIG_USB_EMI62 is not set
 # CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
 # CONFIG_USB_AUERSWALD is not set
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
 # CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGETKIT is not set
-# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_PHIDGET is not set
 # CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
 # CONFIG_USB_SISUSBVGA is not set
 # CONFIG_USB_LD is not set
 
@@ -919,18 +1017,15 @@ CONFIG_USB_MON=y
 CONFIG_INFINIBAND=m
 # CONFIG_INFINIBAND_USER_MAD is not set
 CONFIG_INFINIBAND_USER_ACCESS=m
+CONFIG_INFINIBAND_ADDR_TRANS=y
 CONFIG_INFINIBAND_MTHCA=m
 CONFIG_INFINIBAND_MTHCA_DEBUG=y
+# CONFIG_INFINIBAND_AMSO1100 is not set
 CONFIG_INFINIBAND_IPOIB=m
 CONFIG_INFINIBAND_IPOIB_DEBUG=y
 # CONFIG_INFINIBAND_IPOIB_DEBUG_DATA is not set
 CONFIG_INFINIBAND_SRP=m
-
-#
-# SN Devices
-#
-CONFIG_SGI_IOC4=y
-CONFIG_SGI_IOC3=y
+# CONFIG_INFINIBAND_ISER is not set
 
 #
 # EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
@@ -941,6 +1036,19 @@ CONFIG_SGI_IOC3=y
 #
 # CONFIG_RTC_CLASS is not set
 
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
 #
 # File systems
 #
@@ -965,15 +1073,16 @@ CONFIG_REISERFS_FS_SECURITY=y
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
 CONFIG_XFS_FS=y
-CONFIG_XFS_EXPORT=y
 CONFIG_XFS_QUOTA=y
 # CONFIG_XFS_SECURITY is not set
 CONFIG_XFS_POSIX_ACL=y
 CONFIG_XFS_RT=y
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
 CONFIG_QUOTA=y
 # CONFIG_QFMT_V1 is not set
 # CONFIG_QFMT_V2 is not set
@@ -1007,8 +1116,10 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
 CONFIG_HUGETLBFS=y
 CONFIG_HUGETLB_PAGE=y
 CONFIG_RAMFS=y
@@ -1046,7 +1157,7 @@ CONFIG_NFSD_V4=y
 CONFIG_NFSD_TCP=y
 CONFIG_LOCKD=m
 CONFIG_LOCKD_V4=y
-CONFIG_EXPORTFS=y
+CONFIG_EXPORTFS=m
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=m
 CONFIG_SUNRPC_GSS=m
@@ -1056,7 +1167,9 @@ CONFIG_SMB_FS=m
 # CONFIG_SMB_NLS_DEFAULT is not set
 CONFIG_CIFS=m
 # CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
 # CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_DEBUG2 is not set
 # CONFIG_CIFS_EXPERIMENTAL is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1128,6 +1241,10 @@ CONFIG_NLS_ISO8859_1=y
 # CONFIG_NLS_KOI8_U is not set
 CONFIG_NLS_UTF8=y
 
+#
+# Distributed Lock Manager
+#
+
 #
 # Library routines
 #
@@ -1138,9 +1255,11 @@ CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=m
 CONFIG_ZLIB_DEFLATE=m
 CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_PLIST=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_PENDING_IRQ=y
+CONFIG_IRQ_PER_CPU=y
 
 #
 # Instrumentation Support
@@ -1152,20 +1271,26 @@ CONFIG_GENERIC_PENDING_IRQ=y
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_KERNEL=y
 CONFIG_LOG_BUF_SHIFT=20
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_DEBUG_SLAB is not set
-CONFIG_DEBUG_PREEMPT=y
-# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_RWSEMS is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
 CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_FS is not set
 # CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
 CONFIG_FORCED_INLINING=y
 # CONFIG_RCU_TORTURE_TEST is not set
 CONFIG_IA64_GRANULE_16MB=y
@@ -1186,6 +1311,10 @@ CONFIG_SYSVIPC_COMPAT=y
 # Cryptographic options
 #
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=m
 CONFIG_CRYPTO_HMAC=y
 # CONFIG_CRYPTO_NULL is not set
 # CONFIG_CRYPTO_MD4 is not set
@@ -1195,6 +1324,8 @@ CONFIG_CRYPTO_SHA1=m
 # CONFIG_CRYPTO_SHA512 is not set
 # CONFIG_CRYPTO_WP512 is not set
 # CONFIG_CRYPTO_TGR192 is not set
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
 CONFIG_CRYPTO_DES=m
 # CONFIG_CRYPTO_BLOWFISH is not set
 # CONFIG_CRYPTO_TWOFISH is not set
index e1a1b11473e221a95e2988107f2d45a9572817e8..424e9257c9a09e2b5257a02f89ccc056df692e79 100644 (file)
@@ -54,7 +54,7 @@ static int simeth_close(struct net_device *dev);
 static int simeth_tx(struct sk_buff *skb, struct net_device *dev);
 static int simeth_rx(struct net_device *dev);
 static struct net_device_stats *simeth_get_stats(struct net_device *dev);
-static irqreturn_t simeth_interrupt(int irq, void *dev_id, struct pt_regs * regs);
+static irqreturn_t simeth_interrupt(int irq, void *dev_id);
 static void set_multicast_list(struct net_device *dev);
 static int simeth_device_event(struct notifier_block *this,unsigned long event, void *ptr);
 
@@ -87,7 +87,7 @@ static int simeth_debug;              /* set to 1 to get debug information */
  */
 static struct notifier_block simeth_dev_notifier = {
        simeth_device_event,
-       0
+       NULL
 };
 
 
@@ -497,7 +497,7 @@ simeth_rx(struct net_device *dev)
  * Interrupt handler (Yes, we can do it too !!!)
  */
 static irqreturn_t
-simeth_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+simeth_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
 
index 8f0a16a79a677c8830b5f5385eb0559fc08fe934..bb87682bbb1be5862ec767e6088fd0de21f1f068 100644 (file)
@@ -103,7 +103,7 @@ simscsi_interrupt (unsigned long val)
 
        while ((sc = queue[rd].sc) != 0) {
                atomic_dec(&num_reqs);
-               queue[rd].sc = 0;
+               queue[rd].sc = NULL;
                if (DBG)
                        printk("simscsi_interrupt: done with %ld\n", sc->serial_number);
                (*sc->scsi_done)(sc);
index 246eb3d3757adc85db23f8892ed49beb5c0d5a11..caab986af70c0ef7efa7a881a7b73c43c2254261 100644 (file)
@@ -92,7 +92,7 @@ static struct serial_uart_config uart_config[] = {
        { "ST16650V2", 32, UART_CLEAR_FIFO | UART_USE_FIFO |
                  UART_STARTECH },
        { "TI16750", 64, UART_CLEAR_FIFO | UART_USE_FIFO},
-       { 0, 0}
+       { NULL, 0}
 };
 
 struct tty_driver *hp_simserial_driver;
@@ -130,7 +130,7 @@ static void rs_start(struct tty_struct *tty)
 #endif
 }
 
-static  void receive_chars(struct tty_struct *tty, struct pt_regs *regs)
+static  void receive_chars(struct tty_struct *tty)
 {
        unsigned char ch;
        static unsigned char seen_esc = 0;
@@ -152,7 +152,7 @@ static  void receive_chars(struct tty_struct *tty, struct pt_regs *regs)
                                                ch = ia64_ssc(0, 0, 0, 0,
                                                              SSC_GETCHAR);
                                        while (!ch);
-                                       handle_sysrq(ch, regs, NULL);
+                                       handle_sysrq(ch, NULL);
                                }
 #endif
                                seen_esc = 0;
@@ -170,7 +170,7 @@ static  void receive_chars(struct tty_struct *tty, struct pt_regs *regs)
 /*
  * This is the serial driver's interrupt routine for a single port
  */
-static irqreturn_t rs_interrupt_single(int irq, void *dev_id, struct pt_regs * regs)
+static irqreturn_t rs_interrupt_single(int irq, void *dev_id)
 {
        struct async_struct * info;
 
@@ -187,7 +187,7 @@ static irqreturn_t rs_interrupt_single(int irq, void *dev_id, struct pt_regs * r
         * pretty simple in our case, because we only get interrupts
         * on inbound traffic
         */
-       receive_chars(info->tty, regs);
+       receive_chars(info->tty);
        return IRQ_HANDLED;
 }
 
@@ -555,7 +555,7 @@ static void shutdown(struct async_struct * info)
 
                if (info->xmit.buf) {
                        free_page((unsigned long) info->xmit.buf);
-                       info->xmit.buf = 0;
+                       info->xmit.buf = NULL;
                }
 
                if (info->tty) set_bit(TTY_IO_ERROR, &info->tty->flags);
@@ -628,7 +628,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
        if (tty->driver->flush_buffer) tty->driver->flush_buffer(tty);
        if (tty->ldisc.flush_buffer) tty->ldisc.flush_buffer(tty);
        info->event = 0;
-       info->tty = 0;
+       info->tty = NULL;
        if (info->blocked_open) {
                if (info->close_delay)
                        schedule_timeout_interruptible(info->close_delay);
@@ -668,7 +668,7 @@ static void rs_hangup(struct tty_struct *tty)
        info->event = 0;
        state->count = 0;
        info->flags &= ~ASYNC_NORMAL_ACTIVE;
-       info->tty = 0;
+       info->tty = NULL;
        wake_up_interruptible(&info->open_wait);
 }
 
@@ -714,7 +714,7 @@ startup(struct async_struct *info)
 {
        unsigned long flags;
        int     retval=0;
-       irqreturn_t (*handler)(int, void *, struct pt_regs *);
+       irq_handler_t handler;
        struct serial_state *state= info->state;
        unsigned long page;
 
@@ -769,7 +769,7 @@ startup(struct async_struct *info)
        /*
         * Insert serial port into IRQ chain.
         */
-       info->prev_port = 0;
+       info->prev_port = NULL;
        info->next_port = IRQ_ports[state->irq];
        if (info->next_port)
                info->next_port->prev_port = info;
index 32c3abededc69aac74e522b9d06687066a716ccb..73ef4a85b861df136c132c7b3ab4df76d54b8eb5 100644 (file)
@@ -64,9 +64,6 @@ EXPORT_SYMBOL(pm_idle);
 void (*pm_power_off) (void);
 EXPORT_SYMBOL(pm_power_off);
 
-unsigned char acpi_kbd_controller_present = 1;
-unsigned char acpi_legacy_devices;
-
 unsigned int acpi_cpei_override;
 unsigned int acpi_cpei_phys_cpuid;
 
@@ -628,12 +625,6 @@ static int __init acpi_parse_fadt(unsigned long phys_addr, unsigned long size)
 
        fadt = (struct fadt_descriptor *)fadt_header;
 
-       if (!(fadt->iapc_boot_arch & BAF_8042_KEYBOARD_CONTROLLER))
-               acpi_kbd_controller_present = 0;
-
-       if (fadt->iapc_boot_arch & BAF_LEGACY_DEVICES)
-               acpi_legacy_devices = 1;
-
        acpi_register_gsi(fadt->sci_int, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW);
        return 0;
 }
index 7852382de2fa6666a67383086f0014c93ddce43a..f07c0864b0b424bd7743b310e89ee1868fe1af12 100644 (file)
@@ -194,8 +194,11 @@ void fixup_irqs(void)
         */
        for (irq=0; irq < NR_IRQS; irq++) {
                if (vectors_in_migration[irq]) {
+                       struct pt_regs *old_regs = set_irq_regs(NULL);
+
                        vectors_in_migration[irq]=0;
-                       __do_IRQ(irq, NULL);
+                       __do_IRQ(irq);
+                       set_irq_regs(old_regs);
                }
        }
 
index ab2d19c3661f0ce7b390585667646b3cb2cdccd4..9c6dafa2d0df613e95ee0d776672c85bac6d14b1 100644 (file)
@@ -138,6 +138,7 @@ void destroy_irq(unsigned int irq)
 void
 ia64_handle_irq (ia64_vector vector, struct pt_regs *regs)
 {
+       struct pt_regs *old_regs = set_irq_regs(regs);
        unsigned long saved_tpr;
 
 #if IRQ_DEBUG
@@ -179,11 +180,13 @@ ia64_handle_irq (ia64_vector vector, struct pt_regs *regs)
        saved_tpr = ia64_getreg(_IA64_REG_CR_TPR);
        ia64_srlz_d();
        while (vector != IA64_SPURIOUS_INT_VECTOR) {
-               if (!IS_RESCHEDULE(vector)) {
+               if (unlikely(IS_RESCHEDULE(vector)))
+                        kstat_this_cpu.irqs[vector]++;
+               else {
                        ia64_setreg(_IA64_REG_CR_TPR, vector);
                        ia64_srlz_d();
 
-                       __do_IRQ(local_vector_to_irq(vector), regs);
+                       __do_IRQ(local_vector_to_irq(vector));
 
                        /*
                         * Disable interrupts and send EOI:
@@ -200,6 +203,7 @@ ia64_handle_irq (ia64_vector vector, struct pt_regs *regs)
         * come through until ia64_eoi() has been done.
         */
        irq_exit();
+       set_irq_regs(old_regs);
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
@@ -223,7 +227,11 @@ void ia64_process_pending_intr(void)
          * Perform normal interrupt style processing
          */
        while (vector != IA64_SPURIOUS_INT_VECTOR) {
-               if (!IS_RESCHEDULE(vector)) {
+               if (unlikely(IS_RESCHEDULE(vector)))
+                        kstat_this_cpu.irqs[vector]++;
+               else {
+                       struct pt_regs *old_regs = set_irq_regs(NULL);
+
                        ia64_setreg(_IA64_REG_CR_TPR, vector);
                        ia64_srlz_d();
 
@@ -234,7 +242,8 @@ void ia64_process_pending_intr(void)
                         * Probably could shared code.
                         */
                        vectors_in_migration[local_vector_to_irq(vector)]=0;
-                       __do_IRQ(local_vector_to_irq(vector), NULL);
+                       __do_IRQ(local_vector_to_irq(vector));
+                       set_irq_regs(old_regs);
 
                        /*
                         * Disable interrupts and send EOI
@@ -251,13 +260,24 @@ void ia64_process_pending_intr(void)
 
 
 #ifdef CONFIG_SMP
-extern irqreturn_t handle_IPI (int irq, void *dev_id, struct pt_regs *regs);
+extern irqreturn_t handle_IPI (int irq, void *dev_id);
+
+static irqreturn_t dummy_handler (int irq, void *dev_id)
+{
+       BUG();
+}
 
 static struct irqaction ipi_irqaction = {
        .handler =      handle_IPI,
        .flags =        IRQF_DISABLED,
        .name =         "IPI"
 };
+
+static struct irqaction resched_irqaction = {
+       .handler =      dummy_handler,
+       .flags =        SA_INTERRUPT,
+       .name =         "resched"
+};
 #endif
 
 void
@@ -282,6 +302,7 @@ init_IRQ (void)
        register_percpu_irq(IA64_SPURIOUS_INT_VECTOR, NULL);
 #ifdef CONFIG_SMP
        register_percpu_irq(IA64_IPI_VECTOR, &ipi_irqaction);
+       register_percpu_irq(IA64_IPI_RESCHEDULE, &resched_irqaction);
 #endif
 #ifdef CONFIG_PERFMON
        pfm_init_percpu();
index d4a546aa5048fc4777ac592b15571e676fd0b28f..9620822270a6e122d00c48cc5bb2acb89b313e10 100644 (file)
@@ -60,7 +60,7 @@ machvec_setup (char **arg)
 EXPORT_SYMBOL(machvec_setup);
 
 void
-machvec_timer_interrupt (int irq, void *dev_id, struct pt_regs *regs)
+machvec_timer_interrupt (int irq, void *dev_id)
 {
 }
 EXPORT_SYMBOL(machvec_timer_interrupt);
index 663230183254c7bf9c34d85518f48e0b98995088..7cfa63a98cb36adcd48ddb18d6022f94c6cf063b 100644 (file)
@@ -499,7 +499,7 @@ int cpe_vector = -1;
 int ia64_cpe_irq = -1;
 
 static irqreturn_t
-ia64_mca_cpe_int_handler (int cpe_irq, void *arg, struct pt_regs *ptregs)
+ia64_mca_cpe_int_handler (int cpe_irq, void *arg)
 {
        static unsigned long    cpe_history[CPE_HISTORY_LENGTH];
        static int              index;
@@ -744,7 +744,7 @@ ia64_mca_wakeup_all(void)
  *  Outputs :   None
  */
 static irqreturn_t
-ia64_mca_rendez_int_handler(int rendez_irq, void *arg, struct pt_regs *regs)
+ia64_mca_rendez_int_handler(int rendez_irq, void *arg)
 {
        unsigned long flags;
        int cpu = smp_processor_id();
@@ -753,8 +753,8 @@ ia64_mca_rendez_int_handler(int rendez_irq, void *arg, struct pt_regs *regs)
 
        /* Mask all interrupts */
        local_irq_save(flags);
-       if (notify_die(DIE_MCA_RENDZVOUS_ENTER, "MCA", regs, (long)&nd, 0, 0)
-                       == NOTIFY_STOP)
+       if (notify_die(DIE_MCA_RENDZVOUS_ENTER, "MCA", get_irq_regs(),
+                      (long)&nd, 0, 0) == NOTIFY_STOP)
                ia64_mca_spin(__FUNCTION__);
 
        ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_DONE;
@@ -763,16 +763,16 @@ ia64_mca_rendez_int_handler(int rendez_irq, void *arg, struct pt_regs *regs)
         */
        ia64_sal_mc_rendez();
 
-       if (notify_die(DIE_MCA_RENDZVOUS_PROCESS, "MCA", regs, (long)&nd, 0, 0)
-                       == NOTIFY_STOP)
+       if (notify_die(DIE_MCA_RENDZVOUS_PROCESS, "MCA", get_irq_regs(),
+                      (long)&nd, 0, 0) == NOTIFY_STOP)
                ia64_mca_spin(__FUNCTION__);
 
        /* Wait for the monarch cpu to exit. */
        while (monarch_cpu != -1)
               cpu_relax();     /* spin until monarch leaves */
 
-       if (notify_die(DIE_MCA_RENDZVOUS_LEAVE, "MCA", regs, (long)&nd, 0, 0)
-                       == NOTIFY_STOP)
+       if (notify_die(DIE_MCA_RENDZVOUS_LEAVE, "MCA", get_irq_regs(),
+                      (long)&nd, 0, 0) == NOTIFY_STOP)
                ia64_mca_spin(__FUNCTION__);
 
        /* Enable all interrupts */
@@ -791,12 +791,11 @@ ia64_mca_rendez_int_handler(int rendez_irq, void *arg, struct pt_regs *regs)
  *
  *  Inputs  :   wakeup_irq  (Wakeup-interrupt bit)
  *     arg             (Interrupt handler specific argument)
- *     ptregs          (Exception frame at the time of the interrupt)
  *  Outputs :   None
  *
  */
 static irqreturn_t
-ia64_mca_wakeup_int_handler(int wakeup_irq, void *arg, struct pt_regs *ptregs)
+ia64_mca_wakeup_int_handler(int wakeup_irq, void *arg)
 {
        return IRQ_HANDLED;
 }
@@ -1261,13 +1260,12 @@ static DECLARE_WORK(cmc_enable_work, ia64_mca_cmc_vector_enable_keventd, NULL);
  * Inputs
  *      interrupt number
  *      client data arg ptr
- *      saved registers ptr
  *
  * Outputs
  *     None
  */
 static irqreturn_t
-ia64_mca_cmc_int_handler(int cmc_irq, void *arg, struct pt_regs *ptregs)
+ia64_mca_cmc_int_handler(int cmc_irq, void *arg)
 {
        static unsigned long    cmc_history[CMC_HISTORY_LENGTH];
        static int              index;
@@ -1336,12 +1334,11 @@ out:
  * Inputs
  *     interrupt number
  *     client data arg ptr
- *     saved registers ptr
  * Outputs
  *     handled
  */
 static irqreturn_t
-ia64_mca_cmc_int_caller(int cmc_irq, void *arg, struct pt_regs *ptregs)
+ia64_mca_cmc_int_caller(int cmc_irq, void *arg)
 {
        static int start_count = -1;
        unsigned int cpuid;
@@ -1352,7 +1349,7 @@ ia64_mca_cmc_int_caller(int cmc_irq, void *arg, struct pt_regs *ptregs)
        if (start_count == -1)
                start_count = IA64_LOG_COUNT(SAL_INFO_TYPE_CMC);
 
-       ia64_mca_cmc_int_handler(cmc_irq, arg, ptregs);
+       ia64_mca_cmc_int_handler(cmc_irq, arg);
 
        for (++cpuid ; cpuid < NR_CPUS && !cpu_online(cpuid) ; cpuid++);
 
@@ -1403,14 +1400,13 @@ ia64_mca_cmc_poll (unsigned long dummy)
  * Inputs
  *     interrupt number
  *     client data arg ptr
- *     saved registers ptr
  * Outputs
  *     handled
  */
 #ifdef CONFIG_ACPI
 
 static irqreturn_t
-ia64_mca_cpe_int_caller(int cpe_irq, void *arg, struct pt_regs *ptregs)
+ia64_mca_cpe_int_caller(int cpe_irq, void *arg)
 {
        static int start_count = -1;
        static int poll_time = MIN_CPE_POLL_INTERVAL;
@@ -1422,7 +1418,7 @@ ia64_mca_cpe_int_caller(int cpe_irq, void *arg, struct pt_regs *ptregs)
        if (start_count == -1)
                start_count = IA64_LOG_COUNT(SAL_INFO_TYPE_CPE);
 
-       ia64_mca_cpe_int_handler(cpe_irq, arg, ptregs);
+       ia64_mca_cpe_int_handler(cpe_irq, arg);
 
        for (++cpuid ; cpuid < NR_CPUS && !cpu_online(cpuid) ; cpuid++);
 
index ebaf1e685f5e350312bf72f3efbcb47288f58f1e..0b533441c3c9b2fc434315c23f45dc0924e64b4c 100644 (file)
@@ -21,11 +21,12 @@ pal_entry_point:
        .text
 
 /*
- * Set the PAL entry point address.  This could be written in C code, but we do it here
- * to keep it all in one module (besides, it's so trivial that it's
+ * Set the PAL entry point address.  This could be written in C code, but we
+ * do it here to keep it all in one module (besides, it's so trivial that it's
  * not a big deal).
  *
- * in0         Address of the PAL entry point (text address, NOT a function descriptor).
+ * in0         Address of the PAL entry point (text address, NOT a function
+ *             descriptor).
  */
 GLOBAL_ENTRY(ia64_pal_handler_init)
        alloc r3=ar.pfs,1,0,0,0
@@ -36,9 +37,9 @@ GLOBAL_ENTRY(ia64_pal_handler_init)
 END(ia64_pal_handler_init)
 
 /*
- * Default PAL call handler.  This needs to be coded in assembly because it uses
- * the static calling convention, i.e., the RSE may not be used and calls are
- * done via "br.cond" (not "br.call").
+ * Default PAL call handler.  This needs to be coded in assembly because it
+ * uses the static calling convention, i.e., the RSE may not be used and
+ * calls are done via "br.cond" (not "br.call").
  */
 GLOBAL_ENTRY(ia64_pal_default_handler)
        mov r8=-1
@@ -50,12 +51,10 @@ END(ia64_pal_default_handler)
  *
  * in0         Index of PAL service
  * in1 - in3   Remaining PAL arguments
- * in4        1 ==> clear psr.ic,  0 ==> don't clear psr.ic
- *
  */
 GLOBAL_ENTRY(ia64_pal_call_static)
-       .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(5)
-       alloc loc1 = ar.pfs,5,5,0,0
+       .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(4)
+       alloc loc1 = ar.pfs,4,5,0,0
        movl loc2 = pal_entry_point
 1:     {
          mov r28 = in0
@@ -64,7 +63,6 @@ GLOBAL_ENTRY(ia64_pal_call_static)
        }
        ;;
        ld8 loc2 = [loc2]               // loc2 <- entry point
-       tbit.nz p6,p7 = in4, 0
        adds r8 = 1f-1b,r8
        mov loc4=ar.rsc                 // save RSE configuration
        ;;
@@ -74,13 +72,11 @@ GLOBAL_ENTRY(ia64_pal_call_static)
        .body
        mov r30 = in2
 
-(p6)   rsm psr.i | psr.ic
        mov r31 = in3
        mov b7 = loc2
 
-(p7)   rsm psr.i
+       rsm psr.i
        ;;
-(p6)   srlz.i
        mov rp = r8
        br.cond.sptk.many b7
 1:     mov psr.l = loc3
@@ -96,8 +92,8 @@ END(ia64_pal_call_static)
  * Make a PAL call using the stacked registers calling convention.
  *
  * Inputs:
- *     in0         Index of PAL service
- *     in2 - in3   Remaning PAL arguments
+ *     in0         Index of PAL service
+ *     in2 - in3   Remaining PAL arguments
  */
 GLOBAL_ENTRY(ia64_pal_call_stacked)
        .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(4)
@@ -131,18 +127,18 @@ END(ia64_pal_call_stacked)
  * Make a physical mode PAL call using the static registers calling convention.
  *
  * Inputs:
- *     in0         Index of PAL service
- *     in2 - in3   Remaning PAL arguments
+ *     in0         Index of PAL service
+ *     in2 - in3   Remaining PAL arguments
  *
  * PSR_LP, PSR_TB, PSR_ID, PSR_DA are never set by the kernel.
  * So we don't need to clear them.
  */
-#define PAL_PSR_BITS_TO_CLEAR                                                  \
-       (IA64_PSR_I | IA64_PSR_IT | IA64_PSR_DT  | IA64_PSR_DB | IA64_PSR_RT |  \
-        IA64_PSR_DD | IA64_PSR_SS | IA64_PSR_RI | IA64_PSR_ED |                \
+#define PAL_PSR_BITS_TO_CLEAR                                                \
+       (IA64_PSR_I | IA64_PSR_IT | IA64_PSR_DT  | IA64_PSR_DB | IA64_PSR_RT |\
+        IA64_PSR_DD | IA64_PSR_SS | IA64_PSR_RI | IA64_PSR_ED |              \
         IA64_PSR_DFL | IA64_PSR_DFH)
 
-#define PAL_PSR_BITS_TO_SET                                                    \
+#define PAL_PSR_BITS_TO_SET                                                  \
        (IA64_PSR_BN)
 
 
@@ -178,7 +174,7 @@ GLOBAL_ENTRY(ia64_pal_call_phys_static)
        ;;
        andcm r16=loc3,r16              // removes bits to clear from psr
        br.call.sptk.many rp=ia64_switch_mode_phys
-.ret1: mov rp = r8                     // install return address (physical)
+       mov rp = r8                     // install return address (physical)
        mov loc5 = r19
        mov loc6 = r20
        br.cond.sptk.many b7
@@ -188,7 +184,6 @@ GLOBAL_ENTRY(ia64_pal_call_phys_static)
        mov r19=loc5
        mov r20=loc6
        br.call.sptk.many rp=ia64_switch_mode_virt // return to virtual mode
-.ret2:
        mov psr.l = loc3                // restore init PSR
 
        mov ar.pfs = loc1
@@ -203,8 +198,8 @@ END(ia64_pal_call_phys_static)
  * Make a PAL call using the stacked registers in physical mode.
  *
  * Inputs:
- *     in0         Index of PAL service
- *     in2 - in3   Remaning PAL arguments
+ *     in0         Index of PAL service
+ *     in2 - in3   Remaining PAL arguments
  */
 GLOBAL_ENTRY(ia64_pal_call_phys_stacked)
        .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(5)
@@ -212,7 +207,7 @@ GLOBAL_ENTRY(ia64_pal_call_phys_stacked)
        movl    loc2 = pal_entry_point
 1:     {
          mov r28  = in0                // copy procedure index
-         mov loc0 = rp         // save rp
+         mov loc0 = rp                 // save rp
        }
        .body
        ;;
@@ -245,7 +240,7 @@ GLOBAL_ENTRY(ia64_pal_call_phys_stacked)
        mov r16=loc3                    // r16= original psr
        mov r19=loc5
        mov r20=loc6
-       br.call.sptk.many rp=ia64_switch_mode_virt      // return to virtual mode
+       br.call.sptk.many rp=ia64_switch_mode_virt // return to virtual mode
 
        mov psr.l  = loc3               // restore init PSR
        mov ar.pfs = loc1
@@ -257,10 +252,11 @@ GLOBAL_ENTRY(ia64_pal_call_phys_stacked)
 END(ia64_pal_call_phys_stacked)
 
 /*
- * Save scratch fp scratch regs which aren't saved in pt_regs already (fp10-fp15).
+ * Save scratch fp scratch regs which aren't saved in pt_regs already
+ * (fp10-fp15).
  *
- * NOTE: We need to do this since firmware (SAL and PAL) may use any of the scratch
- * regs fp-low partition.
+ * NOTE: We need to do this since firmware (SAL and PAL) may use any of the
+ * scratch regs fp-low partition.
  *
  * Inputs:
  *      in0    Address of stack storage for fp regs
index 281004ff7b00b87a46de5f91c05c90c706827474..3aaede0d6981783037b1eaec5d0a0b7e364d57ef 100644 (file)
@@ -5558,12 +5558,13 @@ report_spurious2:
 }
 
 static irqreturn_t
-pfm_interrupt_handler(int irq, void *arg, struct pt_regs *regs)
+pfm_interrupt_handler(int irq, void *arg)
 {
        unsigned long start_cycles, total_cycles;
        unsigned long min, max;
        int this_cpu;
        int ret;
+       struct pt_regs *regs = get_irq_regs();
 
        this_cpu = get_cpu();
        if (likely(!pfm_alt_intr_handler)) {
index 62e07f906e05dd4debed3688c151a661c60b64db..39e0cd3a0884e84e1c60b279a8090e6bfb611cd0 100644 (file)
@@ -45,7 +45,7 @@ static struct time_interpolator itc_interpolator = {
 };
 
 static irqreturn_t
-timer_interrupt (int irq, void *dev_id, struct pt_regs *regs)
+timer_interrupt (int irq, void *dev_id)
 {
        unsigned long new_itm;
 
@@ -53,7 +53,7 @@ timer_interrupt (int irq, void *dev_id, struct pt_regs *regs)
                return IRQ_HANDLED;
        }
 
-       platform_timer_interrupt(irq, dev_id, regs);
+       platform_timer_interrupt(irq, dev_id);
 
        new_itm = local_cpu_data->itm_next;
 
@@ -61,10 +61,10 @@ timer_interrupt (int irq, void *dev_id, struct pt_regs *regs)
                printk(KERN_ERR "Oops: timer tick before it's due (itc=%lx,itm=%lx)\n",
                       ia64_get_itc(), new_itm);
 
-       profile_tick(CPU_PROFILING, regs);
+       profile_tick(CPU_PROFILING);
 
        while (1) {
-               update_process_times(user_mode(regs));
+               update_process_times(user_mode(get_irq_regs()));
 
                new_itm += local_cpu_data->itm_delta;
 
@@ -84,6 +84,12 @@ timer_interrupt (int irq, void *dev_id, struct pt_regs *regs)
 
                if (time_after(new_itm, ia64_get_itc()))
                        break;
+
+               /*
+                * Allow IPIs to interrupt the timer loop.
+                */
+               local_irq_enable();
+               local_irq_disable();
        }
 
        do {
index daf977ff2920e2c88aee4c6398a7d135bc22d802..82deaa3a7c4806adecb70daacdbfc7d2997105e0 100644 (file)
@@ -233,6 +233,7 @@ paging_init (void)
        efi_memmap_walk(count_pages, &num_physpages);
 
        max_dma = virt_to_phys((void *) MAX_DMA_ADDRESS) >> PAGE_SHIFT;
+       memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
        max_zone_pfns[ZONE_DMA] = max_dma;
        max_zone_pfns[ZONE_NORMAL] = max_low_pfn;
 
index d497b6b0f5b2c08d4be5cd50478399db993a2dc8..96722cb1b49ddbc296951fa1007b2f418d910dea 100644 (file)
@@ -709,6 +709,7 @@ void __init paging_init(void)
                        max_pfn = mem_data[node].max_pfn;
        }
 
+       memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
        max_zone_pfns[ZONE_DMA] = max_dma;
        max_zone_pfns[ZONE_NORMAL] = max_pfn;
        free_area_init_nodes(max_zone_pfns);
index 96fb81e6321f6a5b33512d908bad33741e28ac99..abca6bd7962f7a14d30adbeb79d4c7b71f61e34b 100644 (file)
@@ -22,7 +22,7 @@
 void hubiio_crb_error_handler(struct hubdev_info *hubdev_info);
 extern void bte_crb_error_handler(cnodeid_t, int, int, ioerror_t *,
                                  int);
-static irqreturn_t hub_eint_handler(int irq, void *arg, struct pt_regs *ep)
+static irqreturn_t hub_eint_handler(int irq, void *arg)
 {
        struct hubdev_info *hubdev_info;
        struct ia64_sal_retval ret_stuff;
@@ -178,7 +178,7 @@ void hubiio_crb_error_handler(struct hubdev_info *hubdev_info)
  */
 void hub_error_init(struct hubdev_info *hubdev_info)
 {
-       if (request_irq(SGI_II_ERROR, (void *)hub_eint_handler, IRQF_SHARED,
+       if (request_irq(SGI_II_ERROR, hub_eint_handler, IRQF_SHARED,
                        "SN_hub_error", (void *)hubdev_info))
                printk("hub_error_init: Failed to request_irq for 0x%p\n",
                    hubdev_info);
index 5f2dcba7fa8da12a5d2827e6e414dbe2b0f85fbf..7a2d824c5ce3976be558a445d04af8d06a11b72f 100644 (file)
@@ -65,7 +65,6 @@ extern void sn_timer_init(void);
 extern unsigned long last_time_offset;
 extern void (*ia64_mark_idle) (int);
 extern void snidle(int);
-extern unsigned char acpi_kbd_controller_present;
 extern unsigned long long (*ia64_printk_clock)(void);
 
 unsigned long sn_rtc_cycles_per_second;
@@ -452,17 +451,6 @@ void __init sn_setup(char **cmdline_p)
 
        ia64_printk_clock = ia64_sn2_printk_clock;
 
-       /*
-        * Old PROMs do not provide an ACPI FADT. Disable legacy keyboard
-        * support here so we don't have to listen to failed keyboard probe
-        * messages.
-        */
-       if (is_shub1() && version <= 0x0209 && acpi_kbd_controller_present) {
-               printk(KERN_INFO "Disabling legacy keyboard support as prom "
-                      "is too old and doesn't provide FADT\n");
-               acpi_kbd_controller_present = 0;
-       }
-
        printk("SGI SAL version %x.%02x\n", version >> 8, version & 0x00FF);
 
        /*
index fa7f69945917dd4b80ae5a5d6dc9897b19d1a9b8..103d6ea8e94b55bb4b7341bf2b43278bee8f0d75 100644 (file)
@@ -36,7 +36,7 @@ extern irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 
 #define SN_LB_INT_WAR_INTERVAL 100
 
-void sn_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+void sn_timer_interrupt(int irq, void *dev_id)
 {
        /* LED blinking */
        if (!pda->hb_count--) {
index 4d026f9dd98bbc71f214d1b01708e43b766b672c..fa96dfc0e1aa756f712027c57267636460f3fde9 100644 (file)
@@ -222,7 +222,7 @@ xpc_timeout_partition_disengage_request(unsigned long data)
  * Notify the heartbeat check thread that an IRQ has been received.
  */
 static irqreturn_t
-xpc_act_IRQ_handler(int irq, void *dev_id, struct pt_regs *regs)
+xpc_act_IRQ_handler(int irq, void *dev_id)
 {
        atomic_inc(&xpc_act_IRQ_rcvd);
        wake_up_interruptible(&xpc_act_IRQ_wq);
@@ -607,12 +607,9 @@ xpc_activate_partition(struct xpc_partition *part)
  *     irq - Interrupt ReQuest number. NOT USED.
  *
  *     dev_id - partid of IPI's potential sender.
- *
- *     regs - processor's context before the processor entered
- *            interrupt code. NOT USED.
  */
 irqreturn_t
-xpc_notify_IRQ_handler(int irq, void *dev_id, struct pt_regs *regs)
+xpc_notify_IRQ_handler(int irq, void *dev_id)
 {
        partid_t partid = (partid_t) (u64) dev_id;
        struct xpc_partition *part = &xpc_partitions[partid];
index 5eb1e1e078b4a1ab511cda2d87271da5a26e6c77..935029fc400d73a632a959b08962ad6b760fdf28 100644 (file)
@@ -126,7 +126,7 @@ int pcibr_ate_alloc(struct pcibus_info *pcibus_info, int count)
  * Setup an Address Translation Entry as specified.  Use either the Bridge
  * internal maps or the external map RAM, as appropriate.
  */
-static inline u64 *pcibr_ate_addr(struct pcibus_info *pcibus_info,
+static inline u64 __iomem *pcibr_ate_addr(struct pcibus_info *pcibus_info,
                                       int ate_index)
 {
        if (ate_index < pcibus_info->pbi_int_ate_size) {
index 838c93c9a16a05843e4b1f262f0339e995d509a0..27dd7df0f446c606bfc17572af0622fab0a45825 100644 (file)
@@ -95,7 +95,7 @@ u16 sn_ioboard_to_pci_bus(struct pci_bus *pci_bus)
  * bridge sends an error interrupt.
  */
 static irqreturn_t
-pcibr_error_intr_handler(int irq, void *arg, struct pt_regs *regs)
+pcibr_error_intr_handler(int irq, void *arg)
 {
        struct pcibus_info *soft = (struct pcibus_info *)arg;
 
@@ -138,7 +138,7 @@ pcibr_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont
        /*
         * register the bridge's error interrupt handler
         */
-       if (request_irq(SGI_PCIASIC_ERROR, (void *)pcibr_error_intr_handler,
+       if (request_irq(SGI_PCIASIC_ERROR, pcibr_error_intr_handler,
                        IRQF_SHARED, "PCIBR error", (void *)(soft))) {
                printk(KERN_WARNING
                       "pcibr cannot allocate interrupt for error handler\n");
index c36b0f5affb3aa2a5d837a4e36f1aa5e427aceea..8a2cb4e691fd6977ebe1300c6c2ba9a5fe3e14db 100644 (file)
@@ -550,13 +550,12 @@ tioca_dma_map(struct pci_dev *pdev, u64 paddr, size_t byte_count, int dma_flags)
  * tioca_error_intr_handler - SGI TIO CA error interrupt handler
  * @irq: unused
  * @arg: pointer to tioca_common struct for the given CA
- * @pt: unused
  *
  * Handle a CA error interrupt.  Simply a wrapper around a SAL call which
  * defers processing to the SGI prom.
  */
 static irqreturn_t
-tioca_error_intr_handler(int irq, void *arg, struct pt_regs *pt)
+tioca_error_intr_handler(int irq, void *arg)
 {
        struct tioca_common *soft = arg;
        struct ia64_sal_retval ret_stuff;
index af7171adcd2c1e83a912871e9114cf9bdc5c216c..46e16dcf5971bf0149a09545f12d247f7c5116d5 100644 (file)
@@ -53,7 +53,7 @@
  */
 
 static void inline
-tioce_mmr_war_pre(struct tioce_kernel *kern, void *mmr_addr)
+tioce_mmr_war_pre(struct tioce_kernel *kern, void __iomem *mmr_addr)
 {
        u64 mmr_base;
        u64 mmr_offset;
@@ -62,7 +62,7 @@ tioce_mmr_war_pre(struct tioce_kernel *kern, void *mmr_addr)
                return;
 
        mmr_base = kern->ce_common->ce_pcibus.bs_base;
-       mmr_offset = (u64)mmr_addr - mmr_base;
+       mmr_offset = (unsigned long)mmr_addr - mmr_base;
 
        if (mmr_offset < 0x45000) {
                u64 mmr_war_offset;
@@ -79,7 +79,7 @@ tioce_mmr_war_pre(struct tioce_kernel *kern, void *mmr_addr)
 }
 
 static void inline
-tioce_mmr_war_post(struct tioce_kernel *kern, void *mmr_addr)
+tioce_mmr_war_post(struct tioce_kernel *kern, void __iomem *mmr_addr)
 {
        u64 mmr_base;
        u64 mmr_offset;
@@ -88,7 +88,7 @@ tioce_mmr_war_post(struct tioce_kernel *kern, void *mmr_addr)
                return;
 
        mmr_base = kern->ce_common->ce_pcibus.bs_base;
-       mmr_offset = (u64)mmr_addr - mmr_base;
+       mmr_offset = (unsigned long)mmr_addr - mmr_base;
 
        if (mmr_offset < 0x45000) {
                if (mmr_offset == 0x100)
@@ -223,7 +223,7 @@ tioce_dma_d64(unsigned long ct_addr, int dma_flags)
  * @pci_dev.
  */
 static inline void
-pcidev_to_tioce(struct pci_dev *pdev, struct tioce **base,
+pcidev_to_tioce(struct pci_dev *pdev, struct tioce __iomem **base,
                struct tioce_kernel **kernel, int *port)
 {
        struct pcidev_info *pcidev_info;
@@ -235,7 +235,7 @@ pcidev_to_tioce(struct pci_dev *pdev, struct tioce **base,
        ce_kernel = (struct tioce_kernel *)ce_common->ce_kernel_private;
 
        if (base)
-               *base = (struct tioce *)ce_common->ce_pcibus.bs_base;
+               *base = (struct tioce __iomem *)ce_common->ce_pcibus.bs_base;
        if (kernel)
                *kernel = ce_kernel;
 
@@ -275,13 +275,13 @@ tioce_alloc_map(struct tioce_kernel *ce_kern, int type, int port,
        u64 pagesize;
        int msi_capable, msi_wanted;
        u64 *ate_shadow;
-       u64 *ate_reg;
+       u64 __iomem *ate_reg;
        u64 addr;
-       struct tioce *ce_mmr;
+       struct tioce __iomem *ce_mmr;
        u64 bus_base;
        struct tioce_dmamap *map;
 
-       ce_mmr = (struct tioce *)ce_kern->ce_common->ce_pcibus.bs_base;
+       ce_mmr = (struct tioce __iomem *)ce_kern->ce_common->ce_pcibus.bs_base;
 
        switch (type) {
        case TIOCE_ATE_M32:
@@ -386,7 +386,7 @@ tioce_dma_d32(struct pci_dev *pdev, u64 ct_addr, int dma_flags)
 {
        int dma_ok;
        int port;
-       struct tioce *ce_mmr;
+       struct tioce __iomem *ce_mmr;
        struct tioce_kernel *ce_kern;
        u64 ct_upper;
        u64 ct_lower;
@@ -461,7 +461,7 @@ tioce_dma_unmap(struct pci_dev *pdev, dma_addr_t bus_addr, int dir)
        int i;
        int port;
        struct tioce_kernel *ce_kern;
-       struct tioce *ce_mmr;
+       struct tioce __iomem *ce_mmr;
        unsigned long flags;
 
        bus_addr = tioce_dma_barrier(bus_addr, 0);
@@ -666,12 +666,11 @@ tioce_dma_consistent(struct pci_dev *pdev, u64 paddr, size_t byte_count, int dma
  * tioce_error_intr_handler - SGI TIO CE error interrupt handler
  * @irq: unused
  * @arg: pointer to tioce_common struct for the given CE
- * @pt: unused
  *
  * Handle a CE error interrupt.  Simply a wrapper around a SAL call which
  * defers processing to the SGI prom.
  */ static irqreturn_t
-tioce_error_intr_handler(int irq, void *arg, struct pt_regs *pt)
+tioce_error_intr_handler(int irq, void *arg)
 {
        struct tioce_common *soft = arg;
        struct ia64_sal_retval ret_stuff;
@@ -701,9 +700,9 @@ static void
 tioce_reserve_m32(struct tioce_kernel *ce_kern, u64 base, u64 limit)
 {
        int ate_index, last_ate, ps;
-       struct tioce *ce_mmr;
+       struct tioce __iomem *ce_mmr;
 
-       ce_mmr = (struct tioce *)ce_kern->ce_common->ce_pcibus.bs_base;
+       ce_mmr = (struct tioce __iomem *)ce_kern->ce_common->ce_pcibus.bs_base;
        ps = ce_kern->ce_ate3240_pagesize;
        ate_index = ATE_PAGE(base, ps);
        last_ate = ate_index + ATE_NPAGES(base, limit-base+1, ps) - 1;
@@ -737,7 +736,7 @@ tioce_kern_init(struct tioce_common *tioce_common)
        int dev;
        u32 tmp;
        unsigned int seg, bus;
-       struct tioce *tioce_mmr;
+       struct tioce __iomem *tioce_mmr;
        struct tioce_kernel *tioce_kern;
 
        tioce_kern = kzalloc(sizeof(struct tioce_kernel), GFP_KERNEL);
@@ -768,7 +767,7 @@ tioce_kern_init(struct tioce_common *tioce_common)
         * the ate's.
         */
 
-       tioce_mmr = (struct tioce *)tioce_common->ce_pcibus.bs_base;
+       tioce_mmr = (struct tioce __iomem *)tioce_common->ce_pcibus.bs_base;
        tioce_mmr_clri(tioce_kern, &tioce_mmr->ce_ure_page_map,
                       CE_URE_PAGESIZE_MASK);
        tioce_mmr_seti(tioce_kern, &tioce_mmr->ce_ure_page_map,
@@ -859,7 +858,7 @@ tioce_force_interrupt(struct sn_irq_info *sn_irq_info)
        struct pcidev_info *pcidev_info;
        struct tioce_common *ce_common;
        struct tioce_kernel *ce_kern;
-       struct tioce *ce_mmr;
+       struct tioce __iomem *ce_mmr;
        u64 force_int_val;
 
        if (!sn_irq_info->irq_bridge)
@@ -873,7 +872,7 @@ tioce_force_interrupt(struct sn_irq_info *sn_irq_info)
                return;
 
        ce_common = (struct tioce_common *)pcidev_info->pdi_pcibus_info;
-       ce_mmr = (struct tioce *)ce_common->ce_pcibus.bs_base;
+       ce_mmr = (struct tioce __iomem *)ce_common->ce_pcibus.bs_base;
        ce_kern = (struct tioce_kernel *)ce_common->ce_kernel_private;
 
        /*
@@ -954,7 +953,7 @@ tioce_target_interrupt(struct sn_irq_info *sn_irq_info)
        struct pcidev_info *pcidev_info;
        struct tioce_common *ce_common;
        struct tioce_kernel *ce_kern;
-       struct tioce *ce_mmr;
+       struct tioce __iomem *ce_mmr;
        int bit;
        u64 vector;
 
@@ -963,7 +962,7 @@ tioce_target_interrupt(struct sn_irq_info *sn_irq_info)
                return;
 
        ce_common = (struct tioce_common *)pcidev_info->pdi_pcibus_info;
-       ce_mmr = (struct tioce *)ce_common->ce_pcibus.bs_base;
+       ce_mmr = (struct tioce __iomem *)ce_common->ce_pcibus.bs_base;
        ce_kern = (struct tioce_kernel *)ce_common->ce_kernel_private;
 
        bit = sn_irq_info->irq_int_bit;
@@ -995,7 +994,7 @@ tioce_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont
        cnodeid_t my_cnode, mem_cnode;
        struct tioce_common *tioce_common;
        struct tioce_kernel *tioce_kern;
-       struct tioce *tioce_mmr;
+       struct tioce __iomem *tioce_mmr;
 
        /*
         * Allocate kernel bus soft and copy from prom.
@@ -1019,7 +1018,7 @@ tioce_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont
         * interrupt handler.
         */
 
-       tioce_mmr = (struct tioce *)tioce_common->ce_pcibus.bs_base;
+       tioce_mmr = (struct tioce __iomem *)tioce_common->ce_pcibus.bs_base;
        tioce_mmr_seti(tioce_kern, &tioce_mmr->ce_adm_int_status_alias, ~0ULL);
        tioce_mmr_seti(tioce_kern, &tioce_mmr->ce_adm_error_summary_alias,
                       ~0ULL);
index 3841861df6a2a0565fc19aad6b59e8a5fa0490ee..f8d8650383e0e6ecb09dd6d36a9ff42df69e3731 100644 (file)
@@ -77,13 +77,16 @@ skip:
  */
 asmlinkage unsigned int do_IRQ(int irq, struct pt_regs *regs)
 {
+       struct pt_regs *old_regs;
+       old_regs = set_irq_regs(regs);
        irq_enter();
 
 #ifdef CONFIG_DEBUG_STACKOVERFLOW
        /* FIXME M32R */
 #endif
-       __do_IRQ(irq, regs);
+       __do_IRQ(irq);
        irq_exit();
+       set_irq_regs(old_regs);
 
        return 1;
 }
index 3f35ab3d2dc28060b6030c76b37726887e8edd5f..0e7778be33ccc93503e5b28a4f902f01e13674b4 100644 (file)
@@ -369,10 +369,10 @@ static void c_stop(struct seq_file *m, void *v)
 }
 
 struct seq_operations cpuinfo_op = {
-       start:  c_start,
-       next:   c_next,
-       stop:   c_stop,
-       show:   show_cpuinfo,
+       .start = c_start,
+       .next = c_next,
+       .stop = c_stop,
+       .show = show_cpuinfo,
 };
 #endif /* CONFIG_PROC_FS */
 
index 67dbbdc9d111bdc89e0b621adf2d9ef438030915..6b2d77da06830c734c01d588881694c115e84c53 100644 (file)
@@ -86,7 +86,7 @@ void __init init_IRQ(void)
        /* INT0 : LAN controller (RTL8019AS) */
        irq_desc[M32R_IRQ_INT0].status = IRQ_DISABLED;
        irq_desc[M32R_IRQ_INT0].chip = &mappi_irq_type;
-       irq_desc[M32R_IRQ_INT0].action = 0;
+       irq_desc[M32R_IRQ_INT0].action = NULL;
        irq_desc[M32R_IRQ_INT0].depth = 1;
        icu_data[M32R_IRQ_INT0].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10;
        disable_mappi_irq(M32R_IRQ_INT0);
@@ -95,7 +95,7 @@ void __init init_IRQ(void)
        /* MFT2 : system timer */
        irq_desc[M32R_IRQ_MFT2].status = IRQ_DISABLED;
        irq_desc[M32R_IRQ_MFT2].chip = &mappi_irq_type;
-       irq_desc[M32R_IRQ_MFT2].action = 0;
+       irq_desc[M32R_IRQ_MFT2].action = NULL;
        irq_desc[M32R_IRQ_MFT2].depth = 1;
        icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN;
        disable_mappi_irq(M32R_IRQ_MFT2);
@@ -104,7 +104,7 @@ void __init init_IRQ(void)
        /* SIO0_R : uart receive data */
        irq_desc[M32R_IRQ_SIO0_R].status = IRQ_DISABLED;
        irq_desc[M32R_IRQ_SIO0_R].chip = &mappi_irq_type;
-       irq_desc[M32R_IRQ_SIO0_R].action = 0;
+       irq_desc[M32R_IRQ_SIO0_R].action = NULL;
        irq_desc[M32R_IRQ_SIO0_R].depth = 1;
        icu_data[M32R_IRQ_SIO0_R].icucr = 0;
        disable_mappi_irq(M32R_IRQ_SIO0_R);
@@ -112,7 +112,7 @@ void __init init_IRQ(void)
        /* SIO0_S : uart send data */
        irq_desc[M32R_IRQ_SIO0_S].status = IRQ_DISABLED;
        irq_desc[M32R_IRQ_SIO0_S].chip = &mappi_irq_type;
-       irq_desc[M32R_IRQ_SIO0_S].action = 0;
+       irq_desc[M32R_IRQ_SIO0_S].action = NULL;
        irq_desc[M32R_IRQ_SIO0_S].depth = 1;
        icu_data[M32R_IRQ_SIO0_S].icucr = 0;
        disable_mappi_irq(M32R_IRQ_SIO0_S);
@@ -120,7 +120,7 @@ void __init init_IRQ(void)
        /* SIO1_R : uart receive data */
        irq_desc[M32R_IRQ_SIO1_R].status = IRQ_DISABLED;
        irq_desc[M32R_IRQ_SIO1_R].chip = &mappi_irq_type;
-       irq_desc[M32R_IRQ_SIO1_R].action = 0;
+       irq_desc[M32R_IRQ_SIO1_R].action = NULL;
        irq_desc[M32R_IRQ_SIO1_R].depth = 1;
        icu_data[M32R_IRQ_SIO1_R].icucr = 0;
        disable_mappi_irq(M32R_IRQ_SIO1_R);
@@ -128,7 +128,7 @@ void __init init_IRQ(void)
        /* SIO1_S : uart send data */
        irq_desc[M32R_IRQ_SIO1_S].status = IRQ_DISABLED;
        irq_desc[M32R_IRQ_SIO1_S].chip = &mappi_irq_type;
-       irq_desc[M32R_IRQ_SIO1_S].action = 0;
+       irq_desc[M32R_IRQ_SIO1_S].action = NULL;
        irq_desc[M32R_IRQ_SIO1_S].depth = 1;
        icu_data[M32R_IRQ_SIO1_S].icucr = 0;
        disable_mappi_irq(M32R_IRQ_SIO1_S);
@@ -138,7 +138,7 @@ void __init init_IRQ(void)
        /* INT1 : pccard0 interrupt */
        irq_desc[M32R_IRQ_INT1].status = IRQ_DISABLED;
        irq_desc[M32R_IRQ_INT1].chip = &mappi_irq_type;
-       irq_desc[M32R_IRQ_INT1].action = 0;
+       irq_desc[M32R_IRQ_INT1].action = NULL;
        irq_desc[M32R_IRQ_INT1].depth = 1;
        icu_data[M32R_IRQ_INT1].icucr = M32R_ICUCR_IEN | M32R_ICUCR_ISMOD00;
        disable_mappi_irq(M32R_IRQ_INT1);
@@ -146,7 +146,7 @@ void __init init_IRQ(void)
        /* INT2 : pccard1 interrupt */
        irq_desc[M32R_IRQ_INT2].status = IRQ_DISABLED;
        irq_desc[M32R_IRQ_INT2].chip = &mappi_irq_type;
-       irq_desc[M32R_IRQ_INT2].action = 0;
+       irq_desc[M32R_IRQ_INT2].action = NULL;
        irq_desc[M32R_IRQ_INT2].depth = 1;
        icu_data[M32R_IRQ_INT2].icucr = M32R_ICUCR_IEN | M32R_ICUCR_ISMOD00;
        disable_mappi_irq(M32R_IRQ_INT2);
index a9174efe80cbf95379d3891de21f0c3b660eeb92..b60cea4aebaa6d9e663cae8eef42084d4b30fd26 100644 (file)
@@ -33,7 +33,7 @@
 int do_signal(struct pt_regs *, sigset_t *);
 
 asmlinkage int
-sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize,
+sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize,
                  unsigned long r2, unsigned long r3, unsigned long r4,
                  unsigned long r5, unsigned long r6, struct pt_regs *regs)
 {
@@ -78,8 +78,8 @@ sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
 struct rt_sigframe
 {
        int sig;
-       struct siginfo *pinfo;
-       void *puc;
+       struct siginfo __user *pinfo;
+       void __user *puc;
        struct siginfo info;
        struct ucontext uc;
 //     struct _fpstate fpstate;
index 8b1f6eb76870896b443ed3a7e090b4a5b6eee400..360129174b2bd17aaeed1fcc37c91e80a8100d05 100644 (file)
@@ -101,7 +101,7 @@ void smp_call_function_interrupt(void);
 
 void smp_send_timer(void);
 void smp_ipi_timer_interrupt(struct pt_regs *);
-void smp_local_timer_interrupt(struct pt_regs *);
+void smp_local_timer_interrupt(void);
 
 void send_IPI_allbutself(int, int);
 static void send_IPI_mask(cpumask_t, int, int);
@@ -231,7 +231,7 @@ void smp_flush_tlb_all(void)
        local_irq_save(flags);
        __flush_tlb_all();
        local_irq_restore(flags);
-       smp_call_function(flush_tlb_all_ipi, 0, 1, 1);
+       smp_call_function(flush_tlb_all_ipi, NULL, 1, 1);
        preempt_enable();
 }
 
@@ -734,9 +734,12 @@ void smp_send_timer(void)
  *==========================================================================*/
 void smp_ipi_timer_interrupt(struct pt_regs *regs)
 {
+       struct pt_regs *old_regs;
+       old_regs = set_irq_regs(regs);
        irq_enter();
-       smp_local_timer_interrupt(regs);
+       smp_local_timer_interrupt();
        irq_exit();
+       set_irq_regs(old_regs);
 }
 
 /*==========================================================================*
@@ -762,9 +765,9 @@ void smp_ipi_timer_interrupt(struct pt_regs *regs)
  * ---------- --- --------------------------------------------------------
  * 2003-06-24 hy  use per_cpu structure.
  *==========================================================================*/
-void smp_local_timer_interrupt(struct pt_regs *regs)
+void smp_local_timer_interrupt(void)
 {
-       int user = user_mode(regs);
+       int user = user_mode(get_irq_regs());
        int cpu_id = smp_processor_id();
 
        /*
@@ -774,7 +777,7 @@ void smp_local_timer_interrupt(struct pt_regs *regs)
         * useful with a profiling multiplier != 1
         */
 
-       profile_tick(CPU_PROFILING, regs);
+       profile_tick(CPU_PROFILING);
 
        if (--per_cpu(prof_counter, cpu_id) <= 0) {
                /*
index b567351f3c5236d41e0b108a2ba516a86fc170fd..b4e7bcb43540444d6db2f4a56855711cc56ffe02 100644 (file)
@@ -31,7 +31,7 @@
 /*
  * sys_tas() - test-and-set
  */
-asmlinkage int sys_tas(int *addr)
+asmlinkage int sys_tas(int __user *addr)
 {
        int oldval;
 
@@ -90,7 +90,7 @@ sys_pipe(unsigned long r0, unsigned long r1, unsigned long r2,
 
        error = do_pipe(fd);
        if (!error) {
-               if (copy_to_user((void *)r0, (void *)fd, 2*sizeof(int)))
+               if (copy_to_user((void __user *)r0, fd, 2*sizeof(int)))
                        error = -EFAULT;
        }
        return error;
@@ -201,7 +201,7 @@ asmlinkage int sys_ipc(uint call, int first, int second,
        }
 }
 
-asmlinkage int sys_uname(struct old_utsname * name)
+asmlinkage int sys_uname(struct old_utsname __user * name)
 {
        int err;
        if (!name)
index d8af155db9846eff93a3bb1aa3ba1776d9eec403..a09038282c78a3f5b452f4c4cbbf06120283d15f 100644 (file)
@@ -35,7 +35,7 @@
 
 #ifdef CONFIG_SMP
 extern void send_IPI_allbutself(int, int);
-extern void smp_local_timer_interrupt(struct pt_regs *);
+extern void smp_local_timer_interrupt(void);
 #endif
 
 #define TICK_SIZE      (tick_nsec / 1000)
@@ -188,15 +188,15 @@ static long last_rtc_update = 0;
  * timer_interrupt() needs to keep up the real-time clock,
  * as well as call the "do_timer()" routine every clocktick
  */
-irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t timer_interrupt(int irq, void *dev_id)
 {
 #ifndef CONFIG_SMP
-       profile_tick(CPU_PROFILING, regs);
+       profile_tick(CPU_PROFILING);
 #endif
        do_timer(1);
 
 #ifndef CONFIG_SMP
-       update_process_times(user_mode(regs));
+       update_process_times(user_mode(get_irq_regs()));
 #endif
        /*
         * If we have an externally synchronized Linux clock, then update
@@ -221,7 +221,7 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
           a hack, so don't look closely for now.. */
 
 #ifdef CONFIG_SMP
-       smp_local_timer_interrupt(regs);
+       smp_local_timer_interrupt();
        smp_send_timer();
 #endif
 
index c1daf2c40c7c4fb05af0f61b503fe9bf20a92bc1..97e0b1c0830e81cf218d4e61c4dbbc0a1de8e0ff 100644 (file)
@@ -268,7 +268,7 @@ static __inline__ void do_trap(int trapnr, int signr, const char * str,
 #define DO_ERROR(trapnr, signr, str, name) \
 asmlinkage void do_##name(struct pt_regs * regs, long error_code) \
 { \
-       do_trap(trapnr, signr, 0, regs, error_code, NULL); \
+       do_trap(trapnr, signr, NULL, regs, error_code, NULL); \
 }
 
 #define DO_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \
index 805b81fedf80a3129fec1c525487cc2d9da239ef..7bc14461a6ac5082f785f887a73964cbcbe3b280 100644 (file)
@@ -600,7 +600,7 @@ config MVME147_SCC
 
 config SERIAL167
        bool "CD2401 support for MVME166/7 serial ports"
-       depends on MVME16x && BROKEN
+       depends on MVME16x
        help
          This is the driver for the serial ports on the Motorola MVME166,
          167, and 172 boards.  Everyone using one of these boards should say
index 96c79d840cff3cac8c04e96fd050e5d8e39e9e88..28d95cfe8ac00f8ba02479b9e12101aa247d0334 100644 (file)
 
 static void amiga_enable_irq(unsigned int irq);
 static void amiga_disable_irq(unsigned int irq);
-static irqreturn_t ami_int1(int irq, void *dev_id, struct pt_regs *fp);
-static irqreturn_t ami_int3(int irq, void *dev_id, struct pt_regs *fp);
-static irqreturn_t ami_int4(int irq, void *dev_id, struct pt_regs *fp);
-static irqreturn_t ami_int5(int irq, void *dev_id, struct pt_regs *fp);
+static irqreturn_t ami_int1(int irq, void *dev_id);
+static irqreturn_t ami_int3(int irq, void *dev_id);
+static irqreturn_t ami_int4(int irq, void *dev_id);
+static irqreturn_t ami_int5(int irq, void *dev_id);
 
 static struct irq_controller amiga_irq_controller = {
        .name           = "amiga",
@@ -113,98 +113,98 @@ static void amiga_disable_irq(unsigned int irq)
  * The builtin Amiga hardware interrupt handlers.
  */
 
-static irqreturn_t ami_int1(int irq, void *dev_id, struct pt_regs *fp)
+static irqreturn_t ami_int1(int irq, void *dev_id)
 {
        unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar;
 
        /* if serial transmit buffer empty, interrupt */
        if (ints & IF_TBE) {
                amiga_custom.intreq = IF_TBE;
-               m68k_handle_int(IRQ_AMIGA_TBE, fp);
+               m68k_handle_int(IRQ_AMIGA_TBE);
        }
 
        /* if floppy disk transfer complete, interrupt */
        if (ints & IF_DSKBLK) {
                amiga_custom.intreq = IF_DSKBLK;
-               m68k_handle_int(IRQ_AMIGA_DSKBLK, fp);
+               m68k_handle_int(IRQ_AMIGA_DSKBLK);
        }
 
        /* if software interrupt set, interrupt */
        if (ints & IF_SOFT) {
                amiga_custom.intreq = IF_SOFT;
-               m68k_handle_int(IRQ_AMIGA_SOFT, fp);
+               m68k_handle_int(IRQ_AMIGA_SOFT);
        }
        return IRQ_HANDLED;
 }
 
-static irqreturn_t ami_int3(int irq, void *dev_id, struct pt_regs *fp)
+static irqreturn_t ami_int3(int irq, void *dev_id)
 {
        unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar;
 
        /* if a blitter interrupt */
        if (ints & IF_BLIT) {
                amiga_custom.intreq = IF_BLIT;
-               m68k_handle_int(IRQ_AMIGA_BLIT, fp);
+               m68k_handle_int(IRQ_AMIGA_BLIT);
        }
 
        /* if a copper interrupt */
        if (ints & IF_COPER) {
                amiga_custom.intreq = IF_COPER;
-               m68k_handle_int(IRQ_AMIGA_COPPER, fp);
+               m68k_handle_int(IRQ_AMIGA_COPPER);
        }
 
        /* if a vertical blank interrupt */
        if (ints & IF_VERTB) {
                amiga_custom.intreq = IF_VERTB;
-               m68k_handle_int(IRQ_AMIGA_VERTB, fp);
+               m68k_handle_int(IRQ_AMIGA_VERTB);
        }
        return IRQ_HANDLED;
 }
 
-static irqreturn_t ami_int4(int irq, void *dev_id, struct pt_regs *fp)
+static irqreturn_t ami_int4(int irq, void *dev_id)
 {
        unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar;
 
        /* if audio 0 interrupt */
        if (ints & IF_AUD0) {
                amiga_custom.intreq = IF_AUD0;
-               m68k_handle_int(IRQ_AMIGA_AUD0, fp);
+               m68k_handle_int(IRQ_AMIGA_AUD0);
        }
 
        /* if audio 1 interrupt */
        if (ints & IF_AUD1) {
                amiga_custom.intreq = IF_AUD1;
-               m68k_handle_int(IRQ_AMIGA_AUD1, fp);
+               m68k_handle_int(IRQ_AMIGA_AUD1);
        }
 
        /* if audio 2 interrupt */
        if (ints & IF_AUD2) {
                amiga_custom.intreq = IF_AUD2;
-               m68k_handle_int(IRQ_AMIGA_AUD2, fp);
+               m68k_handle_int(IRQ_AMIGA_AUD2);
        }
 
        /* if audio 3 interrupt */
        if (ints & IF_AUD3) {
                amiga_custom.intreq = IF_AUD3;
-               m68k_handle_int(IRQ_AMIGA_AUD3, fp);
+               m68k_handle_int(IRQ_AMIGA_AUD3);
        }
        return IRQ_HANDLED;
 }
 
-static irqreturn_t ami_int5(int irq, void *dev_id, struct pt_regs *fp)
+static irqreturn_t ami_int5(int irq, void *dev_id)
 {
        unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar;
 
        /* if serial receive buffer full interrupt */
        if (ints & IF_RBF) {
                /* acknowledge of IF_RBF must be done by the serial interrupt */
-               m68k_handle_int(IRQ_AMIGA_RBF, fp);
+               m68k_handle_int(IRQ_AMIGA_RBF);
        }
 
        /* if a disk sync interrupt */
        if (ints & IF_DSKSYN) {
                amiga_custom.intreq = IF_DSKSYN;
-               m68k_handle_int(IRQ_AMIGA_DSKSYN, fp);
+               m68k_handle_int(IRQ_AMIGA_DSKSYN);
        }
        return IRQ_HANDLED;
 }
index dbad30054721cf5a1a892f8f23c9c4e3f941c9e3..7a20058eb380173e0a6e1a1b266fc847c9eac833 100644 (file)
@@ -82,7 +82,7 @@ unsigned char cia_able_irq(struct ciabase *base, unsigned char mask)
        return old;
 }
 
-static irqreturn_t cia_handler(int irq, void *dev_id, struct pt_regs *fp)
+static irqreturn_t cia_handler(int irq, void *dev_id)
 {
        struct ciabase *base = (struct ciabase *)dev_id;
        int mach_irq;
@@ -93,7 +93,7 @@ static irqreturn_t cia_handler(int irq, void *dev_id, struct pt_regs *fp)
        amiga_custom.intreq = base->int_mask;
        for (; ints; mach_irq++, ints >>= 1) {
                if (ints & 1)
-                       m68k_handle_int(mach_irq, fp);
+                       m68k_handle_int(mach_irq);
        }
        return IRQ_HANDLED;
 }
index 092e50d2cb137781d1378f43fdb006f8ae73e720..3204f412cad8c32cca0fdc81ad10696218062f5d 100644 (file)
@@ -83,7 +83,7 @@ static char amiga_model_name[13] = "Amiga ";
 
 extern char m68k_debug_device[];
 
-static void amiga_sched_init(irqreturn_t (*handler)(int, void *, struct pt_regs *));
+static void amiga_sched_init(irq_handler_t handler);
 /* amiga specific irq functions */
 extern void amiga_init_IRQ (void);
 static void amiga_get_model(char *model);
@@ -487,8 +487,7 @@ void __init config_amiga(void)
 
 static unsigned short jiffy_ticks;
 
-static void __init amiga_sched_init(irqreturn_t (*timer_routine)(int, void *,
-                                                         struct pt_regs *))
+static void __init amiga_sched_init(irq_handler_t timer_routine)
 {
        static struct resource sched_res = {
            .name = "timer", .start = 0x00bfd400, .end = 0x00bfd5ff,
index 6f4581575fb4ca72bd2782746c64b8c2965c25f3..cb8e7609df4c1308ef105864d88030a318ff0634 100644 (file)
@@ -25,7 +25,7 @@ u_long cpuctrl_physaddr;
 u_long timer_physaddr;
 u_long apollo_model;
 
-extern void dn_sched_init(irqreturn_t (*handler)(int,void *,struct pt_regs *));
+extern void dn_sched_init(irq_handler_t handler);
 extern void dn_init_IRQ(void);
 extern unsigned long dn_gettimeoffset(void);
 extern int dn_dummy_hwclk(int, struct rtc_time *);
@@ -38,7 +38,7 @@ extern irqreturn_t dn_process_int(int irq, struct pt_regs *fp);
 #ifdef CONFIG_HEARTBEAT
 static void dn_heartbeat(int on);
 #endif
-static irqreturn_t dn_timer_int(int irq,void *, struct pt_regs *);
+static irqreturn_t dn_timer_int(int irq,void *);
 static void dn_get_model(char *model);
 static const char *apollo_models[] = {
        [APOLLO_DN3000-APOLLO_DN3000] = "DN3000 (Otter)",
@@ -174,13 +174,13 @@ void config_apollo(void) {
 
 }
 
-irqreturn_t dn_timer_int(int irq, void *dev_id, struct pt_regs *fp)
+irqreturn_t dn_timer_int(int irq, void *dev_id)
 {
-       irqreturn_t (*timer_handler)(int, void *, struct pt_regs *) = dev_id;
+       irq_handler_t timer_handler = dev_id;
 
        volatile unsigned char x;
 
-       timer_handler(irq, dev_id, fp);
+       timer_handler(irq, dev_id);
 
        x=*(volatile unsigned char *)(timer+3);
        x=*(volatile unsigned char *)(timer+5);
@@ -188,8 +188,8 @@ irqreturn_t dn_timer_int(int irq, void *dev_id, struct pt_regs *fp)
        return IRQ_HANDLED;
 }
 
-void dn_sched_init(irqreturn_t (*timer_routine)(int, void *, struct pt_regs *)) {
-
+void dn_sched_init(irq_handler_t timer_routine)
+{
        /* program timer 1 */
        *(volatile unsigned char *)(timer+3)=0x01;
        *(volatile unsigned char *)(timer+1)=0x40;
diff --git a/arch/m68k/apollo/dma.c b/arch/m68k/apollo/dma.c
deleted file mode 100644 (file)
index aed8be1..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/kd.h>
-#include <linux/tty.h>
-#include <linux/console.h>
-
-#include <asm/setup.h>
-#include <asm/bootinfo.h>
-#include <asm/system.h>
-#include <asm/pgtable.h>
-#include <asm/apollodma.h>
-#include <asm/io.h>
-
-/* note only works for 16 Bit 1 page DMA's */
-
-static unsigned short next_free_xlat_entry=0;
-
-unsigned short dma_map_page(unsigned long phys_addr,int count,int type) {
-
-       unsigned long page_aligned_addr=phys_addr & (~((1<<12)-1));
-       unsigned short start_map_addr=page_aligned_addr >> 10;
-       unsigned short free_xlat_entry, *xlat_map_entry;
-       int i;
-
-       free_xlat_entry=next_free_xlat_entry;
-       for(i=0,xlat_map_entry=addr_xlat_map+(free_xlat_entry<<2);i<8;i++,xlat_map_entry++) {
-#if 0
-               printk("phys_addr: %x, page_aligned_addr: %x, start_map_addr: %x\n",phys_addr,page_aligned_addr,start_map_addr+i);
-#endif
-               out_be16(xlat_map_entry, start_map_addr+i);
-       }
-
-       next_free_xlat_entry+=2;
-       if(next_free_xlat_entry>125)
-               next_free_xlat_entry=0;
-
-#if 0
-       printk("next_free_xlat_entry: %d\n",next_free_xlat_entry);
-#endif
-
-       return free_xlat_entry<<10;
-}
-
-void dma_unmap_page(unsigned short dma_addr) {
-
-       return ;
-
-}
-
index 9fe07803797bb9c2211decdd76e63717ad2fc258..4274af125998f1b3efdb08b712b2b56d95d80c8d 100644 (file)
@@ -6,7 +6,7 @@
 
 void dn_process_int(unsigned int irq, struct pt_regs *fp)
 {
-       m68k_handle_int(irq, fp);
+       __m68k_handle_int(irq, fp);
 
        *(volatile unsigned char *)(pica)=0x20;
        *(volatile unsigned char *)(picb)=0x20;
index ece13cbf9950a1b69a966b2b99766eeeeeca2be7..7f812641790c8c8c9bfbe06ab1d675c2014574f8 100644 (file)
@@ -332,6 +332,9 @@ static void atari_shutdown_irq(unsigned int irq)
        atari_disable_irq(irq);
        atari_turnoff_irq(irq);
        m68k_irq_shutdown(irq);
+
+       if (irq == IRQ_AUTO_4)
+           vectors[VEC_INT4] = falcon_hblhandler;
 }
 
 static struct irq_controller atari_irq_controller = {
@@ -356,7 +359,7 @@ static struct irq_controller atari_irq_controller = {
 
 void __init atari_init_IRQ(void)
 {
-       m68k_setup_user_interrupt(VEC_USER, 192, NULL);
+       m68k_setup_user_interrupt(VEC_USER, NUM_ATARI_SOURCES - IRQ_USER, NULL);
        m68k_setup_irq_controller(&atari_irq_controller, 1, NUM_ATARI_SOURCES - 1);
 
        /* Initialize the MFP(s) */
@@ -403,8 +406,10 @@ void __init atari_init_IRQ(void)
                 * gets overruns)
                 */
 
-               if (!MACH_IS_HADES)
+               if (!MACH_IS_HADES) {
                        vectors[VEC_INT2] = falcon_hblhandler;
+                       vectors[VEC_INT4] = falcon_hblhandler;
+               }
        }
 
        if (ATARIHW_PRESENT(PCM_8BIT) && ATARIHW_PRESENT(MICROWIRE)) {
index b2079252a954b708a43441fd3f850626193b90ff..ca5cd4344e3d034e9f09608fd099c78b32af7b03 100644 (file)
@@ -62,7 +62,7 @@ static void atari_heartbeat( int on );
 #endif
 
 /* atari specific timer functions (in time.c) */
-extern void atari_sched_init(irqreturn_t (*)(int, void *, struct pt_regs *));
+extern void atari_sched_init(irq_handler_t );
 extern unsigned long atari_gettimeoffset (void);
 extern int atari_mste_hwclk (int, struct rtc_time *);
 extern int atari_tt_hwclk (int, struct rtc_time *);
index 288f5e6a124eb57b73120136eef03dba428a5c35..d64b5804e98097998807e529e487bb27cae35376 100644 (file)
@@ -44,7 +44,7 @@
 
 static int stdma_locked;                       /* the semaphore */
                                                /* int func to be called */
-static irqreturn_t (*stdma_isr)(int, void *, struct pt_regs *);
+static irq_handler_t stdma_isr;
 static void *stdma_isr_data;                   /* data passed to isr */
 static DECLARE_WAIT_QUEUE_HEAD(stdma_wait);    /* wait queue for ST-DMA */
 
@@ -53,7 +53,7 @@ static DECLARE_WAIT_QUEUE_HEAD(stdma_wait);   /* wait queue for ST-DMA */
 
 /***************************** Prototypes *****************************/
 
-static irqreturn_t stdma_int (int irq, void *dummy, struct pt_regs *fp);
+static irqreturn_t stdma_int (int irq, void *dummy);
 
 /************************* End of Prototypes **************************/
 
@@ -75,8 +75,7 @@ static irqreturn_t stdma_int (int irq, void *dummy, struct pt_regs *fp);
  *
  */
 
-void stdma_lock(irqreturn_t (*handler)(int, void *, struct pt_regs *),
-               void *data)
+void stdma_lock(irq_handler_t handler, void *data)
 {
        unsigned long flags;
 
@@ -188,9 +187,9 @@ void __init stdma_init(void)
  *
  */
 
-static irqreturn_t stdma_int(int irq, void *dummy, struct pt_regs *fp)
+static irqreturn_t stdma_int(int irq, void *dummy)
 {
   if (stdma_isr)
-      (*stdma_isr)(irq, stdma_isr_data, fp);
+      (*stdma_isr)(irq, stdma_isr_data);
   return IRQ_HANDLED;
 }
index e79bbc94216dab99289925ba8208181952eb4369..e0d3c8bfb40864791b6c333e3926be8212ba7bc5 100644 (file)
 #include <linux/init.h>
 #include <linux/rtc.h>
 #include <linux/bcd.h>
+#include <linux/delay.h>
 
 #include <asm/atariints.h>
 
 void __init
-atari_sched_init(irqreturn_t (*timer_routine)(int, void *, struct pt_regs *))
+atari_sched_init(irq_handler_t timer_routine)
 {
     /* set Timer C data Register */
     mfp.tim_dt_c = INT_TICKS;
@@ -212,8 +213,12 @@ int atari_tt_hwclk( int op, struct rtc_time *t )
      * additionally the RTC_SET bit is set to prevent an update cycle.
      */
 
-    while( RTC_READ(RTC_FREQ_SELECT) & RTC_UIP )
-        schedule_timeout_interruptible(HWCLK_POLL_INTERVAL);
+    while( RTC_READ(RTC_FREQ_SELECT) & RTC_UIP ) {
+       if (in_atomic() || irqs_disabled())
+           mdelay(1);
+       else
+           schedule_timeout_interruptible(HWCLK_POLL_INTERVAL);
+    }
 
     local_irq_save(flags);
     RTC_WRITE( RTC_CONTROL, ctrl | RTC_SET );
index d1e916ae55a8003f5216bfadb258e0b1eecb5bfe..896ae3d3d91905bcb40b71636e778155345a298b 100644 (file)
@@ -38,7 +38,7 @@
 
 static void bvme6000_get_model(char *model);
 static int  bvme6000_get_hardware_list(char *buffer);
-extern void bvme6000_sched_init(irqreturn_t (*handler)(int, void *, struct pt_regs *));
+extern void bvme6000_sched_init(irq_handler_t handler);
 extern unsigned long bvme6000_gettimeoffset (void);
 extern int bvme6000_hwclk (int, struct rtc_time *);
 extern int bvme6000_set_clock_mmss (unsigned long);
@@ -52,7 +52,7 @@ static unsigned char bin2bcd (unsigned char b);
 /* Save tick handler routine pointer, will point to do_timer() in
  * kernel/sched.c, called via bvme6000_process_int() */
 
-static irqreturn_t (*tick_handler)(int, void *, struct pt_regs *);
+static irq_handler_t tick_handler;
 
 
 int bvme6000_parse_bootinfo(const struct bi_record *bi)
@@ -154,7 +154,7 @@ void __init config_bvme6000(void)
 }
 
 
-irqreturn_t bvme6000_abort_int (int irq, void *dev_id, struct pt_regs *fp)
+irqreturn_t bvme6000_abort_int (int irq, void *dev_id)
 {
         unsigned long *new = (unsigned long *)vectors;
         unsigned long *old = (unsigned long *)0xf8000000;
@@ -171,14 +171,14 @@ irqreturn_t bvme6000_abort_int (int irq, void *dev_id, struct pt_regs *fp)
 }
 
 
-static irqreturn_t bvme6000_timer_int (int irq, void *dev_id, struct pt_regs *fp)
+static irqreturn_t bvme6000_timer_int (int irq, void *dev_id)
 {
     volatile RtcPtr_t rtc = (RtcPtr_t)BVME_RTC_BASE;
     unsigned char msr = rtc->msr & 0xc0;
 
     rtc->msr = msr | 0x20;             /* Ack the interrupt */
 
-    return tick_handler(irq, dev_id, fp);
+    return tick_handler(irq, dev_id);
 }
 
 /*
@@ -190,7 +190,7 @@ static irqreturn_t bvme6000_timer_int (int irq, void *dev_id, struct pt_regs *fp
  * so divide by 8 to get the microsecond result.
  */
 
-void bvme6000_sched_init (irqreturn_t (*timer_routine)(int, void *, struct pt_regs *))
+void bvme6000_sched_init (irq_handler_t timer_routine)
 {
     volatile RtcPtr_t rtc = (RtcPtr_t)BVME_RTC_BASE;
     unsigned char msr = rtc->msr & 0xc0;
index 7df05662b27795d81c6b3b0b3e49d1bb20c53652..dd7c8a2583d3395eaa877580905c821f9556e3c6 100644 (file)
 
 #define INTVAL ((10000 / 4) - 1)
 
-static irqreturn_t hp300_tick(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t hp300_tick(int irq, void *dev_id)
 {
        unsigned long tmp;
-       irqreturn_t (*vector)(int, void *, struct pt_regs *) = dev_id;
+       irq_handler_t vector = dev_id;
        in_8(CLOCKBASE + CLKSR);
        asm volatile ("movpw %1@(5),%0" : "=d" (tmp) : "a" (CLOCKBASE));
        /* Turn off the network and SCSI leds */
        blinken_leds(0, 0xe0);
-       return vector(irq, NULL, regs);
+       return vector(irq, NULL);
 }
 
 unsigned long hp300_gettimeoffset(void)
@@ -63,7 +63,7 @@ unsigned long hp300_gettimeoffset(void)
   return (USECS_PER_JIFFY * ticks) / INTVAL;
 }
 
-void __init hp300_sched_init(irqreturn_t (*vector)(int, void *, struct pt_regs *))
+void __init hp300_sched_init(irq_handler_t vector)
 {
   out_8(CLOCKBASE + CLKCR2, 0x1);              /* select CR1 */
   out_8(CLOCKBASE + CLKCR1, 0x1);              /* reset */
index 8ef9987b49ab92351a2bb06b0c1db32ca3d61da5..f5b3d098b0f5e1295a7f2653941de23c387ec227 100644 (file)
@@ -1,4 +1,4 @@
-extern void hp300_sched_init(irqreturn_t (*vector)(int, void *, struct pt_regs *));
+extern void hp300_sched_init(irq_handler_t vector);
 extern unsigned long hp300_gettimeoffset (void);
 
 
index dae609797dc019f02d9899851f1c1a065a97d207..1c9ecaa473d5795e90ef0540ae3c9accedec9a20 100644 (file)
@@ -9,10 +9,11 @@ else
 endif
 extra-y        += vmlinux.lds
 
-obj-y  := entry.o process.o traps.o ints.o dma.o signal.o ptrace.o \
+obj-y  := entry.o process.o traps.o ints.o signal.o ptrace.o \
           sys_m68k.o time.o semaphore.o setup.o m68k_ksyms.o
 
 obj-$(CONFIG_PCI)      += bios32.o
 obj-$(CONFIG_MODULES)  += module.o
+obj-y$(CONFIG_MMU_SUN3) += dma.o       # no, it's not a typo
 
 EXTRA_AFLAGS := -traditional
index fc449f8b204504ac9193a4472c07ca32a6fb7af6..9d4e4b5b6bd889325d274334fd6b608989440831 100644 (file)
@@ -15,7 +15,7 @@
 #include <asm/scatterlist.h>
 
 void *dma_alloc_coherent(struct device *dev, size_t size,
-                        dma_addr_t *handle, int flag)
+                        dma_addr_t *handle, gfp_t flag)
 {
        struct page *page, **map;
        pgprot_t pgprot;
@@ -51,7 +51,7 @@ void *dma_alloc_coherent(struct device *dev, size_t size,
                pgprot_val(pgprot) |= _PAGE_GLOBAL040 | _PAGE_NOCACHE_S;
        else
                pgprot_val(pgprot) |= _PAGE_NOCACHE030;
-       addr = vmap(map, size, flag, pgprot);
+       addr = vmap(map, size, VM_MAP, pgprot);
        kfree(map);
 
        return addr;
index 9083c8b7659f9be4354bfaaf61243e8fd719ab1f..222ce4244564fbb7d5b8471d13740e7adb74eaa8 100644 (file)
@@ -205,7 +205,7 @@ ENTRY(auto_inthandler)
        movel   %sp,%sp@-
        movel   %d0,%sp@-               |  put vector # on stack
 auto_irqhandler_fixup = . + 2
-       jsr     m68k_handle_int         |  process the IRQ
+       jsr     __m68k_handle_int       |  process the IRQ
        addql   #8,%sp                  |  pop parameters off stack
 
 ret_from_interrupt:
@@ -239,7 +239,7 @@ user_irqvec_fixup = . + 2
        movel   %sp,%sp@-
        movel   %d0,%sp@-               |  put vector # on stack
 user_irqhandler_fixup = . + 2
-       jsr     m68k_handle_int         |  process the IRQ
+       jsr     __m68k_handle_int       |  process the IRQ
        addql   #8,%sp                  |  pop parameters off stack
 
        subqb   #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1)
@@ -706,4 +706,33 @@ sys_call_table:
        .long sys_add_key
        .long sys_request_key   /* 280 */
        .long sys_keyctl
+       .long sys_ioprio_set
+       .long sys_ioprio_get
+       .long sys_inotify_init
+       .long sys_inotify_add_watch     /* 285 */
+       .long sys_inotify_rm_watch
+       .long sys_migrate_pages
+       .long sys_openat
+       .long sys_mkdirat
+       .long sys_mknodat               /* 290 */
+       .long sys_fchownat
+       .long sys_futimesat
+       .long sys_fstatat64
+       .long sys_unlinkat
+       .long sys_renameat              /* 295 */
+       .long sys_linkat
+       .long sys_symlinkat
+       .long sys_readlinkat
+       .long sys_fchmodat
+       .long sys_faccessat             /* 300 */
+       .long sys_ni_syscall            /* Reserved for pselect6 */
+       .long sys_ni_syscall            /* Reserved for ppoll */
+       .long sys_unshare
+       .long sys_set_robust_list
+       .long sys_get_robust_list       /* 305 */
+       .long sys_splice
+       .long sys_sync_file_range
+       .long sys_tee
+       .long sys_vmsplice
+       .long sys_move_pages            /* 310 */
 
index b33e37fb7b0e4eb88a78bfdfb282be42c1c9e61c..84aceca6c05c16297ce244431c1cbdb0f741a441 100644 (file)
@@ -39,6 +39,7 @@
 #include <asm/page.h>
 #include <asm/machdep.h>
 #include <asm/cacheflush.h>
+#include <asm/irq_regs.h>
 
 #ifdef CONFIG_Q40
 #include <asm/q40ints.h>
@@ -104,7 +105,7 @@ void __init init_IRQ(void)
  * @handler: called from auto vector interrupts
  *
  * setup the handler to be called from auto vector interrupts instead of the
- * standard m68k_handle_int(), it will be called with irq numbers in the range
+ * standard __m68k_handle_int(), it will be called with irq numbers in the range
  * from IRQ_AUTO_1 - IRQ_AUTO_7.
  */
 void __init m68k_setup_auto_interrupt(void (*handler)(unsigned int, struct pt_regs *))
@@ -123,7 +124,7 @@ void __init m68k_setup_auto_interrupt(void (*handler)(unsigned int, struct pt_re
  * setup user vector interrupts, this includes activating the specified range
  * of interrupts, only then these interrupts can be requested (note: this is
  * different from auto vector interrupts). An optional handler can be installed
- * to be called instead of the default m68k_handle_int(), it will be called
+ * to be called instead of the default __m68k_handle_int(), it will be called
  * with irq numbers starting from IRQ_USER.
  */
 void __init m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt,
@@ -131,6 +132,7 @@ void __init m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt,
 {
        int i;
 
+       BUG_ON(IRQ_USER + cnt >= NR_IRQS);
        m68k_first_user_vec = vec;
        for (i = 0; i < cnt; i++)
                irq_controller[IRQ_USER + i] = &user_irq_controller;
@@ -215,7 +217,7 @@ int setup_irq(unsigned int irq, struct irq_node *node)
 }
 
 int request_irq(unsigned int irq,
-               irqreturn_t (*handler) (int, void *, struct pt_regs *),
+               irq_handler_t handler,
                unsigned long flags, const char *devname, void *dev_id)
 {
        struct irq_node *node;
@@ -379,18 +381,25 @@ unsigned int irq_canonicalize(unsigned int irq)
 
 EXPORT_SYMBOL(irq_canonicalize);
 
-asmlinkage void m68k_handle_int(unsigned int irq, struct pt_regs *regs)
+asmlinkage void m68k_handle_int(unsigned int irq)
 {
        struct irq_node *node;
-
        kstat_cpu(0).irqs[irq]++;
        node = irq_list[irq];
        do {
-               node->handler(irq, node->dev_id, regs);
+               node->handler(irq, node->dev_id);
                node = node->next;
        } while (node);
 }
 
+asmlinkage void __m68k_handle_int(unsigned int irq, struct pt_regs *regs)
+{
+       struct pt_regs *old_regs;
+       old_regs = set_irq_regs(regs);
+       m68k_handle_int(irq);
+       set_irq_regs(old_regs);
+}
+
 asmlinkage void handle_badint(struct pt_regs *regs)
 {
        kstat_cpu(0).irqs[0]++;
index aff26a52167c4c418ba9bac6f273c0e202012838..6fc69c74fe2eec9b8c9c646baeffd8fe22942997 100644 (file)
@@ -1,65 +1,10 @@
 #include <linux/module.h>
-#include <linux/linkage.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/user.h>
-#include <linux/elfcore.h>
-#include <linux/in6.h>
-#include <linux/interrupt.h>
-
-#include <asm/setup.h>
-#include <asm/machdep.h>
-#include <asm/pgalloc.h>
-#include <asm/irq.h>
-#include <asm/io.h>
 #include <asm/semaphore.h>
-#include <asm/checksum.h>
 
 asmlinkage long long __ashldi3 (long long, int);
 asmlinkage long long __ashrdi3 (long long, int);
 asmlinkage long long __lshrdi3 (long long, int);
 asmlinkage long long __muldi3 (long long, long long);
-extern char m68k_debug_device[];
-
-/* platform dependent support */
-
-EXPORT_SYMBOL(m68k_machtype);
-EXPORT_SYMBOL(m68k_cputype);
-EXPORT_SYMBOL(m68k_is040or060);
-EXPORT_SYMBOL(m68k_realnum_memory);
-EXPORT_SYMBOL(m68k_memory);
-#ifndef CONFIG_SUN3
-EXPORT_SYMBOL(cache_push);
-EXPORT_SYMBOL(cache_clear);
-#ifndef CONFIG_SINGLE_MEMORY_CHUNK
-EXPORT_SYMBOL(mm_vtop);
-EXPORT_SYMBOL(mm_ptov);
-EXPORT_SYMBOL(mm_end_of_chunk);
-#else
-EXPORT_SYMBOL(m68k_memoffset);
-#endif /* !CONFIG_SINGLE_MEMORY_CHUNK */
-EXPORT_SYMBOL(__ioremap);
-EXPORT_SYMBOL(iounmap);
-EXPORT_SYMBOL(kernel_set_cachemode);
-#endif /* !CONFIG_SUN3 */
-EXPORT_SYMBOL(m68k_debug_device);
-EXPORT_SYMBOL(mach_hwclk);
-EXPORT_SYMBOL(mach_get_ss);
-EXPORT_SYMBOL(mach_get_rtc_pll);
-EXPORT_SYMBOL(mach_set_rtc_pll);
-#ifdef CONFIG_INPUT_M68K_BEEP_MODULE
-EXPORT_SYMBOL(mach_beep);
-#endif
-EXPORT_SYMBOL(dump_fpu);
-EXPORT_SYMBOL(dump_thread);
-EXPORT_SYMBOL(strnlen);
-EXPORT_SYMBOL(strrchr);
-EXPORT_SYMBOL(strstr);
-EXPORT_SYMBOL(kernel_thread);
-#ifdef CONFIG_VME
-EXPORT_SYMBOL(vme_brdtype);
-#endif
 
 /* The following are special because they're not called
    explicitly (the C compiler generates them).  Fortunately,
index 45a46646c1b353eec5b565e835d99d16d8df5edc..99fc1226f7f804ed40cf875fca1118d78347e8ac 100644 (file)
@@ -187,6 +187,7 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
        set_fs (fs);
        return pid;
 }
+EXPORT_SYMBOL(kernel_thread);
 
 void flush_thread(void)
 {
@@ -221,13 +222,13 @@ asmlinkage int m68k_clone(struct pt_regs *regs)
 {
        unsigned long clone_flags;
        unsigned long newsp;
-       int *parent_tidptr, *child_tidptr;
+       int __user *parent_tidptr, *child_tidptr;
 
        /* syscall2 puts clone_flags in d1 and usp in d2 */
        clone_flags = regs->d1;
        newsp = regs->d2;
-       parent_tidptr = (int *)regs->d3;
-       child_tidptr = (int *)regs->d4;
+       parent_tidptr = (int __user *)regs->d3;
+       child_tidptr = (int __user *)regs->d4;
        if (!newsp)
                newsp = rdusp();
        return do_fork(clone_flags, newsp, regs, 0,
@@ -311,6 +312,7 @@ int dump_fpu (struct pt_regs *regs, struct user_m68kfp_struct *fpu)
                : "memory");
        return 1;
 }
+EXPORT_SYMBOL(dump_fpu);
 
 /*
  * fill in the user structure for a core dump..
@@ -357,11 +359,12 @@ void dump_thread(struct pt_regs * regs, struct user * dump)
        /* dump floating point stuff */
        dump->u_fpvalid = dump_fpu (regs, &dump->m68kfp);
 }
+EXPORT_SYMBOL(dump_thread);
 
 /*
  * sys_execve() executes a new program.
  */
-asmlinkage int sys_execve(char *name, char **argv, char **envp)
+asmlinkage int sys_execve(char __user *name, char __user * __user *argv, char __user * __user *envp)
 {
        int error;
        char * filename;
index f2d7ee0ee18cde7139051b2a5dc1868536721077..9af3ee0e555d7be8ace62282659b31831cf3642f 100644 (file)
 
 unsigned long m68k_machtype;
 unsigned long m68k_cputype;
+EXPORT_SYMBOL(m68k_machtype);
+EXPORT_SYMBOL(m68k_cputype);
 unsigned long m68k_fputype;
 unsigned long m68k_mmutype;
 #ifdef CONFIG_VME
 unsigned long vme_brdtype;
+EXPORT_SYMBOL(vme_brdtype);
 #endif
 
 int m68k_is040or060;
+EXPORT_SYMBOL(m68k_is040or060);
 
 extern int end;
 extern unsigned long availmem;
 
 int m68k_num_memory;
 int m68k_realnum_memory;
+EXPORT_SYMBOL(m68k_realnum_memory);
+#ifdef CONFIG_SINGLE_MEMORY_CHUNK
 unsigned long m68k_memoffset;
+EXPORT_SYMBOL(m68k_memoffset);
+#endif
 struct mem_info m68k_memory[NUM_MEMINFO];
+EXPORT_SYMBOL(m68k_memory);
 
 static struct mem_info m68k_ramdisk;
 
 static char m68k_command_line[CL_SIZE];
 
 char m68k_debug_device[6] = "";
+EXPORT_SYMBOL(m68k_debug_device);
 
-void (*mach_sched_init) (irqreturn_t (*handler)(int, void *, struct pt_regs *)) __initdata = NULL;
+void (*mach_sched_init) (irq_handler_t handler) __initdata = NULL;
 /* machine dependent irq functions */
 void (*mach_init_IRQ) (void) __initdata = NULL;
 void (*mach_get_model) (char *model);
@@ -72,10 +82,14 @@ int (*mach_get_hardware_list) (char *buffer);
 /* machine dependent timer functions */
 unsigned long (*mach_gettimeoffset) (void);
 int (*mach_hwclk) (int, struct rtc_time*);
+EXPORT_SYMBOL(mach_hwclk);
 int (*mach_set_clock_mmss) (unsigned long);
 unsigned int (*mach_get_ss)(void);
 int (*mach_get_rtc_pll)(struct rtc_pll_info *);
 int (*mach_set_rtc_pll)(struct rtc_pll_info *);
+EXPORT_SYMBOL(mach_get_ss);
+EXPORT_SYMBOL(mach_get_rtc_pll);
+EXPORT_SYMBOL(mach_set_rtc_pll);
 void (*mach_reset)( void );
 void (*mach_halt)( void );
 void (*mach_power_off)( void );
@@ -89,6 +103,7 @@ void (*mach_l2_flush) (int);
 #endif
 #if defined(CONFIG_INPUT_M68K_BEEP) || defined(CONFIG_INPUT_M68K_BEEP_MODULE)
 void (*mach_beep)(unsigned int, unsigned int);
+EXPORT_SYMBOL(mach_beep);
 #endif
 #if defined(CONFIG_ISA) && defined(MULTI_ISA)
 int isa_type;
index 28b2fefa4513b9c8e534c06f6c81294b55de838f..2a599c3ed7878322239737583dd0137399e19077 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <asm/machdep.h>
 #include <asm/io.h>
+#include <asm/irq_regs.h>
 
 #include <linux/time.h>
 #include <linux/timex.h>
@@ -37,13 +38,13 @@ static inline int set_rtc_mmss(unsigned long nowtime)
  * timer_interrupt() needs to keep up the real-time clock,
  * as well as call the "do_timer()" routine every clocktick
  */
-static irqreturn_t timer_interrupt(int irq, void *dummy, struct pt_regs * regs)
+static irqreturn_t timer_interrupt(int irq, void *dummy)
 {
        do_timer(1);
 #ifndef CONFIG_SMP
-       update_process_times(user_mode(regs));
+       update_process_times(user_mode(get_irq_regs()));
 #endif
-       profile_tick(CPU_PROFILING, regs);
+       profile_tick(CPU_PROFILING);
 
 #ifdef CONFIG_HEARTBEAT
        /* use power LED as a heartbeat instead -- much more useful
index 4569406a2e1f8d8855e8d9ae57ebd698c7ad9b1f..759fa244e6cd60cc5e226c486525e64b43aae190 100644 (file)
@@ -326,13 +326,13 @@ static inline int do_040writeback1(unsigned short wbs, unsigned long wba,
 
        switch (wbs & WBSIZ_040) {
        case BA_SIZE_BYTE:
-               res = put_user(wbd & 0xff, (char *)wba);
+               res = put_user(wbd & 0xff, (char __user *)wba);
                break;
        case BA_SIZE_WORD:
-               res = put_user(wbd & 0xffff, (short *)wba);
+               res = put_user(wbd & 0xffff, (short __user *)wba);
                break;
        case BA_SIZE_LONG:
-               res = put_user(wbd, (int *)wba);
+               res = put_user(wbd, (int __user *)wba);
                break;
        }
 
index b92b89e1ea0cf55466b58d76dec6343032c66ff1..891e1347bc4e4c1de3d0455d40905dce19992b08 100644 (file)
@@ -1,6 +1,19 @@
+/*
+ * 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.
+ */
+
+#define __IN_STRING_C
 
-#include <linux/types.h>
 #include <linux/module.h>
+#include <linux/string.h>
+
+char *strcpy(char *dest, const char *src)
+{
+       return __kernel_strcpy(dest, src);
+}
+EXPORT_SYMBOL(strcpy);
 
 void *memset(void *s, int c, size_t count)
 {
index 1bc188c0d983c55db9afbd52313444b73acb40b5..865f9fb9e6866a15cf1e18812be3dec3e229e918 100644 (file)
@@ -84,7 +84,7 @@ unsigned long __generic_copy_to_user(void __user *to, const void *from,
                "       .even\n"
                "20:    lsl.l   #2,%0\n"
                "50:    add.l   %5,%0\n"
-               "       jra     7b\n"
+               "       jra     8b\n"
                "       .previous\n"
                "\n"
                "       .section __ex_table,\"a\"\n"
index 6eaa881793d1064566b5dbdc65cba3a5c824aaec..a1c7ec70674192d510ddc3800b8dd1861ceb375b 100644 (file)
@@ -25,7 +25,7 @@
 int baboon_present,baboon_active;
 volatile struct baboon *baboon;
 
-irqreturn_t baboon_irq(int, void *, struct pt_regs *);
+irqreturn_t baboon_irq(int, void *);
 
 #if 0
 extern int macide_ack_intr(struct ata_channel *);
@@ -64,7 +64,7 @@ void __init baboon_register_interrupts(void)
  * Baboon interrupt handler. This works a lot like a VIA.
  */
 
-irqreturn_t baboon_irq(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t baboon_irq(int irq, void *dev_id)
 {
        int irq_bit,i;
        unsigned char events;
@@ -81,7 +81,7 @@ irqreturn_t baboon_irq(int irq, void *dev_id, struct pt_regs *regs)
        for (i = 0, irq_bit = 1 ; i < 3 ; i++, irq_bit <<= 1) {
                if (events & irq_bit/* & baboon_active*/) {
                        baboon_active &= ~irq_bit;
-                       m68k_handle_int(IRQ_BABOON_0 + i, regs);
+                       m68k_handle_int(IRQ_BABOON_0 + i);
                        baboon_active |= irq_bit;
                        baboon->mb_ifr &= ~irq_bit;
                }
index 85dda1095b1fbc42f3e301ccee3e2e45a7a56e82..562b38d00180f166f5ec100453d77f5c91ca9018 100644 (file)
@@ -72,7 +72,7 @@ extern int show_mac_interrupts(struct seq_file *, void *);
 extern void iop_preinit(void);
 extern void iop_init(void);
 extern void via_init(void);
-extern void via_init_clock(irqreturn_t (*func)(int, void *, struct pt_regs *));
+extern void via_init_clock(irq_handler_t func);
 extern void via_flush_cache(void);
 extern void oss_init(void);
 extern void psc_init(void);
@@ -88,7 +88,7 @@ extern void mac_debugging_long(int, long);
 
 static void mac_get_model(char *str);
 
-static void mac_sched_init(irqreturn_t (*vector)(int, void *, struct pt_regs *))
+static void mac_sched_init(irq_handler_t vector)
 {
        via_init_clock(vector);
 }
index bc657b1057a7cc30d560c80912102e57c1e2a50c..0cea21f581926b07241e35ce621d1a6fc2b685fa 100644 (file)
@@ -132,7 +132,7 @@ static int iop_get_proc_info(char *, char **, off_t, int);
 
 struct listener {
        const char *devname;
-       void (*handler)(struct iop_msg *, struct pt_regs *);
+       void (*handler)(struct iop_msg *);
 };
 
 /*
@@ -152,7 +152,7 @@ static struct iop_msg iop_msg_pool[NUM_IOP_MSGS];
 static struct iop_msg *iop_send_queue[NUM_IOPS][NUM_IOP_CHAN];
 static struct listener iop_listeners[NUM_IOPS][NUM_IOP_CHAN];
 
-irqreturn_t iop_ism_irq(int, void *, struct pt_regs *);
+irqreturn_t iop_ism_irq(int, void *);
 
 extern void oss_irq_enable(int);
 
@@ -342,7 +342,7 @@ void __init iop_register_interrupts(void)
  */
 
 int iop_listen(uint iop_num, uint chan,
-               void (*handler)(struct iop_msg *, struct pt_regs *),
+               void (*handler)(struct iop_msg *),
                const char *devname)
 {
        if ((iop_num >= NUM_IOPS) || !iop_base[iop_num]) return -EINVAL;
@@ -407,7 +407,7 @@ static void iop_do_send(struct iop_msg *msg)
  * has gone into the IOP_MSG_COMPLETE state.
  */
 
-static void iop_handle_send(uint iop_num, uint chan, struct pt_regs *regs)
+static void iop_handle_send(uint iop_num, uint chan)
 {
        volatile struct mac_iop *iop = iop_base[iop_num];
        struct iop_msg *msg,*msg2;
@@ -426,7 +426,7 @@ static void iop_handle_send(uint iop_num, uint chan, struct pt_regs *regs)
        for (i = 0 ; i < IOP_MSG_LEN ; i++, offset++) {
                msg->reply[i] = iop_readb(iop, offset);
        }
-       if (msg->handler) (*msg->handler)(msg, regs);
+       if (msg->handler) (*msg->handler)(msg);
        msg2 = msg;
        msg = msg->next;
        iop_free_msg(msg2);
@@ -440,7 +440,7 @@ static void iop_handle_send(uint iop_num, uint chan, struct pt_regs *regs)
  * gone into the IOP_MSG_NEW state.
  */
 
-static void iop_handle_recv(uint iop_num, uint chan, struct pt_regs *regs)
+static void iop_handle_recv(uint iop_num, uint chan)
 {
        volatile struct mac_iop *iop = iop_base[iop_num];
        int i,offset;
@@ -468,7 +468,7 @@ static void iop_handle_recv(uint iop_num, uint chan, struct pt_regs *regs)
        /* the message ourselves to avoid possible stalls.         */
 
        if (msg->handler) {
-               (*msg->handler)(msg, regs);
+               (*msg->handler)(msg);
        } else {
 #ifdef DEBUG_IOP
                printk("iop_handle_recv: unclaimed message on iop %d channel %d\n", iop_num, chan);
@@ -492,7 +492,7 @@ static void iop_handle_recv(uint iop_num, uint chan, struct pt_regs *regs)
 
 int iop_send_message(uint iop_num, uint chan, void *privdata,
                      uint msg_len, __u8 *msg_data,
-                     void (*handler)(struct iop_msg *, struct pt_regs *))
+                     void (*handler)(struct iop_msg *))
 {
        struct iop_msg *msg, *q;
 
@@ -584,7 +584,7 @@ __u8 *iop_compare_code(uint iop_num, __u8 *code_start,
  * Handle an ISM IOP interrupt
  */
 
-irqreturn_t iop_ism_irq(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t iop_ism_irq(int irq, void *dev_id)
 {
        uint iop_num = (uint) dev_id;
        volatile struct mac_iop *iop = iop_base[iop_num];
@@ -608,7 +608,7 @@ irqreturn_t iop_ism_irq(int irq, void *dev_id, struct pt_regs *regs)
                        printk(" %02X", state);
 #endif
                        if (state == IOP_MSG_COMPLETE) {
-                               iop_handle_send(iop_num, i, regs);
+                               iop_handle_send(iop_num, i);
                        }
                }
 #ifdef DEBUG_IOP
@@ -628,7 +628,7 @@ irqreturn_t iop_ism_irq(int irq, void *dev_id, struct pt_regs *regs)
                        printk(" %02X", state);
 #endif
                        if (state == IOP_MSG_NEW) {
-                               iop_handle_recv(iop_num, i, regs);
+                               iop_handle_recv(iop_num, i);
                        }
                }
 #ifdef DEBUG_IOP
index 694b14bb0de1e7796fa28da75033c62a7d8531ac..f6fcd754d8f67ec6bcf6fb6de63580d1461b6ec1 100644 (file)
 #include <asm/hwtest.h>
 #include <asm/errno.h>
 #include <asm/macints.h>
+#include <asm/irq_regs.h>
 
 #define DEBUG_SPURIOUS
 #define SHUTUP_SONIC
@@ -208,8 +209,8 @@ static void scc_irq_disable(unsigned int);
  * console_loglevel determines NMI handler function
  */
 
-irqreturn_t mac_nmi_handler(int, void *, struct pt_regs *);
-irqreturn_t mac_debug_handler(int, void *, struct pt_regs *);
+irqreturn_t mac_nmi_handler(int, void *);
+irqreturn_t mac_debug_handler(int, void *);
 
 /* #define DEBUG_MACINTS */
 
@@ -393,7 +394,7 @@ int mac_irq_pending(unsigned int irq)
 
 static int num_debug[8];
 
-irqreturn_t mac_debug_handler(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t mac_debug_handler(int irq, void *dev_id)
 {
        if (num_debug[irq] < 10) {
                printk("DEBUG: Unexpected IRQ %d\n", irq);
@@ -405,7 +406,7 @@ irqreturn_t mac_debug_handler(int irq, void *dev_id, struct pt_regs *regs)
 static int in_nmi;
 static volatile int nmi_hold;
 
-irqreturn_t mac_nmi_handler(int irq, void *dev_id, struct pt_regs *fp)
+irqreturn_t mac_nmi_handler(int irq, void *dev_id)
 {
        int i;
        /*
@@ -432,6 +433,7 @@ irqreturn_t mac_nmi_handler(int irq, void *dev_id, struct pt_regs *fp)
 
        if (console_loglevel >= 8) {
 #if 0
+               struct pt_regs *fp = get_irq_regs();
                show_state();
                printk("PC: %08lx\nSR: %04x  SP: %p\n", fp->pc, fp->sr, fp);
                printk("d0: %08lx    d1: %08lx    d2: %08lx    d3: %08lx\n",
@@ -479,7 +481,7 @@ static void scc_irq_disable(unsigned int irq)
  * here is cleaner than hacking it into drivers/char/macserial.c.
  */
 
-void mac_scc_dispatch(int irq, void *dev_id, struct pt_regs *regs)
+void mac_scc_dispatch(int irq, void *dev_id)
 {
        volatile unsigned char *scc = (unsigned char *) mac_bi_data.sccbase + 2;
        unsigned char reg;
@@ -504,7 +506,7 @@ void mac_scc_dispatch(int irq, void *dev_id, struct pt_regs *regs)
        /* pretty much kill the system.                 */
 
        if (reg & 0x38)
-               m68k_handle_int(IRQ_SCCA, regs);
+               m68k_handle_int(IRQ_SCCA);
        if (reg & 0x07)
-               m68k_handle_int(IRQ_SCCB, regs);
+               m68k_handle_int(IRQ_SCCB);
 }
index 63e04365191fe92ced06092ab496290a1d78bf3a..63690819565a317fc31b0c2ffc06ec95b9170d17 100644 (file)
 int oss_present;
 volatile struct mac_oss *oss;
 
-irqreturn_t oss_irq(int, void *, struct pt_regs *);
-irqreturn_t oss_nubus_irq(int, void *, struct pt_regs *);
+irqreturn_t oss_irq(int, void *);
+irqreturn_t oss_nubus_irq(int, void *);
 
-extern irqreturn_t via1_irq(int, void *, struct pt_regs *);
-extern irqreturn_t mac_scc_dispatch(int, void *, struct pt_regs *);
+extern irqreturn_t via1_irq(int, void *);
+extern irqreturn_t mac_scc_dispatch(int, void *);
 
 /*
  * Initialize the OSS
@@ -92,7 +92,7 @@ void __init oss_nubus_init(void)
  * and SCSI; everything else is routed to its own autovector IRQ.
  */
 
-irqreturn_t oss_irq(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t oss_irq(int irq, void *dev_id)
 {
        int events;
 
@@ -113,7 +113,7 @@ irqreturn_t oss_irq(int irq, void *dev_id, struct pt_regs *regs)
                oss->irq_pending &= ~OSS_IP_SOUND;
        } else if (events & OSS_IP_SCSI) {
                oss->irq_level[OSS_SCSI] = OSS_IRQLEV_DISABLED;
-               m68k_handle_int(IRQ_MAC_SCSI, regs);
+               m68k_handle_int(IRQ_MAC_SCSI);
                oss->irq_pending &= ~OSS_IP_SCSI;
                oss->irq_level[OSS_SCSI] = OSS_IRQLEV_SCSI;
        } else {
@@ -128,7 +128,7 @@ irqreturn_t oss_irq(int irq, void *dev_id, struct pt_regs *regs)
  * Unlike the VIA/RBV this is on its own autovector interrupt level.
  */
 
-irqreturn_t oss_nubus_irq(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t oss_nubus_irq(int irq, void *dev_id)
 {
        int events, irq_bit, i;
 
@@ -146,7 +146,7 @@ irqreturn_t oss_nubus_irq(int irq, void *dev_id, struct pt_regs *regs)
        for (i = 0, irq_bit = 1 ; i < 6 ; i++, irq_bit <<= 1) {
                if (events & irq_bit) {
                        oss->irq_level[i] = OSS_IRQLEV_DISABLED;
-                       m68k_handle_int(NUBUS_SOURCE_BASE + i, regs);
+                       m68k_handle_int(NUBUS_SOURCE_BASE + i);
                        oss->irq_pending &= ~irq_bit;
                        oss->irq_level[i] = OSS_IRQLEV_NUBUS;
                }
index e262180917552db70ae05f55221a1f7028ec25ea..15378a5878c94925f1cf88cb2556b58ee150ad14 100644 (file)
@@ -30,7 +30,7 @@
 int psc_present;
 volatile __u8 *psc;
 
-irqreturn_t psc_irq(int, void *, struct pt_regs *);
+irqreturn_t psc_irq(int, void *);
 
 /*
  * Debugging dump, used in various places to see what's going on.
@@ -127,7 +127,7 @@ void __init psc_register_interrupts(void)
  * PSC interrupt handler. It's a lot like the VIA interrupt handler.
  */
 
-irqreturn_t psc_irq(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t psc_irq(int irq, void *dev_id)
 {
        int pIFR        = pIFRbase + ((int) dev_id);
        int pIER        = pIERbase + ((int) dev_id);
@@ -149,7 +149,7 @@ irqreturn_t psc_irq(int irq, void *dev_id, struct pt_regs *regs)
        for (i = 0, irq_bit = 1 ; i < 4 ; i++, irq_bit <<= 1) {
                if (events & irq_bit) {
                        psc_write_byte(pIER, irq_bit);
-                       m68k_handle_int(base_irq + i, regs);
+                       m68k_handle_int(base_irq + i);
                        psc_write_byte(pIFR, irq_bit);
                        psc_write_byte(pIER, irq_bit | 0x80);
                }
index c4aa345d544e6127c27ab41953bf8b940d6aa9ac..e27735be29244212d9547711481edcc6aba32d56 100644 (file)
@@ -63,14 +63,14 @@ static int gIER,gIFR,gBufA,gBufB;
 static int  nubus_active;
 
 void via_debug_dump(void);
-irqreturn_t via1_irq(int, void *, struct pt_regs *);
-irqreturn_t via2_irq(int, void *, struct pt_regs *);
-irqreturn_t via_nubus_irq(int, void *, struct pt_regs *);
+irqreturn_t via1_irq(int, void *);
+irqreturn_t via2_irq(int, void *);
+irqreturn_t via_nubus_irq(int, void *);
 void via_irq_enable(int irq);
 void via_irq_disable(int irq);
 void via_irq_clear(int irq);
 
-extern irqreturn_t mac_scc_dispatch(int, void *, struct pt_regs *);
+extern irqreturn_t mac_scc_dispatch(int, void *);
 extern int oss_present;
 
 /*
@@ -235,7 +235,7 @@ void __init via_init(void)
  * Start the 100 Hz clock
  */
 
-void __init via_init_clock(irqreturn_t (*func)(int, void *, struct pt_regs *))
+void __init via_init_clock(irq_handler_t func)
 {
        via1[vACR] |= 0x40;
        via1[vT1LL] = MAC_CLOCK_LOW;
@@ -412,7 +412,7 @@ void __init via_nubus_init(void)
  * the machspec interrupt number after clearing the interrupt.
  */
 
-irqreturn_t via1_irq(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t via1_irq(int irq, void *dev_id)
 {
        int irq_bit, i;
        unsigned char events, mask;
@@ -424,7 +424,7 @@ irqreturn_t via1_irq(int irq, void *dev_id, struct pt_regs *regs)
        for (i = 0, irq_bit = 1 ; i < 7 ; i++, irq_bit <<= 1)
                if (events & irq_bit) {
                        via1[vIER] = irq_bit;
-                       m68k_handle_int(VIA1_SOURCE_BASE + i, regs);
+                       m68k_handle_int(VIA1_SOURCE_BASE + i);
                        via1[vIFR] = irq_bit;
                        via1[vIER] = irq_bit | 0x80;
                }
@@ -439,14 +439,14 @@ irqreturn_t via1_irq(int irq, void *dev_id, struct pt_regs *regs)
                /* No, it won't be set. that's why we're doing this. */
                via_irq_disable(IRQ_MAC_NUBUS);
                via_irq_clear(IRQ_MAC_NUBUS);
-               m68k_handle_int(IRQ_MAC_NUBUS, regs);
+               m68k_handle_int(IRQ_MAC_NUBUS);
                via_irq_enable(IRQ_MAC_NUBUS);
        }
 #endif
        return IRQ_HANDLED;
 }
 
-irqreturn_t via2_irq(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t via2_irq(int irq, void *dev_id)
 {
        int irq_bit, i;
        unsigned char events, mask;
@@ -459,7 +459,7 @@ irqreturn_t via2_irq(int irq, void *dev_id, struct pt_regs *regs)
                if (events & irq_bit) {
                        via2[gIER] = irq_bit;
                        via2[gIFR] = irq_bit | rbv_clear;
-                       m68k_handle_int(VIA2_SOURCE_BASE + i, regs);
+                       m68k_handle_int(VIA2_SOURCE_BASE + i);
                        via2[gIER] = irq_bit | 0x80;
                }
        return IRQ_HANDLED;
@@ -470,7 +470,7 @@ irqreturn_t via2_irq(int irq, void *dev_id, struct pt_regs *regs)
  * VIA2 dispatcher as a fast interrupt handler.
  */
 
-irqreturn_t via_nubus_irq(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t via_nubus_irq(int irq, void *dev_id)
 {
        int irq_bit, i;
        unsigned char events;
@@ -481,7 +481,7 @@ irqreturn_t via_nubus_irq(int irq, void *dev_id, struct pt_regs *regs)
        for (i = 0, irq_bit = 1 ; i < 7 ; i++, irq_bit <<= 1) {
                if (events & irq_bit) {
                        via_irq_disable(NUBUS_SOURCE_BASE + i);
-                       m68k_handle_int(NUBUS_SOURCE_BASE + i, regs);
+                       m68k_handle_int(NUBUS_SOURCE_BASE + i);
                        via_irq_enable(NUBUS_SOURCE_BASE + i);
                }
        }
index f46f049d29ff34542acf24257a64809f728f9c26..b54ef1726c557f827665ae3055eb2c1f8868c2c7 100644 (file)
@@ -7,6 +7,7 @@
  *          used by other architectures                /Roman Zippel
  */
 
+#include <linux/module.h>
 #include <linux/mm.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
@@ -219,6 +220,7 @@ void __iomem *__ioremap(unsigned long physaddr, unsigned long size, int cachefla
 
        return (void __iomem *)retaddr;
 }
+EXPORT_SYMBOL(__ioremap);
 
 /*
  * Unmap a ioremap()ed region again
@@ -234,6 +236,7 @@ void iounmap(void __iomem *addr)
        free_io_area((__force void *)addr);
 #endif
 }
+EXPORT_SYMBOL(iounmap);
 
 /*
  * __iounmap unmaps nearly everything, so be careful
@@ -360,3 +363,4 @@ void kernel_set_cachemode(void *addr, unsigned long size, int cmode)
 
        flush_tlb_all();
 }
+EXPORT_SYMBOL(kernel_set_cachemode);
index a0c095e17222df5c48c56279d7181d11b4e4e000..0f88812822b1315f83585600bef314921edab9da 100644 (file)
@@ -4,6 +4,7 @@
  *  Copyright (C) 1995  Hamish Macdonald
  */
 
+#include <linux/module.h>
 #include <linux/mm.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
@@ -157,9 +158,8 @@ unsigned long mm_vtop(unsigned long vaddr)
 
        return -1;
 }
-#endif
+EXPORT_SYMBOL(mm_vtop);
 
-#ifndef CONFIG_SINGLE_MEMORY_CHUNK
 unsigned long mm_ptov (unsigned long paddr)
 {
        int i = 0;
@@ -185,6 +185,7 @@ unsigned long mm_ptov (unsigned long paddr)
 #endif
        return -1;
 }
+EXPORT_SYMBOL(mm_ptov);
 #endif
 
 /* invalidate page in both caches */
@@ -298,6 +299,7 @@ void cache_clear (unsigned long paddr, int len)
        mach_l2_flush(0);
 #endif
 }
+EXPORT_SYMBOL(cache_clear);    /* probably can be unexported */
 
 
 /*
@@ -350,6 +352,7 @@ void cache_push (unsigned long paddr, int len)
        mach_l2_flush(1);
 #endif
 }
+EXPORT_SYMBOL(cache_push);     /* probably can be unexported */
 
 #ifndef CONFIG_SINGLE_MEMORY_CHUNK
 int mm_end_of_chunk (unsigned long addr, int len)
@@ -361,4 +364,5 @@ int mm_end_of_chunk (unsigned long addr, int len)
                        return 1;
        return 0;
 }
+EXPORT_SYMBOL(mm_end_of_chunk);
 #endif
index 7f0d86f3fe73a245e7773bb4370684881686b554..1af24cb5bfe136b4f8e18337ad72d8609bc4e755 100644 (file)
@@ -8,6 +8,7 @@
  * for more details.
  */
 
+#include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
@@ -59,7 +60,7 @@ static inline void do_pmeg_mapin(unsigned long phys, unsigned long virt,
        }
 }
 
-void *sun3_ioremap(unsigned long phys, unsigned long size,
+void __iomem *sun3_ioremap(unsigned long phys, unsigned long size,
                   unsigned long type)
 {
        struct vm_struct *area;
@@ -101,22 +102,24 @@ void *sun3_ioremap(unsigned long phys, unsigned long size,
                virt += seg_pages * PAGE_SIZE;
        }
 
-       return (void *)ret;
+       return (void __iomem *)ret;
 
 }
 
 
-void *__ioremap(unsigned long phys, unsigned long size, int cache)
+void __iomem *__ioremap(unsigned long phys, unsigned long size, int cache)
 {
 
        return sun3_ioremap(phys, size, SUN3_PAGE_TYPE_IO);
 
 }
+EXPORT_SYMBOL(__ioremap);
 
-void iounmap(void *addr)
+void iounmap(void __iomem *addr)
 {
        vfree((void *)(PAGE_MASK & (unsigned long)addr));
 }
+EXPORT_SYMBOL(iounmap);
 
 /* sun3_map_test(addr, val) -- Reads a byte from addr, storing to val,
  * trapping the potential read fault.  Returns 0 if the access faulted,
index 0cd0e5bddceece3f4b5423839d5f50da80526f27..4a7df9c3f85a533339350dd48669e09e80be6e9f 100644 (file)
@@ -38,7 +38,7 @@
 
 static void mvme147_get_model(char *model);
 static int  mvme147_get_hardware_list(char *buffer);
-extern void mvme147_sched_init(irqreturn_t (*handler)(int, void *, struct pt_regs *));
+extern void mvme147_sched_init(irq_handler_t handler);
 extern unsigned long mvme147_gettimeoffset (void);
 extern int mvme147_hwclk (int, struct rtc_time *);
 extern int mvme147_set_clock_mmss (unsigned long);
@@ -51,7 +51,7 @@ static int bcd2int (unsigned char b);
 /* Save tick handler routine pointer, will point to do_timer() in
  * kernel/sched.c, called via mvme147_process_int() */
 
-irqreturn_t (*tick_handler)(int, void *, struct pt_regs *);
+irq_handler_t tick_handler;
 
 
 int mvme147_parse_bootinfo(const struct bi_record *bi)
@@ -114,15 +114,15 @@ void __init config_mvme147(void)
 
 /* Using pcc tick timer 1 */
 
-static irqreturn_t mvme147_timer_int (int irq, void *dev_id, struct pt_regs *fp)
+static irqreturn_t mvme147_timer_int (int irq, void *dev_id)
 {
        m147_pcc->t1_int_cntrl = PCC_TIMER_INT_CLR;
        m147_pcc->t1_int_cntrl = PCC_INT_ENAB|PCC_LEVEL_TIMER1;
-       return tick_handler(irq, dev_id, fp);
+       return tick_handler(irq, dev_id);
 }
 
 
-void mvme147_sched_init (irqreturn_t (*timer_routine)(int, void *, struct pt_regs *))
+void mvme147_sched_init (irq_handler_t timer_routine)
 {
        tick_handler = timer_routine;
        request_irq (PCC_IRQ_TIMER1, mvme147_timer_int,
index ce2727ed1bc05d64c37059fd67e49873aa534143..c829ebb6b1af8510f380801138d6207f2d52c904 100644 (file)
@@ -42,7 +42,7 @@ static MK48T08ptr_t volatile rtc = (MK48T08ptr_t)MVME_RTC_BASE;
 
 static void mvme16x_get_model(char *model);
 static int  mvme16x_get_hardware_list(char *buffer);
-extern void mvme16x_sched_init(irqreturn_t (*handler)(int, void *, struct pt_regs *));
+extern void mvme16x_sched_init(irq_handler_t handler);
 extern unsigned long mvme16x_gettimeoffset (void);
 extern int mvme16x_hwclk (int, struct rtc_time *);
 extern int mvme16x_set_clock_mmss (unsigned long);
@@ -54,7 +54,7 @@ int bcd2int (unsigned char b);
 /* Save tick handler routine pointer, will point to do_timer() in
  * kernel/sched.c, called via mvme16x_process_int() */
 
-static irqreturn_t (*tick_handler)(int, void *, struct pt_regs *);
+static irq_handler_t tick_handler;
 
 
 unsigned short mvme16x_config;
@@ -190,7 +190,7 @@ void __init config_mvme16x(void)
     }
 }
 
-static irqreturn_t mvme16x_abort_int (int irq, void *dev_id, struct pt_regs *fp)
+static irqreturn_t mvme16x_abort_int (int irq, void *dev_id)
 {
        p_bdid p = &mvme_bdid;
        unsigned long *new = (unsigned long *)vectors;
@@ -218,13 +218,13 @@ static irqreturn_t mvme16x_abort_int (int irq, void *dev_id, struct pt_regs *fp)
        return IRQ_HANDLED;
 }
 
-static irqreturn_t mvme16x_timer_int (int irq, void *dev_id, struct pt_regs *fp)
+static irqreturn_t mvme16x_timer_int (int irq, void *dev_id)
 {
     *(volatile unsigned char *)0xfff4201b |= 8;
-    return tick_handler(irq, dev_id, fp);
+    return tick_handler(irq, dev_id);
 }
 
-void mvme16x_sched_init (irqreturn_t (*timer_routine)(int, void *, struct pt_regs *))
+void mvme16x_sched_init (irq_handler_t timer_routine)
 {
     p_bdid p = &mvme_bdid;
     int irq;
index 9a1827876408eac1f0c8f369e6890f3066855c33..92f873cc7060f905f8b7c49fb7e95457018065c9 100644 (file)
@@ -39,7 +39,7 @@ extern irqreturn_t q40_process_int (int level, struct pt_regs *regs);
 extern void q40_init_IRQ (void);
 static void q40_get_model(char *model);
 static int  q40_get_hardware_list(char *buffer);
-extern void q40_sched_init(irqreturn_t (*handler)(int, void *, struct pt_regs *));
+extern void q40_sched_init(irq_handler_t handler);
 
 extern unsigned long q40_gettimeoffset (void);
 extern int q40_hwclk (int, struct rtc_time *);
index 472f41c4158b4bef12c46bac7d0e01c88d7f7cb4..31cc07d8cec4dc203240caea1ecc712308b29bdb 100644 (file)
@@ -125,9 +125,9 @@ void q40_mksound(unsigned int hz, unsigned int ticks)
        sound_ticks = ticks << 1;
 }
 
-static irqreturn_t (*q40_timer_routine)(int, void *, struct pt_regs *);
+static irq_handler_t q40_timer_routine;
 
-static irqreturn_t q40_timer_int (int irq, void * dev, struct pt_regs * regs)
+static irqreturn_t q40_timer_int (int irq, void * dev)
 {
        ql_ticks = ql_ticks ? 0 : 1;
        if (sound_ticks) {
@@ -138,11 +138,11 @@ static irqreturn_t q40_timer_int (int irq, void * dev, struct pt_regs * regs)
        }
 
        if (!ql_ticks)
-               q40_timer_routine(irq, dev, regs);
+               q40_timer_routine(irq, dev);
        return IRQ_HANDLED;
 }
 
-void q40_sched_init (irqreturn_t (*timer_routine)(int, void *, struct pt_regs *))
+void q40_sched_init (irq_handler_t timer_routine)
 {
        int timer_irq;
 
@@ -218,11 +218,11 @@ static void q40_irq_handler(unsigned int irq, struct pt_regs *fp)
        switch (irq) {
        case 4:
        case 6:
-               m68k_handle_int(Q40_IRQ_SAMPLE, fp);
+               __m68k_handle_int(Q40_IRQ_SAMPLE, fp);
                return;
        }
        if (mir & Q40_IRQ_FRAME_MASK) {
-               m68k_handle_int(Q40_IRQ_FRAME, fp);
+               __m68k_handle_int(Q40_IRQ_FRAME, fp);
                master_outb(-1, FRAME_CLEAR_REG);
        }
        if ((mir & Q40_IRQ_SER_MASK) || (mir & Q40_IRQ_EXT_MASK)) {
@@ -257,7 +257,7 @@ static void q40_irq_handler(unsigned int irq, struct pt_regs *fp)
                                        goto iirq;
                                }
                                q40_state[irq] |= IRQ_INPROGRESS;
-                               m68k_handle_int(irq, fp);
+                               __m68k_handle_int(irq, fp);
                                q40_state[irq] &= ~IRQ_INPROGRESS;
 
                                /* naively enable everything, if that fails than    */
@@ -288,7 +288,7 @@ static void q40_irq_handler(unsigned int irq, struct pt_regs *fp)
        mir = master_inb(IIRQ_REG);
        /* should test whether keyboard irq is really enabled, doing it in defhand */
        if (mir & Q40_IRQ_KEYB_MASK)
-               m68k_handle_int(Q40_IRQ_KEYBOARD, fp);
+               __m68k_handle_int(Q40_IRQ_KEYBOARD, fp);
 
        return;
 }
index 4d4f0695d985bb92c60e053131821d0e32d7ccf4..be1a8470d63685b4742dbe1d913ffcf8ecdffbfd 100644 (file)
@@ -2,6 +2,6 @@
 # Makefile for Linux arch/m68k/sun3 source directory
 #
 
-obj-y  := sun3_ksyms.o sun3ints.o sun3dvma.o sbus.o idprom.o
+obj-y  := sun3ints.o sun3dvma.o sbus.o idprom.o
 
 obj-$(CONFIG_SUN3) += config.o mmu_emu.o leds.o dvma.o intersil.o
index d09d03b3d956ec75560fa733dfaa4e0733e7ac2c..4851b8437a87f69d1d6ab9659d534819d367aca7 100644 (file)
@@ -35,7 +35,7 @@ extern char _text, _end;
 char sun3_reserved_pmeg[SUN3_PMEGS_NUM];
 
 extern unsigned long sun3_gettimeoffset(void);
-extern void sun3_sched_init(irqreturn_t (*handler)(int, void *, struct pt_regs *));
+extern void sun3_sched_init(irq_handler_t handler);
 extern void sun3_get_model (char* model);
 extern void idprom_init (void);
 extern int sun3_hwclk(int set, struct rtc_time *t);
@@ -162,7 +162,7 @@ void __init config_sun3(void)
        sun3_bootmem_alloc(memory_start, memory_end);
 }
 
-void __init sun3_sched_init(irqreturn_t (*timer_routine)(int, void *, struct pt_regs *))
+void __init sun3_sched_init(irq_handler_t timer_routine)
 {
        sun3_disable_interrupts();
         intersil_clock->cmd_reg=(INTERSIL_RUN|INTERSIL_INT_DISABLE|INTERSIL_24H_MODE);
index 02c1fee6fe744a359b84f3f0967d836d46b78061..dca6ab6a4ede9ac13c31a46d3a7e1bae46a576a7 100644 (file)
@@ -6,6 +6,7 @@
  * Sun3/3x models added by David Monro (davidm@psrg.cs.usyd.edu.au)
  */
 
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/init.h>
@@ -16,6 +17,8 @@
 #include <asm/machines.h>  /* Fun with Sun released architectures. */
 
 struct idprom *idprom;
+EXPORT_SYMBOL(idprom);
+
 static struct idprom idprom_buffer;
 
 /* Here is the master table of Sun machines which use some implementation
diff --git a/arch/m68k/sun3/sun3_ksyms.c b/arch/m68k/sun3/sun3_ksyms.c
deleted file mode 100644 (file)
index 43e5a9a..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-#include <linux/module.h>
-#include <linux/types.h>
-#include <asm/dvma.h>
-#include <asm/idprom.h>
-
-/*
- * Add things here when you find the need for it.
- */
-EXPORT_SYMBOL(dvma_map_align);
-EXPORT_SYMBOL(dvma_unmap);
-EXPORT_SYMBOL(dvma_malloc_align);
-EXPORT_SYMBOL(dvma_free);
-EXPORT_SYMBOL(idprom);
index a2bc2da7f8f0ceba005c7a43a8344d59da4cb78c..8709677fa0255aa03dbe512e8e558c224f546f81 100644 (file)
@@ -6,6 +6,7 @@
  * Contains common routines for sun3/sun3x DVMA management.
  */
 
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/list.h>
@@ -312,6 +313,7 @@ inline unsigned long dvma_map_align(unsigned long kaddr, int len, int align)
        BUG();
        return 0;
 }
+EXPORT_SYMBOL(dvma_map_align);
 
 void dvma_unmap(void *baddr)
 {
@@ -327,7 +329,7 @@ void dvma_unmap(void *baddr)
        return;
 
 }
-
+EXPORT_SYMBOL(dvma_unmap);
 
 void *dvma_malloc_align(unsigned long len, unsigned long align)
 {
@@ -367,6 +369,7 @@ void *dvma_malloc_align(unsigned long len, unsigned long align)
        return (void *)vaddr;
 
 }
+EXPORT_SYMBOL(dvma_malloc_align);
 
 void dvma_free(void *vaddr)
 {
@@ -374,3 +377,4 @@ void dvma_free(void *vaddr)
        return;
 
 }
+EXPORT_SYMBOL(dvma_free);
index dc4ea7e074a620e21e500b66b75ab10c21a31965..baf74e8de8b5ce1b7790731955b9ee713540ab29 100644 (file)
@@ -15,6 +15,7 @@
 #include <asm/intersil.h>
 #include <asm/oplib.h>
 #include <asm/sun3ints.h>
+#include <asm/irq_regs.h>
 #include <linux/seq_file.h>
 
 extern void sun3_leds (unsigned char);
@@ -48,7 +49,7 @@ void sun3_disable_irq(unsigned int irq)
        *sun3_intreg &= ~(1 << irq);
 }
 
-static irqreturn_t sun3_int7(int irq, void *dev_id, struct pt_regs *fp)
+static irqreturn_t sun3_int7(int irq, void *dev_id)
 {
        *sun3_intreg |=  (1 << irq);
        if (!(kstat_cpu(0).irqs[irq] % 2000))
@@ -56,7 +57,7 @@ static irqreturn_t sun3_int7(int irq, void *dev_id, struct pt_regs *fp)
        return IRQ_HANDLED;
 }
 
-static irqreturn_t sun3_int5(int irq, void *dev_id, struct pt_regs *fp)
+static irqreturn_t sun3_int5(int irq, void *dev_id)
 {
 #ifdef CONFIG_SUN3
        intersil_clear();
@@ -67,14 +68,14 @@ static irqreturn_t sun3_int5(int irq, void *dev_id, struct pt_regs *fp)
 #endif
         do_timer(1);
 #ifndef CONFIG_SMP
-       update_process_times(user_mode(fp));
+       update_process_times(user_mode(get_irq_regs()));
 #endif
         if (!(kstat_cpu(0).irqs[irq] % 20))
                 sun3_leds(led_pattern[(kstat_cpu(0).irqs[irq] % 160) / 20]);
        return IRQ_HANDLED;
 }
 
-static irqreturn_t sun3_vec255(int irq, void *dev_id, struct pt_regs *fp)
+static irqreturn_t sun3_vec255(int irq, void *dev_id)
 {
 //     intersil_clear();
        return IRQ_HANDLED;
@@ -84,7 +85,7 @@ static void sun3_inthandle(unsigned int irq, struct pt_regs *fp)
 {
         *sun3_intreg &= ~(1 << irq);
 
-       m68k_handle_int(irq, fp);
+       __m68k_handle_int(irq, fp);
 }
 
 static struct irq_controller sun3_irq_controller = {
index 6f4204fbecd7d4a36a6cb68faced42762389e84d..f5eaafb00d218ce9519545b3ddb1c2600bac9532 100644 (file)
@@ -90,7 +90,7 @@ static void sun3x_timer_tick(int irq, void *dev_id, struct pt_regs *regs)
 }
 #endif
 
-void __init sun3x_sched_init(irqreturn_t (*vector)(int, void *, struct pt_regs *))
+void __init sun3x_sched_init(irq_handler_t vector)
 {
 
        sun3_disable_interrupts();
index e7e43b4ec4a12f8000a3a14420befdbe1164dbd3..6909e1297534a17e810dd216cdbd2f4a31465601 100644 (file)
@@ -3,7 +3,7 @@
 
 extern int sun3x_hwclk(int set, struct rtc_time *t);
 unsigned long sun3x_gettimeoffset (void);
-void sun3x_sched_init(irqreturn_t (*vector)(int, void *, struct pt_regs *));
+void sun3x_sched_init(irq_handler_t vector);
 
 struct mostek_dt {
        volatile unsigned char csr;
index 617e43ec95ae48eb6e89dd44f64df34392dcabe3..4603f4f3c935f282b88d0f487775fd9112ba4ee6 100644 (file)
@@ -296,10 +296,39 @@ ENTRY(sys_call_table)
        .long sys_mq_notify     /* 275 */
        .long sys_mq_getsetattr
        .long sys_waitid
-       .long sys_ni_syscall    /* sys_setaltroot */
-       .long sys_ni_syscall    /* sys_add_key */
-       .long sys_ni_syscall    /* 280 */ /* sys_request_key */
-       .long sys_ni_syscall    /* sys_keyctl */
+       .long sys_ni_syscall    /* for sys_vserver */
+       .long sys_add_key
+       .long sys_request_key   /* 280 */
+       .long sys_keyctl
+       .long sys_ioprio_set
+       .long sys_ioprio_get
+       .long sys_inotify_init
+       .long sys_inotify_add_watch     /* 285 */
+       .long sys_inotify_rm_watch
+       .long sys_migrate_pages
+       .long sys_openat
+       .long sys_mkdirat
+       .long sys_mknodat               /* 290 */
+       .long sys_fchownat
+       .long sys_futimesat
+       .long sys_fstatat64
+       .long sys_unlinkat
+       .long sys_renameat              /* 295 */
+       .long sys_linkat
+       .long sys_symlinkat
+       .long sys_readlinkat
+       .long sys_fchmodat
+       .long sys_faccessat             /* 300 */
+       .long sys_ni_syscall            /* Reserved for pselect6 */
+       .long sys_ni_syscall            /* Reserved for ppoll */
+       .long sys_unshare
+       .long sys_set_robust_list
+       .long sys_get_robust_list       /* 305 */
+       .long sys_splice
+       .long sys_sync_file_range
+       .long sys_tee
+       .long sys_vmsplice
+       .long sys_move_pages            /* 310 */
 
        .rept NR_syscalls-(.-sys_call_table)/4
                .long sys_ni_syscall
index 8a49884bd5ec674204d6d4852f272d70bbca593d..14af6cce2fa22a57d5c76fa72db3051786ab04d2 100644 (file)
@@ -1010,11 +1010,6 @@ endchoice
 config ARC32
        bool
 
-config AU1X00_USB_DEVICE
-       bool
-       depends on MIPS_PB1500 || MIPS_PB1100 || MIPS_PB1000
-       default n
-
 config BOOT_ELF32
        bool
 
@@ -1465,10 +1460,8 @@ config MIPS_MT_DISABLED
          the option of an MT-enabled processor this option will be the only
          option in this menu.
 
-config MIPS_MT_SMTC
-       bool "SMTC: Use all TCs on all VPEs for SMP"
-       depends on CPU_MIPS32_R2
-       #depends on CPU_MIPS64_R2               # once there is hardware ...
+config MIPS_MT_SMP
+       bool "Use 1 TC on each available VPE for SMP"
        depends on SYS_SUPPORTS_MULTITHREADING
        select CPU_MIPSR2_IRQ_VI
        select CPU_MIPSR2_SRS
@@ -1476,11 +1469,13 @@ config MIPS_MT_SMTC
        select SMP
        select SYS_SUPPORTS_SMP
        help
-         This is a kernel model which is known a SMTC or lately has been
-         marketesed into SMVP.
+         This is a kernel model which is also known a VSMP or lately
+         has been marketesed into SMVP.
 
-config MIPS_MT_SMP
-       bool "Use 1 TC on each available VPE for SMP"
+config MIPS_MT_SMTC
+       bool "SMTC: Use all TCs on all VPEs for SMP"
+       depends on CPU_MIPS32_R2
+       #depends on CPU_MIPS64_R2               # once there is hardware ...
        depends on SYS_SUPPORTS_MULTITHREADING
        select CPU_MIPSR2_IRQ_VI
        select CPU_MIPSR2_SRS
@@ -1488,8 +1483,8 @@ config MIPS_MT_SMP
        select SMP
        select SYS_SUPPORTS_SMP
        help
-         This is a kernel model which is also known a VSMP or lately
-         has been marketesed into SMVP.
+         This is a kernel model which is known a SMTC or lately has been
+         marketesed into SMVP.
 
 config MIPS_VPE_LOADER
        bool "VPE loader support."
index 2124350ab94dfa88e609e7fe193f09d45c6c5bf7..641aa30b36385a6860f304709d82b5ab7871345a 100644 (file)
@@ -91,8 +91,17 @@ cflags-y += -ffreestanding
 # carefully avoid to add it redundantly because gcc 3.3/3.4 complains
 # when fed the toolchain default!
 #
-cflags-$(CONFIG_CPU_BIG_ENDIAN)                += $(shell $(CC) -dumpmachine |grep -q 'mips.*el-.*' && echo -EB -D__MIPSEB__)
-cflags-$(CONFIG_CPU_LITTLE_ENDIAN)     += $(shell $(CC) -dumpmachine |grep -q 'mips.*el-.*' || echo -EL -D__MIPSEL__)
+# Certain gcc versions upto gcc 4.1.1 (probably 4.2-subversion as of
+# 2006-10-10 don't properly change the the predefined symbols if -EB / -EL
+# are used, so we kludge that here.  A bug has been filed at
+# http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29413.
+#
+undef-all += -UMIPSEB -U_MIPSEB -U__MIPSEB -U__MIPSEB__
+undef-all += -UMIPSEL -U_MIPSEL -U__MIPSEL -U__MIPSEL__
+predef-be += -DMIPSEB -D_MIPSEB -D__MIPSEB -D__MIPSEB__
+predef-le += -DMIPSEL -D_MIPSEL -D__MIPSEL -D__MIPSEL__
+cflags-$(CONFIG_CPU_BIG_ENDIAN)                += $(shell $(CC) -dumpmachine |grep -q 'mips.*el-.*' && echo -EB $(undef-all) $(predef-be))
+cflags-$(CONFIG_CPU_LITTLE_ENDIAN)     += $(shell $(CC) -dumpmachine |grep -q 'mips.*el-.*' || echo -EL $(undef-all) $(predef-le))
 
 cflags-$(CONFIG_SB1XXX_CORELIS)        += $(call cc-option,-mno-sched-prolog) \
                                   -fno-omit-frame-pointer
index bf682f50b8598b18f8dc29a6c3698fa2c96fd778..4c35525edb4f443b18e107b9a577a74f26a9f5ff 100644 (file)
@@ -10,6 +10,5 @@ obj-y += prom.o irq.o puts.o time.o reset.o \
        au1xxx_irqmap.o clocks.o platform.o power.o setup.o \
        sleeper.o cputable.o dma.o dbdma.o gpio.o
 
-obj-$(CONFIG_AU1X00_USB_DEVICE)        += usbdev.o
 obj-$(CONFIG_KGDB)             += dbg_io.o
 obj-$(CONFIG_PCI)              += pci.o
index c4fae8ff4671564a6fbf07f49fe46be736d822b0..626de44bd888c67c08fd2b0bcc6ec176c9e112fc 100644 (file)
@@ -849,7 +849,7 @@ au1xxx_dbdma_chan_free(u32 chanid)
 EXPORT_SYMBOL(au1xxx_dbdma_chan_free);
 
 static irqreturn_t
-dbdma_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+dbdma_interrupt(int irq, void *dev_id)
 {
        u32 intstat;
        u32 chan_index;
index fb7c47c1585d22da6f25b08186205323374a0f38..c78260d4e837532e3e19b28459f2ced292a06119 100644 (file)
@@ -160,7 +160,7 @@ void dump_au1000_dma_channel(unsigned int dmanr)
  * Requests the DMA done IRQ if irqhandler != NULL.
  */
 int request_au1000_dma(int dev_id, const char *dev_str,
-                      irqreturn_t (*irqhandler)(int, void *, struct pt_regs *),
+                      irq_handler_t irqhandler,
                       unsigned long irqflags,
                       void *irq_dev_id)
 {
index 316722ee8cf504e7972722c882ae9a8e94cad3bb..2abe132bb07d8919607099bc552a6f1943e0e79f 100644 (file)
@@ -67,7 +67,7 @@
 
 extern void set_debug_traps(void);
 extern irq_cpustat_t irq_stat [NR_CPUS];
-extern void mips_timer_interrupt(struct pt_regs *regs);
+extern void mips_timer_interrupt(void);
 
 static void setup_local_irq(unsigned int irq, int type, int int_req);
 static unsigned int startup_irq(unsigned int irq);
@@ -81,10 +81,6 @@ inline void local_disable_irq(unsigned int irq_nr);
 
 void   (*board_init_irq)(void);
 
-#ifdef CONFIG_PM
-extern irqreturn_t counter0_irq(int irq, void *dev_id, struct pt_regs *regs);
-#endif
-
 static DEFINE_SPINLOCK(irq_lock);
 
 
@@ -292,7 +288,7 @@ static struct irq_chip level_irq_type = {
 };
 
 #ifdef CONFIG_PM
-void startup_match20_interrupt(irqreturn_t (*handler)(int, void *, struct pt_regs *))
+void startup_match20_interrupt(irq_handler_t handler)
 {
        struct irq_desc *desc = &irq_desc[AU1000_TOY_MATCH2_INT];
 
@@ -501,14 +497,15 @@ void __init arch_init_irq(void)
  * intcX_reqX_irqdispatch().
  */
 
-void intc0_req0_irqdispatch(struct pt_regs *regs)
+static void intc0_req0_irqdispatch(void)
 {
        int irq = 0;
        static unsigned long intc0_req0 = 0;
 
        intc0_req0 |= au_readl(IC0_REQ0INT);
 
-       if (!intc0_req0) return;
+       if (!intc0_req0)
+               return;
 #ifdef AU1000_USB_DEV_REQ_INT
        /*
         * Because of the tight timing of SETUP token to reply
@@ -517,28 +514,29 @@ void intc0_req0_irqdispatch(struct pt_regs *regs)
         */
        if ((intc0_req0 & (1<<AU1000_USB_DEV_REQ_INT))) {
                intc0_req0 &= ~(1<<AU1000_USB_DEV_REQ_INT);
-               do_IRQ(AU1000_USB_DEV_REQ_INT, regs);
+               do_IRQ(AU1000_USB_DEV_REQ_INT);
                return;
        }
 #endif
        irq = au_ffs(intc0_req0) - 1;
        intc0_req0 &= ~(1<<irq);
-       do_IRQ(irq, regs);
+       do_IRQ(irq);
 }
 
 
-void intc0_req1_irqdispatch(struct pt_regs *regs)
+static void intc0_req1_irqdispatch(void)
 {
        int irq = 0;
        static unsigned long intc0_req1 = 0;
 
        intc0_req1 |= au_readl(IC0_REQ1INT);
 
-       if (!intc0_req1) return;
+       if (!intc0_req1)
+               return;
 
        irq = au_ffs(intc0_req1) - 1;
        intc0_req1 &= ~(1<<irq);
-       do_IRQ(irq, regs);
+       do_IRQ(irq);
 }
 
 
@@ -546,35 +544,37 @@ void intc0_req1_irqdispatch(struct pt_regs *regs)
  * Interrupt Controller 1:
  * interrupts 32 - 63
  */
-void intc1_req0_irqdispatch(struct pt_regs *regs)
+static void intc1_req0_irqdispatch(void)
 {
        int irq = 0;
        static unsigned long intc1_req0 = 0;
 
        intc1_req0 |= au_readl(IC1_REQ0INT);
 
-       if (!intc1_req0) return;
+       if (!intc1_req0)
+               return;
 
        irq = au_ffs(intc1_req0) - 1;
        intc1_req0 &= ~(1<<irq);
        irq += 32;
-       do_IRQ(irq, regs);
+       do_IRQ(irq);
 }
 
 
-void intc1_req1_irqdispatch(struct pt_regs *regs)
+static void intc1_req1_irqdispatch(void)
 {
        int irq = 0;
        static unsigned long intc1_req1 = 0;
 
        intc1_req1 |= au_readl(IC1_REQ1INT);
 
-       if (!intc1_req1) return;
+       if (!intc1_req1)
+               return;
 
        irq = au_ffs(intc1_req1) - 1;
        intc1_req1 &= ~(1<<irq);
        irq += 32;
-       do_IRQ(irq, regs);
+       do_IRQ(irq);
 }
 
 #ifdef CONFIG_PM
@@ -660,20 +660,20 @@ restore_au1xxx_intctl(void)
 }
 #endif /* CONFIG_PM */
 
-asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+asmlinkage void plat_irq_dispatch(void)
 {
        unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;
 
        if (pending & CAUSEF_IP7)
-               mips_timer_interrupt(regs);
+               mips_timer_interrupt();
        else if (pending & CAUSEF_IP2)
-               intc0_req0_irqdispatch(regs);
+               intc0_req0_irqdispatch();
        else if (pending & CAUSEF_IP3)
-               intc0_req1_irqdispatch(regs);
+               intc0_req1_irqdispatch();
        else if (pending & CAUSEF_IP4)
-               intc1_req0_irqdispatch(regs);
+               intc1_req0_irqdispatch();
        else if (pending  & CAUSEF_IP5)
-               intc1_req1_irqdispatch(regs);
+               intc1_req1_irqdispatch();
        else
-               spurious_interrupt(regs);
+               spurious_interrupt();
 }
index 0a067f3113a54704a454501a14452996ec8b87c2..94f09194d63d636381cba295f41a031e3c4ac9d6 100644 (file)
@@ -41,7 +41,6 @@
 
 #include <asm/compiler.h>
 #include <asm/mipsregs.h>
-#include <asm/ptrace.h>
 #include <asm/time.h>
 #include <asm/div64.h>
 #include <asm/mach-au1x00/au1000.h>
@@ -62,7 +61,7 @@ static unsigned int timerhi = 0, timerlo = 0;
 #error "unsupported HZ value! Must be in [100,1000]"
 #endif
 #define MATCH20_INC (328*100/HZ) /* magic number 328 is for HZ=100... */
-extern void startup_match20_interrupt(irqreturn_t (*handler)(int, void *, struct pt_regs *));
+extern void startup_match20_interrupt(irq_handler_t handler);
 static unsigned long last_pc0, last_match20;
 #endif
 
@@ -79,7 +78,8 @@ static inline void ack_r4ktimer(unsigned long newval)
  * is provably more robust.
  */
 unsigned long wtimer;
-void mips_timer_interrupt(struct pt_regs *regs)
+
+void mips_timer_interrupt(void)
 {
        int irq = 63;
        unsigned long count;
@@ -98,7 +98,7 @@ void mips_timer_interrupt(struct pt_regs *regs)
                kstat_this_cpu.irqs[irq]++;
                do_timer(1);
 #ifndef CONFIG_SMP
-               update_process_times(user_mode(regs));
+               update_process_times(user_mode(get_irq_regs()));
 #endif
                r4k_cur += r4k_offset;
                ack_r4ktimer(r4k_cur);
@@ -115,7 +115,7 @@ null:
 }
 
 #ifdef CONFIG_PM
-irqreturn_t counter0_irq(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t counter0_irq(int irq, void *dev_id)
 {
        unsigned long pc0;
        int time_elapsed;
@@ -139,7 +139,7 @@ irqreturn_t counter0_irq(int irq, void *dev_id, struct pt_regs *regs)
        while (time_elapsed > 0) {
                do_timer(1);
 #ifndef CONFIG_SMP
-               update_process_times(user_mode(regs));
+               update_process_times(user_mode(get_irq_regs()));
 #endif
                time_elapsed -= MATCH20_INC;
                last_match20 += MATCH20_INC;
@@ -158,7 +158,7 @@ irqreturn_t counter0_irq(int irq, void *dev_id, struct pt_regs *regs)
                jiffie_drift -= 999;
                do_timer(1); /* increment jiffies by one */
 #ifndef CONFIG_SMP
-               update_process_times(user_mode(regs));
+               update_process_times(user_mode(get_irq_regs()));
 #endif
        }
 
diff --git a/arch/mips/au1000/common/usbdev.c b/arch/mips/au1000/common/usbdev.c
deleted file mode 100644 (file)
index 63bcb3a..0000000
+++ /dev/null
@@ -1,1555 +0,0 @@
-/*
- * BRIEF MODULE DESCRIPTION
- *     Au1000 USB Device-Side (device layer)
- *
- * Copyright 2001-2002 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *             stevel@mvista.com or source@mvista.com
- *
- *  This program is free software; you can redistribute         it and/or modify it
- *  under  the terms of         the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the License, or (at your
- *  option) any later version.
- *
- *  THIS  SOFTWARE  IS PROVIDED          ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,          INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED          TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA, OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN         CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  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 <linux/kernel.h>
-#include <linux/ioport.h>
-#include <linux/sched.h>
-#include <linux/signal.h>
-#include <linux/errno.h>
-#include <linux/poll.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/fcntl.h>
-#include <linux/module.h>
-#include <linux/spinlock.h>
-#include <linux/list.h>
-#include <linux/smp_lock.h>
-#define DEBUG
-#include <linux/usb.h>
-
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <asm/irq.h>
-#include <asm/mipsregs.h>
-#include <asm/au1000.h>
-#include <asm/au1000_dma.h>
-#include <asm/au1000_usbdev.h>
-
-#ifdef DEBUG
-#undef VDEBUG
-#ifdef VDEBUG
-#define vdbg(fmt, arg...) printk(KERN_DEBUG __FILE__ ": " fmt "\n" , ## arg)
-#else
-#define vdbg(fmt, arg...) do {} while (0)
-#endif
-#else
-#define vdbg(fmt, arg...) do {} while (0)
-#endif
-
-#define ALLOC_FLAGS (in_interrupt () ? GFP_ATOMIC : GFP_KERNEL)
-
-#define EP_FIFO_DEPTH 8
-
-typedef enum {
-       SETUP_STAGE = 0,
-       DATA_STAGE,
-       STATUS_STAGE
-} ep0_stage_t;
-
-typedef struct {
-       int read_fifo;
-       int write_fifo;
-       int ctrl_stat;
-       int read_fifo_status;
-       int write_fifo_status;
-} endpoint_reg_t;
-
-typedef struct {
-       usbdev_pkt_t *head;
-       usbdev_pkt_t *tail;
-       int count;
-} pkt_list_t;
-
-typedef struct {
-       int active;
-       struct usb_endpoint_descriptor *desc;
-       endpoint_reg_t *reg;
-       /* Only one of these are used, unless this is the control ep */
-       pkt_list_t inlist;
-       pkt_list_t outlist;
-       unsigned int indma, outdma; /* DMA channel numbers for IN, OUT */
-       /* following are extracted from endpoint descriptor for easy access */
-       int max_pkt_size;
-       int type;
-       int direction;
-       /* WE assign endpoint addresses! */
-       int address;
-       spinlock_t lock;
-} endpoint_t;
-
-
-static struct usb_dev {
-       endpoint_t ep[6];
-       ep0_stage_t ep0_stage;
-
-       struct usb_device_descriptor *   dev_desc;
-       struct usb_interface_descriptor* if_desc;
-       struct usb_config_descriptor *   conf_desc;
-       u8 *                             full_conf_desc;
-       struct usb_string_descriptor *   str_desc[6];
-
-       /* callback to function layer */
-       void (*func_cb)(usbdev_cb_type_t type, unsigned long arg,
-                       void *cb_data);
-       void* cb_data;
-
-       usbdev_state_t state;   // device state
-       int suspended;          // suspended flag
-       int address;            // device address
-       int interface;
-       int num_ep;
-       u8 alternate_setting;
-       u8 configuration;       // configuration value
-       int remote_wakeup_en;
-} usbdev;
-
-
-static endpoint_reg_t ep_reg[] = {
-       // FIFO's 0 and 1 are EP0 default control
-       {USBD_EP0RD, USBD_EP0WR, USBD_EP0CS, USBD_EP0RDSTAT, USBD_EP0WRSTAT },
-       {0},
-       // FIFO 2 is EP2, IN
-       { -1, USBD_EP2WR, USBD_EP2CS, -1, USBD_EP2WRSTAT },
-       // FIFO 3 is EP3, IN
-       {    -1,     USBD_EP3WR, USBD_EP3CS,     -1,         USBD_EP3WRSTAT },
-       // FIFO 4 is EP4, OUT
-       {USBD_EP4RD,     -1,     USBD_EP4CS, USBD_EP4RDSTAT,     -1         },
-       // FIFO 5 is EP5, OUT
-       {USBD_EP5RD,     -1,     USBD_EP5CS, USBD_EP5RDSTAT,     -1         }
-};
-
-static struct {
-       unsigned int id;
-       const char *str;
-} ep_dma_id[] = {
-       { DMA_ID_USBDEV_EP0_TX, "USBDev EP0 IN" },
-       { DMA_ID_USBDEV_EP0_RX, "USBDev EP0 OUT" },
-       { DMA_ID_USBDEV_EP2_TX, "USBDev EP2 IN" },
-       { DMA_ID_USBDEV_EP3_TX, "USBDev EP3 IN" },
-       { DMA_ID_USBDEV_EP4_RX, "USBDev EP4 OUT" },
-       { DMA_ID_USBDEV_EP5_RX, "USBDev EP5 OUT" }
-};
-
-#define DIR_OUT 0
-#define DIR_IN  (1<<3)
-
-#define CONTROL_EP USB_ENDPOINT_XFER_CONTROL
-#define BULK_EP    USB_ENDPOINT_XFER_BULK
-
-static inline endpoint_t *
-epaddr_to_ep(struct usb_dev* dev, int ep_addr)
-{
-       if (ep_addr >= 0 && ep_addr < 2)
-               return &dev->ep[0];
-       if (ep_addr < 6)
-               return &dev->ep[ep_addr];
-       return NULL;
-}
-
-static const char* std_req_name[] = {
-       "GET_STATUS",
-       "CLEAR_FEATURE",
-       "RESERVED",
-       "SET_FEATURE",
-       "RESERVED",
-       "SET_ADDRESS",
-       "GET_DESCRIPTOR",
-       "SET_DESCRIPTOR",
-       "GET_CONFIGURATION",
-       "SET_CONFIGURATION",
-       "GET_INTERFACE",
-       "SET_INTERFACE",
-       "SYNCH_FRAME"
-};
-
-static inline const char*
-get_std_req_name(int req)
-{
-       return (req >= 0 && req <= 12) ? std_req_name[req] : "UNKNOWN";
-}
-
-#if 0
-static void
-dump_setup(struct usb_ctrlrequest* s)
-{
-       dbg("%s: requesttype=%d", __FUNCTION__, s->requesttype);
-       dbg("%s: request=%d %s", __FUNCTION__, s->request,
-           get_std_req_name(s->request));
-       dbg("%s: value=0x%04x", __FUNCTION__, s->wValue);
-       dbg("%s: index=%d", __FUNCTION__, s->index);
-       dbg("%s: length=%d", __FUNCTION__, s->length);
-}
-#endif
-
-static inline usbdev_pkt_t *
-alloc_packet(endpoint_t * ep, int data_size, void* data)
-{
-       usbdev_pkt_t* pkt = kmalloc(sizeof(usbdev_pkt_t) + data_size,
-                                   ALLOC_FLAGS);
-       if (!pkt)
-               return NULL;
-       pkt->ep_addr = ep->address;
-       pkt->size = data_size;
-       pkt->status = 0;
-       pkt->next = NULL;
-       if (data)
-               memcpy(pkt->payload, data, data_size);
-
-       return pkt;
-}
-
-
-/*
- * Link a packet to the tail of the enpoint's packet list.
- * EP spinlock must be held when calling.
- */
-static void
-link_tail(endpoint_t * ep, pkt_list_t * list, usbdev_pkt_t * pkt)
-{
-       if (!list->tail) {
-               list->head = list->tail = pkt;
-               list->count = 1;
-       } else {
-               list->tail->next = pkt;
-               list->tail = pkt;
-               list->count++;
-       }
-}
-
-/*
- * Unlink and return a packet from the head of the given packet
- * list. It is the responsibility of the caller to free the packet.
- * EP spinlock must be held when calling.
- */
-static usbdev_pkt_t *
-unlink_head(pkt_list_t * list)
-{
-       usbdev_pkt_t *pkt;
-
-       pkt = list->head;
-       if (!pkt || !list->count) {
-               return NULL;
-       }
-
-       list->head = pkt->next;
-       if (!list->head) {
-               list->head = list->tail = NULL;
-               list->count = 0;
-       } else
-               list->count--;
-
-       return pkt;
-}
-
-/*
- * Create and attach a new packet to the tail of the enpoint's
- * packet list. EP spinlock must be held when calling.
- */
-static usbdev_pkt_t *
-add_packet(endpoint_t * ep, pkt_list_t * list, int size)
-{
-       usbdev_pkt_t *pkt = alloc_packet(ep, size, NULL);
-       if (!pkt)
-               return NULL;
-
-       link_tail(ep, list, pkt);
-       return pkt;
-}
-
-
-/*
- * Unlink and free a packet from the head of the enpoint's
- * packet list. EP spinlock must be held when calling.
- */
-static inline void
-free_packet(pkt_list_t * list)
-{
-       kfree(unlink_head(list));
-}
-
-/* EP spinlock must be held when calling. */
-static inline void
-flush_pkt_list(pkt_list_t * list)
-{
-       while (list->count)
-               free_packet(list);
-}
-
-/* EP spinlock must be held when calling */
-static inline void
-flush_write_fifo(endpoint_t * ep)
-{
-       if (ep->reg->write_fifo_status >= 0) {
-               au_writel(USBDEV_FSTAT_FLUSH | USBDEV_FSTAT_UF |
-                         USBDEV_FSTAT_OF,
-                         ep->reg->write_fifo_status);
-               //udelay(100);
-               //au_writel(USBDEV_FSTAT_UF | USBDEV_FSTAT_OF,
-               //        ep->reg->write_fifo_status);
-       }
-}
-
-/* EP spinlock must be held when calling */
-static inline void
-flush_read_fifo(endpoint_t * ep)
-{
-       if (ep->reg->read_fifo_status >= 0) {
-               au_writel(USBDEV_FSTAT_FLUSH | USBDEV_FSTAT_UF |
-                         USBDEV_FSTAT_OF,
-                         ep->reg->read_fifo_status);
-               //udelay(100);
-               //au_writel(USBDEV_FSTAT_UF | USBDEV_FSTAT_OF,
-               //        ep->reg->read_fifo_status);
-       }
-}
-
-
-/* EP spinlock must be held when calling. */
-static void
-endpoint_flush(endpoint_t * ep)
-{
-       // First, flush all packets
-       flush_pkt_list(&ep->inlist);
-       flush_pkt_list(&ep->outlist);
-
-       // Now flush the endpoint's h/w FIFO(s)
-       flush_write_fifo(ep);
-       flush_read_fifo(ep);
-}
-
-/* EP spinlock must be held when calling. */
-static void
-endpoint_stall(endpoint_t * ep)
-{
-       u32 cs;
-
-       warn("%s", __FUNCTION__);
-
-       cs = au_readl(ep->reg->ctrl_stat) | USBDEV_CS_STALL;
-       au_writel(cs, ep->reg->ctrl_stat);
-}
-
-/* EP spinlock must be held when calling. */
-static void
-endpoint_unstall(endpoint_t * ep)
-{
-       u32 cs;
-
-       warn("%s", __FUNCTION__);
-
-       cs = au_readl(ep->reg->ctrl_stat) & ~USBDEV_CS_STALL;
-       au_writel(cs, ep->reg->ctrl_stat);
-}
-
-static void
-endpoint_reset_datatoggle(endpoint_t * ep)
-{
-       // FIXME: is this possible?
-}
-
-
-/* EP spinlock must be held when calling. */
-static int
-endpoint_fifo_read(endpoint_t * ep)
-{
-       int read_count = 0;
-       u8 *bufptr;
-       usbdev_pkt_t *pkt = ep->outlist.tail;
-
-       if (!pkt)
-               return -EINVAL;
-
-       bufptr = &pkt->payload[pkt->size];
-       while (au_readl(ep->reg->read_fifo_status) & USBDEV_FSTAT_FCNT_MASK) {
-               *bufptr++ = au_readl(ep->reg->read_fifo) & 0xff;
-               read_count++;
-               pkt->size++;
-       }
-
-       return read_count;
-}
-
-#if 0
-/* EP spinlock must be held when calling. */
-static int
-endpoint_fifo_write(endpoint_t * ep, int index)
-{
-       int write_count = 0;
-       u8 *bufptr;
-       usbdev_pkt_t *pkt = ep->inlist.head;
-
-       if (!pkt)
-               return -EINVAL;
-
-       bufptr = &pkt->payload[index];
-       while ((au_readl(ep->reg->write_fifo_status) &
-               USBDEV_FSTAT_FCNT_MASK) < EP_FIFO_DEPTH) {
-               if (bufptr < pkt->payload + pkt->size) {
-                       au_writel(*bufptr++, ep->reg->write_fifo);
-                       write_count++;
-               } else {
-                       break;
-               }
-       }
-
-       return write_count;
-}
-#endif
-
-/*
- * This routine is called to restart transmission of a packet.
- * The endpoint's TSIZE must be set to the new packet's size,
- * and DMA to the write FIFO needs to be restarted.
- * EP spinlock must be held when calling.
- */
-static void
-kickstart_send_packet(endpoint_t * ep)
-{
-       u32 cs;
-       usbdev_pkt_t *pkt = ep->inlist.head;
-
-       vdbg("%s: ep%d, pkt=%p", __FUNCTION__, ep->address, pkt);
-
-       if (!pkt) {
-               err("%s: head=NULL! list->count=%d", __FUNCTION__,
-                   ep->inlist.count);
-               return;
-       }
-
-       dma_cache_wback_inv((unsigned long)pkt->payload, pkt->size);
-
-       /*
-        * make sure FIFO is empty
-        */
-       flush_write_fifo(ep);
-
-       cs = au_readl(ep->reg->ctrl_stat) & USBDEV_CS_STALL;
-       cs |= (pkt->size << USBDEV_CS_TSIZE_BIT);
-       au_writel(cs, ep->reg->ctrl_stat);
-
-       if (get_dma_active_buffer(ep->indma) == 1) {
-               set_dma_count1(ep->indma, pkt->size);
-               set_dma_addr1(ep->indma, virt_to_phys(pkt->payload));
-               enable_dma_buffer1(ep->indma);  // reenable
-       } else {
-               set_dma_count0(ep->indma, pkt->size);
-               set_dma_addr0(ep->indma, virt_to_phys(pkt->payload));
-               enable_dma_buffer0(ep->indma);  // reenable
-       }
-       if (dma_halted(ep->indma))
-               start_dma(ep->indma);
-}
-
-
-/*
- * This routine is called when a packet in the inlist has been
- * completed. Frees the completed packet and starts sending the
- * next. EP spinlock must be held when calling.
- */
-static usbdev_pkt_t *
-send_packet_complete(endpoint_t * ep)
-{
-       usbdev_pkt_t *pkt = unlink_head(&ep->inlist);
-
-       if (pkt) {
-               pkt->status =
-                       (au_readl(ep->reg->ctrl_stat) & USBDEV_CS_NAK) ?
-                       PKT_STATUS_NAK : PKT_STATUS_ACK;
-
-               vdbg("%s: ep%d, %s pkt=%p, list count=%d", __FUNCTION__,
-                    ep->address, (pkt->status & PKT_STATUS_NAK) ?
-                    "NAK" : "ACK", pkt, ep->inlist.count);
-       }
-
-       /*
-        * The write fifo should already be drained if things are
-        * working right, but flush it anyway just in case.
-        */
-       flush_write_fifo(ep);
-
-       // begin transmitting next packet in the inlist
-       if (ep->inlist.count) {
-               kickstart_send_packet(ep);
-       }
-
-       return pkt;
-}
-
-/*
- * Add a new packet to the tail of the given ep's packet
- * inlist. The transmit complete interrupt frees packets from
- * the head of this list. EP spinlock must be held when calling.
- */
-static int
-send_packet(struct usb_dev* dev, usbdev_pkt_t *pkt, int async)
-{
-       pkt_list_t *list;
-       endpoint_t* ep;
-
-       if (!pkt || !(ep = epaddr_to_ep(dev, pkt->ep_addr)))
-               return -EINVAL;
-
-       if (!pkt->size)
-               return 0;
-
-       list = &ep->inlist;
-
-       if (!async && list->count) {
-               halt_dma(ep->indma);
-               flush_pkt_list(list);
-       }
-
-       link_tail(ep, list, pkt);
-
-       vdbg("%s: ep%d, pkt=%p, size=%d, list count=%d", __FUNCTION__,
-            ep->address, pkt, pkt->size, list->count);
-
-       if (list->count == 1) {
-               /*
-                * if the packet count is one, it means the list was empty,
-                * and no more data will go out this ep until we kick-start
-                * it again.
-                */
-               kickstart_send_packet(ep);
-       }
-
-       return pkt->size;
-}
-
-/*
- * This routine is called to restart reception of a packet.
- * EP spinlock must be held when calling.
- */
-static void
-kickstart_receive_packet(endpoint_t * ep)
-{
-       usbdev_pkt_t *pkt;
-
-       // get and link a new packet for next reception
-       if (!(pkt = add_packet(ep, &ep->outlist, ep->max_pkt_size))) {
-               err("%s: could not alloc new packet", __FUNCTION__);
-               return;
-       }
-
-       if (get_dma_active_buffer(ep->outdma) == 1) {
-               clear_dma_done1(ep->outdma);
-               set_dma_count1(ep->outdma, ep->max_pkt_size);
-               set_dma_count0(ep->outdma, 0);
-               set_dma_addr1(ep->outdma, virt_to_phys(pkt->payload));
-               enable_dma_buffer1(ep->outdma); // reenable
-       } else {
-               clear_dma_done0(ep->outdma);
-               set_dma_count0(ep->outdma, ep->max_pkt_size);
-               set_dma_count1(ep->outdma, 0);
-               set_dma_addr0(ep->outdma, virt_to_phys(pkt->payload));
-               enable_dma_buffer0(ep->outdma); // reenable
-       }
-       if (dma_halted(ep->outdma))
-               start_dma(ep->outdma);
-}
-
-
-/*
- * This routine is called when a packet in the outlist has been
- * completed (received) and we need to prepare for a new packet
- * to be received. Halts DMA and computes the packet size from the
- * remaining DMA counter. Then prepares a new packet for reception
- * and restarts DMA. FIXME: what if another packet comes in
- * on top of the completed packet? Counter would be wrong.
- * EP spinlock must be held when calling.
- */
-static usbdev_pkt_t *
-receive_packet_complete(endpoint_t * ep)
-{
-       usbdev_pkt_t *pkt = ep->outlist.tail;
-       u32 cs;
-
-       halt_dma(ep->outdma);
-
-       cs = au_readl(ep->reg->ctrl_stat);
-
-       if (!pkt)
-               return NULL;
-
-       pkt->size = ep->max_pkt_size - get_dma_residue(ep->outdma);
-       if (pkt->size)
-               dma_cache_inv((unsigned long)pkt->payload, pkt->size);
-       /*
-        * need to pull out any remaining bytes in the FIFO.
-        */
-       endpoint_fifo_read(ep);
-       /*
-        * should be drained now, but flush anyway just in case.
-        */
-       flush_read_fifo(ep);
-
-       pkt->status = (cs & USBDEV_CS_NAK) ? PKT_STATUS_NAK : PKT_STATUS_ACK;
-       if (ep->address == 0 && (cs & USBDEV_CS_SU))
-               pkt->status |= PKT_STATUS_SU;
-
-       vdbg("%s: ep%d, %s pkt=%p, size=%d", __FUNCTION__,
-            ep->address, (pkt->status & PKT_STATUS_NAK) ?
-            "NAK" : "ACK", pkt, pkt->size);
-
-       kickstart_receive_packet(ep);
-
-       return pkt;
-}
-
-
-/*
- ****************************************************************************
- * Here starts the standard device request handlers. They are
- * all called by do_setup() via a table of function pointers.
- ****************************************************************************
- */
-
-static ep0_stage_t
-do_get_status(struct usb_dev* dev, struct usb_ctrlrequest* setup)
-{
-       switch (setup->bRequestType) {
-       case 0x80:      // Device
-               // FIXME: send device status
-               break;
-       case 0x81:      // Interface
-               // FIXME: send interface status
-               break;
-       case 0x82:      // End Point
-               // FIXME: send endpoint status
-               break;
-       default:
-               // Invalid Command
-               endpoint_stall(&dev->ep[0]); // Stall End Point 0
-               break;
-       }
-
-       return STATUS_STAGE;
-}
-
-static ep0_stage_t
-do_clear_feature(struct usb_dev* dev, struct usb_ctrlrequest* setup)
-{
-       switch (setup->bRequestType) {
-       case 0x00:      // Device
-               if ((le16_to_cpu(setup->wValue) & 0xff) == 1)
-                       dev->remote_wakeup_en = 0;
-       else
-                       endpoint_stall(&dev->ep[0]);
-               break;
-       case 0x02:      // End Point
-               if ((le16_to_cpu(setup->wValue) & 0xff) == 0) {
-                       endpoint_t *ep =
-                               epaddr_to_ep(dev,
-                                            le16_to_cpu(setup->wIndex) & 0xff);
-
-                       endpoint_unstall(ep);
-                       endpoint_reset_datatoggle(ep);
-               } else
-                       endpoint_stall(&dev->ep[0]);
-               break;
-       }
-
-       return SETUP_STAGE;
-}
-
-static ep0_stage_t
-do_reserved(struct usb_dev* dev, struct usb_ctrlrequest* setup)
-{
-       // Invalid request, stall End Point 0
-       endpoint_stall(&dev->ep[0]);
-       return SETUP_STAGE;
-}
-
-static ep0_stage_t
-do_set_feature(struct usb_dev* dev, struct usb_ctrlrequest* setup)
-{
-       switch (setup->bRequestType) {
-       case 0x00:      // Device
-               if ((le16_to_cpu(setup->wValue) & 0xff) == 1)
-                       dev->remote_wakeup_en = 1;
-               else
-                       endpoint_stall(&dev->ep[0]);
-               break;
-       case 0x02:      // End Point
-               if ((le16_to_cpu(setup->wValue) & 0xff) == 0) {
-                       endpoint_t *ep =
-                               epaddr_to_ep(dev,
-                                            le16_to_cpu(setup->wIndex) & 0xff);
-
-                       endpoint_stall(ep);
-               } else
-                       endpoint_stall(&dev->ep[0]);
-               break;
-       }
-
-       return SETUP_STAGE;
-}
-
-static ep0_stage_t
-do_set_address(struct usb_dev* dev, struct usb_ctrlrequest* setup)
-{
-       int new_state = dev->state;
-       int new_addr = le16_to_cpu(setup->wValue);
-
-       dbg("%s: our address=%d", __FUNCTION__, new_addr);
-
-       if (new_addr > 127) {
-                       // usb spec doesn't tell us what to do, so just go to
-                       // default state
-               new_state = DEFAULT;
-               dev->address = 0;
-       } else if (dev->address != new_addr) {
-               dev->address = new_addr;
-               new_state = ADDRESS;
-       }
-
-       if (dev->state != new_state) {
-               dev->state = new_state;
-               /* inform function layer of usbdev state change */
-               dev->func_cb(CB_NEW_STATE, dev->state, dev->cb_data);
-       }
-
-       return SETUP_STAGE;
-}
-
-static ep0_stage_t
-do_get_descriptor(struct usb_dev* dev, struct usb_ctrlrequest* setup)
-{
-       int strnum, desc_len = le16_to_cpu(setup->wLength);
-
-               switch (le16_to_cpu(setup->wValue) >> 8) {
-               case USB_DT_DEVICE:
-                       // send device descriptor!
-               desc_len = desc_len > dev->dev_desc->bLength ?
-                       dev->dev_desc->bLength : desc_len;
-                       dbg("sending device desc, size=%d", desc_len);
-               send_packet(dev, alloc_packet(&dev->ep[0], desc_len,
-                                             dev->dev_desc), 0);
-                       break;
-               case USB_DT_CONFIG:
-                       // If the config descr index in low-byte of
-                       // setup->wValue        is valid, send config descr,
-                       // otherwise stall ep0.
-                       if ((le16_to_cpu(setup->wValue) & 0xff) == 0) {
-                               // send config descriptor!
-                               if (desc_len <= USB_DT_CONFIG_SIZE) {
-                                       dbg("sending partial config desc, size=%d",
-                                            desc_len);
-                               send_packet(dev,
-                                           alloc_packet(&dev->ep[0],
-                                                        desc_len,
-                                                        dev->conf_desc),
-                                           0);
-                               } else {
-                               int len = le16_to_cpu(dev->conf_desc->wTotalLength);
-                               dbg("sending whole config desc,"
-                                   " size=%d, our size=%d", desc_len, len);
-                               desc_len = desc_len > len ? len : desc_len;
-                               send_packet(dev,
-                                           alloc_packet(&dev->ep[0],
-                                                        desc_len,
-                                                        dev->full_conf_desc),
-                                           0);
-                               }
-                       } else
-                       endpoint_stall(&dev->ep[0]);
-                       break;
-               case USB_DT_STRING:
-                       // If the string descr index in low-byte of setup->wValue
-                       // is valid, send string descr, otherwise stall ep0.
-                       strnum = le16_to_cpu(setup->wValue) & 0xff;
-                       if (strnum >= 0 && strnum < 6) {
-                               struct usb_string_descriptor *desc =
-                               dev->str_desc[strnum];
-                               desc_len = desc_len > desc->bLength ?
-                                       desc->bLength : desc_len;
-                               dbg("sending string desc %d", strnum);
-                       send_packet(dev,
-                                   alloc_packet(&dev->ep[0], desc_len,
-                                                desc), 0);
-                       } else
-                       endpoint_stall(&dev->ep[0]);
-                       break;
-       default:
-               // Invalid request
-               err("invalid get desc=%d, stalled",
-                           le16_to_cpu(setup->wValue) >> 8);
-               endpoint_stall(&dev->ep[0]);    // Stall endpoint 0
-                       break;
-               }
-
-       return STATUS_STAGE;
-}
-
-static ep0_stage_t
-do_set_descriptor(struct usb_dev* dev, struct usb_ctrlrequest* setup)
-{
-       // TODO: implement
-       // there will be an OUT data stage (the descriptor to set)
-       return DATA_STAGE;
-}
-
-static ep0_stage_t
-do_get_configuration(struct usb_dev* dev, struct usb_ctrlrequest* setup)
-{
-       // send dev->configuration
-       dbg("sending config");
-       send_packet(dev, alloc_packet(&dev->ep[0], 1, &dev->configuration),
-                   0);
-       return STATUS_STAGE;
-}
-
-static ep0_stage_t
-do_set_configuration(struct usb_dev* dev, struct usb_ctrlrequest* setup)
-{
-       // set active config to low-byte of setup->wValue
-       dev->configuration = le16_to_cpu(setup->wValue) & 0xff;
-       dbg("set config, config=%d", dev->configuration);
-       if (!dev->configuration && dev->state > DEFAULT) {
-               dev->state = ADDRESS;
-               /* inform function layer of usbdev state change */
-               dev->func_cb(CB_NEW_STATE, dev->state, dev->cb_data);
-       } else if (dev->configuration == 1) {
-               dev->state = CONFIGURED;
-               /* inform function layer of usbdev state change */
-               dev->func_cb(CB_NEW_STATE, dev->state, dev->cb_data);
-       } else {
-               // FIXME: "respond with request error" - how?
-       }
-
-       return SETUP_STAGE;
-}
-
-static ep0_stage_t
-do_get_interface(struct usb_dev* dev, struct usb_ctrlrequest* setup)
-{
-               // interface must be zero.
-       if ((le16_to_cpu(setup->wIndex) & 0xff) || dev->state == ADDRESS) {
-                       // FIXME: respond with "request error". how?
-       } else if (dev->state == CONFIGURED) {
-               // send dev->alternate_setting
-                       dbg("sending alt setting");
-               send_packet(dev, alloc_packet(&dev->ep[0], 1,
-                                             &dev->alternate_setting), 0);
-               }
-
-       return STATUS_STAGE;
-
-}
-
-static ep0_stage_t
-do_set_interface(struct usb_dev* dev, struct usb_ctrlrequest* setup)
-{
-       if (dev->state == ADDRESS) {
-                       // FIXME: respond with "request error". how?
-       } else if (dev->state == CONFIGURED) {
-               dev->interface = le16_to_cpu(setup->wIndex) & 0xff;
-               dev->alternate_setting =
-                           le16_to_cpu(setup->wValue) & 0xff;
-                       // interface and alternate_setting must be zero
-               if (dev->interface || dev->alternate_setting) {
-                               // FIXME: respond with "request error". how?
-                       }
-               }
-
-       return SETUP_STAGE;
-}
-
-static ep0_stage_t
-do_synch_frame(struct usb_dev* dev, struct usb_ctrlrequest* setup)
-{
-       // TODO
-       return SETUP_STAGE;
-}
-
-typedef ep0_stage_t (*req_method_t)(struct usb_dev* dev,
-                                   struct usb_ctrlrequest* setup);
-
-
-/* Table of the standard device request handlers */
-static const req_method_t req_method[] = {
-       do_get_status,
-       do_clear_feature,
-       do_reserved,
-       do_set_feature,
-       do_reserved,
-       do_set_address,
-       do_get_descriptor,
-       do_set_descriptor,
-       do_get_configuration,
-       do_set_configuration,
-       do_get_interface,
-       do_set_interface,
-       do_synch_frame
-};
-
-
-// SETUP packet request dispatcher
-static void
-do_setup (struct usb_dev* dev, struct usb_ctrlrequest* setup)
-{
-       req_method_t m;
-
-       dbg("%s: req %d %s", __FUNCTION__, setup->bRequestType,
-           get_std_req_name(setup->bRequestType));
-
-       if ((setup->bRequestType & USB_TYPE_MASK) != USB_TYPE_STANDARD ||
-           (setup->bRequestType & USB_RECIP_MASK) != USB_RECIP_DEVICE) {
-               err("%s: invalid requesttype 0x%02x", __FUNCTION__,
-                   setup->bRequestType);
-               return;
-               }
-
-       if ((setup->bRequestType & 0x80) == USB_DIR_OUT && setup->wLength)
-               dbg("%s: OUT phase! length=%d", __FUNCTION__, setup->wLength);
-
-       if (setup->bRequestType < sizeof(req_method)/sizeof(req_method_t))
-               m = req_method[setup->bRequestType];
-                       else
-               m = do_reserved;
-
-       dev->ep0_stage = (*m)(dev, setup);
-}
-
-/*
- * A SETUP, DATA0, or DATA1 packet has been received
- * on the default control endpoint's fifo.
- */
-static void
-process_ep0_receive (struct usb_dev* dev)
-{
-       endpoint_t *ep0 = &dev->ep[0];
-       usbdev_pkt_t *pkt;
-
-       spin_lock(&ep0->lock);
-
-               // complete packet and prepare a new packet
-       pkt = receive_packet_complete(ep0);
-       if (!pkt) {
-               // FIXME: should  put a warn/err here.
-               spin_unlock(&ep0->lock);
-                       return;
-               }
-
-       // unlink immediately from endpoint.
-       unlink_head(&ep0->outlist);
-
-       // override current stage if h/w says it's a setup packet
-       if (pkt->status & PKT_STATUS_SU)
-               dev->ep0_stage = SETUP_STAGE;
-
-       switch (dev->ep0_stage) {
-       case SETUP_STAGE:
-               vdbg("SU bit is %s in setup stage",
-                    (pkt->status & PKT_STATUS_SU) ? "set" : "not set");
-
-                       if (pkt->size == sizeof(struct usb_ctrlrequest)) {
-#ifdef VDEBUG
-                       if (pkt->status & PKT_STATUS_ACK)
-                               vdbg("received SETUP");
-                               else
-                               vdbg("received NAK SETUP");
-#endif
-                       do_setup(dev, (struct usb_ctrlrequest*)pkt->payload);
-               } else
-                       err("%s: wrong size SETUP received", __FUNCTION__);
-               break;
-       case DATA_STAGE:
-               /*
-                * this setup has an OUT data stage. Of the standard
-                * device requests, only set_descriptor has this stage,
-                * so this packet is that descriptor. TODO: drop it for
-                * now, set_descriptor not implemented.
-                *
-                * Need to place a byte in the write FIFO here, to prepare
-                * to send a zero-length DATA ack packet to the host in the
-                * STATUS stage.
-                */
-               au_writel(0, ep0->reg->write_fifo);
-               dbg("received OUT stage DATAx on EP0, size=%d", pkt->size);
-               dev->ep0_stage = SETUP_STAGE;
-               break;
-       case STATUS_STAGE:
-               // this setup had an IN data stage, and host is ACK'ing
-               // the packet we sent during that stage.
-               if (pkt->size != 0)
-                       warn("received non-zero ACK on EP0??");
-#ifdef VDEBUG
-               else
-                       vdbg("received ACK on EP0");
-#endif
-               dev->ep0_stage = SETUP_STAGE;
-               break;
-       }
-
-       spin_unlock(&ep0->lock);
-       // we're done processing the packet, free it
-       kfree(pkt);
-}
-
-
-/*
- * A DATA0/1 packet has been received on one of the OUT endpoints (4 or 5)
- */
-static void
-process_ep_receive (struct usb_dev* dev, endpoint_t *ep)
-{
-       usbdev_pkt_t *pkt;
-
-               spin_lock(&ep->lock);
-       pkt = receive_packet_complete(ep);
-               spin_unlock(&ep->lock);
-
-       dev->func_cb(CB_PKT_COMPLETE, (unsigned long)pkt, dev->cb_data);
-}
-
-
-
-/* This ISR handles the receive complete and suspend events */
-static void
-req_sus_intr (int irq, void *dev_id, struct pt_regs *regs)
-{
-       struct usb_dev *dev = (struct usb_dev *) dev_id;
-       u32 status;
-
-       status = au_readl(USBD_INTSTAT);
-       au_writel(status, USBD_INTSTAT);        // ack'em
-
-       if (status & (1<<0))
-               process_ep0_receive(dev);
-       if (status & (1<<4))
-               process_ep_receive(dev, &dev->ep[4]);
-       if (status & (1<<5))
-               process_ep_receive(dev, &dev->ep[5]);
-}
-
-
-/* This ISR handles the DMA done events on EP0 */
-static void
-dma_done_ep0_intr(int irq, void *dev_id, struct pt_regs *regs)
-{
-       struct usb_dev *dev = (struct usb_dev *) dev_id;
-       usbdev_pkt_t* pkt;
-       endpoint_t *ep0 = &dev->ep[0];
-       u32 cs0, buff_done;
-
-       spin_lock(&ep0->lock);
-       cs0 = au_readl(ep0->reg->ctrl_stat);
-
-       // first check packet transmit done
-       if ((buff_done = get_dma_buffer_done(ep0->indma)) != 0) {
-               // transmitted a DATAx packet during DATA stage
-               // on control endpoint 0
-               // clear DMA done bit
-               if (buff_done & DMA_D0)
-                       clear_dma_done0(ep0->indma);
-               if (buff_done & DMA_D1)
-                       clear_dma_done1(ep0->indma);
-
-               pkt = send_packet_complete(ep0);
-               kfree(pkt);
-       }
-
-       /*
-        * Now check packet receive done. Shouldn't get these,
-        * the receive packet complete intr should happen
-        * before the DMA done intr occurs.
-        */
-       if ((buff_done = get_dma_buffer_done(ep0->outdma)) != 0) {
-               // clear DMA done bit
-               if (buff_done & DMA_D0)
-                       clear_dma_done0(ep0->outdma);
-               if (buff_done & DMA_D1)
-                       clear_dma_done1(ep0->outdma);
-
-               //process_ep0_receive(dev);
-       }
-
-       spin_unlock(&ep0->lock);
-}
-
-/* This ISR handles the DMA done events on endpoints 2,3,4,5 */
-static void
-dma_done_ep_intr(int irq, void *dev_id, struct pt_regs *regs)
-{
-       struct usb_dev *dev = (struct usb_dev *) dev_id;
-       int i;
-
-       for (i = 2; i < 6; i++) {
-       u32 buff_done;
-               usbdev_pkt_t* pkt;
-               endpoint_t *ep = &dev->ep[i];
-
-               if (!ep->active) continue;
-
-       spin_lock(&ep->lock);
-
-               if (ep->direction == USB_DIR_IN) {
-                       buff_done = get_dma_buffer_done(ep->indma);
-                       if (buff_done != 0) {
-                               // transmitted a DATAx pkt on the IN ep
-               // clear DMA done bit
-               if (buff_done & DMA_D0)
-                       clear_dma_done0(ep->indma);
-               if (buff_done & DMA_D1)
-                       clear_dma_done1(ep->indma);
-
-                               pkt = send_packet_complete(ep);
-
-                               spin_unlock(&ep->lock);
-                               dev->func_cb(CB_PKT_COMPLETE,
-                                            (unsigned long)pkt,
-                                            dev->cb_data);
-                               spin_lock(&ep->lock);
-                       }
-               } else {
-       /*
-                        * Check packet receive done (OUT ep). Shouldn't get
-                        * these, the rx packet complete intr should happen
-        * before the DMA done intr occurs.
-        */
-                       buff_done = get_dma_buffer_done(ep->outdma);
-                       if (buff_done != 0) {
-                               // received a DATAx pkt on the OUT ep
-               // clear DMA done bit
-               if (buff_done & DMA_D0)
-                       clear_dma_done0(ep->outdma);
-               if (buff_done & DMA_D1)
-                       clear_dma_done1(ep->outdma);
-
-                               //process_ep_receive(dev, ep);
-       }
-       }
-
-               spin_unlock(&ep->lock);
-       }
-}
-
-
-/***************************************************************************
- * Here begins the external interface functions
- ***************************************************************************
- */
-
-/*
- * allocate a new packet
- */
-int
-usbdev_alloc_packet(int ep_addr, int data_size, usbdev_pkt_t** pkt)
-{
-       endpoint_t * ep = epaddr_to_ep(&usbdev, ep_addr);
-       usbdev_pkt_t* lpkt = NULL;
-
-       if (!ep || !ep->active || ep->address < 2)
-               return -ENODEV;
-       if (data_size > ep->max_pkt_size)
-               return -EINVAL;
-
-       lpkt = *pkt = alloc_packet(ep, data_size, NULL);
-       if (!lpkt)
-               return -ENOMEM;
-       return 0;
-}
-
-
-/*
- * packet send
- */
-int
-usbdev_send_packet(int ep_addr, usbdev_pkt_t * pkt)
-{
-       unsigned long flags;
-       int count;
-       endpoint_t * ep;
-
-       if (!pkt || !(ep = epaddr_to_ep(&usbdev, pkt->ep_addr)) ||
-           !ep->active || ep->address < 2)
-               return -ENODEV;
-       if (ep->direction != USB_DIR_IN)
-               return -EINVAL;
-
-       spin_lock_irqsave(&ep->lock, flags);
-       count = send_packet(&usbdev, pkt, 1);
-       spin_unlock_irqrestore(&ep->lock, flags);
-
-       return count;
-}
-
-/*
- * packet receive
- */
-int
-usbdev_receive_packet(int ep_addr, usbdev_pkt_t** pkt)
-{
-       unsigned long flags;
-       usbdev_pkt_t* lpkt = NULL;
-       endpoint_t *ep = epaddr_to_ep(&usbdev, ep_addr);
-
-       if (!ep || !ep->active || ep->address < 2)
-               return -ENODEV;
-       if (ep->direction != USB_DIR_OUT)
-               return -EINVAL;
-
-       spin_lock_irqsave(&ep->lock, flags);
-       if (ep->outlist.count > 1)
-               lpkt = unlink_head(&ep->outlist);
-       spin_unlock_irqrestore(&ep->lock, flags);
-
-       if (!lpkt) {
-               /* no packet available */
-               *pkt = NULL;
-               return -ENODATA;
-       }
-
-       *pkt = lpkt;
-
-       return lpkt->size;
-}
-
-
-/*
- * return total queued byte count on the endpoint.
- */
-int
-usbdev_get_byte_count(int ep_addr)
-{
-        unsigned long flags;
-        pkt_list_t *list;
-        usbdev_pkt_t *scan;
-        int count = 0;
-       endpoint_t * ep = epaddr_to_ep(&usbdev, ep_addr);
-
-       if (!ep || !ep->active || ep->address < 2)
-               return -ENODEV;
-
-       if (ep->direction == USB_DIR_IN) {
-               list = &ep->inlist;
-
-               spin_lock_irqsave(&ep->lock, flags);
-               for (scan = list->head; scan; scan = scan->next)
-                       count += scan->size;
-               spin_unlock_irqrestore(&ep->lock, flags);
-       } else {
-               list = &ep->outlist;
-
-               spin_lock_irqsave(&ep->lock, flags);
-               if (list->count > 1) {
-                       for (scan = list->head; scan != list->tail;
-                            scan = scan->next)
-                               count += scan->size;
-       }
-               spin_unlock_irqrestore(&ep->lock, flags);
-       }
-
-       return count;
-}
-
-
-void
-usbdev_exit(void)
-{
-       endpoint_t *ep;
-       int i;
-
-       au_writel(0, USBD_INTEN);       // disable usb dev ints
-       au_writel(0, USBD_ENABLE);      // disable usb dev
-
-       free_irq(AU1000_USB_DEV_REQ_INT, &usbdev);
-       free_irq(AU1000_USB_DEV_SUS_INT, &usbdev);
-
-       // free all control endpoint resources
-       ep = &usbdev.ep[0];
-       free_au1000_dma(ep->indma);
-       free_au1000_dma(ep->outdma);
-       endpoint_flush(ep);
-
-       // free ep resources
-       for (i = 2; i < 6; i++) {
-               ep = &usbdev.ep[i];
-               if (!ep->active) continue;
-
-               if (ep->direction == USB_DIR_IN) {
-                       free_au1000_dma(ep->indma);
-               } else {
-               free_au1000_dma(ep->outdma);
-               }
-               endpoint_flush(ep);
-       }
-
-       kfree(usbdev.full_conf_desc);
-}
-
-int
-usbdev_init(struct usb_device_descriptor* dev_desc,
-           struct usb_config_descriptor* config_desc,
-           struct usb_interface_descriptor* if_desc,
-           struct usb_endpoint_descriptor* ep_desc,
-           struct usb_string_descriptor* str_desc[],
-           void (*cb)(usbdev_cb_type_t, unsigned long, void *),
-           void* cb_data)
-{
-       endpoint_t *ep0;
-       int i, ret=0;
-       u8* fcd;
-
-       if (dev_desc->bNumConfigurations > 1 ||
-           config_desc->bNumInterfaces > 1 ||
-           if_desc->bNumEndpoints > 4) {
-               err("Only one config, one i/f, and no more "
-                   "than 4 ep's allowed");
-               ret = -EINVAL;
-               goto out;
-       }
-
-       if (!cb) {
-               err("Function-layer callback required");
-               ret = -EINVAL;
-               goto out;
-       }
-
-       if (dev_desc->bMaxPacketSize0 != USBDEV_EP0_MAX_PACKET_SIZE) {
-               warn("EP0 Max Packet size must be %d",
-                    USBDEV_EP0_MAX_PACKET_SIZE);
-               dev_desc->bMaxPacketSize0 = USBDEV_EP0_MAX_PACKET_SIZE;
-       }
-
-       memset(&usbdev, 0, sizeof(struct usb_dev));
-
-       usbdev.state = DEFAULT;
-       usbdev.dev_desc = dev_desc;
-       usbdev.if_desc = if_desc;
-       usbdev.conf_desc = config_desc;
-       for (i=0; i<6; i++)
-               usbdev.str_desc[i] = str_desc[i];
-       usbdev.func_cb = cb;
-       usbdev.cb_data = cb_data;
-
-       /* Initialize default control endpoint */
-       ep0 = &usbdev.ep[0];
-       ep0->active = 1;
-       ep0->type = CONTROL_EP;
-       ep0->max_pkt_size = USBDEV_EP0_MAX_PACKET_SIZE;
-       spin_lock_init(&ep0->lock);
-       ep0->desc = NULL;       // ep0 has no descriptor
-       ep0->address = 0;
-       ep0->direction = 0;
-       ep0->reg = &ep_reg[0];
-
-       /* Initialize the other requested endpoints */
-       for (i = 0; i < if_desc->bNumEndpoints; i++) {
-               struct usb_endpoint_descriptor* epd = &ep_desc[i];
-       endpoint_t *ep;
-
-               if ((epd->bEndpointAddress & 0x80) == USB_DIR_IN) {
-                       ep = &usbdev.ep[2];
-                       ep->address = 2;
-                       if (ep->active) {
-                               ep = &usbdev.ep[3];
-                               ep->address = 3;
-                               if (ep->active) {
-                                       err("too many IN ep's requested");
-                                       ret = -ENODEV;
-                                       goto out;
-       }
-       }
-               } else {
-                       ep = &usbdev.ep[4];
-                       ep->address = 4;
-                       if (ep->active) {
-                               ep = &usbdev.ep[5];
-                               ep->address = 5;
-                               if (ep->active) {
-                                       err("too many OUT ep's requested");
-                                       ret = -ENODEV;
-                                       goto out;
-       }
-       }
-               }
-
-               ep->active = 1;
-               epd->bEndpointAddress &= ~0x0f;
-               epd->bEndpointAddress |= (u8)ep->address;
-               ep->direction = epd->bEndpointAddress & 0x80;
-               ep->type = epd->bmAttributes & 0x03;
-               ep->max_pkt_size = le16_to_cpu(epd->wMaxPacketSize);
-               spin_lock_init(&ep->lock);
-               ep->desc = epd;
-               ep->reg = &ep_reg[ep->address];
-               }
-
-       /*
-        * initialize the full config descriptor
-        */
-       usbdev.full_conf_desc = fcd = kmalloc(le16_to_cpu(config_desc->wTotalLength),
-                                             ALLOC_FLAGS);
-       if (!fcd) {
-               err("failed to alloc full config descriptor");
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       memcpy(fcd, config_desc, USB_DT_CONFIG_SIZE);
-       fcd += USB_DT_CONFIG_SIZE;
-       memcpy(fcd, if_desc, USB_DT_INTERFACE_SIZE);
-       fcd += USB_DT_INTERFACE_SIZE;
-       for (i = 0; i < if_desc->bNumEndpoints; i++) {
-               memcpy(fcd, &ep_desc[i], USB_DT_ENDPOINT_SIZE);
-               fcd += USB_DT_ENDPOINT_SIZE;
-       }
-
-       /* Now we're ready to enable the controller */
-       au_writel(0x0002, USBD_ENABLE);
-       udelay(100);
-       au_writel(0x0003, USBD_ENABLE);
-       udelay(100);
-
-       /* build and send config table based on ep descriptors */
-       for (i = 0; i < 6; i++) {
-               endpoint_t *ep;
-               if (i == 1)
-                       continue; // skip dummy ep
-               ep = &usbdev.ep[i];
-               if (ep->active) {
-                       au_writel((ep->address << 4) | 0x04, USBD_CONFIG);
-                       au_writel(((ep->max_pkt_size & 0x380) >> 7) |
-                                 (ep->direction >> 4) | (ep->type << 4),
-                                 USBD_CONFIG);
-                       au_writel((ep->max_pkt_size & 0x7f) << 1, USBD_CONFIG);
-                       au_writel(0x00, USBD_CONFIG);
-                       au_writel(ep->address, USBD_CONFIG);
-               } else {
-                       u8 dir = (i==2 || i==3) ? DIR_IN : DIR_OUT;
-                       au_writel((i << 4) | 0x04, USBD_CONFIG);
-                       au_writel(((16 & 0x380) >> 7) | dir |
-                                 (BULK_EP << 4), USBD_CONFIG);
-                       au_writel((16 & 0x7f) << 1, USBD_CONFIG);
-                       au_writel(0x00, USBD_CONFIG);
-                       au_writel(i, USBD_CONFIG);
-               }
-       }
-
-       /*
-        * Enable Receive FIFO Complete interrupts only. Transmit
-        * complete is being handled by the DMA done interrupts.
-        */
-       au_writel(0x31, USBD_INTEN);
-
-       /*
-        * Controller is now enabled, request DMA and IRQ
-        * resources.
-        */
-
-       /* request the USB device transfer complete interrupt */
-       if (request_irq(AU1000_USB_DEV_REQ_INT, req_sus_intr, IRQF_DISABLED,
-                       "USBdev req", &usbdev)) {
-               err("Can't get device request intr");
-               ret = -ENXIO;
-               goto out;
-       }
-       /* request the USB device suspend interrupt */
-       if (request_irq(AU1000_USB_DEV_SUS_INT, req_sus_intr, IRQF_DISABLED,
-                       "USBdev sus", &usbdev)) {
-               err("Can't get device suspend intr");
-               ret = -ENXIO;
-               goto out;
-       }
-
-       /* Request EP0 DMA and IRQ */
-       if ((ep0->indma = request_au1000_dma(ep_dma_id[0].id,
-                                            ep_dma_id[0].str,
-                                            dma_done_ep0_intr,
-                                            IRQF_DISABLED,
-                                            &usbdev)) < 0) {
-               err("Can't get %s DMA", ep_dma_id[0].str);
-               ret = -ENXIO;
-               goto out;
-       }
-       if ((ep0->outdma = request_au1000_dma(ep_dma_id[1].id,
-                                             ep_dma_id[1].str,
-                                             NULL, 0, NULL)) < 0) {
-               err("Can't get %s DMA", ep_dma_id[1].str);
-               ret = -ENXIO;
-               goto out;
-       }
-
-       // Flush the ep0 buffers and FIFOs
-       endpoint_flush(ep0);
-       // start packet reception on ep0
-       kickstart_receive_packet(ep0);
-
-       /* Request DMA and IRQ for the other endpoints */
-       for (i = 2; i < 6; i++) {
-               endpoint_t *ep = &usbdev.ep[i];
-               if (!ep->active)
-                       continue;
-
-               // Flush the endpoint buffers and FIFOs
-               endpoint_flush(ep);
-
-               if (ep->direction == USB_DIR_IN) {
-                       ep->indma =
-                               request_au1000_dma(ep_dma_id[ep->address].id,
-                                                  ep_dma_id[ep->address].str,
-                                                  dma_done_ep_intr,
-                                                  IRQF_DISABLED,
-                                                  &usbdev);
-                       if (ep->indma < 0) {
-                               err("Can't get %s DMA",
-                                   ep_dma_id[ep->address].str);
-                               ret = -ENXIO;
-                               goto out;
-                       }
-               } else {
-                       ep->outdma =
-                               request_au1000_dma(ep_dma_id[ep->address].id,
-                                                  ep_dma_id[ep->address].str,
-                                                  NULL, 0, NULL);
-                       if (ep->outdma < 0) {
-                               err("Can't get %s DMA",
-                                   ep_dma_id[ep->address].str);
-                               ret = -ENXIO;
-                               goto out;
-                       }
-
-                       // start packet reception on OUT endpoint
-                       kickstart_receive_packet(ep);
-               }
-       }
-
- out:
-       if (ret)
-               usbdev_exit();
-       return ret;
-}
-
-EXPORT_SYMBOL(usbdev_init);
-EXPORT_SYMBOL(usbdev_exit);
-EXPORT_SYMBOL(usbdev_alloc_packet);
-EXPORT_SYMBOL(usbdev_receive_packet);
-EXPORT_SYMBOL(usbdev_send_packet);
-EXPORT_SYMBOL(usbdev_get_byte_count);
index 7a79293f852730e403309786bf4644d5b5cc7103..8b08edb977be5fd43ed263d17ac2394c391908a9 100644 (file)
@@ -58,11 +58,6 @@ void __init board_setup(void)
 
        pin_func = 0;
        /* not valid for 1550 */
-#ifdef CONFIG_AU1X00_USB_DEVICE
-       // 2nd USB port is USB device
-       pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8000);
-       au_writel(pin_func, SYS_PINFUNC);
-#endif
 
 #if defined(CONFIG_IRDA) && (defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1100))
        /* set IRFIRSEL instead of GPIO15 */
index e917e54fc68359d7b7fd49db5b6f548f4f92d2ce..13f9bf5f91a628c10e92b6522c9db2d9a921d87d 100644 (file)
@@ -51,15 +51,11 @@ void board_reset (void)
 
 void __init board_setup(void)
 {
-#if defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE)
-#ifdef CONFIG_AU1X00_USB_DEVICE
-       // 2nd USB port is USB device
-       au_writel(au_readl(SYS_PINFUNC) & (u32)(~0x8000), SYS_PINFUNC);
-#endif
+#ifdef CONFIG_USB_OHCI
        // enable USB power switch
        au_writel( au_readl(GPIO2_DIR) | 0x10, GPIO2_DIR );
        au_writel( 0x100000, GPIO2_OUTPUT );
-#endif // defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE)
+#endif // defined (CONFIG_USB_OHCI)
 
 #ifdef CONFIG_PCI
 #if defined(__MIPSEB__)
index 1cf18e16ab54d7f02711356c073445771ebf992c..824cfafaff92ad8ac32217601a79cf43ca05423b 100644 (file)
@@ -54,7 +54,7 @@ void __init board_setup(void)
        au_writel(0, SYS_PINSTATERD);
        udelay(100);
 
-#if defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE)
+#ifdef CONFIG_USB_OHCI
        /* zero and disable FREQ2 */
        sys_freqctrl = au_readl(SYS_FREQCTRL0);
        sys_freqctrl &= ~0xFFF00000;
@@ -104,23 +104,19 @@ void __init board_setup(void)
         */
 #ifdef CONFIG_USB_OHCI
        sys_clksrc |= ((4<<12) | (0<<11) | (0<<10));
-#endif
-#ifdef CONFIG_AU1X00_USB_DEVICE
-       sys_clksrc |= ((4<<7) | (0<<6) | (0<<5));
 #endif
        au_writel(sys_clksrc, SYS_CLKSRC);
 
        // configure pins GPIO[14:9] as GPIO
        pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8080);
 
-#ifndef CONFIG_AU1X00_USB_DEVICE
        // 2nd USB port is USB host
        pin_func |= 0x8000;
-#endif
+
        au_writel(pin_func, SYS_PINFUNC);
        au_writel(0x2800, SYS_TRIOUTCLR);
        au_writel(0x0030, SYS_OUTPUTCLR);
-#endif // defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE)
+#endif // defined (CONFIG_USB_OHCI)
 
        // make gpio 15 an input (for interrupt line)
        pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x100);
index db27b9331ff3025be933d452f93851dd89f510ff..2d1533f116c0c020f57a4de59c952b6167f3545c 100644 (file)
@@ -55,7 +55,7 @@ void __init board_setup(void)
        au_writel(0, SYS_PININPUTEN);
        udelay(100);
 
-#if defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE)
+#ifdef CONFIG_USB_OHCI
        // configure pins GPIO[14:9] as GPIO
        pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x80);
 
@@ -92,12 +92,10 @@ void __init board_setup(void)
 
        // get USB Functionality pin state (device vs host drive pins)
        pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8000);
-#ifndef CONFIG_AU1X00_USB_DEVICE
        // 2nd USB port is USB host
        pin_func |= 0x8000;
-#endif
        au_writel(pin_func, SYS_PINFUNC);
-#endif // defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE)
+#endif // defined (CONFIG_USB_OHCI)
 
        /* Enable sys bus clock divider when IDLE state or no bus activity. */
        au_writel(au_readl(SYS_POWERCTRL) | (0x3 << 5), SYS_POWERCTRL);
index f66779f0d4cdd6fb7e5b09083311d7a9481522c5..91983ba407c4731fd64c40358a1b56c29bdb07d3 100644 (file)
@@ -65,7 +65,7 @@ int __initdata au1xxx_nr_irqs = ARRAY_SIZE(au1xxx_irq_map);
  */
 static volatile int pb1200_cascade_en=0;
 
-irqreturn_t pb1200_cascade_handler( int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t pb1200_cascade_handler( int irq, void *dev_id)
 {
        unsigned short bisr = bcsr->int_status;
        int extirq_nr = 0;
@@ -76,8 +76,9 @@ irqreturn_t pb1200_cascade_handler( int irq, void *dev_id, struct pt_regs *regs)
        {
                extirq_nr = (PB1200_INT_BEGIN-1) + au_ffs(bisr);
                /* Ack and dispatch IRQ */
-               do_IRQ(extirq_nr,regs);
+               do_IRQ(extirq_nr);
        }
+
        return IRQ_RETVAL(1);
 }
 
index 1a9a293de6aba685833689b5ca2e4b5d3ea5111a..0ffdb4fd575b803369e99e64cff34ef98a398a0d 100644 (file)
@@ -56,7 +56,7 @@ void __init board_setup(void)
        au_writel(0, SYS_PINSTATERD);
        udelay(100);
 
-#if defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE)
+#ifdef CONFIG_USB_OHCI
 
        /* GPIO201 is input for PCMCIA card detect */
        /* GPIO203 is input for PCMCIA interrupt request */
@@ -87,20 +87,15 @@ void __init board_setup(void)
         */
 #ifdef CONFIG_USB_OHCI
        sys_clksrc |= ((4<<12) | (0<<11) | (0<<10));
-#endif
-#ifdef CONFIG_AU1X00_USB_DEVICE
-       sys_clksrc |= ((4<<7) | (0<<6) | (0<<5));
 #endif
        au_writel(sys_clksrc, SYS_CLKSRC);
 
 
        pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8000);
-#ifndef CONFIG_AU1X00_USB_DEVICE
        // 2nd USB port is USB host
        pin_func |= 0x8000;
-#endif
        au_writel(pin_func, SYS_PINFUNC);
-#endif // defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE)
+#endif // defined (CONFIG_USB_OHCI)
 
 
 
index c04505afa47f1894dc84481f9d440a038f8913e8..d289e3a868cfad3696d05b97e58fa2c7794507df 100644 (file)
@@ -112,7 +112,7 @@ int putDebugChar(int data)
 }
 
 /* KGDB interrupt handler */
-asmlinkage void excite_kgdb_inthdl(struct pt_regs *regs)
+asmlinkage void excite_kgdb_inthdl(void)
 {
        if (unlikely(
                ((titan_readl(UAIIR) & 0x7) == 4)
index 10bbb8cfb964453c4caa5efb64ab90c1088b402b..6af0b21ebc3291a4d8afb9f863f45b9d87d763b7 100644 (file)
@@ -38,7 +38,7 @@ static int iodev_open(struct inode *, struct file *);
 static int iodev_release(struct inode *, struct file *);
 static ssize_t iodev_read(struct file *, char __user *, size_t s, loff_t *);
 static unsigned int iodev_poll(struct file *, struct poll_table_struct *);
-static irqreturn_t iodev_irqhdl(int, void *, struct pt_regs *);
+static irqreturn_t iodev_irqhdl(int, void *);
 
 
 
@@ -108,16 +108,12 @@ static int __exit iodev_remove(struct device *dev)
        return misc_deregister(&miscdev);
 }
 
-
-
 static int iodev_open(struct inode *i, struct file *f)
 {
        return request_irq(iodev_irq, iodev_irqhdl, IRQF_DISABLED,
                           iodev_name, &miscdev);
 }
 
-
-
 static int iodev_release(struct inode *i, struct file *f)
 {
        free_irq(iodev_irq, &miscdev);
@@ -148,17 +144,13 @@ static unsigned int iodev_poll(struct file *f, struct poll_table_struct *p)
        return POLLOUT | POLLWRNORM;
 }
 
-
-
-
-static irqreturn_t iodev_irqhdl(int irq, void *ctxt, struct pt_regs *regs)
+static irqreturn_t iodev_irqhdl(int irq, void *ctxt)
 {
        wake_up(&wq);
+
        return IRQ_HANDLED;
 }
 
-
-
 static int __init iodev_init_module(void)
 {
        return driver_register(&iodev_driver);
index 511ad8730f548e8594b1b83fd34ab3d72e110191..2e2061a286c5664f45649c6def0d8fc101322583 100644 (file)
@@ -56,7 +56,7 @@ void __init arch_init_irq(void)
 #endif
 }
 
-asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+asmlinkage void plat_irq_dispatch(void)
 {
        const u32
                interrupts = read_c0_cause() >> 8,
@@ -67,7 +67,7 @@ asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
 
        /* process timer interrupt */
        if (pending & (1 << TIMER_IRQ)) {
-               do_IRQ(TIMER_IRQ, regs);
+               do_IRQ(TIMER_IRQ);
                return;
        }
 
@@ -80,7 +80,7 @@ asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
 #else
        if (pending & (1 << USB_IRQ)) {
 #endif
-               do_IRQ(USB_IRQ, regs);
+               do_IRQ(USB_IRQ);
                return;
        }
 
@@ -91,9 +91,9 @@ asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
        if ((pending & (1 << TITAN_IRQ)) && msgint) {
                ocd_writel(msgint, INTP0Clear0 + (TITAN_MSGINT / 0x20 * 0x10));
 #if defined(CONFIG_KGDB)
-               excite_kgdb_inthdl(regs);
+               excite_kgdb_inthdl();
 #endif
-               do_IRQ(TITAN_IRQ, regs);
+               do_IRQ(TITAN_IRQ);
                return;
        }
 
@@ -102,7 +102,7 @@ asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
        msgintmask  = ocd_readl(INTP0Mask0 + (FPGA0_MSGINT / 0x20 * 0x10));
        msgint      = msgintflags & msgintmask & (0x1 << (FPGA0_MSGINT % 0x20));
        if ((pending & (1 << FPGA0_IRQ)) && msgint) {
-               do_IRQ(FPGA0_IRQ, regs);
+               do_IRQ(FPGA0_IRQ);
                return;
        }
 
@@ -111,7 +111,7 @@ asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
        msgintmask  = ocd_readl(INTP0Mask0 + (FPGA1_MSGINT / 0x20 * 0x10));
        msgint      = msgintflags & msgintmask & (0x1 << (FPGA1_MSGINT % 0x20));
        if ((pending & (1 << FPGA1_IRQ)) && msgint) {
-               do_IRQ(FPGA1_IRQ, regs);
+               do_IRQ(FPGA1_IRQ);
                return;
        }
 
@@ -120,10 +120,10 @@ asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
        msgintmask  = ocd_readl(INTP0Mask0 + (PHY_MSGINT / 0x20 * 0x10));
        msgint      = msgintflags & msgintmask & (0x1 << (PHY_MSGINT % 0x20));
        if ((pending & (1 << PHY_IRQ)) && msgint) {
-               do_IRQ(PHY_IRQ, regs);
+               do_IRQ(PHY_IRQ);
                return;
        }
 
        /* Process spurious interrupts */
-       spurious_interrupt(regs);
+       spurious_interrupt();
 }
index 0b75f4fb719570ef4a8f29be227e8c1f3d5d00d0..82e569d5b02c3adc7e04ffe65f067defbd409265 100644 (file)
@@ -16,7 +16,6 @@
 #include <asm/i8259.h>
 #include <asm/irq_cpu.h>
 #include <asm/gt64120.h>
-#include <asm/ptrace.h>
 
 #include <asm/mach-cobalt/cobalt.h>
 
@@ -42,7 +41,7 @@
  *    15  - IDE1
  */
 
-static inline void galileo_irq(struct pt_regs *regs)
+static inline void galileo_irq(void)
 {
        unsigned int mask, pending, devfn;
 
@@ -52,7 +51,7 @@ static inline void galileo_irq(struct pt_regs *regs)
        if (pending & GALILEO_INTR_T0EXP) {
 
                GALILEO_OUTL(~GALILEO_INTR_T0EXP, GT_INTRCAUSE_OFS);
-               do_IRQ(COBALT_GALILEO_IRQ, regs);
+               do_IRQ(COBALT_GALILEO_IRQ);
 
        } else if (pending & GALILEO_INTR_RETRY_CTR) {
 
@@ -68,44 +67,31 @@ static inline void galileo_irq(struct pt_regs *regs)
        }
 }
 
-static inline void via_pic_irq(struct pt_regs *regs)
+static inline void via_pic_irq(void)
 {
        int irq;
 
        irq = i8259_irq();
        if (irq >= 0)
-               do_IRQ(irq, regs);
+               do_IRQ(irq);
 }
 
-asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+asmlinkage void plat_irq_dispatch(void)
 {
-       unsigned pending;
-
-       pending = read_c0_status() & read_c0_cause();
-
-       if (pending & CAUSEF_IP2)                       /* COBALT_GALILEO_IRQ (18) */
-
-               galileo_irq(regs);
-
-       else if (pending & CAUSEF_IP6)                  /* COBALT_VIA_IRQ (22) */
-
-               via_pic_irq(regs);
-
-       else if (pending & CAUSEF_IP3)                  /* COBALT_ETH0_IRQ (19) */
-
-               do_IRQ(COBALT_CPU_IRQ + 3, regs);
-
-       else if (pending & CAUSEF_IP4)                  /* COBALT_ETH1_IRQ (20) */
-
-               do_IRQ(COBALT_CPU_IRQ + 4, regs);
-
-       else if (pending & CAUSEF_IP5)                  /* COBALT_SERIAL_IRQ (21) */
-
-               do_IRQ(COBALT_CPU_IRQ + 5, regs);
-
-       else if (pending & CAUSEF_IP7)                  /* IRQ 23 */
-
-               do_IRQ(COBALT_CPU_IRQ + 7, regs);
+       unsigned pending = read_c0_status() & read_c0_cause();
+
+       if (pending & CAUSEF_IP2)               /* COBALT_GALILEO_IRQ (18) */
+               galileo_irq();
+       else if (pending & CAUSEF_IP6)          /* COBALT_VIA_IRQ (22) */
+               via_pic_irq();
+       else if (pending & CAUSEF_IP3)          /* COBALT_ETH0_IRQ (19) */
+               do_IRQ(COBALT_CPU_IRQ + 3);
+       else if (pending & CAUSEF_IP4)          /* COBALT_ETH1_IRQ (20) */
+               do_IRQ(COBALT_CPU_IRQ + 4);
+       else if (pending & CAUSEF_IP5)          /* COBALT_SERIAL_IRQ (21) */
+               do_IRQ(COBALT_CPU_IRQ + 5);
+       else if (pending & CAUSEF_IP7)          /* IRQ 23 */
+               do_IRQ(COBALT_CPU_IRQ + 7);
 }
 
 static struct irqaction irq_via = {
index 0b347cffc768d5c39b26f51e0ebf60f8b35729d8..bf9dc72b9720580af37436b250c468b077262ff3 100644 (file)
@@ -50,8 +50,8 @@ const char *get_system_type(void)
 
 void __init plat_timer_setup(struct irqaction *irq)
 {
-       /* Load timer value for 1KHz (TCLK is 50MHz) */
-       GALILEO_OUTL(50*1000*1000 / 1000, GT_TC0_OFS);
+       /* Load timer value for HZ (TCLK is 50MHz) */
+       GALILEO_OUTL(50*1000*1000 / HZ, GT_TC0_OFS);
 
        /* Enable timer */
        GALILEO_OUTL(GALILEO_ENTC0 | GALILEO_SELTC0, GT_TC_CONTROL_OFS);
index c6a015940b410d2929d1af85d6278f413bed8486..ba3bf733d27d5d9621c235bdf38413146e548899 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1
-# Thu Jul  6 10:02:58 2006
+# Linux kernel version: 2.6.19-rc1
+# Wed Oct 11 01:41:41 2006
 #
 CONFIG_MIPS=y
 
@@ -25,8 +25,6 @@ CONFIG_MIPS=y
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MIPS_EV64120 is not set
-# CONFIG_MIPS_IVR is not set
-# CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MACH_JAZZ is not set
 # CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
@@ -83,6 +81,7 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
 CONFIG_DMA_COHERENT=y
 CONFIG_CPU_BIG_ENDIAN=y
@@ -132,8 +131,8 @@ CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_64KB is not set
 # CONFIG_SIBYTE_DMA_PAGEOPS is not set
 CONFIG_MIPS_MT_DISABLED=y
-# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
@@ -185,9 +184,11 @@ CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
@@ -195,7 +196,9 @@ CONFIG_IKCONFIG_PROC=y
 # CONFIG_RELAY is not set
 CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -204,12 +207,12 @@ CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
 CONFIG_SLAB=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -228,6 +231,7 @@ CONFIG_STOP_MACHINE=y
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_BLK_DEV_IO_TRACE is not set
 
 #
@@ -249,18 +253,17 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 CONFIG_HW_HAS_PCI=y
 CONFIG_PCI=y
 CONFIG_PCI_DOMAINS=y
+# CONFIG_PCI_MULTITHREAD_PROBE is not set
 CONFIG_PCI_DEBUG=y
 CONFIG_MMU=y
 
 #
 # PCCARD (PCMCIA/CardBus) support
 #
-# CONFIG_PCCARD is not set
 
 #
 # PCI Hotplug Support
 #
-# CONFIG_HOTPLUG_PCI is not set
 
 #
 # Executable file formats
@@ -271,7 +274,7 @@ CONFIG_BINFMT_ELF=y
 CONFIG_MIPS32_COMPAT=y
 CONFIG_COMPAT=y
 CONFIG_MIPS32_O32=y
-# CONFIG_MIPS32_N32 is not set
+CONFIG_MIPS32_N32=y
 CONFIG_BINFMT_ELF32=y
 
 #
@@ -288,6 +291,7 @@ CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
+# CONFIG_XFRM_SUB_POLICY is not set
 CONFIG_NET_KEY=y
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
@@ -308,10 +312,12 @@ CONFIG_IP_PNP_BOOTP=y
 # CONFIG_INET_TUNNEL is not set
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=y
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IPV6 is not set
 # CONFIG_INET6_XFRM_TUNNEL is not set
 # CONFIG_INET6_TUNNEL is not set
@@ -341,7 +347,6 @@ CONFIG_NETWORK_SECMARK=y
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -368,7 +373,6 @@ CONFIG_NETWORK_SECMARK=y
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
 # CONFIG_DEBUG_DRIVER is not set
 # CONFIG_SYS_HYPERVISOR is not set
 
@@ -404,7 +408,7 @@ CONFIG_BLK_DEV_LOOP=m
 CONFIG_BLK_DEV_NBD=m
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_RAM is not set
-# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_BLK_DEV_INITRD=y
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
 
@@ -412,6 +416,7 @@ CONFIG_BLK_DEV_NBD=m
 # ATA/ATAPI/MFM/RLL support
 #
 CONFIG_IDE=y
+CONFIG_IDE_MAX_HWIFS=4
 CONFIG_BLK_DEV_IDE=y
 
 #
@@ -429,10 +434,40 @@ CONFIG_BLK_DEV_IDEFLOPPY=y
 # IDE chipset support/bugfixes
 #
 CONFIG_IDE_GENERIC=y
-# CONFIG_BLK_DEV_IDEPCI is not set
+CONFIG_BLK_DEV_IDEPCI=y
+# CONFIG_IDEPCI_SHARE_IRQ is not set
+# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_GENERIC=y
+# CONFIG_BLK_DEV_OPTI621 is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+# CONFIG_IDEDMA_PCI_AUTO is not set
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+CONFIG_BLK_DEV_CMD64X=y
+# CONFIG_BLK_DEV_TRIFLEX is not set
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_JMICRON is not set
+# CONFIG_BLK_DEV_SC1200 is not set
+# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT821X is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_PDC202XX_OLD is not set
+# CONFIG_BLK_DEV_PDC202XX_NEW is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+# CONFIG_BLK_DEV_SIIMAGE is not set
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_VIA82CXXX is not set
 # CONFIG_BLK_DEV_IDE_SWARM is not set
 # CONFIG_IDE_ARM is not set
-# CONFIG_BLK_DEV_IDEDMA is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
 # CONFIG_IDEDMA_AUTO is not set
 # CONFIG_BLK_DEV_HD is not set
 
@@ -441,6 +476,12 @@ CONFIG_IDE_GENERIC=y
 #
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -516,6 +557,7 @@ CONFIG_NET_SB1250_MAC=y
 # CONFIG_SK98LIN is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -650,7 +692,6 @@ CONFIG_I2C_CHARDEV=y
 # CONFIG_I2C_ALGOBIT is not set
 # CONFIG_I2C_ALGOPCF is not set
 # CONFIG_I2C_ALGOPCA is not set
-CONFIG_I2C_ALGO_SIBYTE=y
 
 #
 # I2C Hardware Bus support
@@ -712,12 +753,12 @@ CONFIG_I2C_DEBUG_CHIP=y
 #
 # Misc devices
 #
+# CONFIG_TIFM_CORE is not set
 
 #
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -729,6 +770,7 @@ CONFIG_VIDEO_V4L2=y
 #
 # CONFIG_FIRMWARE_EDID is not set
 # CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -811,6 +853,7 @@ CONFIG_FS_MBCACHE=y
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -840,8 +883,10 @@ CONFIG_DNOTIFY=y
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
-# CONFIG_TMPFS is not set
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 # CONFIG_CONFIGFS_FS is not set
@@ -851,6 +896,7 @@ CONFIG_RAMFS=y
 #
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
+# CONFIG_ECRYPT_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_HFSPLUS_FS is not set
 # CONFIG_BEFS_FS is not set
@@ -881,7 +927,6 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
 # CONFIG_CIFS is not set
-# CONFIG_CIFS_DEBUG2 is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
@@ -898,6 +943,10 @@ CONFIG_MSDOS_PARTITION=y
 #
 # CONFIG_NLS is not set
 
+#
+# Distributed Lock Manager
+#
+
 #
 # Profiling support
 #
@@ -907,7 +956,8 @@ CONFIG_MSDOS_PARTITION=y
 # Kernel hacking
 #
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
-CONFIG_PRINTK_TIME=y
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_MAGIC_SYSRQ=y
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_KERNEL=y
@@ -920,12 +970,15 @@ CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_DEBUG_SPINLOCK is not set
 CONFIG_DEBUG_MUTEXES=y
 # CONFIG_DEBUG_RWSEMS is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
 # CONFIG_DEBUG_INFO is not set
 # CONFIG_DEBUG_FS is not set
 # CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
 CONFIG_FORCED_INLINING=y
 # CONFIG_RCU_TORTURE_TEST is not set
 CONFIG_CROSSCOMPILE=y
@@ -946,6 +999,10 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
 # Cryptographic options
 #
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=m
 CONFIG_CRYPTO_HMAC=y
 CONFIG_CRYPTO_NULL=y
 CONFIG_CRYPTO_MD4=y
@@ -955,9 +1012,12 @@ CONFIG_CRYPTO_SHA256=y
 CONFIG_CRYPTO_SHA512=y
 CONFIG_CRYPTO_WP512=m
 CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
 CONFIG_CRYPTO_DES=y
 CONFIG_CRYPTO_BLOWFISH=y
 CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRYPTO_TWOFISH_COMMON=y
 CONFIG_CRYPTO_SERPENT=y
 CONFIG_CRYPTO_AES=m
 # CONFIG_CRYPTO_CAST5 is not set
diff --git a/arch/mips/configs/jazz_defconfig b/arch/mips/configs/jazz_defconfig
new file mode 100644 (file)
index 0000000..382083e
--- /dev/null
@@ -0,0 +1,1404 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.19-rc1
+# Sun Oct  8 19:03:07 2006
+#
+CONFIG_MIPS=y
+
+#
+# Machine selection
+#
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
+# CONFIG_BASLER_EXCITE is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+CONFIG_MACH_JAZZ=y
+# CONFIG_LASAT is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_WR_PPMC is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_3 is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
+# CONFIG_MARKEINS is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
+# CONFIG_ACER_PICA_61 is not set
+# CONFIG_MIPS_MAGNUM_4000 is not set
+CONFIG_OLIVETTI_M700=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_ARC=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_DMA_NEED_PCI_MAP_STATE=y
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_I8259=y
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_ARC32=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+CONFIG_ARC_MEMORY=y
+CONFIG_ARC_PROMLIB=y
+
+#
+# CPU selection
+#
+# CONFIG_CPU_MIPS32_R1 is not set
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+CONFIG_CPU_R4X00=y
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_R4X00=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
+
+#
+# Kernel type
+#
+CONFIG_32BIT=y
+# CONFIG_64BIT is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_MIPS_MT_DISABLED=y
+# CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
+# CONFIG_MIPS_VPE_LOADER is not set
+# CONFIG_64BIT_PHYS_ADDR is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+# CONFIG_HZ_48 is not set
+CONFIG_HZ_100=y
+# CONFIG_HZ_128 is not set
+# CONFIG_HZ_250 is not set
+# CONFIG_HZ_256 is not set
+# CONFIG_HZ_1000 is not set
+# CONFIG_HZ_1024 is not set
+CONFIG_SYS_SUPPORTS_100HZ=y
+CONFIG_HZ=100
+# CONFIG_PREEMPT_NONE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
+# CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
+# CONFIG_AUDIT is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_RELAY=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SHMEM=y
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_ISA=y
+CONFIG_MMU=y
+CONFIG_I8253=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PCI Hotplug Support
+#
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_MISC=m
+CONFIG_TRAD_SIGNALS=y
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=m
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+CONFIG_NET_KEY=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+CONFIG_IPV6=m
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+# CONFIG_IPV6_MIP6 is not set
+CONFIG_INET6_XFRM_TUNNEL=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_TUNNEL=m
+# CONFIG_IPV6_SUBTREES is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+CONFIG_NETWORK_SECMARK=y
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_BRIDGE_NETFILTER=y
+
+#
+# Core Netfilter Configuration
+#
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+# CONFIG_NETFILTER_XT_TARGET_DSCP is not set
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_TARGET_SECMARK=m
+# CONFIG_NETFILTER_XT_TARGET_CONNSECMARK is not set
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_DCCP=m
+# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
+CONFIG_NETFILTER_XT_MATCH_ESP=m
+CONFIG_NETFILTER_XT_MATCH_HELPER=m
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_POLICY=m
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_QUOTA=m
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_SCTP=m
+CONFIG_NETFILTER_XT_MATCH_STATE=m
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_IP_NF_CONNTRACK=m
+# CONFIG_IP_NF_CT_ACCT is not set
+CONFIG_IP_NF_CONNTRACK_MARK=y
+CONFIG_IP_NF_CONNTRACK_SECMARK=y
+CONFIG_IP_NF_CONNTRACK_EVENTS=y
+CONFIG_IP_NF_CONNTRACK_NETLINK=m
+CONFIG_IP_NF_CT_PROTO_SCTP=m
+CONFIG_IP_NF_FTP=m
+CONFIG_IP_NF_IRC=m
+# CONFIG_IP_NF_NETBIOS_NS is not set
+CONFIG_IP_NF_TFTP=m
+CONFIG_IP_NF_AMANDA=m
+CONFIG_IP_NF_PPTP=m
+CONFIG_IP_NF_H323=m
+CONFIG_IP_NF_SIP=m
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_IPRANGE=m
+CONFIG_IP_NF_MATCH_TOS=m
+CONFIG_IP_NF_MATCH_RECENT=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_AH=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_MATCH_OWNER=m
+CONFIG_IP_NF_MATCH_ADDRTYPE=m
+CONFIG_IP_NF_MATCH_HASHLIMIT=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_IP_NF_TARGET_TCPMSS=m
+CONFIG_IP_NF_NAT=m
+CONFIG_IP_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_IP_NF_TARGET_NETMAP=m
+CONFIG_IP_NF_TARGET_SAME=m
+CONFIG_IP_NF_NAT_SNMP_BASIC=m
+CONFIG_IP_NF_NAT_IRC=m
+CONFIG_IP_NF_NAT_FTP=m
+CONFIG_IP_NF_NAT_TFTP=m
+CONFIG_IP_NF_NAT_AMANDA=m
+CONFIG_IP_NF_NAT_PPTP=m
+CONFIG_IP_NF_NAT_H323=m
+CONFIG_IP_NF_NAT_SIP=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_TOS=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_TTL=m
+CONFIG_IP_NF_TARGET_CLUSTERIP=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+
+#
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
+#
+CONFIG_IP6_NF_QUEUE=m
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_MATCH_RT=m
+CONFIG_IP6_NF_MATCH_OPTS=m
+CONFIG_IP6_NF_MATCH_FRAG=m
+CONFIG_IP6_NF_MATCH_HL=m
+CONFIG_IP6_NF_MATCH_OWNER=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+CONFIG_IP6_NF_MATCH_AH=m
+CONFIG_IP6_NF_MATCH_EUI64=m
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_TARGET_REJECT=m
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_IP6_NF_TARGET_HL=m
+CONFIG_IP6_NF_RAW=m
+
+#
+# DECnet: Netfilter Configuration
+#
+CONFIG_DECNET_NF_GRABULATOR=m
+
+#
+# Bridge: Netfilter Configuration
+#
+CONFIG_BRIDGE_NF_EBTABLES=m
+CONFIG_BRIDGE_EBT_BROUTE=m
+CONFIG_BRIDGE_EBT_T_FILTER=m
+CONFIG_BRIDGE_EBT_T_NAT=m
+CONFIG_BRIDGE_EBT_802_3=m
+CONFIG_BRIDGE_EBT_AMONG=m
+CONFIG_BRIDGE_EBT_ARP=m
+CONFIG_BRIDGE_EBT_IP=m
+CONFIG_BRIDGE_EBT_LIMIT=m
+CONFIG_BRIDGE_EBT_MARK=m
+CONFIG_BRIDGE_EBT_PKTTYPE=m
+CONFIG_BRIDGE_EBT_STP=m
+CONFIG_BRIDGE_EBT_VLAN=m
+CONFIG_BRIDGE_EBT_ARPREPLY=m
+CONFIG_BRIDGE_EBT_DNAT=m
+CONFIG_BRIDGE_EBT_MARK_T=m
+CONFIG_BRIDGE_EBT_REDIRECT=m
+CONFIG_BRIDGE_EBT_SNAT=m
+CONFIG_BRIDGE_EBT_LOG=m
+CONFIG_BRIDGE_EBT_ULOG=m
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+CONFIG_BRIDGE=m
+# CONFIG_VLAN_8021Q is not set
+CONFIG_DECNET=m
+# CONFIG_DECNET_ROUTER is not set
+CONFIG_LLC=m
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_CLK_JIFFIES=y
+# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set
+# CONFIG_NET_SCH_CLK_CPU is not set
+
+#
+# Queueing/Scheduling
+#
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_INGRESS=m
+
+#
+# Classification
+#
+CONFIG_NET_CLS=y
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_ROUTE=y
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+# CONFIG_CLS_U32_PERF is not set
+# CONFIG_CLS_U32_MARK is not set
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+# CONFIG_NET_EMATCH is not set
+# CONFIG_NET_CLS_ACT is not set
+CONFIG_NET_CLS_POLICE=y
+# CONFIG_NET_CLS_IND is not set
+CONFIG_NET_ESTIMATOR=y
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+CONFIG_HAMRADIO=y
+
+#
+# Packet Radio protocols
+#
+CONFIG_AX25=m
+CONFIG_AX25_DAMA_SLAVE=y
+CONFIG_NETROM=m
+CONFIG_ROSE=m
+
+#
+# AX.25 network device drivers
+#
+CONFIG_MKISS=m
+CONFIG_6PACK=m
+CONFIG_BPQETHER=m
+# CONFIG_BAYCOM_SER_FDX is not set
+# CONFIG_BAYCOM_SER_HDX is not set
+# CONFIG_BAYCOM_PAR is not set
+# CONFIG_BAYCOM_EPP is not set
+# CONFIG_YAM is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_SOFTMAC=m
+# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set
+CONFIG_WIRELESS_EXT=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=m
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+CONFIG_PARPORT=m
+CONFIG_PARPORT_PC=m
+# CONFIG_PARPORT_PC_FIFO is not set
+# CONFIG_PARPORT_PC_SUPERIO is not set
+# CONFIG_PARPORT_GSC is not set
+# CONFIG_PARPORT_AX88796 is not set
+CONFIG_PARPORT_1284=y
+
+#
+# Plug and Play support
+#
+# CONFIG_PNP is not set
+
+#
+# Block devices
+#
+CONFIG_BLK_DEV_FD=m
+CONFIG_PARIDE=m
+CONFIG_PARIDE_PARPORT=m
+
+#
+# Parallel IDE high-level drivers
+#
+CONFIG_PARIDE_PD=m
+CONFIG_PARIDE_PCD=m
+CONFIG_PARIDE_PF=m
+CONFIG_PARIDE_PT=m
+CONFIG_PARIDE_PG=m
+
+#
+# Parallel IDE protocol modules
+#
+CONFIG_PARIDE_ATEN=m
+CONFIG_PARIDE_BPCK=m
+CONFIG_PARIDE_BPCK6=m
+CONFIG_PARIDE_COMM=m
+CONFIG_PARIDE_DSTR=m
+CONFIG_PARIDE_FIT2=m
+CONFIG_PARIDE_FIT3=m
+CONFIG_PARIDE_EPAT=m
+# CONFIG_PARIDE_EPATC8 is not set
+CONFIG_PARIDE_EPIA=m
+CONFIG_PARIDE_FRIQ=m
+CONFIG_PARIDE_FRPW=m
+CONFIG_PARIDE_KBIC=m
+CONFIG_PARIDE_KTTI=m
+CONFIG_PARIDE_ON20=m
+CONFIG_PARIDE_ON26=m
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_RAM=m
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+CONFIG_ATA_OVER_ETH=m
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+CONFIG_RAID_ATTRS=m
+CONFIG_SCSI=y
+CONFIG_SCSI_NETLINK=y
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=m
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+CONFIG_SCSI_CONSTANTS=y
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI Transports
+#
+CONFIG_SCSI_SPI_ATTRS=y
+CONFIG_SCSI_FC_ATTRS=y
+CONFIG_SCSI_ISCSI_ATTRS=m
+CONFIG_SCSI_SAS_ATTRS=m
+# CONFIG_SCSI_SAS_LIBSAS is not set
+
+#
+# SCSI low-level drivers
+#
+CONFIG_ISCSI_TCP=m
+# CONFIG_SCSI_AHA152X is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_IN2000 is not set
+# CONFIG_SCSI_DTC3280 is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GENERIC_NCR5380 is not set
+# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
+CONFIG_SCSI_PPA=m
+CONFIG_SCSI_IMM=m
+# CONFIG_SCSI_IZIP_EPP16 is not set
+# CONFIG_SCSI_IZIP_SLOW_CTR is not set
+# CONFIG_SCSI_NCR53C406A is not set
+# CONFIG_SCSI_PAS16 is not set
+# CONFIG_SCSI_PSI240I is not set
+# CONFIG_SCSI_QLOGIC_FAS is not set
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_DEBUG is not set
+CONFIG_JAZZ_ESP=y
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=m
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID456=m
+CONFIG_MD_RAID5_RESHAPE=y
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+# CONFIG_DM_DEBUG is not set
+# CONFIG_DM_CRYPT is not set
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_EMC=m
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=m
+CONFIG_BONDING=m
+CONFIG_EQUALIZER=m
+CONFIG_TUN=m
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+CONFIG_PHYLIB=m
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+CONFIG_VITESSE_PHY=m
+CONFIG_SMSC_PHY=m
+# CONFIG_FIXED_PHY is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_MIPS_JAZZ_SONIC=y
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_DM9000 is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_HP100 is not set
+CONFIG_NET_ISA=y
+# CONFIG_E2100 is not set
+# CONFIG_EWRK3 is not set
+# CONFIG_EEXPRESS is not set
+# CONFIG_EEXPRESS_PRO is not set
+# CONFIG_HPLAN_PLUS is not set
+# CONFIG_HPLAN is not set
+# CONFIG_LP486E is not set
+# CONFIG_ETH16I is not set
+CONFIG_NE2000=m
+# CONFIG_SEEQ8005 is not set
+CONFIG_NET_PCI=y
+# CONFIG_AC3200 is not set
+# CONFIG_APRICOT is not set
+# CONFIG_CS89x0 is not set
+# CONFIG_LAN_SAA9730 is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+CONFIG_PLIP=m
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+CONFIG_INPUT_FF_MEMLESS=m
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_INPORT is not set
+# CONFIG_MOUSE_LOGIBM is not set
+# CONFIG_MOUSE_PC110PAD is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+CONFIG_SERIO_PARKBD=m
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIO_RAW=m
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=m
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+CONFIG_SERIAL_8250_EXTENDED=y
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_8250_DETECT_IRQ=y
+CONFIG_SERIAL_8250_RSA=y
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=m
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+CONFIG_PRINTER=m
+# CONFIG_LP_CONSOLE is not set
+CONFIG_PPDEV=m
+CONFIG_TIPAR=m
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_HW_RANDOM is not set
+CONFIG_RTC=m
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+CONFIG_W1=m
+CONFIG_W1_CON=y
+
+#
+# 1-wire Bus Masters
+#
+
+#
+# 1-wire Slaves
+#
+# CONFIG_W1_SLAVE_THERM is not set
+# CONFIG_W1_SLAVE_SMEM is not set
+# CONFIG_W1_SLAVE_DS2433 is not set
+
+#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
+# Misc devices
+#
+# CONFIG_TIFM_CORE is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB is not set
+
+#
+# Console display driver support
+#
+CONFIG_VGA_CONSOLE=y
+# CONFIG_VGACON_SOFT_SCROLLBACK is not set
+# CONFIG_MDA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# InfiniBand support
+#
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=m
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+CONFIG_REISERFS_FS=m
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_XFS_FS=m
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_SECURITY=y
+# CONFIG_XFS_POSIX_ACL is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+CONFIG_MINIX_FS=m
+CONFIG_ROMFS_FS=m
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+CONFIG_QUOTACTL=y
+CONFIG_DNOTIFY=y
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_ZISOFS_FS=m
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+CONFIG_NTFS_FS=m
+# CONFIG_NTFS_DEBUG is not set
+# CONFIG_NTFS_RW is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+CONFIG_ADFS_FS=m
+# CONFIG_ADFS_FS_RW is not set
+CONFIG_AFFS_FS=m
+# CONFIG_ECRYPT_FS is not set
+CONFIG_HFS_FS=m
+# CONFIG_HFSPLUS_FS is not set
+CONFIG_BEFS_FS=m
+# CONFIG_BEFS_DEBUG is not set
+CONFIG_BFS_FS=m
+CONFIG_EFS_FS=m
+CONFIG_CRAMFS=m
+CONFIG_VXFS_FS=m
+CONFIG_HPFS_FS=m
+CONFIG_QNX4FS_FS=m
+CONFIG_SYSV_FS=m
+CONFIG_UFS_FS=m
+# CONFIG_UFS_FS_WRITE is not set
+# CONFIG_UFS_DEBUG is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
+# CONFIG_NFSD_V4 is not set
+CONFIG_NFSD_TCP=y
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=m
+CONFIG_SUNRPC_GSS=m
+CONFIG_RPCSEC_GSS_KRB5=m
+CONFIG_RPCSEC_GSS_SPKM3=m
+CONFIG_SMB_FS=m
+# CONFIG_SMB_NLS_DEFAULT is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
+# CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
+CONFIG_NCP_FS=m
+CONFIG_NCPFS_PACKET_SIGNING=y
+CONFIG_NCPFS_IOCTL_LOCKING=y
+CONFIG_NCPFS_STRONG=y
+CONFIG_NCPFS_NFS_NS=y
+CONFIG_NCPFS_OS2_NS=y
+CONFIG_NCPFS_SMALLDOS=y
+CONFIG_NCPFS_NLS=y
+CONFIG_NCPFS_EXTRAS=y
+CONFIG_CODA_FS=m
+CONFIG_CODA_FS_OLD_API=y
+CONFIG_AFS_FS=m
+CONFIG_RXRPC=m
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+
+#
+# Native Language Support
+#
+CONFIG_NLS=m
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+
+#
+# Distributed Lock Manager
+#
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_DEBUG_FS is not set
+CONFIG_CROSSCOMPILE=y
+CONFIG_CMDLINE=""
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=m
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
+CONFIG_PLIST=y
index aeefe2873e38fde99f986f266f93d6249eba533d..101e80347dcefe3edb49e2c2f134910869f66631 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1
-# Thu Jul  6 10:04:13 2006
+# Linux kernel version: 2.6.19-rc1
+# Fri Oct  6 17:34:55 2006
 #
 CONFIG_MIPS=y
 
@@ -25,8 +25,6 @@ CONFIG_MIPS=y
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MIPS_EV64120 is not set
-# CONFIG_MIPS_IVR is not set
-# CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MACH_JAZZ is not set
 # CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
@@ -67,6 +65,7 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
 CONFIG_ARCH_MAY_HAVE_PC_FDC=y
 CONFIG_DMA_NONCOHERENT=y
@@ -134,19 +133,19 @@ CONFIG_MIPS_CPU_SCACHE=y
 CONFIG_CPU_HAS_PREFETCH=y
 # CONFIG_MIPS_MT_DISABLED is not set
 # CONFIG_MIPS_MT_SMTC is not set
-# CONFIG_MIPS_MT_SMP is not set
-CONFIG_MIPS_VPE_LOADER=y
+CONFIG_MIPS_MT_SMP=y
+# CONFIG_MIPS_VPE_LOADER is not set
 CONFIG_MIPS_MT=y
 CONFIG_SYS_SUPPORTS_MULTITHREADING=y
 CONFIG_MIPS_MT_FPAFF=y
-CONFIG_MIPS_VPE_LOADER_TOM=y
-CONFIG_MIPS_VPE_APSP_API=y
-CONFIG_MIPS_APSP_KSPD=y
 # CONFIG_64BIT_PHYS_ADDR is not set
 CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_MIPSR2_IRQ_VI=y
+CONFIG_CPU_MIPSR2_SRS=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_IRQ_PER_CPU=y
 CONFIG_CPU_SUPPORTS_HIGHMEM=y
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_SELECT_MEMORY_MODEL=y
@@ -158,6 +157,9 @@ CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_RESOURCES_64BIT is not set
+CONFIG_SMP=y
+CONFIG_SYS_SUPPORTS_SMP=y
+CONFIG_NR_CPUS=2
 # CONFIG_HZ_48 is not set
 CONFIG_HZ_100=y
 # CONFIG_HZ_128 is not set
@@ -170,6 +172,7 @@ CONFIG_HZ=100
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+CONFIG_PREEMPT_BKL=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -178,7 +181,7 @@ CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 # Code maturity level options
 #
 CONFIG_EXPERIMENTAL=y
-CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
@@ -188,15 +191,20 @@ CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
+# CONFIG_CPUSETS is not set
 CONFIG_RELAY=y
 CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -204,12 +212,12 @@ CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
 CONFIG_SLAB=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -223,10 +231,12 @@ CONFIG_MODULE_UNLOAD=y
 CONFIG_MODVERSIONS=y
 CONFIG_MODULE_SRCVERSION_ALL=y
 CONFIG_KMOD=y
+CONFIG_STOP_MACHINE=y
 
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
@@ -249,6 +259,7 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 #
 CONFIG_HW_HAS_PCI=y
 CONFIG_PCI=y
+# CONFIG_PCI_MULTITHREAD_PROBE is not set
 CONFIG_MMU=y
 
 #
@@ -282,6 +293,7 @@ CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
+# CONFIG_XFRM_SUB_POLICY is not set
 CONFIG_NET_KEY=y
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
@@ -313,10 +325,12 @@ CONFIG_INET_XFRM_TUNNEL=m
 CONFIG_INET_TUNNEL=m
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=y
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
 
 #
 # IP: Virtual Server Configuration
@@ -358,11 +372,16 @@ CONFIG_IPV6_ROUTE_INFO=y
 CONFIG_INET6_AH=m
 CONFIG_INET6_ESP=m
 CONFIG_INET6_IPCOMP=m
+# CONFIG_IPV6_MIP6 is not set
 CONFIG_INET6_XFRM_TUNNEL=m
 CONFIG_INET6_TUNNEL=m
 CONFIG_INET6_XFRM_MODE_TRANSPORT=m
 CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
 CONFIG_IPV6_TUNNEL=m
+# CONFIG_IPV6_SUBTREES is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
 CONFIG_NETWORK_SECMARK=y
 CONFIG_NETFILTER=y
 # CONFIG_NETFILTER_DEBUG is not set
@@ -377,6 +396,7 @@ CONFIG_NETFILTER_NETLINK_LOG=m
 CONFIG_NETFILTER_XTABLES=m
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
 CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+# CONFIG_NETFILTER_XT_TARGET_DSCP is not set
 CONFIG_NETFILTER_XT_TARGET_MARK=m
 CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
 CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
@@ -387,6 +407,7 @@ CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
 CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
 CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
 CONFIG_NETFILTER_XT_MATCH_DCCP=m
+# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
 CONFIG_NETFILTER_XT_MATCH_ESP=m
 CONFIG_NETFILTER_XT_MATCH_HELPER=m
 CONFIG_NETFILTER_XT_MATCH_LENGTH=m
@@ -429,7 +450,6 @@ CONFIG_IP_NF_MATCH_IPRANGE=m
 CONFIG_IP_NF_MATCH_TOS=m
 CONFIG_IP_NF_MATCH_RECENT=m
 CONFIG_IP_NF_MATCH_ECN=m
-CONFIG_IP_NF_MATCH_DSCP=m
 CONFIG_IP_NF_MATCH_AH=m
 CONFIG_IP_NF_MATCH_TTL=m
 CONFIG_IP_NF_MATCH_OWNER=m
@@ -457,7 +477,6 @@ CONFIG_IP_NF_NAT_SIP=m
 CONFIG_IP_NF_MANGLE=m
 CONFIG_IP_NF_TARGET_TOS=m
 CONFIG_IP_NF_TARGET_ECN=m
-CONFIG_IP_NF_TARGET_DSCP=m
 CONFIG_IP_NF_TARGET_TTL=m
 CONFIG_IP_NF_TARGET_CLUSTERIP=m
 CONFIG_IP_NF_RAW=m
@@ -536,13 +555,12 @@ CONFIG_LLC=m
 # CONFIG_LLC2 is not set
 # CONFIG_IPX is not set
 CONFIG_ATALK=m
-CONFIG_DEV_APPLETALK=y
+CONFIG_DEV_APPLETALK=m
 CONFIG_IPDDP=m
 CONFIG_IPDDP_ENCAP=y
 CONFIG_IPDDP_DECAP=y
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-CONFIG_NET_DIVERT=y
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -604,6 +622,7 @@ CONFIG_IEEE80211_CRYPT_CCMP=m
 CONFIG_IEEE80211_SOFTMAC=m
 # CONFIG_IEEE80211_SOFTMAC_DEBUG is not set
 CONFIG_WIRELESS_EXT=y
+CONFIG_FIB_RULES=y
 
 #
 # Device Drivers
@@ -652,6 +671,7 @@ CONFIG_BLK_DEV_NBD=m
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 # CONFIG_BLK_DEV_INITRD is not set
 CONFIG_CDROM_PKTCDVD=m
 CONFIG_CDROM_PKTCDVD_BUFFERS=8
@@ -662,6 +682,7 @@ CONFIG_ATA_OVER_ETH=m
 # ATA/ATAPI/MFM/RLL support
 #
 CONFIG_IDE=y
+CONFIG_IDE_MAX_HWIFS=4
 CONFIG_BLK_DEV_IDE=y
 
 #
@@ -699,6 +720,7 @@ CONFIG_IDEDMA_PCI_AUTO=y
 # CONFIG_BLK_DEV_CS5530 is not set
 # CONFIG_BLK_DEV_HPT34X is not set
 # CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_JMICRON is not set
 # CONFIG_BLK_DEV_SC1200 is not set
 CONFIG_BLK_DEV_PIIX=y
 # CONFIG_BLK_DEV_IT821X is not set
@@ -721,6 +743,7 @@ CONFIG_IDEDMA_AUTO=y
 #
 CONFIG_RAID_ATTRS=m
 CONFIG_SCSI=m
+CONFIG_SCSI_NETLINK=y
 CONFIG_SCSI_PROC_FS=y
 
 #
@@ -742,12 +765,13 @@ CONFIG_SCSI_CONSTANTS=y
 CONFIG_SCSI_LOGGING=y
 
 #
-# SCSI Transport Attributes
+# SCSI Transports
 #
 CONFIG_SCSI_SPI_ATTRS=m
 CONFIG_SCSI_FC_ATTRS=m
 CONFIG_SCSI_ISCSI_ATTRS=m
 CONFIG_SCSI_SAS_ATTRS=m
+# CONFIG_SCSI_SAS_LIBSAS is not set
 
 #
 # SCSI low-level drivers
@@ -765,27 +789,34 @@ CONFIG_AIC7XXX_DEBUG_MASK=0
 CONFIG_AIC7XXX_REG_PRETTY_PRINT=y
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
 # CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ARCMSR is not set
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
-# CONFIG_SCSI_SATA is not set
 # CONFIG_SCSI_HPTIOP is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
 # CONFIG_SCSI_IPS is not set
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
 # CONFIG_SCSI_SYM53C8XX_2 is not set
-# CONFIG_SCSI_IPR is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
 # CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
 # CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
+
 #
 # Multi-device support (RAID and LVM)
 #
@@ -800,6 +831,7 @@ CONFIG_MD_RAID5_RESHAPE=y
 CONFIG_MD_MULTIPATH=m
 CONFIG_MD_FAULTY=m
 CONFIG_BLK_DEV_DM=m
+# CONFIG_DM_DEBUG is not set
 CONFIG_DM_CRYPT=m
 CONFIG_DM_SNAPSHOT=m
 CONFIG_DM_MIRROR=m
@@ -854,6 +886,7 @@ CONFIG_LXT_PHY=m
 CONFIG_CICADA_PHY=m
 CONFIG_VITESSE_PHY=m
 CONFIG_SMSC_PHY=m
+# CONFIG_FIXED_PHY is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -873,6 +906,7 @@ CONFIG_MII=y
 # CONFIG_HP100 is not set
 CONFIG_NET_PCI=y
 CONFIG_PCNET32=y
+# CONFIG_PCNET32_NAPI is not set
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
 # CONFIG_B44 is not set
@@ -909,6 +943,7 @@ CONFIG_PCNET32=y
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -956,6 +991,7 @@ CONFIG_PCNET32=y
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -1070,12 +1106,12 @@ CONFIG_RTC=y
 #
 # Misc devices
 #
+# CONFIG_TIFM_CORE is not set
 
 #
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -1093,6 +1129,7 @@ CONFIG_VIDEO_V4L2=y
 #
 # CONFIG_VGA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -1191,6 +1228,7 @@ CONFIG_XFS_QUOTA=y
 CONFIG_XFS_SECURITY=y
 CONFIG_XFS_POSIX_ACL=y
 # CONFIG_XFS_RT is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 CONFIG_MINIX_FS=m
 CONFIG_ROMFS_FS=m
@@ -1230,8 +1268,10 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 # CONFIG_CONFIGFS_FS is not set
@@ -1279,7 +1319,6 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
 # CONFIG_CIFS is not set
-# CONFIG_CIFS_DEBUG2 is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
@@ -1335,6 +1374,11 @@ CONFIG_NLS_KOI8_R=m
 CONFIG_NLS_KOI8_U=m
 CONFIG_NLS_UTF8=m
 
+#
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
 #
 # Profiling support
 #
@@ -1345,10 +1389,11 @@ CONFIG_NLS_UTF8=m
 #
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_KERNEL is not set
-CONFIG_LOG_BUF_SHIFT=14
+CONFIG_LOG_BUF_SHIFT=15
 # CONFIG_DEBUG_FS is not set
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
@@ -1363,6 +1408,10 @@ CONFIG_CMDLINE=""
 # Cryptographic options
 #
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=m
 CONFIG_CRYPTO_HMAC=y
 CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_MD4=m
@@ -1372,9 +1421,12 @@ CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_WP512=m
 CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
 CONFIG_CRYPTO_DES=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
 CONFIG_CRYPTO_SERPENT=m
 CONFIG_CRYPTO_AES=m
 CONFIG_CRYPTO_CAST5=m
index 741f8258075c96ab27e2a284a0bb258f1654e089..9e672f63a0aa854f297e4dfa2288aeb7f2e9a2fa 100644 (file)
@@ -76,7 +76,6 @@ CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
 CONFIG_SOC_AU1100=y
 CONFIG_SOC_AU1X00=y
 CONFIG_SWAP_IO_SPACE=y
-# CONFIG_AU1X00_USB_DEVICE is not set
 CONFIG_MIPS_L1_CACHE_SHIFT=5
 
 #
index 8576340714da703f2f81216d33f1a29e782cfa92..d0c0f4af1bff7c533b4b626108373d7a187d3221 100644 (file)
@@ -75,7 +75,6 @@ CONFIG_CPU_LITTLE_ENDIAN=y
 CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
 CONFIG_SOC_AU1500=y
 CONFIG_SOC_AU1X00=y
-# CONFIG_AU1X00_USB_DEVICE is not set
 CONFIG_MIPS_L1_CACHE_SHIFT=5
 
 #
index 26b0b9883496d8af2246a01f3b2f7c9ec8bc4e74..280a8001eacfd0a907261697db0f6721c0ddf976 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1
-# Thu Jul  6 10:04:18 2006
+# Linux kernel version: 2.6.19-rc2
+# Sat Oct 14 23:01:16 2006
 #
 CONFIG_MIPS=y
 
@@ -25,8 +25,6 @@ CONFIG_MIPS=y
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MIPS_EV64120 is not set
-# CONFIG_MIPS_IVR is not set
-# CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MACH_JAZZ is not set
 # CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
@@ -41,13 +39,13 @@ CONFIG_MIPS=y
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_PNX8550_V2PCI is not set
-# CONFIG_PNX8550_JBS is not set
+CONFIG_PNX8550_JBS=y
 # CONFIG_DDB5477 is not set
 # CONFIG_MACH_VR41XX is not set
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_QEMU is not set
 # CONFIG_MARKEINS is not set
-CONFIG_SGI_IP22=y
+# CONFIG_SGI_IP22 is not set
 # CONFIG_SGI_IP27 is not set
 # CONFIG_SGI_IP32 is not set
 # CONFIG_SIBYTE_BIGSUR is not set
@@ -67,25 +65,21 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
-CONFIG_ARC=y
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_DMA_NEED_PCI_MAP_STATE=y
-CONFIG_CPU_BIG_ENDIAN=y
-# CONFIG_CPU_LITTLE_ENDIAN is not set
-CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
-CONFIG_IRQ_CPU=y
-CONFIG_SWAP_IO_SPACE=y
-CONFIG_ARC32=y
-CONFIG_BOOT_ELF32=y
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_PNX8550=y
+CONFIG_SOC_PNX8550=y
 CONFIG_MIPS_L1_CACHE_SHIFT=5
-# CONFIG_ARC_CONSOLE is not set
-CONFIG_ARC_PROMLIB=y
 
 #
 # CPU selection
 #
-# CONFIG_CPU_MIPS32_R1 is not set
+CONFIG_CPU_MIPS32_R1=y
 # CONFIG_CPU_MIPS32_R2 is not set
 # CONFIG_CPU_MIPS64_R1 is not set
 # CONFIG_CPU_MIPS64_R2 is not set
@@ -93,7 +87,7 @@ CONFIG_ARC_PROMLIB=y
 # CONFIG_CPU_TX39XX is not set
 # CONFIG_CPU_VR41XX is not set
 # CONFIG_CPU_R4300 is not set
-CONFIG_CPU_R4X00=y
+# CONFIG_CPU_R4X00 is not set
 # CONFIG_CPU_TX49XX is not set
 # CONFIG_CPU_R5000 is not set
 # CONFIG_CPU_R5432 is not set
@@ -104,12 +98,11 @@ CONFIG_CPU_R4X00=y
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
-CONFIG_SYS_HAS_CPU_R4X00=y
-CONFIG_SYS_HAS_CPU_R5000=y
+CONFIG_SYS_HAS_CPU_MIPS32_R1=y
+CONFIG_CPU_MIPS32=y
+CONFIG_CPU_MIPSR1=y
 CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
-CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
 CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
 
 #
 # Kernel type
@@ -120,17 +113,17 @@ CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
 # CONFIG_PAGE_SIZE_64KB is not set
-CONFIG_BOARD_SCACHE=y
-CONFIG_IP22_CPU_SCACHE=y
+CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_MIPS_MT_DISABLED=y
-# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 # CONFIG_64BIT_PHYS_ADDR is not set
 CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_CPU_SUPPORTS_HIGHMEM=y
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_FLATMEM_MANUAL=y
@@ -144,12 +137,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_HZ_48 is not set
 # CONFIG_HZ_100 is not set
 # CONFIG_HZ_128 is not set
-# CONFIG_HZ_250 is not set
+CONFIG_HZ_250=y
 # CONFIG_HZ_256 is not set
-CONFIG_HZ_1000=y
+# CONFIG_HZ_1000 is not set
 # CONFIG_HZ_1024 is not set
 CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
-CONFIG_HZ=1000
+CONFIG_HZ=250
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
@@ -171,16 +164,20 @@ CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 # CONFIG_RELAY is not set
 CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -189,12 +186,12 @@ CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
 CONFIG_SLAB=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -211,6 +208,7 @@ CONFIG_KMOD=y
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
@@ -231,8 +229,10 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 #
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
 #
-CONFIG_HW_HAS_EISA=y
-# CONFIG_EISA is not set
+CONFIG_HW_HAS_PCI=y
+CONFIG_PCI=y
+# CONFIG_PCI_MULTITHREAD_PROBE is not set
+# CONFIG_PCI_DEBUG is not set
 CONFIG_MMU=y
 
 #
@@ -243,6 +243,7 @@ CONFIG_MMU=y
 #
 # PCI Hotplug Support
 #
+# CONFIG_HOTPLUG_PCI is not set
 
 #
 # Executable file formats
@@ -265,6 +266,7 @@ CONFIG_PACKET=y
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
@@ -283,16 +285,18 @@ CONFIG_IP_PNP_BOOTP=y
 # CONFIG_INET_IPCOMP is not set
 # CONFIG_INET_XFRM_TUNNEL is not set
 # CONFIG_INET_TUNNEL is not set
-CONFIG_INET_XFRM_MODE_TRANSPORT=m
-CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IPV6 is not set
 # CONFIG_INET6_XFRM_TUNNEL is not set
 # CONFIG_INET6_TUNNEL is not set
-CONFIG_NETWORK_SECMARK=y
+# CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
 
 #
@@ -318,7 +322,6 @@ CONFIG_NETWORK_SECMARK=y
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -371,13 +374,20 @@ CONFIG_FW_LOADER=y
 #
 # Block devices
 #
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 CONFIG_BLK_DEV_INITRD=y
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
@@ -386,6 +396,7 @@ CONFIG_BLK_DEV_INITRD=y
 # ATA/ATAPI/MFM/RLL support
 #
 CONFIG_IDE=y
+CONFIG_IDE_MAX_HWIFS=4
 CONFIG_BLK_DEV_IDE=y
 
 #
@@ -404,8 +415,39 @@ CONFIG_BLK_DEV_IDESCSI=y
 # IDE chipset support/bugfixes
 #
 CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_IDEPCI_SHARE_IRQ=y
+CONFIG_BLK_DEV_OFFBOARD=y
+CONFIG_BLK_DEV_GENERIC=y
+# CONFIG_BLK_DEV_OPTI621 is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+# CONFIG_IDEDMA_PCI_AUTO is not set
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+# CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_TRIFLEX is not set
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+CONFIG_BLK_DEV_HPT366=y
+# CONFIG_BLK_DEV_JMICRON is not set
+# CONFIG_BLK_DEV_SC1200 is not set
+# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT821X is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_PDC202XX_OLD is not set
+# CONFIG_BLK_DEV_PDC202XX_NEW is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+# CONFIG_BLK_DEV_SIIMAGE is not set
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_VIA82CXXX is not set
 # CONFIG_IDE_ARM is not set
-# CONFIG_BLK_DEV_IDEDMA is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
 # CONFIG_IDEDMA_AUTO is not set
 # CONFIG_BLK_DEV_HD is not set
 
@@ -414,6 +456,7 @@ CONFIG_IDE_GENERIC=y
 #
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
+CONFIG_SCSI_NETLINK=y
 CONFIG_SCSI_PROC_FS=y
 
 #
@@ -434,21 +477,53 @@ CONFIG_SCSI_CONSTANTS=y
 # CONFIG_SCSI_LOGGING is not set
 
 #
-# SCSI Transport Attributes
+# SCSI Transports
 #
 # CONFIG_SCSI_SPI_ATTRS is not set
 CONFIG_SCSI_FC_ATTRS=y
 CONFIG_SCSI_ISCSI_ATTRS=m
 # CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
 
 #
 # SCSI low-level drivers
 #
 CONFIG_ISCSI_TCP=m
-# CONFIG_SGIWD93_SCSI is not set
-# CONFIG_SCSI_SATA is not set
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ARCMSR is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_HPTIOP is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
+# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
+
 #
 # Multi-device support (RAID and LVM)
 #
@@ -458,14 +533,19 @@ CONFIG_ISCSI_TCP=m
 # Fusion MPT device support
 #
 # CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
+# CONFIG_FUSION_SAS is not set
 
 #
 # IEEE 1394 (FireWire) support
 #
+# CONFIG_IEEE1394 is not set
 
 #
 # I2O device support
 #
+# CONFIG_I2O is not set
 
 #
 # Network device support
@@ -476,6 +556,11 @@ CONFIG_NETDEVICES=y
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
 
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
 #
 # PHY device support
 #
@@ -486,20 +571,73 @@ CONFIG_NETDEVICES=y
 #
 CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_DM9000 is not set
-# CONFIG_SGISEEQ is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_B44 is not set
+# CONFIG_FORCEDETH is not set
+# CONFIG_DGRS is not set
+# CONFIG_EEPRO100 is not set
+# CONFIG_E100 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_8139CP is not set
+CONFIG_8139TOO=y
+# CONFIG_8139TOO_PIO is not set
+CONFIG_8139TOO_TUNE_TWISTER=y
+CONFIG_8139TOO_8129=y
+# CONFIG_8139_OLD_RX_RESET is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_LAN_SAA9730 is not set
 
 #
 # Ethernet (1000 Mbit)
 #
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
 
 #
 # Ethernet (10000 Mbit)
 #
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
 
 #
 # Token Ring devices
 #
+# CONFIG_TR is not set
 
 #
 # Wireless LAN (non-hamradio)
@@ -510,8 +648,11 @@ CONFIG_MII=y
 # Wan interfaces
 #
 # CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
+# CONFIG_NET_FC is not set
 # CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
@@ -531,6 +672,7 @@ CONFIG_MII=y
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -556,6 +698,7 @@ CONFIG_INPUT=y
 CONFIG_SERIO=y
 # CONFIG_SERIO_I8042 is not set
 # CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_PCIPS2 is not set
 CONFIG_SERIO_LIBPS2=y
 # CONFIG_SERIO_RAW is not set
 # CONFIG_GAMEPORT is not set
@@ -566,7 +709,7 @@ CONFIG_SERIO_LIBPS2=y
 CONFIG_VT=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
-CONFIG_VT_HW_CONSOLE_BINDING=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
@@ -577,7 +720,8 @@ CONFIG_VT_HW_CONSOLE_BINDING=y
 #
 # Non-8250 serial port support
 #
-# CONFIG_SERIAL_IP22_ZILOG is not set
+# CONFIG_SERIAL_IP3106 is not set
+# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -591,16 +735,17 @@ CONFIG_LEGACY_PTY_COUNT=256
 # Watchdog Cards
 #
 # CONFIG_WATCHDOG is not set
-# CONFIG_HW_RANDOM is not set
+CONFIG_HW_RANDOM=y
 # CONFIG_RTC is not set
-# CONFIG_SGI_DS1286 is not set
 # CONFIG_GEN_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
 
 #
 # Ftape, the floppy tape device driver
 #
+# CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
 #
@@ -631,35 +776,37 @@ CONFIG_HWMON=y
 # CONFIG_HWMON_VID is not set
 # CONFIG_SENSORS_ABITUGURU is not set
 # CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_VT1211 is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
 # Misc devices
 #
+# CONFIG_TIFM_CORE is not set
 
 #
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
 #
 # CONFIG_DVB is not set
+# CONFIG_USB_DABUSB is not set
 
 #
 # Graphics support
 #
-# CONFIG_FIRMWARE_EDID is not set
+CONFIG_FIRMWARE_EDID=y
 # CONFIG_FB is not set
 
 #
 # Console display driver support
 #
 # CONFIG_VGA_CONSOLE is not set
-# CONFIG_SGI_NEWPORT_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -669,14 +816,130 @@ CONFIG_DUMMY_CONSOLE=y
 #
 # USB support
 #
-# CONFIG_USB_ARCH_HAS_HCD is not set
-# CONFIG_USB_ARCH_HAS_OHCI is not set
-# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+# CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_EHCI_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
 
 #
 # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
 #
 
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_DPCM=y
+CONFIG_USB_STORAGE_USBAT=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Input Devices
+#
+# CONFIG_USB_HID is not set
+
+#
+# USB HID Boot Protocol drivers
+#
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+# CONFIG_USB_AIPTEK is not set
+# CONFIG_USB_WACOM is not set
+# CONFIG_USB_ACECAD is not set
+# CONFIG_USB_KBTAB is not set
+# CONFIG_USB_POWERMATE is not set
+# CONFIG_USB_TOUCHSCREEN is not set
+# CONFIG_USB_YEALINK is not set
+# CONFIG_USB_XPAD is not set
+# CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_ATI_REMOTE2 is not set
+# CONFIG_USB_KEYSPAN_REMOTE is not set
+# CONFIG_USB_APPLETOUCH is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGET is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD is not set
+
+#
+# USB DSL modem support
+#
+
 #
 # USB Gadget Support
 #
@@ -703,6 +966,7 @@ CONFIG_DUMMY_CONSOLE=y
 #
 # InfiniBand support
 #
+# CONFIG_INFINIBAND is not set
 
 #
 # EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
@@ -733,10 +997,12 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -769,8 +1035,10 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 #
 CONFIG_PROC_FS=y
 # CONFIG_PROC_KCORE is not set
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 # CONFIG_CONFIGFS_FS is not set
@@ -813,7 +1081,6 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
 # CONFIG_CIFS is not set
-# CONFIG_CIFS_DEBUG2 is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
@@ -824,7 +1091,6 @@ CONFIG_SUNRPC=y
 #
 # CONFIG_PARTITION_ADVANCED is not set
 CONFIG_MSDOS_PARTITION=y
-CONFIG_SGI_PARTITION=y
 
 #
 # Native Language Support
@@ -880,6 +1146,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 #
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_MAGIC_SYSRQ=y
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_KERNEL=y
@@ -893,13 +1160,17 @@ CONFIG_DEBUG_SLAB=y
 # CONFIG_DEBUG_SPINLOCK is not set
 CONFIG_DEBUG_MUTEXES=y
 # CONFIG_DEBUG_RWSEMS is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
 # CONFIG_DEBUG_INFO is not set
 # CONFIG_DEBUG_FS is not set
 # CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
 CONFIG_FORCED_INLINING=y
+# CONFIG_HEADERS_CHECK is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE="console=ttyS1,38400n8 kgdb=ttyS0 root=/dev/nfs ip=bootp"
@@ -918,6 +1189,9 @@ CONFIG_CMDLINE="console=ttyS1,38400n8 kgdb=ttyS0 root=/dev/nfs ip=bootp"
 # Cryptographic options
 #
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=m
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_MANAGER=m
 # CONFIG_CRYPTO_HMAC is not set
 # CONFIG_CRYPTO_NULL is not set
 # CONFIG_CRYPTO_MD4 is not set
@@ -927,6 +1201,8 @@ CONFIG_CRYPTO_MD5=m
 # CONFIG_CRYPTO_SHA512 is not set
 # CONFIG_CRYPTO_WP512 is not set
 # CONFIG_CRYPTO_TGR192 is not set
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
 # CONFIG_CRYPTO_DES is not set
 # CONFIG_CRYPTO_BLOWFISH is not set
 # CONFIG_CRYPTO_TWOFISH is not set
index e93266b37dd918a9e752aba99dbcc1c503d52d90..64b9fbf44a64dce63f4f55c43cf5fa08e148a3bb 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1
-# Thu Jul  6 10:04:18 2006
+# Linux kernel version: 2.6.19-rc2
+# Sat Oct 14 23:12:15 2006
 #
 CONFIG_MIPS=y
 
@@ -25,8 +25,6 @@ CONFIG_MIPS=y
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MIPS_EV64120 is not set
-# CONFIG_MIPS_IVR is not set
-# CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MACH_JAZZ is not set
 # CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
@@ -40,14 +38,14 @@ CONFIG_MIPS=y
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
-# CONFIG_PNX8550_V2PCI is not set
+CONFIG_PNX8550_V2PCI=y
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_DDB5477 is not set
 # CONFIG_MACH_VR41XX is not set
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_QEMU is not set
 # CONFIG_MARKEINS is not set
-CONFIG_SGI_IP22=y
+# CONFIG_SGI_IP22 is not set
 # CONFIG_SGI_IP27 is not set
 # CONFIG_SGI_IP32 is not set
 # CONFIG_SIBYTE_BIGSUR is not set
@@ -67,25 +65,21 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
-CONFIG_ARC=y
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_DMA_NEED_PCI_MAP_STATE=y
-CONFIG_CPU_BIG_ENDIAN=y
-# CONFIG_CPU_LITTLE_ENDIAN is not set
-CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
-CONFIG_IRQ_CPU=y
-CONFIG_SWAP_IO_SPACE=y
-CONFIG_ARC32=y
-CONFIG_BOOT_ELF32=y
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_PNX8550=y
+CONFIG_SOC_PNX8550=y
 CONFIG_MIPS_L1_CACHE_SHIFT=5
-# CONFIG_ARC_CONSOLE is not set
-CONFIG_ARC_PROMLIB=y
 
 #
 # CPU selection
 #
-# CONFIG_CPU_MIPS32_R1 is not set
+CONFIG_CPU_MIPS32_R1=y
 # CONFIG_CPU_MIPS32_R2 is not set
 # CONFIG_CPU_MIPS64_R1 is not set
 # CONFIG_CPU_MIPS64_R2 is not set
@@ -93,7 +87,7 @@ CONFIG_ARC_PROMLIB=y
 # CONFIG_CPU_TX39XX is not set
 # CONFIG_CPU_VR41XX is not set
 # CONFIG_CPU_R4300 is not set
-CONFIG_CPU_R4X00=y
+# CONFIG_CPU_R4X00 is not set
 # CONFIG_CPU_TX49XX is not set
 # CONFIG_CPU_R5000 is not set
 # CONFIG_CPU_R5432 is not set
@@ -104,12 +98,11 @@ CONFIG_CPU_R4X00=y
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
-CONFIG_SYS_HAS_CPU_R4X00=y
-CONFIG_SYS_HAS_CPU_R5000=y
+CONFIG_SYS_HAS_CPU_MIPS32_R1=y
+CONFIG_CPU_MIPS32=y
+CONFIG_CPU_MIPSR1=y
 CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
-CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
 CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
 
 #
 # Kernel type
@@ -120,17 +113,17 @@ CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
 # CONFIG_PAGE_SIZE_64KB is not set
-CONFIG_BOARD_SCACHE=y
-CONFIG_IP22_CPU_SCACHE=y
+CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_MIPS_MT_DISABLED=y
-# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 # CONFIG_64BIT_PHYS_ADDR is not set
 CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_CPU_SUPPORTS_HIGHMEM=y
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_FLATMEM_MANUAL=y
@@ -144,12 +137,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_HZ_48 is not set
 # CONFIG_HZ_100 is not set
 # CONFIG_HZ_128 is not set
-# CONFIG_HZ_250 is not set
+CONFIG_HZ_250=y
 # CONFIG_HZ_256 is not set
-CONFIG_HZ_1000=y
+# CONFIG_HZ_1000 is not set
 # CONFIG_HZ_1024 is not set
 CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
-CONFIG_HZ=1000
+CONFIG_HZ=250
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
@@ -171,16 +164,20 @@ CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 # CONFIG_RELAY is not set
 CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -188,12 +185,12 @@ CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
 CONFIG_SLAB=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -210,6 +207,7 @@ CONFIG_KMOD=y
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
@@ -230,8 +228,9 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 #
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
 #
-CONFIG_HW_HAS_EISA=y
-# CONFIG_EISA is not set
+CONFIG_HW_HAS_PCI=y
+CONFIG_PCI=y
+# CONFIG_PCI_MULTITHREAD_PROBE is not set
 CONFIG_MMU=y
 
 #
@@ -242,6 +241,7 @@ CONFIG_MMU=y
 #
 # PCI Hotplug Support
 #
+# CONFIG_HOTPLUG_PCI is not set
 
 #
 # Executable file formats
@@ -264,6 +264,7 @@ CONFIG_PACKET=y
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
@@ -282,12 +283,14 @@ CONFIG_IP_PNP=y
 # CONFIG_INET_IPCOMP is not set
 # CONFIG_INET_XFRM_TUNNEL is not set
 # CONFIG_INET_TUNNEL is not set
-CONFIG_INET_XFRM_MODE_TRANSPORT=m
-CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
 
 #
 # IP: Virtual Server Configuration
@@ -300,12 +303,18 @@ CONFIG_IPV6_ROUTE_INFO=y
 # CONFIG_INET6_AH is not set
 # CONFIG_INET6_ESP is not set
 # CONFIG_INET6_IPCOMP is not set
+# CONFIG_IPV6_MIP6 is not set
 # CONFIG_INET6_XFRM_TUNNEL is not set
 # CONFIG_INET6_TUNNEL is not set
 CONFIG_INET6_XFRM_MODE_TRANSPORT=m
 CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=m
 # CONFIG_IPV6_TUNNEL is not set
-CONFIG_NETWORK_SECMARK=y
+# CONFIG_IPV6_SUBTREES is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_NETWORK_SECMARK is not set
 CONFIG_NETFILTER=y
 # CONFIG_NETFILTER_DEBUG is not set
 
@@ -318,9 +327,9 @@ CONFIG_NETFILTER_XTABLES=m
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
 CONFIG_NETFILTER_XT_TARGET_MARK=m
 CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
-CONFIG_NETFILTER_XT_TARGET_SECMARK=m
 CONFIG_NETFILTER_XT_MATCH_COMMENT=m
 CONFIG_NETFILTER_XT_MATCH_DCCP=m
+# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
 CONFIG_NETFILTER_XT_MATCH_ESP=m
 CONFIG_NETFILTER_XT_MATCH_LENGTH=m
 CONFIG_NETFILTER_XT_MATCH_LIMIT=m
@@ -329,10 +338,10 @@ CONFIG_NETFILTER_XT_MATCH_MARK=m
 # CONFIG_NETFILTER_XT_MATCH_POLICY is not set
 CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
 CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
-CONFIG_NETFILTER_XT_MATCH_QUOTA=m
+# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set
 CONFIG_NETFILTER_XT_MATCH_REALM=m
 CONFIG_NETFILTER_XT_MATCH_SCTP=m
-CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
+# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set
 CONFIG_NETFILTER_XT_MATCH_STRING=m
 CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
 
@@ -373,7 +382,6 @@ CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -426,13 +434,20 @@ CONFIG_FW_LOADER=y
 #
 # Block devices
 #
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 CONFIG_BLK_DEV_INITRD=y
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
@@ -441,6 +456,7 @@ CONFIG_BLK_DEV_INITRD=y
 # ATA/ATAPI/MFM/RLL support
 #
 CONFIG_IDE=y
+CONFIG_IDE_MAX_HWIFS=4
 CONFIG_BLK_DEV_IDE=y
 
 #
@@ -459,9 +475,41 @@ CONFIG_IDEDISK_MULTI_MODE=y
 # IDE chipset support/bugfixes
 #
 CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_IDEPCI_SHARE_IRQ=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+# CONFIG_BLK_DEV_GENERIC is not set
+# CONFIG_BLK_DEV_OPTI621 is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+CONFIG_IDEDMA_PCI_AUTO=y
+# CONFIG_IDEDMA_ONLYDISK is not set
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+CONFIG_BLK_DEV_CMD64X=y
+# CONFIG_BLK_DEV_TRIFLEX is not set
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_JMICRON is not set
+# CONFIG_BLK_DEV_SC1200 is not set
+# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT821X is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_PDC202XX_OLD is not set
+# CONFIG_BLK_DEV_PDC202XX_NEW is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+# CONFIG_BLK_DEV_SIIMAGE is not set
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_VIA82CXXX is not set
 # CONFIG_IDE_ARM is not set
-# CONFIG_BLK_DEV_IDEDMA is not set
-# CONFIG_IDEDMA_AUTO is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+CONFIG_IDEDMA_AUTO=y
 # CONFIG_BLK_DEV_HD is not set
 
 #
@@ -469,6 +517,7 @@ CONFIG_IDE_GENERIC=y
 #
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
+CONFIG_SCSI_NETLINK=y
 CONFIG_SCSI_PROC_FS=y
 
 #
@@ -489,21 +538,58 @@ CONFIG_BLK_DEV_SD=y
 # CONFIG_SCSI_LOGGING is not set
 
 #
-# SCSI Transport Attributes
+# SCSI Transports
 #
 CONFIG_SCSI_SPI_ATTRS=m
 CONFIG_SCSI_FC_ATTRS=y
 CONFIG_SCSI_ISCSI_ATTRS=m
 # CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
 
 #
 # SCSI low-level drivers
 #
 CONFIG_ISCSI_TCP=m
-# CONFIG_SGIWD93_SCSI is not set
-# CONFIG_SCSI_SATA is not set
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+CONFIG_SCSI_AIC7XXX=m
+CONFIG_AIC7XXX_CMDS_PER_DEVICE=32
+CONFIG_AIC7XXX_RESET_DELAY_MS=15000
+# CONFIG_AIC7XXX_DEBUG_ENABLE is not set
+CONFIG_AIC7XXX_DEBUG_MASK=0
+# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ARCMSR is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_HPTIOP is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
+# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
+
 #
 # Multi-device support (RAID and LVM)
 #
@@ -513,14 +599,19 @@ CONFIG_ISCSI_TCP=m
 # Fusion MPT device support
 #
 # CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
+# CONFIG_FUSION_SAS is not set
 
 #
 # IEEE 1394 (FireWire) support
 #
+# CONFIG_IEEE1394 is not set
 
 #
 # I2O device support
 #
+# CONFIG_I2O is not set
 
 #
 # Network device support
@@ -531,6 +622,11 @@ CONFIG_NETDEVICES=y
 # CONFIG_EQUALIZER is not set
 CONFIG_TUN=m
 
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
 #
 # PHY device support
 #
@@ -541,20 +637,73 @@ CONFIG_TUN=m
 #
 CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_DM9000 is not set
-# CONFIG_SGISEEQ is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_B44 is not set
+# CONFIG_FORCEDETH is not set
+# CONFIG_DGRS is not set
+# CONFIG_EEPRO100 is not set
+# CONFIG_E100 is not set
+# CONFIG_FEALNX is not set
+CONFIG_NATSEMI=y
+# CONFIG_NE2K_PCI is not set
+# CONFIG_8139CP is not set
+CONFIG_8139TOO=y
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_OLD_RX_RESET is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_LAN_SAA9730 is not set
 
 #
 # Ethernet (1000 Mbit)
 #
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
 
 #
 # Ethernet (10000 Mbit)
 #
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
 
 #
 # Token Ring devices
 #
+# CONFIG_TR is not set
 
 #
 # Wireless LAN (non-hamradio)
@@ -565,6 +714,8 @@ CONFIG_MII=y
 # Wan interfaces
 #
 # CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
 CONFIG_PPP=m
 # CONFIG_PPP_MULTILINK is not set
 # CONFIG_PPP_FILTER is not set
@@ -575,6 +726,8 @@ CONFIG_PPP_DEFLATE=m
 CONFIG_PPP_MPPE=m
 # CONFIG_PPPOE is not set
 # CONFIG_SLIP is not set
+CONFIG_SLHC=m
+# CONFIG_NET_FC is not set
 # CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
@@ -594,6 +747,7 @@ CONFIG_PPP_MPPE=m
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -616,6 +770,7 @@ CONFIG_KEYBOARD_ATKBD=y
 # CONFIG_KEYBOARD_LKKBD is not set
 # CONFIG_KEYBOARD_XTKBD is not set
 # CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
 CONFIG_INPUT_MOUSE=y
 CONFIG_MOUSE_PS2=y
 # CONFIG_MOUSE_SERIAL is not set
@@ -630,6 +785,7 @@ CONFIG_MOUSE_PS2=y
 CONFIG_SERIO=y
 CONFIG_SERIO_I8042=y
 CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PCIPS2 is not set
 CONFIG_SERIO_LIBPS2=y
 # CONFIG_SERIO_RAW is not set
 # CONFIG_GAMEPORT is not set
@@ -640,7 +796,7 @@ CONFIG_SERIO_LIBPS2=y
 CONFIG_VT=y
 # CONFIG_VT_CONSOLE is not set
 CONFIG_HW_CONSOLE=y
-CONFIG_VT_HW_CONSOLE_BINDING=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
 CONFIG_SERIAL_NONSTANDARD=y
 # CONFIG_COMPUTONE is not set
 # CONFIG_ROCKETPORT is not set
@@ -650,6 +806,7 @@ CONFIG_SERIAL_NONSTANDARD=y
 # CONFIG_MOXA_SMARTIO is not set
 # CONFIG_ISI is not set
 # CONFIG_SYNCLINKMP is not set
+# CONFIG_SYNCLINK_GT is not set
 # CONFIG_N_HDLC is not set
 # CONFIG_RISCOM8 is not set
 # CONFIG_SPECIALIX is not set
@@ -665,7 +822,8 @@ CONFIG_SERIAL_NONSTANDARD=y
 #
 # Non-8250 serial port support
 #
-# CONFIG_SERIAL_IP22_ZILOG is not set
+# CONFIG_SERIAL_IP3106 is not set
+# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -679,16 +837,17 @@ CONFIG_LEGACY_PTY_COUNT=256
 # Watchdog Cards
 #
 # CONFIG_WATCHDOG is not set
-# CONFIG_HW_RANDOM is not set
+CONFIG_HW_RANDOM=y
 # CONFIG_RTC is not set
-# CONFIG_SGI_DS1286 is not set
 # CONFIG_GEN_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
 
 #
 # Ftape, the floppy tape device driver
 #
+# CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
 #
@@ -709,14 +868,30 @@ CONFIG_I2C_CHARDEV=m
 CONFIG_I2C_ALGOBIT=m
 # CONFIG_I2C_ALGOPCF is not set
 # CONFIG_I2C_ALGOPCA is not set
-# CONFIG_I2C_ALGO_SGI is not set
 
 #
 # I2C Hardware Bus support
 #
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
+# CONFIG_I2C_NFORCE2 is not set
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_PROSAVAGE is not set
+# CONFIG_I2C_SAVAGE4 is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
 # CONFIG_I2C_STUB is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+# CONFIG_I2C_VOODOO3 is not set
 # CONFIG_I2C_PCA_ISA is not set
 
 #
@@ -776,9 +951,13 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_LM92 is not set
 # CONFIG_SENSORS_MAX1619 is not set
 # CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_SIS5595 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_VIA686A is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_VT8231 is not set
 # CONFIG_SENSORS_W83781D is not set
 # CONFIG_SENSORS_W83791D is not set
 # CONFIG_SENSORS_W83792D is not set
@@ -790,23 +969,25 @@ CONFIG_HWMON=y
 #
 # Misc devices
 #
+# CONFIG_TIFM_CORE is not set
 
 #
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
 #
 # CONFIG_DVB is not set
+# CONFIG_USB_DABUSB is not set
 
 #
 # Graphics support
 #
-# CONFIG_FIRMWARE_EDID is not set
+CONFIG_FIRMWARE_EDID=y
 CONFIG_FB=y
+# CONFIG_FB_DDC is not set
 # CONFIG_FB_CFB_FILLRECT is not set
 # CONFIG_FB_CFB_COPYAREA is not set
 # CONFIG_FB_CFB_IMAGEBLIT is not set
@@ -814,14 +995,32 @@ CONFIG_FB=y
 # CONFIG_FB_BACKLIGHT is not set
 # CONFIG_FB_MODE_HELPERS is not set
 # CONFIG_FB_TILEBLITTING is not set
+# CONFIG_FB_CIRRUS is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
 # CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_NVIDIA is not set
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_MATROX is not set
+# CONFIG_FB_RADEON is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_SAVAGE is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_NEOMAGIC is not set
+# CONFIG_FB_KYRO is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_SMIVGX is not set
+# CONFIG_FB_TRIDENT is not set
 # CONFIG_FB_VIRTUAL is not set
 
 #
 # Console display driver support
 #
 # CONFIG_VGA_CONSOLE is not set
-# CONFIG_SGI_NEWPORT_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
 # CONFIG_FRAMEBUFFER_CONSOLE is not set
 
@@ -839,14 +1038,128 @@ CONFIG_DUMMY_CONSOLE=y
 #
 # USB support
 #
-# CONFIG_USB_ARCH_HAS_HCD is not set
-# CONFIG_USB_ARCH_HAS_OHCI is not set
-# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_EHCI_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_OHCI_HCD is not set
+# CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
 
 #
 # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
 #
 
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+CONFIG_USB_HIDINPUT=y
+# CONFIG_USB_HIDINPUT_POWERBOOK is not set
+# CONFIG_HID_FF is not set
+CONFIG_USB_HIDDEV=y
+# CONFIG_USB_AIPTEK is not set
+# CONFIG_USB_WACOM is not set
+# CONFIG_USB_ACECAD is not set
+# CONFIG_USB_KBTAB is not set
+# CONFIG_USB_POWERMATE is not set
+# CONFIG_USB_TOUCHSCREEN is not set
+# CONFIG_USB_YEALINK is not set
+# CONFIG_USB_XPAD is not set
+# CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_ATI_REMOTE2 is not set
+# CONFIG_USB_KEYSPAN_REMOTE is not set
+# CONFIG_USB_APPLETOUCH is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGET is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TEST is not set
+
+#
+# USB DSL modem support
+#
+
 #
 # USB Gadget Support
 #
@@ -873,6 +1186,7 @@ CONFIG_DUMMY_CONSOLE=y
 #
 # InfiniBand support
 #
+# CONFIG_INFINIBAND is not set
 
 #
 # EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
@@ -906,6 +1220,7 @@ CONFIG_EXT3_FS=y
 CONFIG_EXT3_FS_XATTR=y
 # CONFIG_EXT3_FS_POSIX_ACL is not set
 # CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4DEV_FS is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 CONFIG_FS_MBCACHE=y
@@ -917,6 +1232,7 @@ CONFIG_XFS_FS=m
 # CONFIG_XFS_SECURITY is not set
 # CONFIG_XFS_POSIX_ACL is not set
 # CONFIG_XFS_RT is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -949,8 +1265,10 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 #
 CONFIG_PROC_FS=y
 # CONFIG_PROC_KCORE is not set
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 # CONFIG_CONFIGFS_FS is not set
@@ -994,7 +1312,6 @@ CONFIG_SUNRPC=y
 CONFIG_SMB_FS=m
 # CONFIG_SMB_NLS_DEFAULT is not set
 # CONFIG_CIFS is not set
-# CONFIG_CIFS_DEBUG2 is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
@@ -1005,7 +1322,6 @@ CONFIG_SMB_FS=m
 #
 # CONFIG_PARTITION_ADVANCED is not set
 CONFIG_MSDOS_PARTITION=y
-CONFIG_SGI_PARTITION=y
 
 #
 # Native Language Support
@@ -1061,11 +1377,13 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 #
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
 
@@ -1079,6 +1397,9 @@ CONFIG_CMDLINE=""
 # Cryptographic options
 #
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=m
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_MANAGER=m
 # CONFIG_CRYPTO_HMAC is not set
 # CONFIG_CRYPTO_NULL is not set
 # CONFIG_CRYPTO_MD4 is not set
@@ -1088,6 +1409,8 @@ CONFIG_CRYPTO_SHA1=m
 # CONFIG_CRYPTO_SHA512 is not set
 # CONFIG_CRYPTO_WP512 is not set
 # CONFIG_CRYPTO_TGR192 is not set
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
 # CONFIG_CRYPTO_DES is not set
 # CONFIG_CRYPTO_BLOWFISH is not set
 # CONFIG_CRYPTO_TWOFISH is not set
index ad7271b3f2666dee49c35463b85ebf800cd23ac2..f7e8194809a143cce88097282da1eadc2e74bb55 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc1
-# Thu Jul  6 10:04:21 2006
+# Linux kernel version: 2.6.19-rc2
+# Wed Oct 18 12:57:11 2006
 #
 CONFIG_MIPS=y
 
@@ -25,8 +25,6 @@ CONFIG_MIPS=y
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MIPS_EV64120 is not set
-# CONFIG_MIPS_IVR is not set
-# CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MACH_JAZZ is not set
 # CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
@@ -72,11 +70,11 @@ CONFIG_TANBAC_TB0287=y
 # CONFIG_VICTOR_MPC30X is not set
 # CONFIG_ZAO_CAPCELLA is not set
 CONFIG_PCI_VR41XX=y
-# CONFIG_VRC4173 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
 CONFIG_DMA_NONCOHERENT=y
 CONFIG_DMA_NEED_PCI_MAP_STATE=y
@@ -123,8 +121,8 @@ CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_16KB is not set
 # CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_MIPS_MT_DISABLED=y
-# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
@@ -169,15 +167,19 @@ CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
 # CONFIG_RELAY is not set
 CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
+# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 # CONFIG_HOTPLUG is not set
@@ -185,12 +187,12 @@ CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
 CONFIG_SLAB=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -208,6 +210,7 @@ CONFIG_KMOD=y
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
@@ -230,17 +233,16 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 #
 CONFIG_HW_HAS_PCI=y
 CONFIG_PCI=y
+# CONFIG_PCI_MULTITHREAD_PROBE is not set
 CONFIG_MMU=y
 
 #
 # PCCARD (PCMCIA/CardBus) support
 #
-# CONFIG_PCCARD is not set
 
 #
 # PCI Hotplug Support
 #
-# CONFIG_HOTPLUG_PCI is not set
 
 #
 # Executable file formats
@@ -263,6 +265,7 @@ CONFIG_PACKET=y
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
@@ -291,13 +294,10 @@ CONFIG_SYN_COOKIES=y
 CONFIG_INET_TUNNEL=m
 CONFIG_INET_XFRM_MODE_TRANSPORT=m
 CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=y
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 CONFIG_TCP_CONG_ADVANCED=y
-
-#
-# TCP congestion control
-#
 CONFIG_TCP_CONG_BIC=y
 CONFIG_TCP_CONG_CUBIC=m
 CONFIG_TCP_CONG_WESTWOOD=m
@@ -308,7 +308,13 @@ CONFIG_TCP_CONG_HTCP=m
 # CONFIG_TCP_CONG_SCALABLE is not set
 # CONFIG_TCP_CONG_LP is not set
 # CONFIG_TCP_CONG_VENO is not set
-# CONFIG_TCP_CONG_COMPOUND is not set
+CONFIG_DEFAULT_BIC=y
+# CONFIG_DEFAULT_CUBIC is not set
+# CONFIG_DEFAULT_HTCP is not set
+# CONFIG_DEFAULT_VEGAS is not set
+# CONFIG_DEFAULT_WESTWOOD is not set
+# CONFIG_DEFAULT_RENO is not set
+CONFIG_DEFAULT_TCP_CONG="bic"
 # CONFIG_IPV6 is not set
 # CONFIG_INET6_XFRM_TUNNEL is not set
 # CONFIG_INET6_TUNNEL is not set
@@ -338,7 +344,6 @@ CONFIG_NETWORK_SECMARK=y
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -355,6 +360,7 @@ CONFIG_NETWORK_SECMARK=y
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_IEEE80211 is not set
+CONFIG_FIB_RULES=y
 
 #
 # Device Drivers
@@ -365,7 +371,6 @@ CONFIG_NETWORK_SECMARK=y
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
 # CONFIG_SYS_HYPERVISOR is not set
 
 #
@@ -403,6 +408,7 @@ CONFIG_BLK_DEV_NBD=m
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 # CONFIG_BLK_DEV_INITRD is not set
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
@@ -410,65 +416,14 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
 #
 # ATA/ATAPI/MFM/RLL support
 #
-CONFIG_IDE=y
-CONFIG_BLK_DEV_IDE=y
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
-# CONFIG_BLK_DEV_IDE_SATA is not set
-CONFIG_BLK_DEV_IDEDISK=y
-# CONFIG_IDEDISK_MULTI_MODE is not set
-# CONFIG_BLK_DEV_IDECD is not set
-# CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
-# CONFIG_BLK_DEV_IDESCSI is not set
-# CONFIG_IDE_TASK_IOCTL is not set
-
-#
-# IDE chipset support/bugfixes
-#
-CONFIG_IDE_GENERIC=y
-CONFIG_BLK_DEV_IDEPCI=y
-# CONFIG_IDEPCI_SHARE_IRQ is not set
-# CONFIG_BLK_DEV_OFFBOARD is not set
-# CONFIG_BLK_DEV_GENERIC is not set
-# CONFIG_BLK_DEV_OPTI621 is not set
-CONFIG_BLK_DEV_IDEDMA_PCI=y
-# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
-# CONFIG_IDEDMA_PCI_AUTO is not set
-# CONFIG_BLK_DEV_AEC62XX is not set
-# CONFIG_BLK_DEV_ALI15X3 is not set
-# CONFIG_BLK_DEV_AMD74XX is not set
-# CONFIG_BLK_DEV_CMD64X is not set
-# CONFIG_BLK_DEV_TRIFLEX is not set
-# CONFIG_BLK_DEV_CY82C693 is not set
-# CONFIG_BLK_DEV_CS5520 is not set
-# CONFIG_BLK_DEV_CS5530 is not set
-# CONFIG_BLK_DEV_HPT34X is not set
-# CONFIG_BLK_DEV_HPT366 is not set
-# CONFIG_BLK_DEV_SC1200 is not set
-# CONFIG_BLK_DEV_PIIX is not set
-# CONFIG_BLK_DEV_IT821X is not set
-# CONFIG_BLK_DEV_NS87415 is not set
-# CONFIG_BLK_DEV_PDC202XX_OLD is not set
-# CONFIG_BLK_DEV_PDC202XX_NEW is not set
-# CONFIG_BLK_DEV_SVWKS is not set
-CONFIG_BLK_DEV_SIIMAGE=y
-# CONFIG_BLK_DEV_SLC90E66 is not set
-# CONFIG_BLK_DEV_TRM290 is not set
-# CONFIG_BLK_DEV_VIA82CXXX is not set
-# CONFIG_IDE_ARM is not set
-CONFIG_BLK_DEV_IDEDMA=y
-# CONFIG_IDEDMA_IVB is not set
-# CONFIG_IDEDMA_AUTO is not set
-# CONFIG_BLK_DEV_HD is not set
+# CONFIG_IDE is not set
 
 #
 # SCSI device support
 #
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
+# CONFIG_SCSI_NETLINK is not set
 CONFIG_SCSI_PROC_FS=y
 
 #
@@ -489,12 +444,13 @@ CONFIG_BLK_DEV_SD=y
 # CONFIG_SCSI_LOGGING is not set
 
 #
-# SCSI Transport Attributes
+# SCSI Transports
 #
 # CONFIG_SCSI_SPI_ATTRS is not set
 # CONFIG_SCSI_FC_ATTRS is not set
 # CONFIG_SCSI_ISCSI_ATTRS is not set
 # CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
 
 #
 # SCSI low-level drivers
@@ -507,27 +463,83 @@ CONFIG_BLK_DEV_SD=y
 # CONFIG_SCSI_AIC7XXX is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
 # CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ARCMSR is not set
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
-# CONFIG_SCSI_SATA is not set
 # CONFIG_SCSI_HPTIOP is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
 # CONFIG_SCSI_IPS is not set
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
 # CONFIG_SCSI_SYM53C8XX_2 is not set
 # CONFIG_SCSI_IPR is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
 # CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
 # CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+CONFIG_ATA=y
+# CONFIG_SATA_AHCI is not set
+# CONFIG_SATA_SVW is not set
+# CONFIG_ATA_PIIX is not set
+# CONFIG_SATA_MV is not set
+# CONFIG_SATA_NV is not set
+# CONFIG_PDC_ADMA is not set
+# CONFIG_SATA_QSTOR is not set
+# CONFIG_SATA_PROMISE is not set
+# CONFIG_SATA_SX4 is not set
+# CONFIG_SATA_SIL is not set
+# CONFIG_SATA_SIL24 is not set
+# CONFIG_SATA_SIS is not set
+# CONFIG_SATA_ULI is not set
+# CONFIG_SATA_VIA is not set
+# CONFIG_SATA_VITESSE is not set
+# CONFIG_PATA_ALI is not set
+# CONFIG_PATA_AMD is not set
+# CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATIIXP is not set
+# CONFIG_PATA_CMD64X is not set
+# CONFIG_PATA_CS5520 is not set
+# CONFIG_PATA_CS5530 is not set
+# CONFIG_PATA_CYPRESS is not set
+# CONFIG_PATA_EFAR is not set
+# CONFIG_ATA_GENERIC is not set
+# CONFIG_PATA_HPT366 is not set
+# CONFIG_PATA_HPT37X is not set
+# CONFIG_PATA_HPT3X2N is not set
+# CONFIG_PATA_HPT3X3 is not set
+# CONFIG_PATA_IT821X is not set
+# CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_TRIFLEX is not set
+# CONFIG_PATA_MPIIX is not set
+# CONFIG_PATA_OLDPIIX is not set
+# CONFIG_PATA_NETCELL is not set
+# CONFIG_PATA_NS87410 is not set
+# CONFIG_PATA_OPTI is not set
+# CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC_OLD is not set
+# CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RZ1000 is not set
+# CONFIG_PATA_SC1200 is not set
+# CONFIG_PATA_SERVERWORKS is not set
+# CONFIG_PATA_PDC2027X is not set
+CONFIG_PATA_SIL680=y
+# CONFIG_PATA_SIS is not set
+# CONFIG_PATA_VIA is not set
+# CONFIG_PATA_WINBOND is not set
+
 #
 # Multi-device support (RAID and LVM)
 #
@@ -632,6 +644,7 @@ CONFIG_R8169=y
 # CONFIG_SK98LIN is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -679,6 +692,7 @@ CONFIG_R8169=y
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -758,7 +772,6 @@ CONFIG_GPIO_VR41XX=y
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -784,12 +797,12 @@ CONFIG_GPIO_VR41XX=y
 #
 # Misc devices
 #
+# CONFIG_TIFM_CORE is not set
 
 #
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -897,13 +910,13 @@ CONFIG_USB_STORAGE=m
 # CONFIG_USB_STORAGE_DEBUG is not set
 # CONFIG_USB_STORAGE_DATAFAB is not set
 # CONFIG_USB_STORAGE_FREECOM is not set
-# CONFIG_USB_STORAGE_ISD200 is not set
 # CONFIG_USB_STORAGE_DPCM is not set
 # CONFIG_USB_STORAGE_USBAT is not set
 # CONFIG_USB_STORAGE_SDDR09 is not set
 # CONFIG_USB_STORAGE_SDDR55 is not set
 # CONFIG_USB_STORAGE_JUMPSHOT is not set
 # CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_KARMA is not set
 # CONFIG_USB_LIBUSUAL is not set
 
 #
@@ -932,6 +945,7 @@ CONFIG_USB_HIDINPUT=y
 # CONFIG_USB_ATI_REMOTE2 is not set
 # CONFIG_USB_KEYSPAN_REMOTE is not set
 # CONFIG_USB_APPLETOUCH is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
 
 #
 # USB Imaging devices
@@ -963,16 +977,17 @@ CONFIG_USB_MON=y
 #
 # CONFIG_USB_EMI62 is not set
 # CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
 # CONFIG_USB_AUERSWALD is not set
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
 # CONFIG_USB_LED is not set
-# CONFIG_USB_CY7C63 is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGETKIT is not set
-# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_PHIDGET is not set
 # CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
 # CONFIG_USB_APPLEDISPLAY is not set
 # CONFIG_USB_SISUSBVGA is not set
 # CONFIG_USB_LD is not set
@@ -1041,6 +1056,7 @@ CONFIG_EXT3_FS=y
 CONFIG_EXT3_FS_XATTR=y
 # CONFIG_EXT3_FS_POSIX_ACL is not set
 # CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4DEV_FS is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 CONFIG_FS_MBCACHE=y
@@ -1052,6 +1068,7 @@ CONFIG_XFS_QUOTA=y
 # CONFIG_XFS_SECURITY is not set
 CONFIG_XFS_POSIX_ACL=y
 # CONFIG_XFS_RT is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 CONFIG_ROMFS_FS=m
@@ -1082,8 +1099,10 @@ CONFIG_AUTOFS4_FS=y
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 # CONFIG_CONFIGFS_FS is not set
@@ -1123,7 +1142,6 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
 # CONFIG_CIFS is not set
-# CONFIG_CIFS_DEBUG2 is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
@@ -1150,11 +1168,13 @@ CONFIG_MSDOS_PARTITION=y
 #
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE="mem=64M console=ttyVR0,115200 ip=any root=/dev/nfs"
 
@@ -1169,10 +1189,6 @@ CONFIG_CMDLINE="mem=64M console=ttyVR0,115200 ip=any root=/dev/nfs"
 #
 # CONFIG_CRYPTO is not set
 
-#
-# Hardware crypto devices
-#
-
 #
 # Library routines
 #
index 513fc6722d8469b69601c60946270658596cac97..a8bd2e66705ce3fda7885426903ee4a4da98d2e6 100644 (file)
@@ -153,8 +153,7 @@ u8 i8259_interrupt_ack(void)
  * the first level int-handler will jump here if it is a vrc5477 irq
  */
 #define        NUM_5477_IRQS   32
-static void
-vrc5477_irq_dispatch(struct pt_regs *regs)
+static void vrc5477_irq_dispatch(void)
 {
        u32 intStatus;
        u32 bitmask;
@@ -178,7 +177,7 @@ vrc5477_irq_dispatch(struct pt_regs *regs)
                /* check for i8259 interrupts */
                if (intStatus & (1 << VRC5477_I8259_CASCADE)) {
                        int i8259_irq = i8259_interrupt_ack();
-                       do_IRQ(I8259_IRQ_BASE + i8259_irq, regs);
+                       do_IRQ(I8259_IRQ_BASE + i8259_irq);
                        return;
                }
        }
@@ -186,7 +185,7 @@ vrc5477_irq_dispatch(struct pt_regs *regs)
        for (i=0, bitmask=1; i<= NUM_5477_IRQS; bitmask <<=1, i++) {
                /* do we need to "and" with the int mask? */
                if (intStatus & bitmask) {
-                       do_IRQ(VRC5477_IRQ_BASE + i, regs);
+                       do_IRQ(VRC5477_IRQ_BASE + i);
                        return;
                }
        }
@@ -194,18 +193,18 @@ vrc5477_irq_dispatch(struct pt_regs *regs)
 
 #define VR5477INTS (STATUSF_IP2|STATUSF_IP3|STATUSF_IP4|STATUSF_IP5|STATUSF_IP6)
 
-asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+asmlinkage void plat_irq_dispatch(void)
 {
        unsigned int pending = read_c0_cause() & read_c0_status();
 
        if (pending & STATUSF_IP7)
-               do_IRQ(CPU_IRQ_BASE + 7, regs);
+               do_IRQ(CPU_IRQ_BASE + 7);
        else if (pending & VR5477INTS)
-               vrc5477_irq_dispatch(regs);
+               vrc5477_irq_dispatch();
        else if (pending & STATUSF_IP0)
-               do_IRQ(CPU_IRQ_BASE, regs);
+               do_IRQ(CPU_IRQ_BASE);
        else if (pending & STATUSF_IP1)
-               do_IRQ(CPU_IRQ_BASE + 1, regs);
+               do_IRQ(CPU_IRQ_BASE + 1);
        else
-               spurious_interrupt(regs);
+               spurious_interrupt();
 }
index cc24c5ed0c05d2b90a87c1829ca8c384111d2ce1..3e374d05978f0ede0b0b057348a99eb4f3c70c98 100644 (file)
@@ -24,6 +24,7 @@
 #include <asm/addrspace.h>
 #include <asm/bootinfo.h>
 #include <asm/cpu.h>
+#include <asm/irq_regs.h>
 #include <asm/processor.h>
 #include <asm/system.h>
 #include <asm/traps.h>
@@ -200,8 +201,10 @@ int dec_ecc_be_handler(struct pt_regs *regs, int is_fixup)
        return dec_ecc_be_backend(regs, is_fixup, 0);
 }
 
-irqreturn_t dec_ecc_be_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t dec_ecc_be_interrupt(int irq, void *dev_id)
 {
+       struct pt_regs *regs = get_irq_regs();
+
        int action = dec_ecc_be_backend(regs, 0, 1);
 
        if (action == MIPS_BE_DISCARD)
index 455a65b91cb0b707e3656cc450238ae5f45a73cd..31dd47d1002d4d8cce90ce890478ca2fe4f1d811 100644 (file)
                 srlv   t3,t1,t2
 
 handle_it:
-               jal     do_IRQ
-                move   a1,sp
-
-               j       ret_from_irq
+               LONG_L  s0, TI_REGS($28)
+               LONG_S  sp, TI_REGS($28)
+               PTR_LA  ra, ret_from_irq
+               j       do_IRQ
                 nop
 
 #ifdef CONFIG_32BIT
@@ -277,9 +277,8 @@ fpu:
 #endif
 
 spurious:
-               jal     spurious_interrupt
-                nop
-               j       ret_from_irq
+               PTR_LA  ra, _ret_from_irq
+               j       spurious_interrupt
                 nop
                END(plat_irq_dispatch)
 
index b9271db9bc767d8a64d85f6c5ce458a8340251cf..f19b4617a0a6c4a67f9439a86956aa14ebe91678 100644 (file)
@@ -150,10 +150,10 @@ int dec_kn01_be_handler(struct pt_regs *regs, int is_fixup)
        return dec_kn01_be_backend(regs, is_fixup, 0);
 }
 
-irqreturn_t dec_kn01_be_interrupt(int irq, void *dev_id,
-                                   struct pt_regs *regs)
+irqreturn_t dec_kn01_be_interrupt(int irq, void *dev_id)
 {
        volatile u16 *csr = (void *)CKSEG1ADDR(KN01_SLOT_BASE + KN01_CSR);
+       struct pt_regs *regs = get_irq_regs();
        int action;
 
        if (!(*csr & KN01_CSR_MEMERR))
index 6cd3f94f79fefb79660163da670982f67c49ae73..7a053aadcd3a1d3141e7c32c6997005d3fad5028 100644 (file)
@@ -21,6 +21,8 @@
 #include <linux/types.h>
 
 #include <asm/addrspace.h>
+#include <asm/irq_regs.h>
+#include <asm/ptrace.h>
 #include <asm/system.h>
 #include <asm/traps.h>
 
@@ -104,9 +106,9 @@ int dec_kn02xa_be_handler(struct pt_regs *regs, int is_fixup)
        return dec_kn02xa_be_backend(regs, is_fixup, 0);
 }
 
-irqreturn_t dec_kn02xa_be_interrupt(int irq, void *dev_id,
-                                   struct pt_regs *regs)
+irqreturn_t dec_kn02xa_be_interrupt(int irq, void *dev_id)
 {
+       struct pt_regs *regs = get_irq_regs();
        int action = dec_kn02xa_be_backend(regs, 0, 1);
 
        if (action == MIPS_BE_DISCARD)
index f78c6da479217c7f806560a27c6b63c3fbcbec5f..56397227adb09d20a8a031c0c40ac07c925f2d57 100644 (file)
@@ -8,7 +8,6 @@
 #include <linux/linkage.h>
 
 #include <asm/addrspace.h>
-#include <asm/ptrace.h>
 
 typedef void ATTRIB_NORET (* noret_func_t)(void);
 
@@ -35,7 +34,7 @@ void ATTRIB_NORET dec_machine_power_off(void)
        back_to_prom();
 }
 
-irqreturn_t dec_intr_halt(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t dec_intr_halt(int irq, void *dev_id)
 {
        dec_machine_halt();
 }
index d43241c2f5414bd94cee8eb55d7aced5e9828805..6b7481e97becc0ede20ce2414dc76c73ef3e1bf1 100644 (file)
@@ -46,7 +46,7 @@
 extern void dec_machine_restart(char *command);
 extern void dec_machine_halt(void);
 extern void dec_machine_power_off(void);
-extern irqreturn_t dec_intr_halt(int irq, void *dev_id, struct pt_regs *regs);
+extern irqreturn_t dec_intr_halt(int irq, void *dev_id);
 
 unsigned long dec_kn_slot_base, dec_kn_slot_size;
 
index 3af57693c84c01f167710df8c7a0ce5c102e11c7..c191b3e9d9d9e3101a9614fb4be17f0fa55bd9b6 100644 (file)
@@ -39,7 +39,7 @@
 /*
  * the first level int-handler will jump here if it is a emma2rh irq
  */
-asmlinkage void emma2rh_irq_dispatch(struct pt_regs *regs)
+void emma2rh_irq_dispatch(void)
 {
        u32 intStatus;
        u32 bitmask;
@@ -56,7 +56,7 @@ asmlinkage void emma2rh_irq_dispatch(struct pt_regs *regs)
                    & emma2rh_in32(EMMA2RH_BHIF_SW_INT_EN);
                for (i = 0, bitmask = 1; i < 32; i++, bitmask <<= 1) {
                        if (swIntStatus & bitmask) {
-                               do_IRQ(EMMA2RH_SW_IRQ_BASE + i, regs);
+                               do_IRQ(EMMA2RH_SW_IRQ_BASE + i);
                                return;
                        }
                }
@@ -65,7 +65,7 @@ asmlinkage void emma2rh_irq_dispatch(struct pt_regs *regs)
 
        for (i = 0, bitmask = 1; i < 32; i++, bitmask <<= 1) {
                if (intStatus & bitmask) {
-                       do_IRQ(EMMA2RH_IRQ_BASE + i, regs);
+                       do_IRQ(EMMA2RH_IRQ_BASE + i);
                        return;
                }
        }
@@ -81,7 +81,7 @@ asmlinkage void emma2rh_irq_dispatch(struct pt_regs *regs)
                    & emma2rh_in32(EMMA2RH_GPIO_INT_MASK);
                for (i = 0, bitmask = 1; i < 32; i++, bitmask <<= 1) {
                        if (gpioIntStatus & bitmask) {
-                               do_IRQ(EMMA2RH_GPIO_IRQ_BASE + i, regs);
+                               do_IRQ(EMMA2RH_GPIO_IRQ_BASE + i);
                                return;
                        }
                }
@@ -90,7 +90,7 @@ asmlinkage void emma2rh_irq_dispatch(struct pt_regs *regs)
 
        for (i = 32, bitmask = 1; i < 64; i++, bitmask <<= 1) {
                if (intStatus & bitmask) {
-                       do_IRQ(EMMA2RH_IRQ_BASE + i, regs);
+                       do_IRQ(EMMA2RH_IRQ_BASE + i);
                        return;
                }
        }
@@ -100,7 +100,7 @@ asmlinkage void emma2rh_irq_dispatch(struct pt_regs *regs)
 
        for (i = 64, bitmask = 1; i < 96; i++, bitmask <<= 1) {
                if (intStatus & bitmask) {
-                       do_IRQ(EMMA2RH_IRQ_BASE + i, regs);
+                       do_IRQ(EMMA2RH_IRQ_BASE + i);
                        return;
                }
        }
index 2a736be42c8ca0fa933a4cf543fc5eba3ec88f39..c93369cb411533d60d44f43516030e0822714353 100644 (file)
@@ -57,7 +57,7 @@
 extern void emma2rh_sw_irq_init(u32 base);
 extern void emma2rh_gpio_irq_init(u32 base);
 extern void emma2rh_irq_init(u32 base);
-extern asmlinkage void emma2rh_irq_dispatch(struct pt_regs *regs);
+extern void emma2rh_irq_dispatch(void);
 
 static struct irqaction irq_cascade = {
           .handler = no_action,
@@ -114,20 +114,20 @@ void __init arch_init_irq(void)
        setup_irq(CPU_IRQ_BASE + CPU_EMMA2RH_CASCADE, &irq_cascade);
 }
 
-asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+asmlinkage void plat_irq_dispatch(void)
 {
         unsigned int pending = read_c0_status() & read_c0_cause();
 
        if (pending & STATUSF_IP7)
-               do_IRQ(CPU_IRQ_BASE + 7, regs);
+               do_IRQ(CPU_IRQ_BASE + 7);
        else if (pending & STATUSF_IP2)
-               emma2rh_irq_dispatch(regs);
+               emma2rh_irq_dispatch();
        else if (pending & STATUSF_IP1)
-               do_IRQ(CPU_IRQ_BASE + 1, regs);
+               do_IRQ(CPU_IRQ_BASE + 1);
        else if (pending & STATUSF_IP0)
-               do_IRQ(CPU_IRQ_BASE + 0, regs);
+               do_IRQ(CPU_IRQ_BASE + 0);
        else
-               spurious_interrupt(regs);
+               spurious_interrupt();
 }
 
 
index 7feca49350d18b4bc6ea2ed630c09bbfb3fd1937..c83ae6acd6013a5e3dbb4d748756ad0aab39b5d6 100644 (file)
@@ -10,7 +10,7 @@
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/kernel_stat.h>
-#include <asm/ptrace.h>
+#include <asm/irq_regs.h>
 #include <asm/gt64120.h>
 
 /*
@@ -19,7 +19,7 @@
  * differently than other MIPS interrupts.
  */
 
-static void gt64120_irq(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t gt64120_irq(int irq, void *dev_id)
 {
        unsigned int irq_src, int_high_src, irq_src_mask, int_high_src_mask;
        int handled = 0;
@@ -36,12 +36,14 @@ static void gt64120_irq(int irq, void *dev_id, struct pt_regs *regs)
                irq_src &= ~0x00000800;
                do_timer(1);
 #ifndef CONFIG_SMP
-               update_process_times(user_mode(regs));
+               update_process_times(user_mode(get_irq_regs()));
 #endif
        }
 
        GT_WRITE(GT_INTRCAUSE_OFS, 0);
        GT_WRITE(GT_HINTRCAUSE_OFS, 0);
+
+       return IRQ_HANDLED;
 }
 
 /*
index 5d939ac58f3f3634d1e184e938fac3761f292def..ed4d82b9a24a95e43576c54979017380bfaf2448 100644 (file)
 #include <asm/system.h>
 #include <asm/gt64120.h>
 
-asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+asmlinkage void plat_irq_dispatch(void)
 {
        unsigned int pending = read_c0_status() & read_c0_cause();
 
        if (pending & STATUSF_IP4)              /* int2 hardware line (timer) */
-               do_IRQ(4, regs);
+               do_IRQ(4);
        else if (pending & STATUSF_IP2)         /* int0 hardware line */
-               do_IRQ(GT_INTA, regs);
+               do_IRQ(GT_INTA);
        else if (pending & STATUSF_IP5)         /* int3 hardware line */
-               do_IRQ(GT_INTD, regs);
+               do_IRQ(GT_INTD);
        else if (pending & STATUSF_IP6)         /* int4 hardware line */
-               do_IRQ(6, regs);
+               do_IRQ(6);
        else if (pending & STATUSF_IP7)         /* compare int */
-               do_IRQ(7, regs);
+               do_IRQ(7);
        else
-               spurious_interrupt(regs);
+               spurious_interrupt();
 }
 
 static void disable_ev64120_irq(unsigned int irq_nr)
index 4236da31ecc679abafd9af5e4c50f55d163ffe79..91c2d3f41617a57a4551e3784d6b6154684d42fb 100644 (file)
@@ -42,7 +42,6 @@
 #include <asm/irq.h>
 #include <asm/pci.h>
 #include <asm/processor.h>
-#include <asm/ptrace.h>
 #include <asm/time.h>
 #include <asm/reboot.h>
 #include <asm/traps.h>
index 885f67f32ea3dfa501916f5ed8e194984063c3a1..d9294401ccb067a46510b00118407c4275bdb1bf 100644 (file)
 #include <asm/mipsregs.h>
 #include <asm/system.h>
 
-asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+asmlinkage void plat_irq_dispatch(void)
 {
        unsigned int pending = read_c0_status() & read_c0_cause();
 
        if (pending & STATUSF_IP2)              /* int0 hardware line */
-               do_IRQ(2, regs);
+               do_IRQ(2);
        else if (pending & STATUSF_IP3)         /* int1 hardware line */
-               do_IRQ(3, regs);
+               do_IRQ(3);
        else if (pending & STATUSF_IP4)         /* int2 hardware line */
-               do_IRQ(4, regs);
+               do_IRQ(4);
        else if (pending & STATUSF_IP5)         /* int3 hardware line */
-               do_IRQ(5, regs);
+               do_IRQ(5);
        else if (pending & STATUSF_IP6)         /* int4 hardware line */
-               do_IRQ(6, regs);
+               do_IRQ(6);
        else if (pending & STATUSF_IP7)         /* cpu timer */
-               do_IRQ(7, regs);
+               do_IRQ(7);
        else {
                /*
                 * Now look at the extended interrupts
@@ -71,13 +71,13 @@ asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
                pending = (read_c0_cause() & (read_c0_intcontrol() << 8)) >> 16;
 
                if (pending & STATUSF_IP8)              /* int6 hardware line */
-                       do_IRQ(8, regs);
+                       do_IRQ(8);
                else if (pending & STATUSF_IP9)         /* int7 hardware line */
-                       do_IRQ(9, regs);
+                       do_IRQ(9);
                else if (pending & STATUSF_IP10)        /* int8 hardware line */
-                       do_IRQ(10, regs);
+                       do_IRQ(10);
                else if (pending & STATUSF_IP11)        /* int9 hardware line */
-                       do_IRQ(11, regs);
+                       do_IRQ(11);
        }
 }
 
index 9804642ecf8945ed1235c5bdcc08bcb55d18a124..0e5bbee2d5b7f6402294dc8ce05113a4692e9376 100644 (file)
@@ -56,7 +56,6 @@
 #include <asm/irq.h>
 #include <asm/pci.h>
 #include <asm/processor.h>
-#include <asm/ptrace.h>
 #include <asm/reboot.h>
 #include <asm/traps.h>
 #include <linux/bootmem.h>
index 8d75a43ce877b4fb29c90405567307cba134ea71..eedfc24e1eae8c8004bacfa27f3f1443ed23a43c 100644 (file)
 #include <asm/irq_cpu.h>
 #include <asm/gt64120.h>
 
-asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+asmlinkage void plat_irq_dispatch(void)
 {
        unsigned int pending = read_c0_status() & read_c0_cause();
 
        if (pending & STATUSF_IP7)
-               do_IRQ(WRPPMC_MIPS_TIMER_IRQ, regs);    /* CPU Compare/Count internal timer */
+               do_IRQ(WRPPMC_MIPS_TIMER_IRQ);  /* CPU Compare/Count internal timer */
        else if (pending & STATUSF_IP6)
-               do_IRQ(WRPPMC_UART16550_IRQ, regs);     /* UART 16550 port */
+               do_IRQ(WRPPMC_UART16550_IRQ);   /* UART 16550 port */
        else if (pending & STATUSF_IP3)
-               do_IRQ(WRPPMC_PCI_INTA_IRQ, regs);      /* PCI INT_A */
+               do_IRQ(WRPPMC_PCI_INTA_IRQ);    /* PCI INT_A */
        else
-               spurious_interrupt(regs);
+               spurious_interrupt();
 }
 
 /**
index eef05093deb41b174a8b3e10fda4bfc85cf50d02..d5bd6b3a09335b5bdfbe6fda8b60df2de0bdc24d 100644 (file)
@@ -94,26 +94,26 @@ void __init arch_init_irq(void)
        change_c0_status(ST0_IM, IE_IRQ4 | IE_IRQ3 | IE_IRQ2 | IE_IRQ1);
 }
 
-static void loc_call(unsigned int irq, struct pt_regs *regs, unsigned int mask)
+static void loc_call(unsigned int irq, unsigned int mask)
 {
        r4030_write_reg16(JAZZ_IO_IRQ_ENABLE,
                          r4030_read_reg16(JAZZ_IO_IRQ_ENABLE) & mask);
-       do_IRQ(irq, regs);
+       do_IRQ(irq);
        r4030_write_reg16(JAZZ_IO_IRQ_ENABLE,
                          r4030_read_reg16(JAZZ_IO_IRQ_ENABLE) | mask);
 }
 
-static void ll_local_dev(struct pt_regs *regs)
+static void ll_local_dev(void)
 {
        switch (r4030_read_reg32(JAZZ_IO_IRQ_SOURCE)) {
        case 0:
                panic("Unimplemented loc_no_irq handler");
                break;
        case 4:
-               loc_call(JAZZ_PARALLEL_IRQ, regs, JAZZ_IE_PARALLEL);
+               loc_call(JAZZ_PARALLEL_IRQ, JAZZ_IE_PARALLEL);
                break;
        case 8:
-               loc_call(JAZZ_PARALLEL_IRQ, regs, JAZZ_IE_FLOPPY);
+               loc_call(JAZZ_PARALLEL_IRQ, JAZZ_IE_FLOPPY);
                break;
        case 12:
                panic("Unimplemented loc_sound handler");
@@ -122,27 +122,27 @@ static void ll_local_dev(struct pt_regs *regs)
                panic("Unimplemented loc_video handler");
                break;
        case 20:
-               loc_call(JAZZ_ETHERNET_IRQ, regs, JAZZ_IE_ETHERNET);
+               loc_call(JAZZ_ETHERNET_IRQ, JAZZ_IE_ETHERNET);
                break;
        case 24:
-               loc_call(JAZZ_SCSI_IRQ, regs, JAZZ_IE_SCSI);
+               loc_call(JAZZ_SCSI_IRQ, JAZZ_IE_SCSI);
                break;
        case 28:
-               loc_call(JAZZ_KEYBOARD_IRQ, regs, JAZZ_IE_KEYBOARD);
+               loc_call(JAZZ_KEYBOARD_IRQ, JAZZ_IE_KEYBOARD);
                break;
        case 32:
-               loc_call(JAZZ_MOUSE_IRQ, regs, JAZZ_IE_MOUSE);
+               loc_call(JAZZ_MOUSE_IRQ, JAZZ_IE_MOUSE);
                break;
        case 36:
-               loc_call(JAZZ_SERIAL1_IRQ, regs, JAZZ_IE_SERIAL1);
+               loc_call(JAZZ_SERIAL1_IRQ, JAZZ_IE_SERIAL1);
                break;
        case 40:
-               loc_call(JAZZ_SERIAL2_IRQ, regs, JAZZ_IE_SERIAL2);
+               loc_call(JAZZ_SERIAL2_IRQ, JAZZ_IE_SERIAL2);
                break;
        }
 }
 
-asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+asmlinkage void plat_irq_dispatch(void)
 {
        unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
 
@@ -150,13 +150,13 @@ asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
                write_c0_compare(0);
        else if (pending & IE_IRQ4) {
                r4030_read_reg32(JAZZ_TIMER_REGISTER);
-               do_IRQ(JAZZ_TIMER_IRQ, regs);
+               do_IRQ(JAZZ_TIMER_IRQ);
        } else if (pending & IE_IRQ3)
                panic("Unimplemented ISA NMI handler");
        else if (pending & IE_IRQ2)
-               do_IRQ(r4030_read_reg32(JAZZ_EISA_IRQ_ACK), regs);
+               do_IRQ(r4030_read_reg32(JAZZ_EISA_IRQ_ACK));
        else if (pending & IE_IRQ1) {
-               ll_local_dev(regs);
+               ll_local_dev();
        } else if (unlikely(pending & IE_IRQ0))
                panic("Unimplemented local_dma handler");
        else if (pending & IE_SW1) {
index 487a9ea1ef00cd1809d9d5a5b0c57d96e3b5c1b2..d848f1a07786bf6c1de0f538e1e61d7a5494c122 100644 (file)
 #include <linux/fb.h>
 #include <linux/ide.h>
 #include <linux/pm.h>
+#include <linux/screen_info.h>
 
 #include <asm/bootinfo.h>
 #include <asm/irq.h>
 #include <asm/jazz.h>
 #include <asm/jazzdma.h>
-#include <asm/ptrace.h>
 #include <asm/reboot.h>
 #include <asm/io.h>
 #include <asm/pgtable.h>
@@ -37,7 +37,7 @@ extern void jazz_machine_restart(char *command);
 extern void jazz_machine_halt(void);
 extern void jazz_machine_power_off(void);
 
-void __init plat_time_init(struct irqaction *irq)
+void __init plat_timer_setup(struct irqaction *irq)
 {
        /* set the clock to 100 Hz */
        r4030_write_reg32(JAZZ_TIMER_INTERVAL, 9);
@@ -45,10 +45,27 @@ void __init plat_time_init(struct irqaction *irq)
 }
 
 static struct resource jazz_io_resources[] = {
-       { "dma1", 0x00, 0x1f, IORESOURCE_BUSY },
-       { "timer", 0x40, 0x5f, IORESOURCE_BUSY },
-       { "dma page reg", 0x80, 0x8f, IORESOURCE_BUSY },
-       { "dma2", 0xc0, 0xdf, IORESOURCE_BUSY },
+       {
+               .start  = 0x00,
+               .end    = 0x1f,
+               .name   = "dma1",
+               .flags  = IORESOURCE_BUSY
+       }, {
+               .start  = 0x40,
+               .end    = 0x5f,
+               .name   = "timer",
+               .end    = IORESOURCE_BUSY
+       }, {
+               .start  = 0x80,
+               .end    = 0x8f,
+               .name   = "dma page reg",
+               .flags  = IORESOURCE_BUSY
+       }, {
+               .start  = 0xc0,
+               .end    = 0xdf,
+               .name   = "dma2",
+               .flags  = IORESOURCE_BUSY
+       }
 };
 
 void __init plat_mem_setup(void)
@@ -81,8 +98,6 @@ void __init plat_mem_setup(void)
        _machine_halt = jazz_machine_halt;
        pm_power_off = jazz_machine_power_off;
 
-#warning "Somebody should check if screen_info is ok for Jazz."
-
        screen_info = (struct screen_info) {
                0, 0,           /* orig-x, orig-y */
                0,              /* unused */
index 722174481467e96b31dd314a226f27b78bc70f54..39a0243bed9ac10e13b0fea7dfe25c83f29fca74 100644 (file)
@@ -46,6 +46,7 @@
 #include <linux/smp_lock.h>
 #include <linux/bitops.h>
 
+#include <asm/irq_regs.h>
 #include <asm/io.h>
 #include <asm/mipsregs.h>
 #include <asm/system.h>
@@ -239,45 +240,80 @@ struct tb_irq_space jmr3927_ioc_irqspace = {
        .space_id = 0,
        can_share : 1
 };
+
 struct tb_irq_space jmr3927_irc_irqspace = {
-       .next = NULL,
-       .start_irqno = JMR3927_IRQ_IRC,
-       nr_irqs : JMR3927_NR_IRQ_IRC,
-       .mask_func = mask_irq_irc,
-       .unmask_func = unmask_irq_irc,
-       .name = "on-chip",
-       .space_id = 0,
-       can_share : 0
+       .next           = NULL,
+       .start_irqno    = JMR3927_IRQ_IRC,
+       .nr_irqs        = JMR3927_NR_IRQ_IRC,
+       .mask_func      = mask_irq_irc,
+       .unmask_func    = unmask_irq_irc,
+       .name           = "on-chip",
+       .space_id       = 0,
+       .can_share      = 0
 };
 
-void jmr3927_spurious(struct pt_regs *regs)
+
+#ifdef CONFIG_TX_BRANCH_LIKELY_BUG_WORKAROUND
+static int tx_branch_likely_bug_count = 0;
+static int have_tx_branch_likely_bug = 0;
+
+static void tx_branch_likely_bug_fixup(void)
+{
+       struct pt_regs *regs = get_irq_regs();
+
+       /* TX39/49-BUG: Under this condition, the insn in delay slot
+           of the branch likely insn is executed (not nullified) even
+           the branch condition is false. */
+       if (!have_tx_branch_likely_bug)
+               return;
+       if ((regs->cp0_epc & 0xfff) == 0xffc &&
+           KSEGX(regs->cp0_epc) != KSEG0 &&
+           KSEGX(regs->cp0_epc) != KSEG1) {
+               unsigned int insn = *(unsigned int*)(regs->cp0_epc - 4);
+               /* beql,bnel,blezl,bgtzl */
+               /* bltzl,bgezl,blezall,bgezall */
+               /* bczfl, bcztl */
+               if ((insn & 0xf0000000) == 0x50000000 ||
+                   (insn & 0xfc0e0000) == 0x04020000 ||
+                   (insn & 0xf3fe0000) == 0x41020000) {
+                       regs->cp0_epc -= 4;
+                       tx_branch_likely_bug_count++;
+                       printk(KERN_INFO
+                              "fix branch-likery bug in %s (insn %08x)\n",
+                              current->comm, insn);
+               }
+       }
+}
+#endif
+
+static void jmr3927_spurious(void)
 {
 #ifdef CONFIG_TX_BRANCH_LIKELY_BUG_WORKAROUND
-       tx_branch_likely_bug_fixup(regs);
+       tx_branch_likely_bug_fixup();
 #endif
        printk(KERN_WARNING "spurious interrupt (cause 0x%lx, pc 0x%lx, ra 0x%lx).\n",
               regs->cp0_cause, regs->cp0_epc, regs->regs[31]);
 }
 
-asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+asmlinkage void plat_irq_dispatch(void)
 {
        int irq;
 
 #ifdef CONFIG_TX_BRANCH_LIKELY_BUG_WORKAROUND
-       tx_branch_likely_bug_fixup(regs);
+       tx_branch_likely_bug_fixup();
 #endif
        if ((regs->cp0_cause & CAUSEF_IP7) == 0) {
 #if 0
-               jmr3927_spurious(regs);
+               jmr3927_spurious();
 #endif
                return;
        }
        irq = (regs->cp0_cause >> CAUSEB_IP2) & 0x0f;
 
-       do_IRQ(irq + JMR3927_IRQ_IRC, regs);
+       do_IRQ(irq + JMR3927_IRQ_IRC);
 }
 
-static irqreturn_t jmr3927_ioc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t jmr3927_ioc_interrupt(int irq, void *dev_id)
 {
        unsigned char istat = jmr3927_ioc_reg_in(JMR3927_IOC_INTS2_ADDR);
        int i;
@@ -285,7 +321,7 @@ static irqreturn_t jmr3927_ioc_interrupt(int irq, void *dev_id, struct pt_regs *
        for (i = 0; i < JMR3927_NR_IRQ_IOC; i++) {
                if (istat & (1 << i)) {
                        irq = JMR3927_IRQ_IOC + i;
-                       do_IRQ(irq, regs);
+                       do_IRQ(irq);
                }
        }
        return IRQ_HANDLED;
@@ -295,7 +331,7 @@ static struct irqaction ioc_action = {
        jmr3927_ioc_interrupt, 0, CPU_MASK_NONE, "IOC", NULL, NULL,
 };
 
-static irqreturn_t jmr3927_isac_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t jmr3927_isac_interrupt(int irq, void *dev_id)
 {
        unsigned char istat = jmr3927_isac_reg_in(JMR3927_ISAC_INTS2_ADDR);
        int i;
@@ -303,7 +339,7 @@ static irqreturn_t jmr3927_isac_interrupt(int irq, void *dev_id, struct pt_regs
        for (i = 0; i < JMR3927_NR_IRQ_ISAC; i++) {
                if (istat & (1 << i)) {
                        irq = JMR3927_IRQ_ISAC + i;
-                       do_IRQ(irq, regs);
+                       do_IRQ(irq);
                }
        }
        return IRQ_HANDLED;
@@ -314,7 +350,7 @@ static struct irqaction isac_action = {
 };
 
 
-static irqreturn_t jmr3927_isaerr_interrupt(int irq, void * dev_id, struct pt_regs * regs)
+static irqreturn_t jmr3927_isaerr_interrupt(int irq, void *dev_id)
 {
        printk(KERN_WARNING "ISA error interrupt (irq 0x%x).\n", irq);
 
@@ -324,7 +360,7 @@ static struct irqaction isaerr_action = {
        jmr3927_isaerr_interrupt, 0, CPU_MASK_NONE, "ISA error", NULL, NULL,
 };
 
-static irqreturn_t jmr3927_pcierr_interrupt(int irq, void * dev_id, struct pt_regs * regs)
+static irqreturn_t jmr3927_pcierr_interrupt(int irq, void *dev_id)
 {
        printk(KERN_WARNING "PCI error interrupt (irq 0x%x).\n", irq);
        printk(KERN_WARNING "pcistat:%02x, lbstat:%04lx\n",
@@ -439,33 +475,3 @@ void jmr3927_irq_init(u32 irq_base)
 
        jmr3927_irq_base = irq_base;
 }
-
-#ifdef CONFIG_TX_BRANCH_LIKELY_BUG_WORKAROUND
-static int tx_branch_likely_bug_count = 0;
-static int have_tx_branch_likely_bug = 0;
-void tx_branch_likely_bug_fixup(struct pt_regs *regs)
-{
-       /* TX39/49-BUG: Under this condition, the insn in delay slot
-           of the branch likely insn is executed (not nullified) even
-           the branch condition is false. */
-       if (!have_tx_branch_likely_bug)
-               return;
-       if ((regs->cp0_epc & 0xfff) == 0xffc &&
-           KSEGX(regs->cp0_epc) != KSEG0 &&
-           KSEGX(regs->cp0_epc) != KSEG1) {
-               unsigned int insn = *(unsigned int*)(regs->cp0_epc - 4);
-               /* beql,bnel,blezl,bgtzl */
-               /* bltzl,bgezl,blezall,bgezall */
-               /* bczfl, bcztl */
-               if ((insn & 0xf0000000) == 0x50000000 ||
-                   (insn & 0xfc0e0000) == 0x04020000 ||
-                   (insn & 0xf3fe0000) == 0x41020000) {
-                       regs->cp0_epc -= 4;
-                       tx_branch_likely_bug_count++;
-                       printk(KERN_INFO
-                              "fix branch-likery bug in %s (insn %08x)\n",
-                              current->comm, insn);
-               }
-       }
-}
-#endif
index ec28077d5ee2a165fe15929638c1c3bec83b5d19..e9ce5b3721af74d8324b45bdadf2f71ce97ac77b 100644 (file)
@@ -93,11 +93,12 @@ void output_thread_info_defines(void)
        offset("#define TI_TASK            ", struct thread_info, task);
        offset("#define TI_EXEC_DOMAIN     ", struct thread_info, exec_domain);
        offset("#define TI_FLAGS           ", struct thread_info, flags);
+       offset("#define TI_TP_VALUE        ", struct thread_info, tp_value);
        offset("#define TI_CPU             ", struct thread_info, cpu);
        offset("#define TI_PRE_COUNT       ", struct thread_info, preempt_count);
        offset("#define TI_ADDR_LIMIT      ", struct thread_info, addr_limit);
        offset("#define TI_RESTART_BLOCK   ", struct thread_info, restart_block);
-       offset("#define TI_TP_VALUE        ", struct thread_info, tp_value);
+       offset("#define TI_REGS            ", struct thread_info, regs);
        constant("#define _THREAD_SIZE_ORDER ", THREAD_SIZE_ORDER);
        constant("#define _THREAD_SIZE       ", THREAD_SIZE);
        constant("#define _THREAD_MASK       ", THREAD_MASK);
index 9fbf8430c8499972ab80047026c803e64306a253..8485af340ee1a3c0316e8d5a60dc07d9246572d3 100644 (file)
@@ -135,7 +135,6 @@ static inline void check_wait(void)
        case CPU_R5000:
        case CPU_NEVADA:
        case CPU_RM7000:
-       case CPU_RM9000:
        case CPU_4KC:
        case CPU_4KEC:
        case CPU_4KSC:
@@ -164,6 +163,14 @@ static inline void check_wait(void)
                } else
                        printk(" unavailable.\n");
                break;
+       case CPU_RM9000:
+               if ((c->processor_id & 0x00ff) >= 0x40) {
+                       cpu_wait = r4k_wait;
+                       printk(" available.\n");
+               } else {
+                       printk(" unavailable.\n");
+               }
+               break;
        default:
                printk(" unavailable.\n");
                break;
index 766655f352508db89fa12941f614e7a84df2d7c3..417c08ac76eb52e393a617ab0a5871db07413475 100644 (file)
 #include <asm/mipsmtregs.h>
 #endif
 
-#ifdef CONFIG_PREEMPT
-       .macro  preempt_stop
-       .endm
-#else
+#ifndef CONFIG_PREEMPT
        .macro  preempt_stop
        local_irq_disable
        .endm
 
        .text
        .align  5
+FEXPORT(ret_from_irq)
+       LONG_S  s0, TI_REGS($28)
+#ifdef CONFIG_PREEMPT
+FEXPORT(ret_from_exception)
+#else
+       b       _ret_from_irq
 FEXPORT(ret_from_exception)
        preempt_stop
-FEXPORT(ret_from_irq)
+#endif
+FEXPORT(_ret_from_irq)
        LONG_L  t0, PT_STATUS(sp)               # returning to kernel mode?
        andi    t0, t0, KU_USER
        beqz    t0, resume_kernel
@@ -79,7 +83,6 @@ FEXPORT(syscall_exit)
 FEXPORT(restore_all)                   # restore full frame
 #ifdef CONFIG_MIPS_MT_SMTC
 /* Detect and execute deferred IPI "interrupts" */
-       move    a0,sp
        jal     deferred_smtc_ipi
 /* Re-arm any temporarily masked interrupts not explicitly "acked" */
        mfc0    v0, CP0_TCSTATUS
index af6ef2fd8300338f26e45e3acf7073027b8a6df6..5baca16993d08f512c2a1956a21755fd55521a94 100644 (file)
@@ -131,8 +131,9 @@ NESTED(handle_int, PT_SIZE, sp)
        CLI
        TRACE_IRQS_OFF
 
+       LONG_L  s0, TI_REGS($28)
+       LONG_S  sp, TI_REGS($28)
        PTR_LA  ra, ret_from_irq
-       move    a0, sp
        j       plat_irq_dispatch
        END(handle_int)
 
@@ -219,7 +220,9 @@ NESTED(except_vec_vi_handler, 0, sp)
 #endif /* CONFIG_MIPS_MT_SMTC */
        CLI
        TRACE_IRQS_OFF
-       move    a0, sp
+
+       LONG_L  s0, TI_REGS($28)
+       LONG_S  sp, TI_REGS($28)
        PTR_LA  ra, ret_from_irq
        jr      v0
        END(except_vec_vi_handler)
index 63dfeb41796bdb848747192cf6186a559713172a..650a80ca37418f1e0399f683520c9ab54887ccd3 100644 (file)
@@ -1,16 +1,17 @@
 /*
- * Copyright (c) 2004 MIPS Inc
- * Author: chris@mips.com
- *
  * 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) 2004 MIPS Inc
+ * Author: chris@mips.com
+ *
+ * Copyright (C) 2004, 06 Ralf Baechle <ralf@linux-mips.org>
  */
 #include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
-#include <asm/ptrace.h>
 #include <linux/sched.h>
 #include <linux/kernel_stat.h>
 #include <asm/io.h>
@@ -115,14 +116,14 @@ static void end_msc_irq(unsigned int irq)
 /*
  * Interrupt handler for interrupts coming from SOC-it.
  */
-void ll_msc_irq(struct pt_regs *regs)
+void ll_msc_irq(void)
 {
        unsigned int irq;
 
        /* read the interrupt vector register */
        MSCIC_READ(MSC01_IC_VEC, irq);
        if (irq < 64)
-               do_IRQ(irq + irq_base, regs);
+               do_IRQ(irq + irq_base);
        else {
                /* Ignore spurious interrupt */
        }
index b117e64da64d855f7b22922ff7bb5547fcb387bb..37d106202b83a7695cb0614013693bb57d5a2bbd 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright 2002 Momentum Computer
  * Author: mdharm@momenco.com
- * Copyright (C) 2004 Ralf Baechle <ralf@linux-mips.org>
+ * Copyright (C) 2004, 06 Ralf Baechle <ralf@linux-mips.org>
  *
  * This program is free software; you can redistribute  it and/or modify it
  * under  the terms of  the GNU General  Public License as published by the
@@ -15,7 +15,6 @@
 #include <linux/mv643xx.h>
 #include <linux/sched.h>
 
-#include <asm/ptrace.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/marvell.h>
@@ -113,7 +112,7 @@ static void end_mv64340_irq(unsigned int irq)
  * Interrupt handler for interrupts coming from the Marvell chip.
  * It could be built in ethernet ports etc...
  */
-void ll_mv64340_irq(struct pt_regs *regs)
+void ll_mv64340_irq(void)
 {
        unsigned int irq_src_low, irq_src_high;
        unsigned int irq_mask_low, irq_mask_high;
@@ -129,9 +128,9 @@ void ll_mv64340_irq(struct pt_regs *regs)
        irq_src_high &= irq_mask_high;
 
        if (irq_src_low)
-               do_IRQ(ls1bit32(irq_src_low) + irq_base, regs);
+               do_IRQ(ls1bit32(irq_src_low) + irq_base);
        else
-               do_IRQ(ls1bit32(irq_src_high) + irq_base + 32, regs);
+               do_IRQ(ls1bit32(irq_src_high) + irq_base + 32);
 }
 
 #define shutdown_mv64340_irq   disable_mv64340_irq
index d955aaefbb8eb1b521872e6685e18b849ff58c56..dd24434392b6355e248756869cbae341c2b47d17 100644 (file)
@@ -53,12 +53,12 @@ unsigned long irq_hwmask[NR_IRQS];
  * SMP cross-CPU interrupts have their own specific
  * handlers).
  */
-asmlinkage unsigned int do_IRQ(unsigned int irq, struct pt_regs *regs)
+asmlinkage unsigned int do_IRQ(unsigned int irq)
 {
        irq_enter();
 
        __DO_IRQ_SMTC_HOOK();
-       __do_IRQ(irq, regs);
+       __do_IRQ(irq);
 
        irq_exit();
 
@@ -110,7 +110,7 @@ skip:
        return 0;
 }
 
-asmlinkage void spurious_interrupt(struct pt_regs *regs)
+asmlinkage void spurious_interrupt(void)
 {
        atomic_inc(&irq_err_count);
 }
index 53f4171fc188a9695eb094b6a4ddda7977af349c..7a3ebbeba1f3aa036fd583e7472aa838595b10aa 100644 (file)
@@ -1055,7 +1055,9 @@ asmlinkage long sys32_newuname(struct new_utsname __user * name)
 asmlinkage int sys32_personality(unsigned long personality)
 {
        int ret;
-       if (current->personality == PER_LINUX32 && personality == PER_LINUX)
+       personality &= 0xffffffff;
+       if (personality(current->personality) == PER_LINUX32 &&
+           personality == PER_LINUX)
                personality = PER_LINUX32;
        ret = sys_personality(personality);
        if (ret == PER_LINUX32)
index d8beef1079020da34071e338ec3f08ab386a882b..4ed37ba19731071b369180cd12d3895ece7becbe 100644 (file)
@@ -89,9 +89,9 @@ static const char *cpu_name[] = {
 
 static int show_cpuinfo(struct seq_file *m, void *v)
 {
-       unsigned int version = current_cpu_data.processor_id;
-       unsigned int fp_vers = current_cpu_data.fpu_id;
        unsigned long n = (unsigned long) v - 1;
+       unsigned int version = cpu_data[n].processor_id;
+       unsigned int fp_vers = cpu_data[n].fpu_id;
        char fmt [64];
 
 #ifdef CONFIG_SMP
@@ -107,9 +107,9 @@ static int show_cpuinfo(struct seq_file *m, void *v)
 
        seq_printf(m, "processor\t\t: %ld\n", n);
        sprintf(fmt, "cpu model\t\t: %%s V%%d.%%d%s\n",
-               cpu_has_fpu ? "  FPU V%d.%d" : "");
-       seq_printf(m, fmt, cpu_name[current_cpu_data.cputype <= CPU_LAST ?
-                                   current_cpu_data.cputype : CPU_UNKNOWN],
+               cpu_data[n].options & MIPS_CPU_FPU ? "  FPU V%d.%d" : "");
+       seq_printf(m, fmt, cpu_name[cpu_data[n].cputype <= CPU_LAST ?
+                                   cpu_data[n].cputype : CPU_UNKNOWN],
                                   (version >> 4) & 0x0f, version & 0x0f,
                                   (fp_vers >> 4) & 0x0f, fp_vers & 0x0f);
        seq_printf(m, "BogoMIPS\t\t: %lu.%02lu\n",
@@ -118,7 +118,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
        seq_printf(m, "wait instruction\t: %s\n", cpu_wait ? "yes" : "no");
        seq_printf(m, "microsecond timers\t: %s\n",
                      cpu_has_counter ? "yes" : "no");
-       seq_printf(m, "tlb_entries\t\t: %d\n", current_cpu_data.tlbsize);
+       seq_printf(m, "tlb_entries\t\t: %d\n", cpu_data[n].tlbsize);
        seq_printf(m, "extra interrupt vector\t: %s\n",
                      cpu_has_divec ? "yes" : "no");
        seq_printf(m, "hardware watchpoint\t: %s\n",
index 045d987bc683b3da05fe6f5a700c413154d9e5f8..ec8209f3a0c68af6c70df1e43403ab23687f62f6 100644 (file)
@@ -115,7 +115,7 @@ void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp)
        status |= KU_USER;
        regs->cp0_status = status;
        clear_used_math();
-       lose_fpu();
+       clear_fpu_owner();
        if (cpu_has_dsp)
                __init_dsp();
        regs->cp0_epc = pc;
@@ -358,10 +358,8 @@ static int __init frame_info_init(void)
        unsigned long size = 0;
 #ifdef CONFIG_KALLSYMS
        unsigned long ofs;
-       char *modname;
-       char namebuf[KSYM_NAME_LEN + 1];
 
-       kallsyms_lookup((unsigned long)schedule, &size, &ofs, &modname, namebuf);
+       kallsyms_lookup_size_offset((unsigned long)schedule, &size, &ofs);
 #endif
        schedule_mfi.func = schedule;
        schedule_mfi.func_size = size;
@@ -403,8 +401,6 @@ unsigned long unwind_stack(struct task_struct *task, unsigned long *sp,
 {
        unsigned long stack_page;
        struct mips_frame_info info;
-       char *modname;
-       char namebuf[KSYM_NAME_LEN + 1];
        unsigned long size, ofs;
        int leaf;
        extern void ret_from_irq(void);
@@ -433,7 +429,7 @@ unsigned long unwind_stack(struct task_struct *task, unsigned long *sp,
                }
                return 0;
        }
-       if (!kallsyms_lookup(pc, &size, &ofs, &modname, namebuf))
+       if (!kallsyms_lookup_size_offset(pc, &size, &ofs))
                return 0;
        /*
         * Return ra if an exception occured at the first instruction
index 362d1728e5317d7b99f014a045f2c821c341056f..258d74fd0b638a8eb7c64c9431c3b7bdc26dc58e 100644 (file)
@@ -106,6 +106,7 @@ int ptrace_setregs (struct task_struct *child, __s64 __user *data)
 int ptrace_getfpregs (struct task_struct *child, __u32 __user *data)
 {
        int i;
+       unsigned int tmp;
 
        if (!access_ok(VERIFY_WRITE, data, 33 * 8))
                return -EIO;
@@ -121,10 +122,10 @@ int ptrace_getfpregs (struct task_struct *child, __u32 __user *data)
 
        __put_user (child->thread.fpu.fcr31, data + 64);
 
+       preempt_disable();
        if (cpu_has_fpu) {
-               unsigned int flags, tmp;
+               unsigned int flags;
 
-               preempt_disable();
                if (cpu_has_mipsmt) {
                        unsigned int vpflags = dvpe();
                        flags = read_c0_status();
@@ -138,11 +139,11 @@ int ptrace_getfpregs (struct task_struct *child, __u32 __user *data)
                        __asm__ __volatile__("cfc1\t%0,$0" : "=r" (tmp));
                        write_c0_status(flags);
                }
-               preempt_enable();
-               __put_user (tmp, data + 65);
        } else {
-               __put_user ((__u32) 0, data + 65);
+               tmp = 0;
        }
+       preempt_enable();
+       __put_user (tmp, data + 65);
 
        return 0;
 }
@@ -245,16 +246,17 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
                        unsigned int mtflags;
 #endif /* CONFIG_MIPS_MT_SMTC */
 
-                       if (!cpu_has_fpu)
+                       preempt_disable();
+                       if (!cpu_has_fpu) {
+                               preempt_enable();
                                break;
+                       }
 
 #ifdef CONFIG_MIPS_MT_SMTC
                        /* Read-modify-write of Status must be atomic */
                        local_irq_save(irqflags);
                        mtflags = dmt();
 #endif /* CONFIG_MIPS_MT_SMTC */
-
-                       preempt_disable();
                        if (cpu_has_mipsmt) {
                                unsigned int vpflags = dvpe();
                                flags = read_c0_status();
index f40ecd8be05fc7b5376a4b24856d9236f17fb5c2..d9a39c1694505c61370c610079514af27825a11d 100644 (file)
@@ -175,7 +175,9 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data)
                        unsigned int mtflags;
 #endif /* CONFIG_MIPS_MT_SMTC */
 
+                       preempt_disable();
                        if (!cpu_has_fpu) {
+                               preempt_enable();
                                tmp = 0;
                                break;
                        }
@@ -186,7 +188,6 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data)
                        mtflags = dmt();
 #endif /* CONFIG_MIPS_MT_SMTC */
 
-                       preempt_disable();
                        if (cpu_has_mipsmt) {
                                unsigned int vpflags = dvpe();
                                flags = read_c0_status();
index cdab1b2cd1343c0185ed4d5161059222076a6e0a..8c8c8324f775301e7ccfd16dfe77918771cd7e93 100644 (file)
@@ -61,16 +61,16 @@ static int sp_stopping = 0;
 
 extern void *vpe_get_shared(int index);
 
-static void rtlx_dispatch(struct pt_regs *regs)
+static void rtlx_dispatch(void)
 {
-       do_IRQ(MIPSCPU_INT_BASE + MIPS_CPU_RTLX_IRQ, regs);
+       do_IRQ(MIPSCPU_INT_BASE + MIPS_CPU_RTLX_IRQ);
 }
 
 
 /* Interrupt handler may be called before rtlx_init has otherwise had
    a chance to run.
 */
-static irqreturn_t rtlx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t rtlx_interrupt(int irq, void *dev_id)
 {
        int i;
 
index 61362e6fa9eccfbfb79b8abfde01d57b431f6e08..720fac3435d5aa9d49c1e2393fc476c7949c1168 100644 (file)
@@ -652,7 +652,8 @@ einval:     li      v0, -EINVAL
        sys     sys_vmsplice            4
        sys     sys_move_pages          6
        sys     sys_set_robust_list     2
-       sys     sys_get_robust_list     3
+       sys     sys_get_robust_list     3       /* 4310 */
+       sys     sys_ni_syscall          0
        .endm
 
        /* We pre-compute the number of _instruction_ bytes needed to
index 6c7b5ed0ea6e0ccec04ebfff052e0e9fd2fc780e..3a34f62c8b1b3152b9fb3ac68911a47484eb3743 100644 (file)
@@ -468,3 +468,4 @@ sys_call_table:
        PTR     sys_move_pages
        PTR     sys_set_robust_list
        PTR     sys_get_robust_list
+       PTR     sys_ni_syscall                  /* 5270 */
index 6d9f18727ac51e5baf3232f4624f733c8789732b..67b92a1d6c72268aa2ba12120011fd8754db4a71 100644 (file)
@@ -280,7 +280,7 @@ EXPORT(sysn32_call_table)
        PTR     sys_sync
        PTR     sys_acct
        PTR     sys32_settimeofday
-       PTR     sys_mount                       /* 6160 */
+       PTR     compat_sys_mount                /* 6160 */
        PTR     sys_umount
        PTR     sys_swapon
        PTR     sys_swapoff
@@ -394,3 +394,4 @@ EXPORT(sysn32_call_table)
        PTR     sys_move_pages
        PTR     compat_sys_set_robust_list
        PTR     compat_sys_get_robust_list
+       PTR     sys_ni_syscall
index 2e6d0673163e1896cc2ac05d3299755f77f43aac..2875c4a3fa5801f8d5b87f1b895d91003b85f510 100644 (file)
@@ -226,7 +226,7 @@ sys_call_table:
        PTR     sys_ni_syscall                  /* was sys_stat */
        PTR     sys_lseek
        PTR     sys_getpid                      /* 4020 */
-       PTR     sys_mount
+       PTR     compat_sys_mount
        PTR     sys_oldumount
        PTR     sys_setuid
        PTR     sys_getuid
@@ -516,4 +516,5 @@ sys_call_table:
        PTR     compat_sys_move_pages
        PTR     compat_sys_set_robust_list
        PTR     compat_sys_get_robust_list      /* 4310 */
+       PTR     sys_ni_syscall
        .size   sys_call_table,.-sys_call_table
index 766253c44f3fd8d3dcae954755702e13bb78506a..3b5f3b632622c852ee1e699f7af9bc7f90c610e0 100644 (file)
@@ -106,22 +106,22 @@ void __init sanitize_tlb_entries(void)
        clear_c0_mvpcontrol(MVPCONTROL_VPC);
 }
 
-static void ipi_resched_dispatch (struct pt_regs *regs)
+static void ipi_resched_dispatch(void)
 {
-       do_IRQ(MIPSCPU_INT_BASE + MIPS_CPU_IPI_RESCHED_IRQ, regs);
+       do_IRQ(MIPSCPU_INT_BASE + MIPS_CPU_IPI_RESCHED_IRQ);
 }
 
-static void ipi_call_dispatch (struct pt_regs *regs)
+static void ipi_call_dispatch(void)
 {
-       do_IRQ(MIPSCPU_INT_BASE + MIPS_CPU_IPI_CALL_IRQ, regs);
+       do_IRQ(MIPSCPU_INT_BASE + MIPS_CPU_IPI_CALL_IRQ);
 }
 
-irqreturn_t ipi_resched_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t ipi_resched_interrupt(int irq, void *dev_id)
 {
        return IRQ_HANDLED;
 }
 
-irqreturn_t ipi_call_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t ipi_call_interrupt(int irq, void *dev_id)
 {
        smp_call_function_interrupt();
 
@@ -250,8 +250,8 @@ void __init plat_prepare_cpus(unsigned int max_cpus)
 {
        /* set up ipi interrupts */
        if (cpu_has_vint) {
-               set_vi_handler (MIPS_CPU_IPI_RESCHED_IRQ, ipi_resched_dispatch);
-               set_vi_handler (MIPS_CPU_IPI_CALL_IRQ, ipi_call_dispatch);
+               set_vi_handler(MIPS_CPU_IPI_RESCHED_IRQ, ipi_resched_dispatch);
+               set_vi_handler(MIPS_CPU_IPI_CALL_IRQ, ipi_call_dispatch);
        }
 
        cpu_ipi_resched_irq = MIPSCPU_INT_BASE + MIPS_CPU_IPI_RESCHED_IRQ;
index 221895802dca8eecd1be9e374173f4f1522facaa..db80957ada8957631070f40bb10f847cd01eb26e 100644 (file)
@@ -310,7 +310,7 @@ static void flush_tlb_all_ipi(void *info)
 
 void flush_tlb_all(void)
 {
-       on_each_cpu(flush_tlb_all_ipi, 0, 1, 1);
+       on_each_cpu(flush_tlb_all_ipi, NULL, 1, 1);
 }
 
 static void flush_tlb_mm_ipi(void *mm)
@@ -467,14 +467,18 @@ static DEFINE_PER_CPU(struct cpu, cpu_devices);
 
 static int __init topology_init(void)
 {
-       int cpu;
-       int ret;
+       int i, ret;
 
-       for_each_present_cpu(cpu) {
-               ret = register_cpu(&per_cpu(cpu_devices, cpu), cpu);
+#ifdef CONFIG_NUMA
+       for_each_online_node(i)
+               register_one_node(i);
+#endif /* CONFIG_NUMA */
+
+       for_each_present_cpu(i) {
+               ret = register_cpu(&per_cpu(cpu_devices, i), i);
                if (ret)
                        printk(KERN_WARNING "topology_init: register_cpu %d "
-                              "failed (%d)\n", cpu, ret);
+                              "failed (%d)\n", i, ret);
        }
 
        return 0;
index 76cb31d574824a3bb6f876d10ebacb470a0a02a6..1cb9441f1474f76692319df943b8ee20b4bf994a 100644 (file)
@@ -97,15 +97,12 @@ FEXPORT(__smtc_ipi_vector)
        SAVE_ALL
        CLI
        TRACE_IRQS_OFF
-       move    a0,sp
        /* Function to be invoked passed stack pad slot 5 */
        lw      t0,PT_PADSLOT5(sp)
        /* Argument from sender passed in stack pad slot 4 */
-       lw      a1,PT_PADSLOT4(sp)
-       jalr    t0
-       nop
-       j       ret_from_irq
-       nop
+       lw      a0,PT_PADSLOT4(sp)
+       PTR_LA  ra, _ret_from_irq
+       jr      t0
 
 /*
  * Called from idle loop to provoke processing of queued IPIs
index 604bcc5cb7c8599dcb180ac8d314fa769f1ef990..cc1f7474f7d7097fe042cb25fee23746e38c4606 100644 (file)
@@ -82,7 +82,7 @@ struct smtc_ipi_q freeIPIq;
 
 /* Forward declarations */
 
-void ipi_decode(struct pt_regs *, struct smtc_ipi *);
+void ipi_decode(struct smtc_ipi *);
 void post_direct_ipi(int cpu, struct smtc_ipi *pipi);
 void setup_cross_vpe_interrupts(void);
 void init_smtc_stats(void);
@@ -820,19 +820,19 @@ void post_direct_ipi(int cpu, struct smtc_ipi *pipi)
        write_tc_c0_tcrestart(__smtc_ipi_vector);
 }
 
-void ipi_resched_interrupt(struct pt_regs *regs)
+static void ipi_resched_interrupt(void)
 {
        /* Return from interrupt should be enough to cause scheduler check */
 }
 
 
-void ipi_call_interrupt(struct pt_regs *regs)
+static void ipi_call_interrupt(void)
 {
        /* Invoke generic function invocation code in smp.c */
        smp_call_function_interrupt();
 }
 
-void ipi_decode(struct pt_regs *regs, struct smtc_ipi *pipi)
+void ipi_decode(struct smtc_ipi *pipi)
 {
        void *arg_copy = pipi->arg;
        int type_copy = pipi->type;
@@ -846,15 +846,15 @@ void ipi_decode(struct pt_regs *regs, struct smtc_ipi *pipi)
 #ifdef SMTC_IDLE_HOOK_DEBUG
                clock_hang_reported[dest_copy] = 0;
 #endif /* SMTC_IDLE_HOOK_DEBUG */
-               local_timer_interrupt(0, NULL, regs);
+               local_timer_interrupt(0, NULL);
                break;
        case LINUX_SMP_IPI:
                switch ((int)arg_copy) {
                case SMP_RESCHEDULE_YOURSELF:
-                       ipi_resched_interrupt(regs);
+                       ipi_resched_interrupt();
                        break;
                case SMP_CALL_FUNCTION:
-                       ipi_call_interrupt(regs);
+                       ipi_call_interrupt();
                        break;
                default:
                        printk("Impossible SMTC IPI Argument 0x%x\n",
@@ -868,7 +868,7 @@ void ipi_decode(struct pt_regs *regs, struct smtc_ipi *pipi)
        }
 }
 
-void deferred_smtc_ipi(struct pt_regs *regs)
+void deferred_smtc_ipi(void)
 {
        struct smtc_ipi *pipi;
        unsigned long flags;
@@ -883,7 +883,7 @@ void deferred_smtc_ipi(struct pt_regs *regs)
                while((pipi = smtc_ipi_dq(&IPIQ[q])) != NULL) {
                        /* ipi_decode() should be called with interrupts off */
                        local_irq_save(flags);
-                       ipi_decode(regs, pipi);
+                       ipi_decode(pipi);
                        local_irq_restore(flags);
                }
        }
@@ -917,7 +917,7 @@ void smtc_timer_broadcast(int vpe)
 
 static int cpu_ipi_irq = MIPSCPU_INT_BASE + MIPS_CPU_IPI_IRQ;
 
-static irqreturn_t ipi_interrupt(int irq, void *dev_idm, struct pt_regs *regs)
+static irqreturn_t ipi_interrupt(int irq, void *dev_idm)
 {
        int my_vpe = cpu_data[smp_processor_id()].vpe_id;
        int my_tc = cpu_data[smp_processor_id()].tc_id;
@@ -978,7 +978,7 @@ static irqreturn_t ipi_interrupt(int irq, void *dev_idm, struct pt_regs *regs)
                                 * with interrupts off
                                 */
                                local_irq_save(flags);
-                               ipi_decode(regs, pipi);
+                               ipi_decode(pipi);
                                local_irq_restore(flags);
                        }
                }
@@ -987,9 +987,9 @@ static irqreturn_t ipi_interrupt(int irq, void *dev_idm, struct pt_regs *regs)
        return IRQ_HANDLED;
 }
 
-static void ipi_irq_dispatch(struct pt_regs *regs)
+static void ipi_irq_dispatch(void)
 {
-       do_IRQ(cpu_ipi_irq, regs);
+       do_IRQ(cpu_ipi_irq);
 }
 
 static struct irqaction irq_ipi;
index 4aabe526a68e3e38b9eb4a59670168d695255b15..a586aba337a7afcbd0f93f50c36c59167face762 100644 (file)
@@ -57,7 +57,7 @@ static void save_context_stack(struct stack_trace *trace,
                pc = unwind_stack(task, &sp, pc, &ra);
        } while (pc);
 #else
-       save_raw_context_stack(sp);
+       save_raw_context_stack(trace, sp);
 #endif
 }
 
index a8340802f2d76a3c27acd634a1e658b6a0a8518e..debe86c2f6911fe2eff60b8090d35364d76982fe 100644 (file)
@@ -322,18 +322,17 @@ static long last_rtc_update;
  * a broadcasted inter-processor interrupt which itself is triggered
  * by the global timer interrupt.
  */
-void local_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+void local_timer_interrupt(int irq, void *dev_id)
 {
-       if (current->pid)
-               profile_tick(CPU_PROFILING, regs);
-       update_process_times(user_mode(regs));
+       profile_tick(CPU_PROFILING);
+       update_process_times(user_mode(get_irq_regs()));
 }
 
 /*
  * High-level timer interrupt service routines.  This function
  * is set as irqaction->handler and is invoked through do_IRQ.
  */
-irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t timer_interrupt(int irq, void *dev_id)
 {
        unsigned long j;
        unsigned int count;
@@ -419,22 +418,22 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
         * In SMP mode, local_timer_interrupt() is invoked by appropriate
         * low-level local timer interrupt handler.
         */
-       local_timer_interrupt(irq, dev_id, regs);
+       local_timer_interrupt(irq, dev_id);
 
        return IRQ_HANDLED;
 }
 
-int null_perf_irq(struct pt_regs *regs)
+int null_perf_irq(void)
 {
        return 0;
 }
 
-int (*perf_irq)(struct pt_regs *regs) = null_perf_irq;
+int (*perf_irq)(void) = null_perf_irq;
 
 EXPORT_SYMBOL(null_perf_irq);
 EXPORT_SYMBOL(perf_irq);
 
-asmlinkage void ll_timer_interrupt(int irq, struct pt_regs *regs)
+asmlinkage void ll_timer_interrupt(int irq)
 {
        int r2 = cpu_has_mips_r2;
 
@@ -448,25 +447,25 @@ asmlinkage void ll_timer_interrupt(int irq, struct pt_regs *regs)
         * performance counter interrupt handler anyway.
         */
        if (!r2 || (read_c0_cause() & (1 << 26)))
-               if (perf_irq(regs))
+               if (perf_irq())
                        goto out;
 
        /* we keep interrupt disabled all the time */
        if (!r2 || (read_c0_cause() & (1 << 30)))
-               timer_interrupt(irq, NULL, regs);
+               timer_interrupt(irq, NULL);
 
 out:
        irq_exit();
 }
 
-asmlinkage void ll_local_timer_interrupt(int irq, struct pt_regs *regs)
+asmlinkage void ll_local_timer_interrupt(int irq)
 {
        irq_enter();
        if (smp_processor_id() != 0)
                kstat_this_cpu.irqs[irq]++;
 
        /* we keep interrupt disabled all the time */
-       local_timer_interrupt(irq, NULL, regs);
+       local_timer_interrupt(irq, NULL);
 
        irq_exit();
 }
index b7292a56d4cd80b65d4bf2ef6f6ff016d371c857..cce8313ec27dcacc41247e863376efe50d986809 100644 (file)
@@ -66,7 +66,7 @@ extern asmlinkage void handle_mcheck(void);
 extern asmlinkage void handle_reserved(void);
 
 extern int fpu_emulator_cop1Handler(struct pt_regs *xcp,
-       struct mips_fpu_struct *ctx);
+       struct mips_fpu_struct *ctx, int has_fpu);
 
 void (*board_be_init)(void);
 int (*board_be_handler)(struct pt_regs *regs, int is_fixup);
@@ -641,7 +641,7 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
                preempt_enable();
 
                /* Run the emulator */
-               sig = fpu_emulator_cop1Handler (regs, &current->thread.fpu);
+               sig = fpu_emulator_cop1Handler (regs, &current->thread.fpu, 1);
 
                preempt_disable();
 
@@ -791,11 +791,13 @@ asmlinkage void do_cpu(struct pt_regs *regs)
                        set_used_math();
                }
 
-               preempt_enable();
-
-               if (!cpu_has_fpu) {
-                       int sig = fpu_emulator_cop1Handler(regs,
-                                               &current->thread.fpu);
+               if (cpu_has_fpu) {
+                       preempt_enable();
+               } else {
+                       int sig;
+                       preempt_enable();
+                       sig = fpu_emulator_cop1Handler(regs,
+                                               &current->thread.fpu, 0);
                        if (sig)
                                force_sig(sig, current);
 #ifdef CONFIG_MIPS_MT_FPAFF
index 456be8fc961a293772b2e2280280bced6ffca27d..a144a002dcc438cd118cbca7dbc7cc77d8b4291b 100644 (file)
@@ -108,14 +108,14 @@ static unsigned long get_int_status_200(void)
        return int_status;
 }
 
-asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+asmlinkage void plat_irq_dispatch(void)
 {
        unsigned long int_status;
        unsigned int cause = read_c0_cause();
        int irq;
 
        if (cause & CAUSEF_IP7) {       /* R4000 count / compare IRQ */
-               ll_timer_interrupt(7, regs);
+               ll_timer_interrupt(7);
                return;
        }
 
@@ -125,7 +125,7 @@ asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
        if (int_status) {
                irq = ls1bit32(int_status);
 
-               do_IRQ(irq, regs);
+               do_IRQ(irq);
        }
 }
 
index 3f0d5d26d506d27abc452b394268a57532df00b4..80531b35cd61e315382e2d036eaff313e94973f8 100644 (file)
@@ -38,8 +38,6 @@
 
 #include <asm/inst.h>
 #include <asm/bootinfo.h>
-#include <asm/cpu.h>
-#include <asm/cpu-features.h>
 #include <asm/processor.h>
 #include <asm/ptrace.h>
 #include <asm/signal.h>
@@ -1233,7 +1231,8 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
        return 0;
 }
 
-int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
+int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
+       int has_fpu)
 {
        unsigned long oldepc, prevepc;
        mips_instruction insn;
@@ -1263,7 +1262,7 @@ int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
                        ieee754_csr.rm = mips_rm[ieee754_csr.rm];
                }
 
-               if (cpu_has_fpu)
+               if (has_fpu)
                        break;
                if (sig)
                        break;
index a020a3cb4f4bc4767130546fc287f0c09f1cb049..be624b8c3b0ec33d93d4cefe89d3fac26840d706 100644 (file)
@@ -101,7 +101,7 @@ static inline int ls1bit32(unsigned int x)
        return b;
 }
 
-static inline void atlas_hw0_irqdispatch(struct pt_regs *regs)
+static inline void atlas_hw0_irqdispatch(void)
 {
        unsigned long int_status;
        int irq;
@@ -116,7 +116,7 @@ static inline void atlas_hw0_irqdispatch(struct pt_regs *regs)
 
        DEBUG_INT("atlas_hw0_irqdispatch: irq=%d\n", irq);
 
-       do_IRQ(irq, regs);
+       do_IRQ(irq);
 }
 
 static inline int clz(unsigned long x)
@@ -188,7 +188,7 @@ static inline unsigned int irq_ffs(unsigned int pending)
  * then we just return, if multiple IRQs are pending then we will just take
  * another exception, big deal.
  */
-asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+asmlinkage void plat_irq_dispatch(void)
 {
        unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
        int irq;
@@ -196,11 +196,11 @@ asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
        irq = irq_ffs(pending);
 
        if (irq == MIPSCPU_INT_ATLAS)
-               atlas_hw0_irqdispatch(regs);
+               atlas_hw0_irqdispatch();
        else if (irq >= 0)
-               do_IRQ(MIPSCPU_INT_BASE + irq, regs);
+               do_IRQ(MIPSCPU_INT_BASE + irq);
        else
-               spurious_interrupt(regs);
+               spurious_interrupt();
 }
 
 static inline void init_atlas_irqs (int base)
index 8d15861fce618248aeab570ccee13ef637bd769f..c079e2ae02a1d0484884005f779f6d5e323815e0 100644 (file)
@@ -30,7 +30,6 @@
 
 #include <asm/mipsregs.h>
 #include <asm/mipsmtregs.h>
-#include <asm/ptrace.h>
 #include <asm/hardirq.h>
 #include <asm/irq.h>
 #include <asm/div64.h>
@@ -82,19 +81,19 @@ static inline void scroll_display_message(void)
        }
 }
 
-static void mips_timer_dispatch (struct pt_regs *regs)
+static void mips_timer_dispatch(void)
 {
-       do_IRQ (mips_cpu_timer_irq, regs);
+       do_IRQ(mips_cpu_timer_irq);
 }
 
 /*
  * Redeclare until I get around mopping the timer code insanity on MIPS.
  */
-extern int null_perf_irq(struct pt_regs *regs);
+extern int null_perf_irq(void);
 
-extern int (*perf_irq)(struct pt_regs *regs);
+extern int (*perf_irq)(void);
 
-irqreturn_t mips_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t mips_timer_interrupt(int irq, void *dev_id)
 {
        int cpu = smp_processor_id();
 
@@ -119,7 +118,7 @@ irqreturn_t mips_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
         * perf counter overflow, or both.
         */
        if (read_c0_cause() & (1 << 26))
-               perf_irq(regs);
+               perf_irq();
 
        if (read_c0_cause() & (1 << 30)) {
                /* If timer interrupt, make it de-assert */
@@ -139,13 +138,13 @@ irqreturn_t mips_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                 * the tick on VPE 0 to run the full timer_interrupt().
                 */
                if (cpu_data[cpu].vpe_id == 0) {
-                               timer_interrupt(irq, NULL, regs);
+                               timer_interrupt(irq, NULL);
                                smtc_timer_broadcast(cpu_data[cpu].vpe_id);
                                scroll_display_message();
                } else {
                        write_c0_compare(read_c0_count() +
                                         (mips_hpt_frequency/HZ));
-                       local_timer_interrupt(irq, dev_id, regs);
+                       local_timer_interrupt(irq, dev_id);
                        smtc_timer_broadcast(cpu_data[cpu].vpe_id);
                }
        }
@@ -159,12 +158,12 @@ irqreturn_t mips_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                 * timer int.
                 */
                if (!r2 || (read_c0_cause() & (1 << 26)))
-                       if (perf_irq(regs))
+                       if (perf_irq())
                                goto out;
 
                /* we keep interrupt disabled all the time */
                if (!r2 || (read_c0_cause() & (1 << 30)))
-                       timer_interrupt(irq, NULL, regs);
+                       timer_interrupt(irq, NULL);
 
                scroll_display_message();
        } else {
@@ -180,7 +179,7 @@ irqreturn_t mips_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                /*
                 * Other CPUs should do profiling and process accounting
                 */
-               local_timer_interrupt(irq, dev_id, regs);
+               local_timer_interrupt(irq, dev_id);
        }
 out:
 #endif /* CONFIG_MIPS_MT_SMTC */
@@ -188,7 +187,7 @@ out:
 }
 
 /*
- * Estimate CPU frequency.  Sets mips_counter_frequency as a side-effect
+ * Estimate CPU frequency.  Sets mips_hpt_frequency as a side-effect
  */
 static unsigned int __init estimate_cpu_frequency(void)
 {
index 7cc0ba4f553ab2bae354b14fe07983faf47cfb37..90ad5bf3e2f175c8dd3c5ab055860ae988c3fdb2 100644 (file)
@@ -32,6 +32,7 @@
 #include <asm/i8259.h>
 #include <asm/irq_cpu.h>
 #include <asm/io.h>
+#include <asm/irq_regs.h>
 #include <asm/mips-boards/malta.h>
 #include <asm/mips-boards/maltaint.h>
 #include <asm/mips-boards/piix4.h>
@@ -114,7 +115,7 @@ static inline int get_int(void)
        return irq;
 }
 
-static void malta_hw0_irqdispatch(struct pt_regs *regs)
+static void malta_hw0_irqdispatch(void)
 {
        int irq;
 
@@ -123,17 +124,21 @@ static void malta_hw0_irqdispatch(struct pt_regs *regs)
                return;  /* interrupt has already been cleared */
        }
 
-       do_IRQ(MALTA_INT_BASE+irq, regs);
+       do_IRQ(MALTA_INT_BASE + irq);
 }
 
-void corehi_irqdispatch(struct pt_regs *regs)
+static void corehi_irqdispatch(void)
 {
+       unsigned int intedge, intsteer, pcicmd, pcibadaddr;
+        unsigned int pcimstat, intisr, inten, intpol;
        unsigned int intrcause,datalo,datahi;
-        unsigned int pcimstat, intisr, inten, intpol, intedge, intsteer, pcicmd, pcibadaddr;
+       struct pt_regs *regs = get_irq_regs();
 
         printk("CoreHI interrupt, shouldn't happen, so we die here!!!\n");
-        printk("epc   : %08lx\nStatus: %08lx\nCause : %08lx\nbadVaddr : %08lx\n"
-, regs->cp0_epc, regs->cp0_status, regs->cp0_cause, regs->cp0_badvaddr);
+        printk("epc   : %08lx\nStatus: %08lx\n"
+              "Cause : %08lx\nbadVaddr : %08lx\n",
+              regs->cp0_epc, regs->cp0_status,
+              regs->cp0_cause, regs->cp0_badvaddr);
 
        /* Read all the registers and then print them as there is a
           problem with interspersed printk's upsetting the Bonito controller.
@@ -146,7 +151,7 @@ void corehi_irqdispatch(struct pt_regs *regs)
         case MIPS_REVISION_CORID_CORE_FPGA3:
         case MIPS_REVISION_CORID_CORE_24K:
         case MIPS_REVISION_CORID_CORE_EMUL_MSC:
-                ll_msc_irq(regs);
+                ll_msc_irq();
                 break;
         case MIPS_REVISION_CORID_QED_RM5261:
         case MIPS_REVISION_CORID_CORE_LV:
@@ -208,23 +213,23 @@ static inline unsigned int irq_ffs(unsigned int pending)
        unsigned int a0 = 7;
        unsigned int t0;
 
-       t0 = s0 & 0xf000;
+       t0 = pending & 0xf000;
        t0 = t0 < 1;
        t0 = t0 << 2;
        a0 = a0 - t0;
-       s0 = s0 << t0;
+       pending = pending << t0;
 
-       t0 = s0 & 0xc000;
+       t0 = pending & 0xc000;
        t0 = t0 < 1;
        t0 = t0 << 1;
        a0 = a0 - t0;
-       s0 = s0 << t0;
+       pending = pending << t0;
 
-       t0 = s0 & 0x8000;
+       t0 = pending & 0x8000;
        t0 = t0 < 1;
        //t0 = t0 << 2;
        a0 = a0 - t0;
-       //s0 = s0 << t0;
+       //pending = pending << t0;
 
        return a0;
 #endif
@@ -255,7 +260,7 @@ static inline unsigned int irq_ffs(unsigned int pending)
  * another exception, big deal.
  */
 
-asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+asmlinkage void plat_irq_dispatch(void)
 {
        unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
        int irq;
@@ -263,11 +268,11 @@ asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
        irq = irq_ffs(pending);
 
        if (irq == MIPSCPU_INT_I8259A)
-               malta_hw0_irqdispatch(regs);
+               malta_hw0_irqdispatch();
        else if (irq > 0)
-               do_IRQ(MIPSCPU_INT_BASE + irq, regs);
+               do_IRQ(MIPSCPU_INT_BASE + irq);
        else
-               spurious_interrupt(regs);
+               spurious_interrupt();
 }
 
 static struct irqaction i8259irq = {
index 9168d934c661477d421c784f4569c0cbffc668d3..f445fcddfdfd925bc9ca4525db4c970998b35e29 100644 (file)
@@ -98,7 +98,7 @@ static inline unsigned int irq_ffs(unsigned int pending)
  * then we just return, if multiple IRQs are pending then we will just take
  * another exception, big deal.
  */
-asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+asmlinkage void plat_irq_dispatch(void)
 {
        unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
        int irq;
@@ -106,7 +106,7 @@ asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
        irq = irq_ffs(pending);
 
        if (irq >= 0)
-               do_IRQ(MIPSCPU_INT_BASE + irq, regs);
+               do_IRQ(MIPSCPU_INT_BASE + irq);
        else
                spurious_interrupt(regs);
 }
index 2c15c8efec4e30c8e0bdc27df5e5327c644117b5..2ce449dce6f2401b7bb47542e6a5b8b8f31ff4a5 100644 (file)
@@ -71,12 +71,7 @@ static inline unsigned int irq_ffs(unsigned int pending)
 #endif
 }
 
-static inline void sim_hw0_irqdispatch(struct pt_regs *regs)
-{
-       do_IRQ(2, regs);
-}
-
-asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+asmlinkage void plat_irq_dispatch(void)
 {
        unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
        int irq;
@@ -84,9 +79,9 @@ asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
        irq = irq_ffs(pending);
 
        if (irq > 0)
-               do_IRQ(MIPSCPU_INT_BASE + irq, regs);
+               do_IRQ(MIPSCPU_INT_BASE + irq);
        else
-               spurious_interrupt(regs);
+               spurious_interrupt();
 }
 
 void __init arch_init_irq(void)
index 230929ecd57f3cbd8e4fb5a7872d5beedf2a194a..24a4ed00cc0a0f39786a5e6749dadff0aee6296d 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/mc146818rtc.h>
 #include <linux/timex.h>
 #include <asm/mipsregs.h>
-#include <asm/ptrace.h>
 #include <asm/hardirq.h>
 #include <asm/irq.h>
 #include <asm/div64.h>
@@ -33,7 +32,7 @@
 
 unsigned long cpu_khz;
 
-irqreturn_t sim_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t sim_timer_interrupt(int irq, void *dev_id)
 {
 #ifdef CONFIG_SMP
        int cpu = smp_processor_id();
@@ -44,7 +43,7 @@ irqreturn_t sim_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
         */
 #ifndef CONFIG_MIPS_MT_SMTC
        if (cpu == 0) {
-               timer_interrupt(irq, dev_id, regs);
+               timer_interrupt(irq, dev_id);
        }
        else {
                /* Everyone else needs to reset the timer int here as
@@ -84,7 +83,7 @@ irqreturn_t sim_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        irq_enable_hazard();
        evpe(vpflags);
 
-       if(cpu_data[cpu].vpe_id == 0) timer_interrupt(irq, dev_id, regs);
+       if(cpu_data[cpu].vpe_id == 0) timer_interrupt(irq, dev_id);
        else write_c0_compare (read_c0_count() + ( mips_hpt_frequency/HZ));
        smtc_timer_broadcast(cpu_data[cpu].vpe_id);
 
@@ -93,17 +92,17 @@ irqreturn_t sim_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        /*
         * every CPU should do profiling and process accounting
         */
-       local_timer_interrupt (irq, dev_id, regs);
+       local_timer_interrupt (irq, dev_id);
        return IRQ_HANDLED;
 #else
-       return timer_interrupt (irq, dev_id, regs);
+       return timer_interrupt (irq, dev_id);
 #endif
 }
 
 
 
 /*
- * Estimate CPU frequency.  Sets mips_counter_frequency as a side-effect
+ * Estimate CPU frequency.  Sets mips_hpt_frequency as a side-effect
  */
 static unsigned int __init estimate_cpu_frequency(void)
 {
@@ -177,9 +176,9 @@ void __init sim_time_init(void)
 
 static int mips_cpu_timer_irq;
 
-static void mips_timer_dispatch (struct pt_regs *regs)
+static void mips_timer_dispatch(void)
 {
-       do_IRQ (mips_cpu_timer_irq, regs);
+       do_IRQ(mips_cpu_timer_irq);
 }
 
 
index 88b72c9a84957f2ac787ccf83fa46c4dbb0818d2..2de4d3c367a2c2da9adb6bcf29b5105c46c01f78 100644 (file)
 #include <asm/cachectl.h>
 #include <asm/cpu.h>
 #include <asm/dma.h>
+#include <asm/kmap_types.h>
 #include <asm/mmu_context.h>
 #include <asm/sections.h>
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
 #include <asm/tlb.h>
+#include <asm/fixmap.h>
+
+/* Atomicity and interruptability */
+#ifdef CONFIG_MIPS_MT_SMTC
+
+#include <asm/mipsmtregs.h>
+
+#define ENTER_CRITICAL(flags) \
+       { \
+       unsigned int mvpflags; \
+       local_irq_save(flags);\
+       mvpflags = dvpe()
+#define EXIT_CRITICAL(flags) \
+       evpe(mvpflags); \
+       local_irq_restore(flags); \
+       }
+#else
+
+#define ENTER_CRITICAL(flags) local_irq_save(flags)
+#define EXIT_CRITICAL(flags) local_irq_restore(flags)
+
+#endif /* CONFIG_MIPS_MT_SMTC */
 
 DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
 
@@ -80,13 +103,142 @@ unsigned long setup_zero_pages(void)
        return 1UL << order;
 }
 
-#ifdef CONFIG_HIGHMEM
-pte_t *kmap_pte;
-pgprot_t kmap_prot;
+/*
+ * These are almost like kmap_atomic / kunmap_atmic except they take an
+ * additional address argument as the hint.
+ */
 
 #define kmap_get_fixmap_pte(vaddr)                                     \
        pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)), (vaddr))
 
+#ifdef CONFIG_MIPS_MT_SMTC
+static pte_t *kmap_coherent_pte;
+static void __init kmap_coherent_init(void)
+{
+       unsigned long vaddr;
+
+       /* cache the first coherent kmap pte */
+       vaddr = __fix_to_virt(FIX_CMAP_BEGIN);
+       kmap_coherent_pte = kmap_get_fixmap_pte(vaddr);
+}
+#else
+static inline void kmap_coherent_init(void) {}
+#endif
+
+static inline void *kmap_coherent(struct page *page, unsigned long addr)
+{
+       enum fixed_addresses idx;
+       unsigned long vaddr, flags, entrylo;
+       unsigned long old_ctx;
+       pte_t pte;
+       int tlbidx;
+
+       inc_preempt_count();
+       idx = (addr >> PAGE_SHIFT) & (FIX_N_COLOURS - 1);
+#ifdef CONFIG_MIPS_MT_SMTC
+       idx += FIX_N_COLOURS * smp_processor_id();
+#endif
+       vaddr = __fix_to_virt(FIX_CMAP_END - idx);
+       pte = mk_pte(page, PAGE_KERNEL);
+#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32_R1)
+       entrylo = pte.pte_high;
+#else
+       entrylo = pte_val(pte) >> 6;
+#endif
+
+       ENTER_CRITICAL(flags);
+       old_ctx = read_c0_entryhi();
+       write_c0_entryhi(vaddr & (PAGE_MASK << 1));
+       write_c0_entrylo0(entrylo);
+       write_c0_entrylo1(entrylo);
+#ifdef CONFIG_MIPS_MT_SMTC
+       set_pte(kmap_coherent_pte - (FIX_CMAP_END - idx), pte);
+       /* preload TLB instead of local_flush_tlb_one() */
+       mtc0_tlbw_hazard();
+       tlb_probe();
+       tlb_probe_hazard();
+       tlbidx = read_c0_index();
+       mtc0_tlbw_hazard();
+       if (tlbidx < 0)
+               tlb_write_random();
+       else
+               tlb_write_indexed();
+#else
+       tlbidx = read_c0_wired();
+       write_c0_wired(tlbidx + 1);
+       write_c0_index(tlbidx);
+       mtc0_tlbw_hazard();
+       tlb_write_indexed();
+#endif
+       tlbw_use_hazard();
+       write_c0_entryhi(old_ctx);
+       EXIT_CRITICAL(flags);
+
+       return (void*) vaddr;
+}
+
+#define UNIQUE_ENTRYHI(idx) (CKSEG0 + ((idx) << (PAGE_SHIFT + 1)))
+
+static inline void kunmap_coherent(struct page *page)
+{
+#ifndef CONFIG_MIPS_MT_SMTC
+       unsigned int wired;
+       unsigned long flags, old_ctx;
+
+       ENTER_CRITICAL(flags);
+       old_ctx = read_c0_entryhi();
+       wired = read_c0_wired() - 1;
+       write_c0_wired(wired);
+       write_c0_index(wired);
+       write_c0_entryhi(UNIQUE_ENTRYHI(wired));
+       write_c0_entrylo0(0);
+       write_c0_entrylo1(0);
+       mtc0_tlbw_hazard();
+       tlb_write_indexed();
+       tlbw_use_hazard();
+       write_c0_entryhi(old_ctx);
+       EXIT_CRITICAL(flags);
+#endif
+       dec_preempt_count();
+       preempt_check_resched();
+}
+
+void copy_to_user_page(struct vm_area_struct *vma,
+       struct page *page, unsigned long vaddr, void *dst, const void *src,
+       unsigned long len)
+{
+       if (cpu_has_dc_aliases) {
+               void *vto = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK);
+               memcpy(vto, src, len);
+               kunmap_coherent(page);
+       } else
+               memcpy(dst, src, len);
+       if ((vma->vm_flags & VM_EXEC) && !cpu_has_ic_fills_f_dc)
+               flush_cache_page(vma, vaddr, page_to_pfn(page));
+}
+
+EXPORT_SYMBOL(copy_to_user_page);
+
+void copy_from_user_page(struct vm_area_struct *vma,
+       struct page *page, unsigned long vaddr, void *dst, const void *src,
+       unsigned long len)
+{
+       if (cpu_has_dc_aliases) {
+               void *vfrom =
+                       kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK);
+               memcpy(dst, vfrom, len);
+               kunmap_coherent(page);
+       } else
+               memcpy(dst, src, len);
+}
+
+EXPORT_SYMBOL(copy_from_user_page);
+
+
+#ifdef CONFIG_HIGHMEM
+pte_t *kmap_pte;
+pgprot_t kmap_prot;
+
 static void __init kmap_init(void)
 {
        unsigned long kmap_vstart;
@@ -97,11 +249,12 @@ static void __init kmap_init(void)
 
        kmap_prot = PAGE_KERNEL;
 }
+#endif /* CONFIG_HIGHMEM */
 
-#ifdef CONFIG_32BIT
 void __init fixrange_init(unsigned long start, unsigned long end,
        pgd_t *pgd_base)
 {
+#if defined(CONFIG_HIGHMEM) || defined(CONFIG_MIPS_MT_SMTC)
        pgd_t *pgd;
        pud_t *pud;
        pmd_t *pmd;
@@ -122,7 +275,7 @@ void __init fixrange_init(unsigned long start, unsigned long end,
                        for (; (k < PTRS_PER_PMD) && (vaddr != end); pmd++, k++) {
                                if (pmd_none(*pmd)) {
                                        pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
-                                       set_pmd(pmd, __pmd(pte));
+                                       set_pmd(pmd, __pmd((unsigned long)pte));
                                        if (pte != pte_offset_kernel(pmd, 0))
                                                BUG();
                                }
@@ -132,9 +285,8 @@ void __init fixrange_init(unsigned long start, unsigned long end,
                }
                j = 0;
        }
+#endif
 }
-#endif /* CONFIG_32BIT */
-#endif /* CONFIG_HIGHMEM */
 
 #ifndef CONFIG_NEED_MULTIPLE_NODES
 extern void pagetable_init(void);
@@ -175,6 +327,7 @@ void __init paging_init(void)
 #ifdef CONFIG_HIGHMEM
        kmap_init();
 #endif
+       kmap_coherent_init();
 
        max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
        low = max_low_pfn;
index 3101d1db55921b3c195351be551a39623c34d19b..cea7d0ea36e44c42b30d1a4b36bf7c461f7b4b66 100644 (file)
@@ -176,7 +176,7 @@ void __iomem * __ioremap(phys_t phys_addr, phys_t size, unsigned long flags)
 
 #define IS_KSEG1(addr) (((unsigned long)(addr) & ~0x1fffffffUL) == CKSEG1)
 
-void __iounmap(volatile void __iomem *addr)
+void __iounmap(const volatile void __iomem *addr)
 {
        struct vm_struct *p;
 
index 4bdaa05f485b446e0d66587015cbd8378abf4a69..4a61e624b0ecfcd921a560d426e92e1df2df1de2 100644 (file)
@@ -31,9 +31,10 @@ void pgd_init(unsigned long page)
 
 void __init pagetable_init(void)
 {
-#ifdef CONFIG_HIGHMEM
        unsigned long vaddr;
-       pgd_t *pgd, *pgd_base;
+       pgd_t *pgd_base;
+#ifdef CONFIG_HIGHMEM
+       pgd_t *pgd;
        pud_t *pud;
        pmd_t *pmd;
        pte_t *pte;
@@ -44,7 +45,6 @@ void __init pagetable_init(void)
        pgd_init((unsigned long)swapper_pg_dir
                 + sizeof(pgd_t) * USER_PTRS_PER_PGD);
 
-#ifdef CONFIG_HIGHMEM
        pgd_base = swapper_pg_dir;
 
        /*
@@ -53,6 +53,7 @@ void __init pagetable_init(void)
        vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
        fixrange_init(vaddr, 0, pgd_base);
 
+#ifdef CONFIG_HIGHMEM
        /*
         * Permanent kmaps:
         */
index 44b5e97fff65f75286fdd15f33c2bcf40841082a..8d600d307d5ddb3f617ffc34929ea98d4613b4a7 100644 (file)
@@ -8,6 +8,7 @@
  */
 #include <linux/init.h>
 #include <linux/mm.h>
+#include <asm/fixmap.h>
 #include <asm/pgtable.h>
 
 void pgd_init(unsigned long page)
@@ -52,7 +53,17 @@ void pmd_init(unsigned long addr, unsigned long pagetable)
 
 void __init pagetable_init(void)
 {
+       unsigned long vaddr;
+       pgd_t *pgd_base;
+
        /* Initialize the entire pgd.  */
        pgd_init((unsigned long)swapper_pg_dir);
        pmd_init((unsigned long)invalid_pmd_table, (unsigned long)invalid_pte_table);
+
+       pgd_base = swapper_pg_dir;
+       /*
+        * Fixed mappings:
+        */
+       vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
+       fixrange_init(vaddr, 0, pgd_base);
 }
index f9067469a65618dafb3786069819d878f1d506b8..2efb25aa1aed10363fde84e3e5bb9a4c4bfd1476 100644 (file)
 #include <asm/mipsregs.h>
 #include <asm/time.h>
 
-asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+asmlinkage void plat_irq_dispatch(void)
 {
        unsigned int pending = read_c0_cause() & read_c0_status();
 
        if (pending & STATUSF_IP0)
-               do_IRQ(0, regs);
+               do_IRQ(0);
        else if (pending & STATUSF_IP1)
-               do_IRQ(1, regs);
+               do_IRQ(1);
        else if (pending & STATUSF_IP2)
-               do_IRQ(2, regs);
+               do_IRQ(2);
        else if (pending & STATUSF_IP3)
-               do_IRQ(3, regs);
+               do_IRQ(3);
        else if (pending & STATUSF_IP4)
-               do_IRQ(4, regs);
+               do_IRQ(4);
        else if (pending & STATUSF_IP5)
-               do_IRQ(5, regs);
+               do_IRQ(5);
        else if (pending & STATUSF_IP6)
-               do_IRQ(6, regs);
+               do_IRQ(6);
        else if (pending & STATUSF_IP7)
-               ll_timer_interrupt(7, regs);
+               ll_timer_interrupt(7);
        else {
                /*
                 * Now look at the extended interrupts
                 */
                pending = (read_c0_cause() & (read_c0_intcontrol() << 8)) >> 16;
                if (pending & STATUSF_IP8)
-                       ll_mv64340_irq(regs);
+                       ll_mv64340_irq();
        }
 }
 
index e6fe2992227d7b728fc7fcbaad2734444ad18dc9..5a510142b9785b961ab0b0c0b078bb61424e9888 100644 (file)
@@ -62,7 +62,6 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/processor.h>
-#include <asm/ptrace.h>
 #include <asm/reboot.h>
 #include <asm/tlbflush.h>
 
index 793782a9c195cb56c8ad8013f57ae01e67ad000b..cea0e5deb80e78a38d95786f3b6a75e831715935 100644 (file)
@@ -75,26 +75,26 @@ void __init arch_init_irq(void)
 
 }
 
-asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+asmlinkage void plat_irq_dispatch(void)
 {
        unsigned int pending = read_c0_cause() & read_c0_status();
 
        if (pending & STATUSF_IP0)
-               do_IRQ(0, regs);
+               do_IRQ(0);
        else if (pending & STATUSF_IP1)
-               do_IRQ(1, regs);
+               do_IRQ(1);
        else if (pending & STATUSF_IP2)
-               do_IRQ(2, regs);
+               do_IRQ(2);
        else if (pending & STATUSF_IP3)
-               do_IRQ(3, regs);
+               do_IRQ(3);
        else if (pending & STATUSF_IP4)
-               do_IRQ(4, regs);
+               do_IRQ(4);
        else if (pending & STATUSF_IP5)
-               do_IRQ(5, regs);
+               do_IRQ(5);
        else if (pending & STATUSF_IP6)
-               do_IRQ(6, regs);
+               do_IRQ(6);
        else if (pending & STATUSF_IP7)
-               do_IRQ(7, regs);
+               do_IRQ(7);
        else {
                /*
                 * Now look at the extended interrupts
@@ -102,8 +102,8 @@ asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
                pending = (read_c0_cause() & (read_c0_intcontrol() << 8)) >> 16;
 
                if (pending & STATUSF_IP8)
-                       ll_mv64340_irq(regs);
+                       ll_mv64340_irq();
                else
-                       spurious_interrupt(regs);
+                       spurious_interrupt();
        }
 }
index 435d0787329ebba91867c2fea4ab4b326328531e..7d74f8c541295e37bd7fa70bab38ae0ea9445e5d 100644 (file)
@@ -67,7 +67,6 @@
 #include <asm/irq.h>
 #include <asm/pci.h>
 #include <asm/processor.h>
-#include <asm/ptrace.h>
 #include <asm/reboot.h>
 #include <asm/mc146818rtc.h>
 #include <asm/tlbflush.h>
index a5dc230520dffc9bdb06924c8c1dff8bc5cf7d9a..47e3fa32b075d30aec910e540e0a94d6b4513330 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/kernel.h>
-#include <asm/ptrace.h>
 #include <linux/sched.h>
 #include <linux/kernel_stat.h>
 #include <asm/io.h>
@@ -112,7 +111,7 @@ static void end_cpci_irq(unsigned int irq)
  * Interrupt handler for interrupts coming from the FPGA chip.
  * It could be built in ethernet ports etc...
  */
-void ll_cpci_irq(struct pt_regs *regs)
+void ll_cpci_irq(void)
 {
        unsigned int irq_src, irq_mask;
 
@@ -123,7 +122,7 @@ void ll_cpci_irq(struct pt_regs *regs)
        /* mask for just the interrupts we want */
        irq_src &= ~irq_mask;
 
-       do_IRQ(ls1bit8(irq_src) + CPCI_IRQ_BASE, regs);
+       do_IRQ(ls1bit8(irq_src) + CPCI_IRQ_BASE);
 }
 
 #define shutdown_cpci_irq      disable_cpci_irq
index 9d44ae1e156b65b698afa0c6a284e9b19491fd33..ea65223a6d2c013a7d03252c5857b1f31b11325c 100644 (file)
@@ -59,31 +59,31 @@ static struct irqaction cascade_mv64340 = {
        no_action, IRQF_DISABLED, CPU_MASK_NONE, "cascade via MV64340", NULL, NULL
 };
 
-extern void ll_uart_irq(struct pt_regs *regs);
-extern void ll_cpci_irq(struct pt_regs *regs);
+extern void ll_uart_irq(void);
+extern void ll_cpci_irq(void);
 
-asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+asmlinkage void plat_irq_dispatch(void)
 {
        unsigned int pending = read_c0_cause() & read_c0_status();
 
        if (pending & STATUSF_IP0)
-               do_IRQ(0, regs);
+               do_IRQ(0);
        else if (pending & STATUSF_IP1)
-               do_IRQ(1, regs);
+               do_IRQ(1);
        else if (pending & STATUSF_IP2)
-               do_IRQ(2, regs);
+               do_IRQ(2);
        else if (pending & STATUSF_IP3)
-               ll_uart_irq(regs);
+               ll_uart_irq();
        else if (pending & STATUSF_IP4)
-               do_IRQ(4, regs);
+               do_IRQ(4);
        else if (pending & STATUSF_IP5)
-               ll_cpci_irq(regs);
+               ll_cpci_irq();
        else if (pending & STATUSF_IP6)
-               ll_mv64340_irq(regs);
+               ll_mv64340_irq();
        else if (pending & STATUSF_IP7)
-               do_IRQ(7, regs);
+               do_IRQ(7);
        else
-               spurious_interrupt(regs);
+               spurious_interrupt();
 }
 
 void __init arch_init_irq(void)
index 36f570ecc6fb70c61597ddc459062d117260f800..9c0c462af6502fba5a133cf6e241ba957ad4f726 100644 (file)
@@ -62,7 +62,6 @@
 #include <asm/irq.h>
 #include <asm/pci.h>
 #include <asm/processor.h>
-#include <asm/ptrace.h>
 #include <asm/reboot.h>
 #include <asm/marvell.h>
 #include <linux/bootmem.h>
index 9f33d8f1d8268fe859fecaae7e95a390b87d7fec..510257dc205a3e021a8d7326bb58b44ac93e40a2 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/kernel.h>
-#include <asm/ptrace.h>
 #include <linux/sched.h>
 #include <linux/kernel_stat.h>
 #include <asm/io.h>
@@ -105,7 +104,7 @@ static void end_uart_irq(unsigned int irq)
 /*
  * Interrupt handler for interrupts coming from the FPGA chip.
  */
-void ll_uart_irq(struct pt_regs *regs)
+void ll_uart_irq(void)
 {
        unsigned int irq_src, irq_mask;
 
@@ -116,7 +115,7 @@ void ll_uart_irq(struct pt_regs *regs)
        /* mask for just the interrupts we want */
        irq_src &= ~irq_mask;
 
-       do_IRQ(ls1bit8(irq_src) + 74, regs);
+       do_IRQ(ls1bit8(irq_src) + 74);
 }
 
 #define shutdown_uart_irq      disable_uart_irq
index 6cd87cf0195a1ca8ce2dea022502527054ff1aec..7b5cc6648f7e358d5e2811348ccaadb92c42e278 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
-#include <asm/ptrace.h>
 #include <linux/sched.h>
 #include <linux/kernel_stat.h>
 #include <asm/gt64240.h>
@@ -108,7 +107,7 @@ int disable_galileo_irq(int int_cause, int bit_num)
  * we keep this particular structure in the function.
  */
 
-static irqreturn_t gt64240_p0int_irq(int irq, void *dev, struct pt_regs *regs)
+static irqreturn_t gt64240_p0int_irq(int irq, void *dev)
 {
        uint32_t irq_src, irq_src_mask;
        int handled;
@@ -135,7 +134,7 @@ static irqreturn_t gt64240_p0int_irq(int irq, void *dev, struct pt_regs *regs)
                /* handle the timer call */
                do_timer(1);
 #ifndef CONFIG_SMP
-               update_process_times(user_mode(regs));
+               update_process_times(user_mode(get_irq_regs()));
 #endif
        }
 
index 7a4a419804f19f0c202f6dcc6c3ea91d9d100231..da46524e87cb50d4a8fe8a738231918096fce3b0 100644 (file)
 #include <asm/mipsregs.h>
 #include <asm/system.h>
 
-asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+asmlinkage void plat_irq_dispatch(void)
 {
        unsigned int pending = read_c0_cause() & read_c0_status();
 
        if (pending & STATUSF_IP2)
-               do_IRQ(2, regs);
+               do_IRQ(2);
        else if (pending & STATUSF_IP3)
-               do_IRQ(3, regs);
+               do_IRQ(3);
        else if (pending & STATUSF_IP4)
-               do_IRQ(4, regs);
+               do_IRQ(4);
        else if (pending & STATUSF_IP5)
-               do_IRQ(5, regs);
+               do_IRQ(5);
        else if (pending & STATUSF_IP6)
-               do_IRQ(6, regs);
+               do_IRQ(6);
        else if (pending & STATUSF_IP7)
-               do_IRQ(7, regs);
+               do_IRQ(7);
        else {
                /*
                 * Now look at the extended interrupts
@@ -71,15 +71,15 @@ asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
                pending = (read_c0_cause() & (read_c0_intcontrol() << 8)) >> 16;
 
                if (pending & STATUSF_IP8)
-                       do_IRQ(8, regs);
+                       do_IRQ(8);
                else if (pending & STATUSF_IP9)
-                       do_IRQ(9, regs);
+                       do_IRQ(9);
                else if (pending & STATUSF_IP10)
-                       do_IRQ(10, regs);
+                       do_IRQ(10);
                else if (pending & STATUSF_IP11)
-                       do_IRQ(11, regs);
+                       do_IRQ(11);
                else
-                       spurious_interrupt(regs);
+                       spurious_interrupt();
        }
 }
 
index c580b1de33bc68e385f86c8cf22dc5680cfcaef2..56ec47039c16b3cfe742d500d528baadb5c35aa3 100644 (file)
@@ -58,7 +58,6 @@
 #include <asm/irq.h>
 #include <asm/pci.h>
 #include <asm/processor.h>
-#include <asm/ptrace.h>
 #include <asm/reboot.h>
 #include <linux/bootmem.h>
 
index 5cfce7d87a4da1b279bce8bf6f7682690dbe120b..fa6b4aae75233f764d1979f7b1f0e5fd9944545e 100644 (file)
 #ifndef OP_IMPL_H
 #define OP_IMPL_H 1
 
-struct pt_regs;
-
-extern int null_perf_irq(struct pt_regs *regs);
-extern int (*perf_irq)(struct pt_regs *regs);
+extern int null_perf_irq(void);
+extern int (*perf_irq)(void);
 
 /* Per-counter configuration as set via oprofilefs.  */
 struct op_counter_config {
index a175d673540f9af91e8b460b30e02785436cd688..dd0aec9c3ce1df31f45368087a0496edb006a937 100644 (file)
@@ -3,12 +3,13 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2004, 2005 by Ralf Baechle
+ * Copyright (C) 2004, 05, 06 by Ralf Baechle
  * Copyright (C) 2005 by MIPS Technologies, Inc.
  */
 #include <linux/oprofile.h>
 #include <linux/interrupt.h>
 #include <linux/smp.h>
+#include <asm/irq_regs.h>
 
 #include "op_impl.h"
 
@@ -170,7 +171,7 @@ static void mipsxx_cpu_stop(void *args)
        }
 }
 
-static int mipsxx_perfcount_handler(struct pt_regs *regs)
+static int mipsxx_perfcount_handler(void)
 {
        unsigned int counters = op_model_mipsxx_ops.num_counters;
        unsigned int control;
@@ -184,7 +185,7 @@ static int mipsxx_perfcount_handler(struct pt_regs *regs)
                counter = r_c0_perfcntr ## n();                         \
                if ((control & M_PERFCTL_INTERRUPT_ENABLE) &&           \
                    (counter & M_COUNTER_OVERFLOW)) {                   \
-                       oprofile_add_sample(regs, n);                   \
+                       oprofile_add_sample(get_irq_regs(), n);         \
                        w_c0_perfcntr ## n(reg.counter[n]);             \
                        handled = 1;                                    \
                }
index b7063fefa65b46d80c658697fbe629f9e95bd4f4..7dc9bf6f132183ede615e84742bff4c41fe84fe0 100644 (file)
@@ -80,8 +80,7 @@ static void rm9000_cpu_stop(void *args)
        write_c0_perfcontrol(0);
 }
 
-static irqreturn_t rm9000_perfcount_handler(int irq, void * dev_id,
-       struct pt_regs *regs)
+static irqreturn_t rm9000_perfcount_handler(int irq, void * dev_id)
 {
        unsigned int control = read_c0_perfcontrol();
        uint32_t counter1, counter2;
index 17c7932cf0ae1775b89ab24584abfc4430d542c8..618ea7dbc47444535cc53095f5f738fda0470b4c 100644 (file)
@@ -22,7 +22,7 @@
  * registered on the bridge error irq.  It's conceivable that some of these
  * conditions warrant a panic.  Anybody care to say which ones?
  */
-static irqreturn_t macepci_error(int irq, void *dev, struct pt_regs *regs)
+static irqreturn_t macepci_error(int irq, void *dev)
 {
        char s;
        unsigned int flags = mace->pci.error;
index 3c93512be1ec11bd54de27b47bcdb4222dc34e38..710611615ca2759f4563322a2747ea98f56b4efc 100644 (file)
@@ -23,6 +23,7 @@
  *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  *
  */
+#include <linux/compiler.h>
 #include <linux/init.h>
 #include <linux/irq.h>
 #include <linux/sched.h>
@@ -52,7 +53,7 @@ static char gic_prio[PNX8550_INT_GIC_TOTINT] = {
        1                       //  70
 };
 
-static void hw0_irqdispatch(int irq, struct pt_regs *regs)
+static void hw0_irqdispatch(int irq)
 {
        /* find out which interrupt */
        irq = PNX8550_GIC_VECTOR_0 >> 3;
@@ -61,42 +62,39 @@ static void hw0_irqdispatch(int irq, struct pt_regs *regs)
                printk("hw0_irqdispatch: irq 0, spurious interrupt?\n");
                return;
        }
-       do_IRQ(PNX8550_INT_GIC_MIN + irq, regs);
+       do_IRQ(PNX8550_INT_GIC_MIN + irq);
 }
 
 
-static void timer_irqdispatch(int irq, struct pt_regs *regs)
+static void timer_irqdispatch(int irq)
 {
        irq = (0x01c0 & read_c0_config7()) >> 6;
 
-       if (irq == 0) {
+       if (unlikely(irq == 0)) {
                printk("timer_irqdispatch: irq 0, spurious interrupt?\n");
                return;
        }
 
-       if (irq & 0x1) {
-               do_IRQ(PNX8550_INT_TIMER1, regs);
-       }
-       if (irq & 0x2) {
-               do_IRQ(PNX8550_INT_TIMER2, regs);
-       }
-       if (irq & 0x4) {
-               do_IRQ(PNX8550_INT_TIMER3, regs);
-       }
+       if (irq & 0x1)
+               do_IRQ(PNX8550_INT_TIMER1);
+       if (irq & 0x2)
+               do_IRQ(PNX8550_INT_TIMER2);
+       if (irq & 0x4)
+               do_IRQ(PNX8550_INT_TIMER3);
 }
 
-asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+asmlinkage void plat_irq_dispatch(void)
 {
        unsigned int pending = read_c0_status() & read_c0_cause();
 
        if (pending & STATUSF_IP2)
-               hw0_irqdispatch(2, regs);
+               hw0_irqdispatch(2);
        else if (pending & STATUSF_IP7) {
                if (read_c0_config7() & 0x01c0)
-                       timer_irqdispatch(7, regs);
+                       timer_irqdispatch(7);
        }
 
-       spurious_interrupt(regs);
+       spurious_interrupt();
 }
 
 static inline void modify_cp0_intmask(unsigned clr_mask, unsigned set_mask)
index b91d0aa3b7ed3667374d0873cc56782d07e570dd..adb048527e7610d0e3dfc639c128f541e5a001ae 100644 (file)
 #define HYPERTRANSPORT_INTC     0x7a           /* INTC# */
 #define HYPERTRANSPORT_INTD     0x7b           /* INTD# */
 
-extern void jaguar_mailbox_irq(struct pt_regs *);
-
 /*
  * Handle hypertransport & SMP interrupts. The interrupt lines are scarce.
  * For interprocessor interrupts, the best thing to do is to use the INTMSG
  * register. We use the same external interrupt line, i.e. INTB3 and monitor
  * another status bit
  */
-asmlinkage void ll_ht_smp_irq_handler(int irq, struct pt_regs *regs)
+static void ll_ht_smp_irq_handler(int irq)
 {
        u32 status = OCD_READ(RM9000x2_OCD_INTP0STATUS4);
 
@@ -107,50 +105,35 @@ asmlinkage void ll_ht_smp_irq_handler(int irq, struct pt_regs *regs)
        }
 #endif /* CONFIG_HT_LEVEL_TRIGGER */
 
-       do_IRQ(irq, regs);
-}
-
-asmlinkage void do_extended_irq(struct pt_regs *regs)
-{
-       unsigned int intcontrol = read_c0_intcontrol();
-       unsigned int cause = read_c0_cause();
-       unsigned int status = read_c0_status();
-       unsigned int pending_sr, pending_ic;
-
-       pending_sr = status & cause & 0xff00;
-       pending_ic = (cause >> 8) & intcontrol & 0xff00;
-
-       if (pending_ic & (1 << 13))
-               do_IRQ(13, regs);
-
+       do_IRQ(irq);
 }
 
-asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+asmlinkage void plat_irq_dispatch(void)
 {
        unsigned int cause = read_c0_cause();
        unsigned int status = read_c0_status();
        unsigned int pending = cause & status;
 
        if (pending & STATUSF_IP7) {
-               do_IRQ(7, regs);
+               do_IRQ(7);
        } else if (pending & STATUSF_IP2) {
 #ifdef CONFIG_HYPERTRANSPORT
-               ll_ht_smp_irq_handler(2, regs);
+               ll_ht_smp_irq_handler(2);
 #else
-               do_IRQ(2, regs);
+               do_IRQ(2);
 #endif
        } else if (pending & STATUSF_IP3) {
-               do_IRQ(3, regs);
+               do_IRQ(3);
        } else if (pending & STATUSF_IP4) {
-               do_IRQ(4, regs);
+               do_IRQ(4);
        } else if (pending & STATUSF_IP5) {
 #ifdef CONFIG_SMP
-               titan_mailbox_irq(regs);
+               titan_mailbox_irq();
 #else
-               do_IRQ(5, regs);
+               do_IRQ(5);
 #endif
        } else if (pending & STATUSF_IP6) {
-               do_IRQ(4, regs);
+               do_IRQ(4);
        }
 }
 
@@ -178,18 +161,3 @@ void __init arch_init_irq(void)
        register_gdb_console();
 #endif
 }
-
-#ifdef CONFIG_KGDB
-/*
- * The 16550 DUART has two ports, but is allocated one IRQ
- * for the serial console. Hence, a generic framework for
- * serial IRQ routing in place. Currently, just calls the
- * do_IRQ fuction. But, going in the future, need to check
- * DUART registers for channel A and B, then decide the
- * appropriate action
- */
-asmlinkage void yosemite_kgdb_irq(int irq, struct pt_regs *regs)
-{
-       do_IRQ(irq, regs);
-}
-#endif
index 0a6ee8e5eec2d2e710fe0617769f5ceacd0f2484..1b9b0d396d3ed3e588bac9661fbb01316e21263d 100644 (file)
@@ -46,7 +46,6 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/processor.h>
-#include <asm/ptrace.h>
 #include <asm/reboot.h>
 #include <asm/serial.h>
 #include <asm/titan_dep.h>
index c197311e15d3ba80eae04bcd64b1ba51de8579d7..65fa3a23ea5e9fb2f022c80dd29c423970d5122e 100644 (file)
@@ -110,7 +110,7 @@ void prom_smp_finish(void)
 {
 }
 
-asmlinkage void titan_mailbox_irq(struct pt_regs *regs)
+asmlinkage void titan_mailbox_irq(void)
 {
        int cpu = smp_processor_id();
        unsigned long status;
index 3352374c4c7d2ed9bd2e21249fe8276b4ef8c445..f5ea2fe10f141d598b70a85f3d6514b73c54331c 100644 (file)
@@ -9,19 +9,19 @@
 
 extern asmlinkage void qemu_handle_int(void);
 
-asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+asmlinkage void plat_irq_dispatch(void)
 {
        unsigned int pending = read_c0_status() & read_c0_cause();
 
        if (pending & 0x8000) {
-               ll_timer_interrupt(Q_COUNT_COMPARE_IRQ, regs);
+               ll_timer_interrupt(Q_COUNT_COMPARE_IRQ);
                return;
        }
        if (pending & 0x0400) {
                int irq = i8259_irq();
 
                if (likely(irq >= 0))
-                       do_IRQ(irq, regs);
+                       do_IRQ(irq);
 
                return;
        }
index a28dc7800072b24428e88414932b3b85647b8496..de6a0cc32fea8712988687ea10001ca6d8f106c5 100644 (file)
@@ -12,6 +12,7 @@
 #include <asm/system.h>
 #include <asm/traps.h>
 #include <asm/branch.h>
+#include <asm/irq_regs.h>
 #include <asm/sgi/mc.h>
 #include <asm/sgi/hpc3.h>
 #include <asm/sgi/ioc.h>
@@ -85,9 +86,10 @@ static void print_buserr(void)
  * and then clear the interrupt when this happens.
  */
 
-void ip22_be_interrupt(int irq, struct pt_regs *regs)
+void ip22_be_interrupt(int irq)
 {
        const int field = 2 * sizeof(unsigned long);
+       const struct pt_regs *regs = get_irq_regs();
 
        save_and_clear_buserr();
        print_buserr();
index ee0514a2992278f80aaf03012ca8f8bc2663c169..0d18ed47c47ad4fa0c408de7ad19c46e6b2c5f07 100644 (file)
@@ -70,7 +70,7 @@ static char __init *decode_eisa_sig(unsigned long addr)
        return sig_str;
 }
 
-static irqreturn_t ip22_eisa_intr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t ip22_eisa_intr(int irq, void *dev_id)
 {
        u8 eisa_irq;
        u8 dma1, dma2;
@@ -80,7 +80,7 @@ static irqreturn_t ip22_eisa_intr(int irq, void *dev_id, struct pt_regs *regs)
        dma2 = inb(EISA_DMA2_STATUS);
 
        if (eisa_irq < EISA_MAX_IRQ) {
-               do_IRQ(eisa_irq, regs);
+               do_IRQ(eisa_irq);
                return IRQ_HANDLED;
        }
 
@@ -89,6 +89,7 @@ static irqreturn_t ip22_eisa_intr(int irq, void *dev_id, struct pt_regs *regs)
 
        outb(0x20, EISA_INT2_CTRL);
        outb(0x20, EISA_INT1_CTRL);
+
        return IRQ_NONE;
 }
 
index f66026e5d64b002f1cce34e60f451c62f674d793..af518898eaa147a04fa349eebc3c1f97bbf6976d 100644 (file)
@@ -222,7 +222,7 @@ static struct irq_chip ip22_local3_irq_type = {
        .end            = end_local3_irq,
 };
 
-static void indy_local0_irqdispatch(struct pt_regs *regs)
+static void indy_local0_irqdispatch(void)
 {
        u8 mask = sgint->istat0 & sgint->imask0;
        u8 mask2;
@@ -236,11 +236,10 @@ static void indy_local0_irqdispatch(struct pt_regs *regs)
 
        /* if irq == 0, then the interrupt has already been cleared */
        if (irq)
-               do_IRQ(irq, regs);
-       return;
+               do_IRQ(irq);
 }
 
-static void indy_local1_irqdispatch(struct pt_regs *regs)
+static void indy_local1_irqdispatch(void)
 {
        u8 mask = sgint->istat1 & sgint->imask1;
        u8 mask2;
@@ -254,19 +253,18 @@ static void indy_local1_irqdispatch(struct pt_regs *regs)
 
        /* if irq == 0, then the interrupt has already been cleared */
        if (irq)
-               do_IRQ(irq, regs);
-       return;
+               do_IRQ(irq);
 }
 
-extern void ip22_be_interrupt(int irq, struct pt_regs *regs);
+extern void ip22_be_interrupt(int irq);
 
-static void indy_buserror_irq(struct pt_regs *regs)
+static void indy_buserror_irq(void)
 {
        int irq = SGI_BUSERR_IRQ;
 
        irq_enter();
        kstat_this_cpu.irqs[irq]++;
-       ip22_be_interrupt(irq, regs);
+       ip22_be_interrupt(irq);
        irq_exit();
 }
 
@@ -305,8 +303,8 @@ static struct irqaction map1_cascade = {
 #define SGI_INTERRUPTS SGINT_LOCAL3
 #endif
 
-extern void indy_r4k_timer_interrupt(struct pt_regs *regs);
-extern void indy_8254timer_irq(struct pt_regs *regs);
+extern void indy_r4k_timer_interrupt(void);
+extern void indy_8254timer_irq(void);
 
 /*
  * IRQs on the INDY look basically (barring software IRQs which we don't use
@@ -336,7 +334,7 @@ extern void indy_8254timer_irq(struct pt_regs *regs);
  * another exception, big deal.
  */
 
-asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+asmlinkage void plat_irq_dispatch(void)
 {
        unsigned int pending = read_c0_cause();
 
@@ -344,15 +342,15 @@ asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
         * First we check for r4k counter/timer IRQ.
         */
        if (pending & CAUSEF_IP7)
-               indy_r4k_timer_interrupt(regs);
+               indy_r4k_timer_interrupt();
        else if (pending & CAUSEF_IP2)
-               indy_local0_irqdispatch(regs);
+               indy_local0_irqdispatch();
        else if (pending & CAUSEF_IP3)
-               indy_local1_irqdispatch(regs);
+               indy_local1_irqdispatch();
        else if (pending & CAUSEF_IP6)
-               indy_buserror_irq(regs);
+               indy_buserror_irq();
        else if (pending & (CAUSEF_IP4 | CAUSEF_IP5))
-               indy_8254timer_irq(regs);
+               indy_8254timer_irq();
 }
 
 extern void mips_cpu_irq_init(unsigned int irq_base);
index 7a941ecff3bbd505066013f125118b55c9c0d39f..66df5ac8f089b27ed0bc257ec4c0c02fe158abde 100644 (file)
@@ -169,7 +169,7 @@ static inline void volume_down_button(unsigned long data)
        }
 }
 
-static irqreturn_t panel_int(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t panel_int(int irq, void *dev_id)
 {
        unsigned int buttons;
 
index 0e061890f7973fab7d33c114ae89a6820c6c44dd..2055547340995d4bf6de64f11a54bbb1cf59a399 100644 (file)
@@ -175,7 +175,7 @@ static __init void indy_time_init(void)
 }
 
 /* Generic SGI handler for (spurious) 8254 interrupts */
-void indy_8254timer_irq(struct pt_regs *regs)
+void indy_8254timer_irq(void)
 {
        int irq = SGI_8254_0_IRQ;
        ULONG cnt;
@@ -189,13 +189,13 @@ void indy_8254timer_irq(struct pt_regs *regs)
        irq_exit();
 }
 
-void indy_r4k_timer_interrupt(struct pt_regs *regs)
+void indy_r4k_timer_interrupt(void)
 {
        int irq = SGI_TIMER_IRQ;
 
        irq_enter();
        kstat_this_cpu.irqs[irq]++;
-       timer_interrupt(irq, NULL, regs);
+       timer_interrupt(irq, NULL);
        irq_exit();
 }
 
index 24a85372284f02351db48d4f78866c71d1092b6e..f01ba1f9077084852a051e53cb8d4624befedfa2 100644 (file)
@@ -30,7 +30,6 @@
 #include <asm/mipsregs.h>
 #include <asm/system.h>
 
-#include <asm/ptrace.h>
 #include <asm/processor.h>
 #include <asm/pci/bridge.h>
 #include <asm/sn/addrs.h>
@@ -129,7 +128,7 @@ static int ms1bit(unsigned long x)
  * Kanoj 05.13.00
  */
 
-static void ip27_do_irq_mask0(struct pt_regs *regs)
+static void ip27_do_irq_mask0(void)
 {
        int irq, swlevel;
        hubreg_t pend0, mask0;
@@ -164,13 +163,13 @@ static void ip27_do_irq_mask0(struct pt_regs *regs)
                struct slice_data *si = cpu_data[cpu].data;
 
                irq = si->level_to_irq[swlevel];
-               do_IRQ(irq, regs);
+               do_IRQ(irq);
        }
 
        LOCAL_HUB_L(PI_INT_PEND0);
 }
 
-static void ip27_do_irq_mask1(struct pt_regs *regs)
+static void ip27_do_irq_mask1(void)
 {
        int irq, swlevel;
        hubreg_t pend1, mask1;
@@ -190,17 +189,17 @@ static void ip27_do_irq_mask1(struct pt_regs *regs)
        /* "map" swlevel to irq */
        irq = si->level_to_irq[swlevel];
        LOCAL_HUB_CLR_INTR(swlevel);
-       do_IRQ(irq, regs);
+       do_IRQ(irq);
 
        LOCAL_HUB_L(PI_INT_PEND1);
 }
 
-static void ip27_prof_timer(struct pt_regs *regs)
+static void ip27_prof_timer(void)
 {
        panic("CPU %d got a profiling interrupt", smp_processor_id());
 }
 
-static void ip27_hub_error(struct pt_regs *regs)
+static void ip27_hub_error(void)
 {
        panic("CPU %d got a hub error interrupt", smp_processor_id());
 }
@@ -418,22 +417,22 @@ int __devinit request_bridge_irq(struct bridge_controller *bc)
        return irq;
 }
 
-extern void ip27_rt_timer_interrupt(struct pt_regs *regs);
+extern void ip27_rt_timer_interrupt(void);
 
-asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+asmlinkage void plat_irq_dispatch(void)
 {
        unsigned long pending = read_c0_cause() & read_c0_status();
 
        if (pending & CAUSEF_IP4)
-               ip27_rt_timer_interrupt(regs);
+               ip27_rt_timer_interrupt();
        else if (pending & CAUSEF_IP2)  /* PI_INT_PEND_0 or CC_PEND_{A|B} */
-               ip27_do_irq_mask0(regs);
+               ip27_do_irq_mask0();
        else if (pending & CAUSEF_IP3)  /* PI_INT_PEND_1 */
-               ip27_do_irq_mask1(regs);
+               ip27_do_irq_mask1();
        else if (pending & CAUSEF_IP5)
-               ip27_prof_timer(regs);
+               ip27_prof_timer();
        else if (pending & CAUSEF_IP6)
-               ip27_hub_error(regs);
+               ip27_hub_error();
 }
 
 void __init arch_init_irq(void)
index d777b7d1a9fec6c30e3058208887cc12ffbf1ff7..f9f404a8ddad625348975d4678ee4183b21de102 100644 (file)
@@ -26,7 +26,7 @@ static cpumask_t ktext_repmask;
  * kernel.  For example, we should never put a copy on a headless node,
  * and we should respect the topology of the machine.
  */
-void __init setup_replication_mask()
+void __init setup_replication_mask(void)
 {
        cnodeid_t       cnode;
 
index 257ce118e380fd2dd7d4e104c4eb02c87a4ec20f..4e870fc4469b8e2db1e78340e8297b68878114b0 100644 (file)
@@ -89,7 +89,7 @@ static int set_rtc_mmss(unsigned long nowtime)
 
 static unsigned int rt_timer_irq;
 
-void ip27_rt_timer_interrupt(struct pt_regs *regs)
+void ip27_rt_timer_interrupt(void)
 {
        int cpu = smp_processor_id();
        int cpuA = cputoslice(cpu) == 0;
@@ -111,7 +111,7 @@ again:
        if (cpu == 0)
                do_timer(1);
 
-       update_process_times(user_mode(regs));
+       update_process_times(user_mode(get_irq_regs()));
 
        /*
         * If we have an externally synchronized Linux clock, then update
index 41b5eca1148c20bdbf1047686ffcd85238b61253..bff508704d031a9320d95021c398181efd1d2a98 100644 (file)
@@ -14,7 +14,6 @@
 #include <asm/bootinfo.h>
 #include <asm/io.h>
 #include <asm/mipsregs.h>
-#include <asm/ptrace.h>
 #include <asm/page.h>
 #include <asm/ip32/crime.h>
 #include <asm/ip32/mace.h>
@@ -40,8 +39,7 @@ void __init crime_init(void)
                id, rev, field, (unsigned long) CRIME_BASE);
 }
 
-irqreturn_t
-crime_memerr_intr (unsigned int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t crime_memerr_intr(unsigned int irq, void *dev_id)
 {
        unsigned long stat, addr;
        int fatal = 0;
@@ -92,8 +90,7 @@ crime_memerr_intr (unsigned int irq, void *dev_id, struct pt_regs *regs)
        return IRQ_HANDLED;
 }
 
-irqreturn_t
-crime_cpuerr_intr (unsigned int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t crime_cpuerr_intr(unsigned int irq, void *dev_id)
 {
        unsigned long stat = crime->cpu_error_stat & CRIME_CPU_ERROR_MASK;
        unsigned long addr = crime->cpu_error_addr & CRIME_CPU_ERROR_ADDR_MASK;
index c64a820373decb5e7c1ccb61962e437b0b41a973..c9acadd0846b8e513522d4d3da045bb76106751c 100644 (file)
@@ -120,10 +120,8 @@ static void inline flush_mace_bus(void)
 static DEFINE_SPINLOCK(ip32_irq_lock);
 
 /* Some initial interrupts to set up */
-extern irqreturn_t crime_memerr_intr (int irq, void *dev_id,
-                                     struct pt_regs *regs);
-extern irqreturn_t crime_cpuerr_intr (int irq, void *dev_id,
-                                     struct pt_regs *regs);
+extern irqreturn_t crime_memerr_intr(int irq, void *dev_id);
+extern irqreturn_t crime_cpuerr_intr(int irq, void *dev_id);
 
 struct irqaction memerr_irq = { crime_memerr_intr, IRQF_DISABLED,
                        CPU_MASK_NONE, "CRIME memory error", NULL, NULL };
@@ -479,7 +477,7 @@ static struct irq_chip ip32_mace_interrupt = {
        .end = end_mace_irq,
 };
 
-static void ip32_unknown_interrupt(struct pt_regs *regs)
+static void ip32_unknown_interrupt(void)
 {
        printk ("Unknown interrupt occurred!\n");
        printk ("cp0_status: %08x\n", read_c0_status());
@@ -492,7 +490,7 @@ static void ip32_unknown_interrupt(struct pt_regs *regs)
        printk ("MACE PCI control register: %08x\n", mace->pci.control);
 
        printk("Register dump:\n");
-       show_regs(regs);
+       show_regs(get_irq_regs());
 
        printk("Please mail this report to linux-mips@linux-mips.org\n");
        printk("Spinning...");
@@ -501,7 +499,7 @@ static void ip32_unknown_interrupt(struct pt_regs *regs)
 
 /* CRIME 1.1 appears to deliver all interrupts to this one pin. */
 /* change this to loop over all edge-triggered irqs, exception masked out ones */
-static void ip32_irq0(struct pt_regs *regs)
+static void ip32_irq0(void)
 {
        uint64_t crime_int;
        int irq = 0;
@@ -516,50 +514,50 @@ static void ip32_irq0(struct pt_regs *regs)
        }
        irq++;
        DBG("*irq %u*\n", irq);
-       do_IRQ(irq, regs);
+       do_IRQ(irq);
 }
 
-static void ip32_irq1(struct pt_regs *regs)
+static void ip32_irq1(void)
 {
-       ip32_unknown_interrupt(regs);
+       ip32_unknown_interrupt();
 }
 
-static void ip32_irq2(struct pt_regs *regs)
+static void ip32_irq2(void)
 {
-       ip32_unknown_interrupt(regs);
+       ip32_unknown_interrupt();
 }
 
-static void ip32_irq3(struct pt_regs *regs)
+static void ip32_irq3(void)
 {
-       ip32_unknown_interrupt(regs);
+       ip32_unknown_interrupt();
 }
 
-static void ip32_irq4(struct pt_regs *regs)
+static void ip32_irq4(void)
 {
-       ip32_unknown_interrupt(regs);
+       ip32_unknown_interrupt();
 }
 
-static void ip32_irq5(struct pt_regs *regs)
+static void ip32_irq5(void)
 {
-       ll_timer_interrupt(IP32_R4K_TIMER_IRQ, regs);
+       ll_timer_interrupt(IP32_R4K_TIMER_IRQ);
 }
 
-asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+asmlinkage void plat_irq_dispatch(void)
 {
        unsigned int pending = read_c0_cause();
 
        if (likely(pending & IE_IRQ0))
-               ip32_irq0(regs);
+               ip32_irq0();
        else if (unlikely(pending & IE_IRQ1))
-               ip32_irq1(regs);
+               ip32_irq1();
        else if (unlikely(pending & IE_IRQ2))
-               ip32_irq2(regs);
+               ip32_irq2();
        else if (unlikely(pending & IE_IRQ3))
-               ip32_irq3(regs);
+               ip32_irq3();
        else if (unlikely(pending & IE_IRQ4))
-               ip32_irq4(regs);
+               ip32_irq4();
        else if (likely(pending & IE_IRQ5))
-               ip32_irq5(regs);
+               ip32_irq5();
 }
 
 void __init arch_init_irq(void)
index fd0932b2d5218ef58a08a79056c5f2af68c23d61..db8084411538bc3bcdfa6ef047eca8f1d835c2ed 100644 (file)
@@ -135,7 +135,7 @@ static inline void ip32_power_button(void)
        add_timer(&power_timer);
 }
 
-static irqreturn_t ip32_rtc_int(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t ip32_rtc_int(int irq, void *dev_id)
 {
        volatile unsigned char reg_c;
 
index a46b75b23ecb1e2ef10f4470279764f23905dacc..8b1f4148492396d50b56d5dc8bcb81df903ae974 100644 (file)
@@ -25,9 +25,9 @@
 #include <linux/kernel_stat.h>
 
 #include <asm/errno.h>
+#include <asm/irq_regs.h>
 #include <asm/signal.h>
 #include <asm/system.h>
-#include <asm/ptrace.h>
 #include <asm/io.h>
 
 #include <asm/sibyte/bcm1480_regs.h>
@@ -284,8 +284,7 @@ void __init init_bcm1480_irqs(void)
 }
 
 
-static irqreturn_t bcm1480_dummy_handler(int irq, void *dev_id,
-       struct pt_regs *regs)
+static irqreturn_t bcm1480_dummy_handler(int irq, void *dev_id)
 {
        return IRQ_NONE;
 }
@@ -453,7 +452,7 @@ void __init arch_init_irq(void)
 #define duart_out(reg, val)     csr_out32(val, IOADDR(A_DUART_CHANREG(kgdb_port,reg)))
 #define duart_in(reg)           csr_in32(IOADDR(A_DUART_CHANREG(kgdb_port,reg)))
 
-void bcm1480_kgdb_interrupt(struct pt_regs *regs)
+static void bcm1480_kgdb_interrupt(void)
 {
        /*
         * Clear break-change status (allow some time for the remote
@@ -464,16 +463,15 @@ void bcm1480_kgdb_interrupt(struct pt_regs *regs)
        mdelay(500);
        duart_out(R_DUART_CMD, V_DUART_MISC_CMD_RESET_BREAK_INT |
                                M_DUART_RX_EN | M_DUART_TX_EN);
-       set_async_breakpoint(&regs->cp0_epc);
+       set_async_breakpoint(&get_irq_regs()->cp0_epc);
 }
 
 #endif         /* CONFIG_KGDB */
 
-extern void bcm1480_timer_interrupt(struct pt_regs *regs);
-extern void bcm1480_mailbox_interrupt(struct pt_regs *regs);
-extern void bcm1480_kgdb_interrupt(struct pt_regs *regs);
+extern void bcm1480_timer_interrupt(void);
+extern void bcm1480_mailbox_interrupt(void);
 
-asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+asmlinkage void plat_irq_dispatch(void)
 {
        unsigned int pending;
 
@@ -486,21 +484,21 @@ asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
 
 #ifdef CONFIG_SIBYTE_BCM1480_PROF
        if (pending & CAUSEF_IP7)       /* Cpu performance counter interrupt */
-               sbprof_cpu_intr(exception_epc(regs));
+               sbprof_cpu_intr();
        else
 #endif
 
        if (pending & CAUSEF_IP4)
-               bcm1480_timer_interrupt(regs);
+               bcm1480_timer_interrupt();
 
 #ifdef CONFIG_SMP
        else if (pending & CAUSEF_IP3)
-               bcm1480_mailbox_interrupt(regs);
+               bcm1480_mailbox_interrupt();
 #endif
 
 #ifdef CONFIG_KGDB
        else if (pending & CAUSEF_IP6)
-               bcm1480_kgdb_interrupt(regs);           /* KGDB (uart 1) */
+               bcm1480_kgdb_interrupt();               /* KGDB (uart 1) */
 #endif
 
        else if (pending & CAUSEF_IP2) {
@@ -521,9 +519,9 @@ asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
 
                if (mask_h) {
                        if (mask_h ^ 1)
-                               do_IRQ(fls64(mask_h) - 1, regs);
+                               do_IRQ(fls64(mask_h) - 1);
                        else
-                               do_IRQ(63 + fls64(mask_l), regs);
+                               do_IRQ(63 + fls64(mask_l));
                }
        }
 }
index 584a4b33faac055b3deee2ffe4b63ec4014b73ec..bf328277c775e12f649ebeeeeb4af7f10710e493 100644 (file)
@@ -34,21 +34,21 @@ extern void smp_call_function_interrupt(void);
  * independent of board/firmware
  */
 
-static void *mailbox_0_set_regs[] = {
+static volatile void *mailbox_0_set_regs[] = {
        IOADDR(A_BCM1480_IMR_CPU0_BASE + R_BCM1480_IMR_MAILBOX_0_SET_CPU),
        IOADDR(A_BCM1480_IMR_CPU1_BASE + R_BCM1480_IMR_MAILBOX_0_SET_CPU),
        IOADDR(A_BCM1480_IMR_CPU2_BASE + R_BCM1480_IMR_MAILBOX_0_SET_CPU),
        IOADDR(A_BCM1480_IMR_CPU3_BASE + R_BCM1480_IMR_MAILBOX_0_SET_CPU),
 };
 
-static void *mailbox_0_clear_regs[] = {
+static volatile void *mailbox_0_clear_regs[] = {
        IOADDR(A_BCM1480_IMR_CPU0_BASE + R_BCM1480_IMR_MAILBOX_0_CLR_CPU),
        IOADDR(A_BCM1480_IMR_CPU1_BASE + R_BCM1480_IMR_MAILBOX_0_CLR_CPU),
        IOADDR(A_BCM1480_IMR_CPU2_BASE + R_BCM1480_IMR_MAILBOX_0_CLR_CPU),
        IOADDR(A_BCM1480_IMR_CPU3_BASE + R_BCM1480_IMR_MAILBOX_0_CLR_CPU),
 };
 
-static void *mailbox_0_regs[] = {
+static volatile void *mailbox_0_regs[] = {
        IOADDR(A_BCM1480_IMR_CPU0_BASE + R_BCM1480_IMR_MAILBOX_0_CPU),
        IOADDR(A_BCM1480_IMR_CPU1_BASE + R_BCM1480_IMR_MAILBOX_0_CPU),
        IOADDR(A_BCM1480_IMR_CPU2_BASE + R_BCM1480_IMR_MAILBOX_0_CPU),
@@ -88,7 +88,7 @@ void core_send_ipi(int cpu, unsigned int action)
        __raw_writeq((((u64)action)<< 48), mailbox_0_set_regs[cpu]);
 }
 
-void bcm1480_mailbox_interrupt(struct pt_regs *regs)
+void bcm1480_mailbox_interrupt(void)
 {
        int cpu = smp_processor_id();
        unsigned int action;
index 7e088f6c4a8664dc9abc947d06c210fe3eb73629..bf12af46132e07e48fee7ed0a0c8c4f5ce7bba2f 100644 (file)
@@ -31,7 +31,6 @@
 #include <linux/kernel_stat.h>
 
 #include <asm/irq.h>
-#include <asm/ptrace.h>
 #include <asm/addrspace.h>
 #include <asm/time.h>
 #include <asm/io.h>
@@ -100,10 +99,10 @@ void bcm1480_time_init(void)
 
 #include <asm/sibyte/sb1250.h>
 
-void bcm1480_timer_interrupt(struct pt_regs *regs)
+void bcm1480_timer_interrupt(void)
 {
        int cpu = smp_processor_id();
-       int irq = K_BCM1480_INT_TIMER_0+cpu;
+       int irq = K_BCM1480_INT_TIMER_0 + cpu;
 
        /* Reset the timer */
        __raw_writeq(M_SCD_TIMER_ENABLE|M_SCD_TIMER_MODE_CONTINUOUS,
@@ -113,13 +112,13 @@ void bcm1480_timer_interrupt(struct pt_regs *regs)
                /*
                 * CPU 0 handles the global timer interrupt job
                 */
-               ll_timer_interrupt(irq, regs);
+               ll_timer_interrupt(irq);
        }
        else {
                /*
                 * other CPUs should just do profiling and process accounting
                 */
-               ll_local_timer_interrupt(irq, regs);
+               ll_local_timer_interrupt(irq);
        }
 }
 
index 992e0d8dbb67599cd10a66c95008c07759632cbb..d1a906e683b2aa2c63ffe89d884b0056f4abcd47 100644 (file)
@@ -88,7 +88,7 @@ static void arm_tb(void)
        sbp.tb_armed = 1;
 }
 
-static irqreturn_t sbprof_tb_intr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t sbprof_tb_intr(int irq, void *dev_id)
 {
        int i;
        DBG(printk(DEVNAME ": tb_intr\n"));
@@ -138,7 +138,7 @@ static irqreturn_t sbprof_tb_intr(int irq, void *dev_id, struct pt_regs *regs)
        return IRQ_HANDLED;
 }
 
-static irqreturn_t sbprof_pc_intr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t sbprof_pc_intr(int irq, void *dev_id)
 {
        printk(DEVNAME ": unexpected pc_intr");
        return IRQ_NONE;
index bb90649fbc485b79ea3a04c17f6dc9a72d9f985e..45274bd3cd8b8958643cfd7fb1750db0620ad55a 100644 (file)
@@ -171,7 +171,7 @@ static void create_proc_decoder(struct bw_stats_struct *stats)
  * notes: possible re-entry due to multiple sources
  *        should check/indicate saturation
  */
-static irqreturn_t sibyte_bw_int(int irq, void *data, struct pt_regs *regs)
+static irqreturn_t sibyte_bw_int(int irq, void *data)
 {
        struct bw_stats_struct *stats = data;
        unsigned long cntr;
index f9bd9f074517575cae863c3b03b2200d22c5677a..d5d26770daf60b2b1984d825b0334e17d2a11c87 100644 (file)
@@ -28,7 +28,6 @@
 #include <asm/errno.h>
 #include <asm/signal.h>
 #include <asm/system.h>
-#include <asm/ptrace.h>
 #include <asm/io.h>
 
 #include <asm/sibyte/sb1250_regs.h>
@@ -254,8 +253,7 @@ void __init init_sb1250_irqs(void)
 }
 
 
-static irqreturn_t  sb1250_dummy_handler(int irq, void *dev_id,
-       struct pt_regs *regs)
+static irqreturn_t  sb1250_dummy_handler(int irq, void *dev_id)
 {
        return IRQ_NONE;
 }
@@ -403,7 +401,7 @@ void __init arch_init_irq(void)
 #define duart_out(reg, val)     csr_out32(val, IOADDR(A_DUART_CHANREG(kgdb_port,reg)))
 #define duart_in(reg)           csr_in32(IOADDR(A_DUART_CHANREG(kgdb_port,reg)))
 
-static void sb1250_kgdb_interrupt(struct pt_regs *regs)
+static void sb1250_kgdb_interrupt(void)
 {
        /*
         * Clear break-change status (allow some time for the remote
@@ -414,16 +412,15 @@ static void sb1250_kgdb_interrupt(struct pt_regs *regs)
        mdelay(500);
        duart_out(R_DUART_CMD, V_DUART_MISC_CMD_RESET_BREAK_INT |
                                M_DUART_RX_EN | M_DUART_TX_EN);
-       set_async_breakpoint(&regs->cp0_epc);
+       set_async_breakpoint(&get_irq_regs()->cp0_epc);
 }
 
 #endif         /* CONFIG_KGDB */
 
-extern void sb1250_timer_interrupt(struct pt_regs *regs);
-extern void sb1250_mailbox_interrupt(struct pt_regs *regs);
-extern void sb1250_kgdb_interrupt(struct pt_regs *regs);
+extern void sb1250_timer_interrupt(void);
+extern void sb1250_mailbox_interrupt(void);
 
-asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+asmlinkage void plat_irq_dispatch(void)
 {
        unsigned int pending;
 
@@ -446,21 +443,21 @@ asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
 
 #ifdef CONFIG_SIBYTE_SB1250_PROF
        if (pending & CAUSEF_IP7) /* Cpu performance counter interrupt */
-               sbprof_cpu_intr(exception_epc(regs));
+               sbprof_cpu_intr();
        else
 #endif
 
        if (pending & CAUSEF_IP4)
-               sb1250_timer_interrupt(regs);
+               sb1250_timer_interrupt();
 
 #ifdef CONFIG_SMP
        else if (pending & CAUSEF_IP3)
-               sb1250_mailbox_interrupt(regs);
+               sb1250_mailbox_interrupt();
 #endif
 
 #ifdef CONFIG_KGDB
        else if (pending & CAUSEF_IP6)                  /* KGDB (uart 1) */
-               sb1250_kgdb_interrupt(regs);
+               sb1250_kgdb_interrupt();
 #endif
 
        else if (pending & CAUSEF_IP2) {
@@ -475,9 +472,9 @@ asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
                mask = __raw_readq(IOADDR(A_IMR_REGISTER(smp_processor_id(),
                                              R_IMR_INTERRUPT_STATUS_BASE)));
                if (mask)
-                       do_IRQ(fls64(mask) - 1, regs);
+                       do_IRQ(fls64(mask) - 1);
                else
-                       spurious_interrupt(regs);
+                       spurious_interrupt();
        } else
-               spurious_interrupt(regs);
+               spurious_interrupt();
 }
index f859db02d3c9727811de843f7aff442ab3a5636b..c38e1f34460d44847473d17f297af2f4a3a14d6b 100644 (file)
@@ -76,7 +76,7 @@ void core_send_ipi(int cpu, unsigned int action)
        __raw_writeq((((u64)action) << 48), mailbox_set_regs[cpu]);
 }
 
-void sb1250_mailbox_interrupt(struct pt_regs *regs)
+void sb1250_mailbox_interrupt(void)
 {
        int cpu = smp_processor_id();
        unsigned int action;
index 4b669dc86ef4de85e2de49ea9a6b50e414c6510f..0ccf1796dd78bd6684a31f7844b8a619cf60dfe6 100644 (file)
@@ -31,7 +31,6 @@
 #include <linux/kernel_stat.h>
 
 #include <asm/irq.h>
-#include <asm/ptrace.h>
 #include <asm/addrspace.h>
 #include <asm/time.h>
 #include <asm/io.h>
@@ -125,7 +124,7 @@ void sb1250_time_init(void)
         */
 }
 
-void sb1250_timer_interrupt(struct pt_regs *regs)
+void sb1250_timer_interrupt(void)
 {
        int cpu = smp_processor_id();
        int irq = K_INT_TIMER_0 + cpu;
@@ -138,13 +137,13 @@ void sb1250_timer_interrupt(struct pt_regs *regs)
                /*
                 * CPU 0 handles the global timer interrupt job
                 */
-               ll_timer_interrupt(irq, regs);
+               ll_timer_interrupt(irq);
        }
        else {
                /*
                 * other CPUs should just do profiling and process accounting
                 */
-               ll_local_timer_interrupt(irq, regs);
+               ll_local_timer_interrupt(irq);
        }
 }
 
index cda165f42b6a336e12c7ae3403a0f6c6972e7c3b..48fb74a7aaecd817162844e8d53d9a7adf513fe3 100644 (file)
@@ -69,20 +69,20 @@ static struct irq_chip pciasic_irq_type = {
  * hwint0 should deal with MP agent, ASIC PCI, EISA NMI and debug
  * button interrupts.  Later ...
  */
-static void pciasic_hwint0(struct pt_regs *regs)
+static void pciasic_hwint0(void)
 {
        panic("Received int0 but no handler yet ...");
 }
 
 /* This interrupt was used for the com1 console on the first prototypes.  */
-static void pciasic_hwint2(struct pt_regs *regs)
+static void pciasic_hwint2(void)
 {
        /* I think this shouldn't happen on production machines.  */
        panic("hwint2 and no handler yet");
 }
 
 /* hwint5 is the r4k count / compare interrupt  */
-static void pciasic_hwint5(struct pt_regs *regs)
+static void pciasic_hwint5(void)
 {
        panic("hwint5 and no handler yet");
 }
@@ -103,7 +103,7 @@ static unsigned int ls1bit8(unsigned int x)
  *
  * The EISA_INT bit in CSITPEND is high active, all others are low active.
  */
-static void pciasic_hwint1(struct pt_regs *regs)
+static void pciasic_hwint1(void)
 {
        u8 pend = *(volatile char *)PCIMT_CSITPEND;
        unsigned long flags;
@@ -119,13 +119,13 @@ static void pciasic_hwint1(struct pt_regs *regs)
                if (unlikely(irq < 0))
                        return;
 
-               do_IRQ(irq, regs);
+               do_IRQ(irq);
        }
 
        if (!(pend & IT_SCSI)) {
                flags = read_c0_status();
                clear_c0_status(ST0_IM);
-               do_IRQ(PCIMT_IRQ_SCSI, regs);
+               do_IRQ(PCIMT_IRQ_SCSI);
                write_c0_status(flags);
        }
 }
@@ -133,7 +133,7 @@ static void pciasic_hwint1(struct pt_regs *regs)
 /*
  * hwint 3 should deal with the PCI A - D interrupts,
  */
-static void pciasic_hwint3(struct pt_regs *regs)
+static void pciasic_hwint3(void)
 {
        u8 pend = *(volatile char *)PCIMT_CSITPEND;
        int irq;
@@ -141,21 +141,21 @@ static void pciasic_hwint3(struct pt_regs *regs)
        pend &= (IT_INTA | IT_INTB | IT_INTC | IT_INTD);
        clear_c0_status(IE_IRQ3);
        irq = PCIMT_IRQ_INT2 + ls1bit8(pend);
-       do_IRQ(irq, regs);
+       do_IRQ(irq);
        set_c0_status(IE_IRQ3);
 }
 
 /*
  * hwint 4 is used for only the onboard PCnet 32.
  */
-static void pciasic_hwint4(struct pt_regs *regs)
+static void pciasic_hwint4(void)
 {
        clear_c0_status(IE_IRQ4);
-       do_IRQ(PCIMT_IRQ_ETHERNET, regs);
+       do_IRQ(PCIMT_IRQ_ETHERNET);
        set_c0_status(IE_IRQ4);
 }
 
-asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+asmlinkage void plat_irq_dispatch(void)
 {
        unsigned int pending = read_c0_status() & read_c0_cause();
        static unsigned char led_cache;
@@ -163,17 +163,17 @@ asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
        *(volatile unsigned char *) PCIMT_CSLED = ++led_cache;
 
        if (pending & 0x0800)
-               pciasic_hwint1(regs);
+               pciasic_hwint1();
        else if (pending & 0x4000)
-               pciasic_hwint4(regs);
+               pciasic_hwint4();
        else if (pending & 0x2000)
-               pciasic_hwint3(regs);
+               pciasic_hwint3();
        else if (pending & 0x1000)
-               pciasic_hwint2(regs);
+               pciasic_hwint2();
        else if (pending & 0x8000)
-               pciasic_hwint5(regs);
+               pciasic_hwint5();
        else if (pending & 0x0400)
-               pciasic_hwint0(regs);
+               pciasic_hwint0();
 }
 
 void __init init_pciasic(void)
index 4e98feb15410ea2833fd990e30419ea4b3ee38cc..afeb7f13e5b50a2f290bce79f5209b901fb36bfc 100644 (file)
@@ -31,7 +31,6 @@
 #include <asm/irq.h>
 #include <asm/mc146818-time.h>
 #include <asm/processor.h>
-#include <asm/ptrace.h>
 #include <asm/reboot.h>
 #include <asm/sni.h>
 #include <asm/time.h>
index cd176f6a06c8c297c2e5bb7282b612ad552ee0f2..8266a88a3f8881ac6eeb90b6793a2ab7c3927a72 100644 (file)
@@ -576,24 +576,24 @@ static int tx4927_irq_nested(void)
        return (sw_irq);
 }
 
-asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+asmlinkage void plat_irq_dispatch(void)
 {
        unsigned int pending = read_c0_status() & read_c0_cause();
 
        if (pending & STATUSF_IP7)                      /* cpu timer */
-               do_IRQ(TX4927_IRQ_CPU_TIMER, regs);
+               do_IRQ(TX4927_IRQ_CPU_TIMER);
        else if (pending & STATUSF_IP2) {               /* tx4927 pic */
                unsigned int irq = tx4927_irq_nested();
 
                if (unlikely(irq == 0)) {
-                       spurious_interrupt(regs);
+                       spurious_interrupt();
                        return;
                }
-               do_IRQ(irq, regs);
+               do_IRQ(irq);
        } else if (pending & STATUSF_IP0)               /* user line 0 */
-               do_IRQ(TX4927_IRQ_USER0, regs);
+               do_IRQ(TX4927_IRQ_USER0);
        else if (pending & STATUSF_IP1)                 /* user line 1 */
-               do_IRQ(TX4927_IRQ_USER1, regs);
+               do_IRQ(TX4927_IRQ_USER1);
        else
-               spurious_interrupt(regs);
+               spurious_interrupt();
 }
index 3ace4037343e0ca8734a2ed47f259e4da2fd07e4..4658b2ae4833f81d46f8ee59aa6d7660d4723260 100644 (file)
@@ -53,19 +53,9 @@ void __init tx4927_time_init(void);
 void dump_cp0(char *key);
 
 
-void (*__wbflush) (void);
-
-static void tx4927_write_buffer_flush(void)
-{
-       __asm__ __volatile__
-           ("sync\n\t" "nop\n\t" "loop: bc0f loop\n\t" "nop\n\t");
-}
-
-
 void __init plat_mem_setup(void)
 {
        board_time_init = tx4927_time_init;
-       __wbflush = tx4927_write_buffer_flush;
 
 #ifdef CONFIG_TOSHIBA_RBTX4927
        {
index b0f021f2a6c435ab37b932bd89ad70e269b24513..0c3c3f6682300473a214ddf902ceb8ec347ea3ad 100644 (file)
@@ -127,9 +127,9 @@ JP7 is not bus master -- do NOT use -- only 4 pci bus master's allowed -- SouthB
 #include <asm/irq.h>
 #include <asm/pci.h>
 #include <asm/processor.h>
-#include <asm/ptrace.h>
 #include <asm/reboot.h>
 #include <asm/time.h>
+#include <asm/wbflush.h>
 #include <linux/bootmem.h>
 #include <linux/blkdev.h>
 #ifdef CONFIG_RTC_DS1742
index f0d70c47600528a7e3c7601d9608d8955c817c24..735cb8778f4c257f9df9d8413bd78683cec775e8 100644 (file)
@@ -58,8 +58,8 @@
 #include <asm/page.h>
 #include <asm/io.h>
 #include <asm/irq.h>
+#include <asm/irq_regs.h>
 #include <asm/processor.h>
-#include <asm/ptrace.h>
 #include <asm/reboot.h>
 #include <asm/time.h>
 #include <linux/bootmem.h>
@@ -160,8 +160,7 @@ int tx4927_pci66 = 0;               /* 0:auto */
 char *toshiba_name = "";
 
 #ifdef CONFIG_PCI
-static void tx4927_pcierr_interrupt(int irq, void *dev_id,
-                                   struct pt_regs *regs)
+static void tx4927_pcierr_interrupt(int irq, void *dev_id)
 {
 #ifdef CONFIG_BLK_DEV_IDEPCI
        /* ignore MasterAbort for ide probing... */
@@ -185,7 +184,7 @@ static void tx4927_pcierr_interrupt(int irq, void *dev_id,
               (unsigned long) tx4927_ccfgptr->ccfg,
               (unsigned long) (tx4927_ccfgptr->tear >> 32),
               (unsigned long) tx4927_ccfgptr->tear);
-       show_regs(regs);
+       show_regs(get_irq_regs());
 }
 
 void __init toshiba_rbtx4927_pci_irq_init(void)
index cbfb34221b5915d69563d9c9ff1c086605368b9c..77fe2454f5b91f1509b8cc075f2faae183828473 100644 (file)
@@ -30,6 +30,7 @@
 #include <asm/irq.h>
 #include <asm/mipsregs.h>
 #include <asm/system.h>
+#include <asm/wbflush.h>
 #include <asm/tx4938/rbtx4938.h>
 
 /**********************************************************************************/
@@ -104,8 +105,6 @@ tx4938_irq_cp0_init(void)
                irq_desc[i].depth = 1;
                irq_desc[i].chip = &tx4938_irq_cp0_type;
        }
-
-       return;
 }
 
 static unsigned int
@@ -113,7 +112,7 @@ tx4938_irq_cp0_startup(unsigned int irq)
 {
        tx4938_irq_cp0_enable(irq);
 
-       return (0);
+       return 0;
 }
 
 static void
@@ -144,16 +143,12 @@ tx4938_irq_cp0_disable(unsigned int irq)
        clear_c0_status(tx4938_irq_cp0_mask(irq));
 
        spin_unlock_irqrestore(&tx4938_cp0_lock, flags);
-
-       return;
 }
 
 static void
 tx4938_irq_cp0_mask_and_ack(unsigned int irq)
 {
        tx4938_irq_cp0_disable(irq);
-
-       return;
 }
 
 static void
@@ -162,8 +157,6 @@ tx4938_irq_cp0_end(unsigned int irq)
        if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
                tx4938_irq_cp0_enable(irq);
        }
-
-       return;
 }
 
 /**********************************************************************************/
@@ -227,7 +220,7 @@ tx4938_irq_pic_addr(int irq)
                }
        }
 
-       return (0);
+       return 0;
 }
 
 u32
@@ -278,7 +271,7 @@ tx4938_irq_pic_mask(int irq)
                        return (0x00000007);
                }
        }
-       return (0x00000000);
+       return 0x00000000;
 }
 
 static void
@@ -292,8 +285,6 @@ tx4938_irq_pic_modify(unsigned pic_reg, unsigned clr_bits, unsigned set_bits)
        TX4938_WR(pic_reg, val);
        mmiowb();
        TX4938_RD(pic_reg);
-
-       return;
 }
 
 static void __init
@@ -317,8 +308,6 @@ tx4938_irq_pic_init(void)
        TX4938_WR(0xff1ff600, TX4938_RD(0xff1ff600) | 0x1);     /* irq enable */
 
        spin_unlock_irqrestore(&tx4938_pic_lock, flags);
-
-       return;
 }
 
 static unsigned int
@@ -326,15 +315,13 @@ tx4938_irq_pic_startup(unsigned int irq)
 {
        tx4938_irq_pic_enable(irq);
 
-       return (0);
+       return 0;
 }
 
 static void
 tx4938_irq_pic_shutdown(unsigned int irq)
 {
        tx4938_irq_pic_disable(irq);
-
-       return;
 }
 
 static void
@@ -348,8 +335,6 @@ tx4938_irq_pic_enable(unsigned int irq)
                              tx4938_irq_pic_mask(irq));
 
        spin_unlock_irqrestore(&tx4938_pic_lock, flags);
-
-       return;
 }
 
 static void
@@ -363,16 +348,12 @@ tx4938_irq_pic_disable(unsigned int irq)
                              tx4938_irq_pic_mask(irq), 0);
 
        spin_unlock_irqrestore(&tx4938_pic_lock, flags);
-
-       return;
 }
 
 static void
 tx4938_irq_pic_mask_and_ack(unsigned int irq)
 {
        tx4938_irq_pic_disable(irq);
-
-       return;
 }
 
 static void
@@ -381,8 +362,6 @@ tx4938_irq_pic_end(unsigned int irq)
        if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
                tx4938_irq_pic_enable(irq);
        }
-
-       return;
 }
 
 /**********************************************************************************/
@@ -394,8 +373,6 @@ tx4938_irq_init(void)
 {
        tx4938_irq_cp0_init();
        tx4938_irq_pic_init();
-
-       return;
 }
 
 int
@@ -417,23 +394,23 @@ tx4938_irq_nested(void)
        }
 
        wbflush();
-       return (sw_irq);
+       return sw_irq;
 }
 
-asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+asmlinkage void plat_irq_dispatch(void)
 {
        unsigned int pending = read_c0_cause() & read_c0_status();
 
        if (pending & STATUSF_IP7)
-               do_IRQ(TX4938_IRQ_CPU_TIMER, regs);
+               do_IRQ(TX4938_IRQ_CPU_TIMER);
        else if (pending & STATUSF_IP2) {
                int irq = tx4938_irq_nested();
                if (irq)
-                       do_IRQ(irq, regs);
+                       do_IRQ(irq);
                else
-                       spurious_interrupt(regs);
+                       spurious_interrupt();
        } else if (pending & STATUSF_IP1)
-               do_IRQ(TX4938_IRQ_USER1, regs);
+               do_IRQ(TX4938_IRQ_USER1);
        else if (pending & STATUSF_IP0)
-               do_IRQ(TX4938_IRQ_USER0, regs);
+               do_IRQ(TX4938_IRQ_USER0);
 }
index 71859c4fee84779848dd4032ddf0c8500faeabeb..f415a1f18fba657c350c09c6ead11d0571e411ac 100644 (file)
@@ -41,29 +41,10 @@ void __init tx4938_setup(void);
 void __init tx4938_time_init(void);
 void dump_cp0(char *key);
 
-void (*__wbflush) (void);
-
-static void
-tx4938_write_buffer_flush(void)
-{
-       mmiowb();
-
-       __asm__ __volatile__(
-               ".set   push\n\t"
-               ".set   noreorder\n\t"
-               "lw     $0,%0\n\t"
-               "nop\n\t"
-               ".set   pop"
-               : /* no output */
-               : "m" (*(int *)KSEG1)
-               : "memory");
-}
-
 void __init
 plat_mem_setup(void)
 {
        board_time_init = tx4938_time_init;
-       __wbflush = tx4938_write_buffer_flush;
        toshiba_rbtx4938_setup();
 }
 
index 83f2750825a46864ced603eb3c1d7fb1886c3139..102e473c10a28f1213e18f544d192a34785a8025 100644 (file)
@@ -81,9 +81,9 @@ IRQ  Device
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/processor.h>
-#include <asm/ptrace.h>
 #include <asm/reboot.h>
 #include <asm/time.h>
+#include <asm/wbflush.h>
 #include <linux/bootmem.h>
 #include <asm/tx4938/rbtx4938.h>
 
index fae3136f462da00bebd063d88d9e833ee36467d6..b926e6a75c29b8ace85a6fea448eacf92dc4bd48 100644 (file)
@@ -35,7 +35,8 @@ void __init txx9_spi_init(unsigned long base, int (*cs_func)(int chipid, int on)
 }
 
 static DECLARE_WAIT_QUEUE_HEAD(txx9_spi_wait);
-static void txx9_spi_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+
+static void txx9_spi_interrupt(int irq, void *dev_id)
 {
        /* disable rx intr */
        tx4938_spiptr->cr0 &= ~TXx9_SPCR0_RBSIE;
index 7a5c31d58378cd0abefa03d215e71de8415bd44a..c215c0d39fae930dfc74d7bfd3db2dd6b53312e1 100644 (file)
@@ -635,7 +635,7 @@ int vr41xx_set_intassign(unsigned int irq, unsigned char intassign)
 
 EXPORT_SYMBOL(vr41xx_set_intassign);
 
-static int icu_get_irq(unsigned int irq, struct pt_regs *regs)
+static int icu_get_irq(unsigned int irq)
 {
        uint16_t pend1, pend2;
        uint16_t mask1, mask2;
index 4733c5344467f1f0f441f9066ecc1ef684426f48..397ba94cd7ec251c504227c9733f27be98f15887 100644 (file)
@@ -25,7 +25,7 @@
 #include <asm/vr41xx/irq.h>
 
 typedef struct irq_cascade {
-       int (*get_irq)(unsigned int, struct pt_regs *);
+       int (*get_irq)(unsigned int);
 } irq_cascade_t;
 
 static irq_cascade_t irq_cascade[NR_IRQS] __cacheline_aligned;
@@ -36,7 +36,7 @@ static struct irqaction cascade_irqaction = {
        .name           = "cascade",
 };
 
-int cascade_irq(unsigned int irq, int (*get_irq)(unsigned int, struct pt_regs *))
+int cascade_irq(unsigned int irq, int (*get_irq)(unsigned int))
 {
        int retval = 0;
 
@@ -59,7 +59,7 @@ int cascade_irq(unsigned int irq, int (*get_irq)(unsigned int, struct pt_regs *)
 
 EXPORT_SYMBOL_GPL(cascade_irq);
 
-static void irq_dispatch(unsigned int irq, struct pt_regs *regs)
+static void irq_dispatch(unsigned int irq)
 {
        irq_cascade_t *cascade;
        struct irq_desc *desc;
@@ -74,39 +74,39 @@ static void irq_dispatch(unsigned int irq, struct pt_regs *regs)
                unsigned int source_irq = irq;
                desc = irq_desc + source_irq;
                desc->chip->ack(source_irq);
-               irq = cascade->get_irq(irq, regs);
+               irq = cascade->get_irq(irq);
                if (irq < 0)
                        atomic_inc(&irq_err_count);
                else
-                       irq_dispatch(irq, regs);
+                       irq_dispatch(irq);
                desc->chip->end(source_irq);
        } else
-               do_IRQ(irq, regs);
+               do_IRQ(irq);
 }
 
-asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+asmlinkage void plat_irq_dispatch(void)
 {
        unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
 
        if (pending & CAUSEF_IP7)
-               do_IRQ(7, regs);
+               do_IRQ(7);
        else if (pending & 0x7800) {
                if (pending & CAUSEF_IP3)
-                       irq_dispatch(3, regs);
+                       irq_dispatch(3);
                else if (pending & CAUSEF_IP4)
-                       irq_dispatch(4, regs);
+                       irq_dispatch(4);
                else if (pending & CAUSEF_IP5)
-                       irq_dispatch(5, regs);
+                       irq_dispatch(5);
                else if (pending & CAUSEF_IP6)
-                       irq_dispatch(6, regs);
+                       irq_dispatch(6);
        } else if (pending & CAUSEF_IP2)
-               irq_dispatch(2, regs);
+               irq_dispatch(2);
        else if (pending & CAUSEF_IP0)
-               do_IRQ(0, regs);
+               do_IRQ(0);
        else if (pending & CAUSEF_IP1)
-               do_IRQ(1, regs);
+               do_IRQ(1);
        else
-               spurious_interrupt(regs);
+               spurious_interrupt();
 }
 
 void __init arch_init_irq(void)
index 2d58b92b57e368094635d1d4431bdcb782ed6d40..4204cd1f3cf9c2f3fce7769b51e606278055635e 100644 (file)
@@ -73,7 +73,7 @@ struct getdents_callback {
 #define ROUND_UP(x) (((x)+sizeof(long)-1) & ~(sizeof(long)-1))
 
 static int filldir(void * __buf, const char * name, int namlen, loff_t offset,
-               ino_t ino, unsigned d_type)
+               u64 ino, unsigned d_type)
 {
        struct hpux_dirent * dirent;
        struct getdents_callback * buf = (struct getdents_callback *) __buf;
index 3d569a485a1a6540735f282eb87879705fd4574c..d6c486e9501ced09bded130f5f4049ee1d3a0c30 100644 (file)
@@ -424,7 +424,10 @@ struct parisc_device * create_tree_node(char id, struct device *parent)
        /* make the generic dma mask a pointer to the parisc one */
        dev->dev.dma_mask = &dev->dma_mask;
        dev->dev.coherent_dma_mask = dev->dma_mask;
-       device_register(&dev->dev);
+       if (device_register(&dev->dev)) {
+               kfree(dev);
+               return NULL;
+       }
 
        return dev;
 }
@@ -850,8 +853,10 @@ static void print_parisc_device(struct parisc_device *dev)
  */
 void init_parisc_bus(void)
 {
-       bus_register(&parisc_bus_type);
-       device_register(&root);
+       if (bus_register(&parisc_bus_type))
+               panic("Could not register PA-RISC bus type\n");
+       if (device_register(&root))
+               panic("Could not register PA-RISC root device\n");
        get_device(&root);
 }
 
index c2531ae032cf74895e4d6ef518607b856ba810c3..9158b707c0dd7a083850b16827a05eea7362efd8 100644 (file)
@@ -160,13 +160,14 @@ void __init set_firmware_width(void)
 {
 #ifdef __LP64__
        int retval;
+       unsigned long flags;
 
-        spin_lock_irq(&pdc_lock);
+        spin_lock_irqsave(&pdc_lock, flags);
        retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_CAPABILITIES, __pa(pdc_result), 0);
        convert_to_wide(pdc_result);
        if(pdc_result[0] != NARROW_FIRMWARE)
                parisc_narrow_firmware = 0;
-        spin_unlock_irq(&pdc_lock);
+        spin_unlock_irqrestore(&pdc_lock, flags);
 #endif
 }
 
@@ -196,10 +197,11 @@ void pdc_emergency_unlock(void)
 int pdc_add_valid(unsigned long address)
 {
         int retval;
+       unsigned long flags;
 
-        spin_lock_irq(&pdc_lock);
+        spin_lock_irqsave(&pdc_lock, flags);
         retval = mem_pdc_call(PDC_ADD_VALID, PDC_ADD_VALID_VERIFY, address);
-        spin_unlock_irq(&pdc_lock);
+        spin_unlock_irqrestore(&pdc_lock, flags);
 
         return retval;
 }
@@ -216,15 +218,16 @@ EXPORT_SYMBOL(pdc_add_valid);
 int __init pdc_chassis_info(struct pdc_chassis_info *chassis_info, void *led_info, unsigned long len)
 {
         int retval;
+       unsigned long flags;
 
-        spin_lock_irq(&pdc_lock);
+        spin_lock_irqsave(&pdc_lock, flags);
         memcpy(&pdc_result, chassis_info, sizeof(*chassis_info));
         memcpy(&pdc_result2, led_info, len);
         retval = mem_pdc_call(PDC_CHASSIS, PDC_RETURN_CHASSIS_INFO,
                               __pa(pdc_result), __pa(pdc_result2), len);
         memcpy(chassis_info, pdc_result, sizeof(*chassis_info));
         memcpy(led_info, pdc_result2, len);
-        spin_unlock_irq(&pdc_lock);
+        spin_unlock_irqrestore(&pdc_lock, flags);
 
         return retval;
 }
@@ -239,13 +242,14 @@ int __init pdc_chassis_info(struct pdc_chassis_info *chassis_info, void *led_inf
 int pdc_pat_chassis_send_log(unsigned long state, unsigned long data)
 {
        int retval = 0;
+       unsigned long flags;
         
        if (!is_pdc_pat())
                return -1;
 
-       spin_lock_irq(&pdc_lock);
+       spin_lock_irqsave(&pdc_lock, flags);
        retval = mem_pdc_call(PDC_PAT_CHASSIS_LOG, PDC_PAT_CHASSIS_WRITE_LOG, __pa(&state), __pa(&data));
-       spin_unlock_irq(&pdc_lock);
+       spin_unlock_irqrestore(&pdc_lock, flags);
 
        return retval;
 }
@@ -258,10 +262,11 @@ int pdc_pat_chassis_send_log(unsigned long state, unsigned long data)
 int pdc_chassis_disp(unsigned long disp)
 {
        int retval = 0;
+       unsigned long flags;
 
-       spin_lock_irq(&pdc_lock);
+       spin_lock_irqsave(&pdc_lock, flags);
        retval = mem_pdc_call(PDC_CHASSIS, PDC_CHASSIS_DISP, disp);
-       spin_unlock_irq(&pdc_lock);
+       spin_unlock_irqrestore(&pdc_lock, flags);
 
        return retval;
 }
@@ -273,11 +278,12 @@ int pdc_chassis_disp(unsigned long disp)
 int pdc_chassis_warn(unsigned long *warn)
 {
        int retval = 0;
+       unsigned long flags;
 
-       spin_lock_irq(&pdc_lock);
+       spin_lock_irqsave(&pdc_lock, flags);
        retval = mem_pdc_call(PDC_CHASSIS, PDC_CHASSIS_WARN, __pa(pdc_result));
        *warn = pdc_result[0];
-       spin_unlock_irq(&pdc_lock);
+       spin_unlock_irqrestore(&pdc_lock, flags);
 
        return retval;
 }
@@ -292,15 +298,16 @@ int pdc_chassis_warn(unsigned long *warn)
 int __init pdc_coproc_cfg(struct pdc_coproc_cfg *pdc_coproc_info)
 {
         int retval;
+       unsigned long flags;
 
-        spin_lock_irq(&pdc_lock);
+        spin_lock_irqsave(&pdc_lock, flags);
         retval = mem_pdc_call(PDC_COPROC, PDC_COPROC_CFG, __pa(pdc_result));
         convert_to_wide(pdc_result);
         pdc_coproc_info->ccr_functional = pdc_result[0];
         pdc_coproc_info->ccr_present = pdc_result[1];
         pdc_coproc_info->revision = pdc_result[17];
         pdc_coproc_info->model = pdc_result[18];
-        spin_unlock_irq(&pdc_lock);
+        spin_unlock_irqrestore(&pdc_lock, flags);
 
         return retval;
 }
@@ -320,14 +327,15 @@ int pdc_iodc_read(unsigned long *actcnt, unsigned long hpa, unsigned int index,
                  void *iodc_data, unsigned int iodc_data_size)
 {
        int retval;
+       unsigned long flags;
 
-       spin_lock_irq(&pdc_lock);
+       spin_lock_irqsave(&pdc_lock, flags);
        retval = mem_pdc_call(PDC_IODC, PDC_IODC_READ, __pa(pdc_result), hpa, 
                              index, __pa(pdc_result2), iodc_data_size);
        convert_to_wide(pdc_result);
        *actcnt = pdc_result[0];
        memcpy(iodc_data, pdc_result2, iodc_data_size);
-       spin_unlock_irq(&pdc_lock);
+       spin_unlock_irqrestore(&pdc_lock, flags);
 
        return retval;
 }
@@ -346,14 +354,15 @@ int pdc_system_map_find_mods(struct pdc_system_map_mod_info *pdc_mod_info,
                             struct pdc_module_path *mod_path, long mod_index)
 {
        int retval;
+       unsigned long flags;
 
-       spin_lock_irq(&pdc_lock);
+       spin_lock_irqsave(&pdc_lock, flags);
        retval = mem_pdc_call(PDC_SYSTEM_MAP, PDC_FIND_MODULE, __pa(pdc_result), 
                              __pa(pdc_result2), mod_index);
        convert_to_wide(pdc_result);
        memcpy(pdc_mod_info, pdc_result, sizeof(*pdc_mod_info));
        memcpy(mod_path, pdc_result2, sizeof(*mod_path));
-       spin_unlock_irq(&pdc_lock);
+       spin_unlock_irqrestore(&pdc_lock, flags);
 
        pdc_mod_info->mod_addr = f_extend(pdc_mod_info->mod_addr);
        return retval;
@@ -372,13 +381,14 @@ int pdc_system_map_find_addrs(struct pdc_system_map_addr_info *pdc_addr_info,
                              long mod_index, long addr_index)
 {
        int retval;
+       unsigned long flags;
 
-       spin_lock_irq(&pdc_lock);
+       spin_lock_irqsave(&pdc_lock, flags);
        retval = mem_pdc_call(PDC_SYSTEM_MAP, PDC_FIND_ADDRESS, __pa(pdc_result),
                              mod_index, addr_index);
        convert_to_wide(pdc_result);
        memcpy(pdc_addr_info, pdc_result, sizeof(*pdc_addr_info));
-       spin_unlock_irq(&pdc_lock);
+       spin_unlock_irqrestore(&pdc_lock, flags);
 
        pdc_addr_info->mod_addr = f_extend(pdc_addr_info->mod_addr);
        return retval;
@@ -393,12 +403,13 @@ int pdc_system_map_find_addrs(struct pdc_system_map_addr_info *pdc_addr_info,
 int pdc_model_info(struct pdc_model *model) 
 {
        int retval;
+       unsigned long flags;
 
-       spin_lock_irq(&pdc_lock);
+       spin_lock_irqsave(&pdc_lock, flags);
        retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_INFO, __pa(pdc_result), 0);
        convert_to_wide(pdc_result);
        memcpy(model, pdc_result, sizeof(*model));
-       spin_unlock_irq(&pdc_lock);
+       spin_unlock_irqrestore(&pdc_lock, flags);
 
        return retval;
 }
@@ -414,8 +425,9 @@ int pdc_model_info(struct pdc_model *model)
 int pdc_model_sysmodel(char *name)
 {
         int retval;
+       unsigned long flags;
 
-        spin_lock_irq(&pdc_lock);
+        spin_lock_irqsave(&pdc_lock, flags);
         retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_SYSMODEL, __pa(pdc_result),
                               OS_ID_HPUX, __pa(name));
         convert_to_wide(pdc_result);
@@ -425,7 +437,7 @@ int pdc_model_sysmodel(char *name)
         } else {
                 name[0] = 0;
         }
-        spin_unlock_irq(&pdc_lock);
+        spin_unlock_irqrestore(&pdc_lock, flags);
 
         return retval;
 }
@@ -443,12 +455,13 @@ int pdc_model_sysmodel(char *name)
 int pdc_model_versions(unsigned long *versions, int id)
 {
         int retval;
+       unsigned long flags;
 
-        spin_lock_irq(&pdc_lock);
+        spin_lock_irqsave(&pdc_lock, flags);
         retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_VERSIONS, __pa(pdc_result), id);
         convert_to_wide(pdc_result);
         *versions = pdc_result[0];
-        spin_unlock_irq(&pdc_lock);
+        spin_unlock_irqrestore(&pdc_lock, flags);
 
         return retval;
 }
@@ -463,13 +476,14 @@ int pdc_model_versions(unsigned long *versions, int id)
 int pdc_model_cpuid(unsigned long *cpu_id)
 {
         int retval;
+       unsigned long flags;
 
-        spin_lock_irq(&pdc_lock);
+        spin_lock_irqsave(&pdc_lock, flags);
         pdc_result[0] = 0; /* preset zero (call may not be implemented!) */
         retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_CPU_ID, __pa(pdc_result), 0);
         convert_to_wide(pdc_result);
         *cpu_id = pdc_result[0];
-        spin_unlock_irq(&pdc_lock);
+        spin_unlock_irqrestore(&pdc_lock, flags);
 
         return retval;
 }
@@ -484,13 +498,14 @@ int pdc_model_cpuid(unsigned long *cpu_id)
 int pdc_model_capabilities(unsigned long *capabilities)
 {
         int retval;
+       unsigned long flags;
 
-        spin_lock_irq(&pdc_lock);
+        spin_lock_irqsave(&pdc_lock, flags);
         pdc_result[0] = 0; /* preset zero (call may not be implemented!) */
         retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_CAPABILITIES, __pa(pdc_result), 0);
         convert_to_wide(pdc_result);
         *capabilities = pdc_result[0];
-        spin_unlock_irq(&pdc_lock);
+        spin_unlock_irqrestore(&pdc_lock, flags);
 
         return retval;
 }
@@ -504,12 +519,13 @@ int pdc_model_capabilities(unsigned long *capabilities)
 int pdc_cache_info(struct pdc_cache_info *cache_info)
 {
         int retval;
+       unsigned long flags;
 
-        spin_lock_irq(&pdc_lock);
+        spin_lock_irqsave(&pdc_lock, flags);
         retval = mem_pdc_call(PDC_CACHE, PDC_CACHE_INFO, __pa(pdc_result), 0);
         convert_to_wide(pdc_result);
         memcpy(cache_info, pdc_result, sizeof(*cache_info));
-        spin_unlock_irq(&pdc_lock);
+        spin_unlock_irqrestore(&pdc_lock, flags);
 
         return retval;
 }
@@ -523,13 +539,14 @@ int pdc_cache_info(struct pdc_cache_info *cache_info)
 int pdc_spaceid_bits(unsigned long *space_bits)
 {
        int retval;
+       unsigned long flags;
 
-       spin_lock_irq(&pdc_lock);
+       spin_lock_irqsave(&pdc_lock, flags);
        pdc_result[0] = 0;
        retval = mem_pdc_call(PDC_CACHE, PDC_CACHE_RET_SPID, __pa(pdc_result), 0);
        convert_to_wide(pdc_result);
        *space_bits = pdc_result[0];
-       spin_unlock_irq(&pdc_lock);
+       spin_unlock_irqrestore(&pdc_lock, flags);
 
        return retval;
 }
@@ -544,11 +561,12 @@ int pdc_spaceid_bits(unsigned long *space_bits)
 int pdc_btlb_info(struct pdc_btlb_info *btlb) 
 {
         int retval;
+       unsigned long flags;
 
-        spin_lock_irq(&pdc_lock);
+        spin_lock_irqsave(&pdc_lock, flags);
         retval = mem_pdc_call(PDC_BLOCK_TLB, PDC_BTLB_INFO, __pa(pdc_result), 0);
         memcpy(btlb, pdc_result, sizeof(*btlb));
-        spin_unlock_irq(&pdc_lock);
+        spin_unlock_irqrestore(&pdc_lock, flags);
 
         if(retval < 0) {
                 btlb->max_size = 0;
@@ -572,13 +590,14 @@ int pdc_mem_map_hpa(struct pdc_memory_map *address,
                struct pdc_module_path *mod_path)
 {
         int retval;
+       unsigned long flags;
 
-        spin_lock_irq(&pdc_lock);
+        spin_lock_irqsave(&pdc_lock, flags);
         memcpy(pdc_result2, mod_path, sizeof(*mod_path));
         retval = mem_pdc_call(PDC_MEM_MAP, PDC_MEM_MAP_HPA, __pa(pdc_result),
                                __pa(pdc_result2));
         memcpy(address, pdc_result, sizeof(*address));
-        spin_unlock_irq(&pdc_lock);
+        spin_unlock_irqrestore(&pdc_lock, flags);
 
         return retval;
 }
@@ -594,8 +613,9 @@ int pdc_mem_map_hpa(struct pdc_memory_map *address,
 int pdc_lan_station_id(char *lan_addr, unsigned long hpa)
 {
        int retval;
+       unsigned long flags;
 
-       spin_lock_irq(&pdc_lock);
+       spin_lock_irqsave(&pdc_lock, flags);
        retval = mem_pdc_call(PDC_LAN_STATION_ID, PDC_LAN_STATION_ID_READ,
                        __pa(pdc_result), hpa);
        if (retval < 0) {
@@ -604,7 +624,7 @@ int pdc_lan_station_id(char *lan_addr, unsigned long hpa)
        } else {
                memcpy(lan_addr, pdc_result, PDC_LAN_STATION_ID_SIZE);
        }
-       spin_unlock_irq(&pdc_lock);
+       spin_unlock_irqrestore(&pdc_lock, flags);
 
        return retval;
 }
@@ -623,13 +643,14 @@ EXPORT_SYMBOL(pdc_lan_station_id);
 int pdc_stable_read(unsigned long staddr, void *memaddr, unsigned long count)
 {
        int retval;
+       unsigned long flags;
 
-       spin_lock_irq(&pdc_lock);
+       spin_lock_irqsave(&pdc_lock, flags);
        retval = mem_pdc_call(PDC_STABLE, PDC_STABLE_READ, staddr,
                __pa(pdc_result), count);
        convert_to_wide(pdc_result);
        memcpy(memaddr, pdc_result, count);
-       spin_unlock_irq(&pdc_lock);
+       spin_unlock_irqrestore(&pdc_lock, flags);
 
        return retval;
 }
@@ -648,13 +669,14 @@ EXPORT_SYMBOL(pdc_stable_read);
 int pdc_stable_write(unsigned long staddr, void *memaddr, unsigned long count)
 {
        int retval;
+       unsigned long flags;
 
-       spin_lock_irq(&pdc_lock);
+       spin_lock_irqsave(&pdc_lock, flags);
        memcpy(pdc_result, memaddr, count);
        convert_to_wide(pdc_result);
        retval = mem_pdc_call(PDC_STABLE, PDC_STABLE_WRITE, staddr,
                __pa(pdc_result), count);
-       spin_unlock_irq(&pdc_lock);
+       spin_unlock_irqrestore(&pdc_lock, flags);
 
        return retval;
 }
@@ -672,11 +694,12 @@ EXPORT_SYMBOL(pdc_stable_write);
 int pdc_stable_get_size(unsigned long *size)
 {
        int retval;
+       unsigned long flags;
 
-       spin_lock_irq(&pdc_lock);
+       spin_lock_irqsave(&pdc_lock, flags);
        retval = mem_pdc_call(PDC_STABLE, PDC_STABLE_RETURN_SIZE, __pa(pdc_result));
        *size = pdc_result[0];
-       spin_unlock_irq(&pdc_lock);
+       spin_unlock_irqrestore(&pdc_lock, flags);
 
        return retval;
 }
@@ -691,10 +714,11 @@ EXPORT_SYMBOL(pdc_stable_get_size);
 int pdc_stable_verify_contents(void)
 {
        int retval;
+       unsigned long flags;
 
-       spin_lock_irq(&pdc_lock);
+       spin_lock_irqsave(&pdc_lock, flags);
        retval = mem_pdc_call(PDC_STABLE, PDC_STABLE_VERIFY_CONTENTS);
-       spin_unlock_irq(&pdc_lock);
+       spin_unlock_irqrestore(&pdc_lock, flags);
 
        return retval;
 }
@@ -709,10 +733,11 @@ EXPORT_SYMBOL(pdc_stable_verify_contents);
 int pdc_stable_initialize(void)
 {
        int retval;
+       unsigned long flags;
 
-       spin_lock_irq(&pdc_lock);
+       spin_lock_irqsave(&pdc_lock, flags);
        retval = mem_pdc_call(PDC_STABLE, PDC_STABLE_INITIALIZE);
-       spin_unlock_irq(&pdc_lock);
+       spin_unlock_irqrestore(&pdc_lock, flags);
 
        return retval;
 }
@@ -735,8 +760,9 @@ EXPORT_SYMBOL(pdc_stable_initialize);
 int pdc_get_initiator(struct hardware_path *hwpath, struct pdc_initiator *initiator)
 {
        int retval;
+       unsigned long flags;
 
-       spin_lock_irq(&pdc_lock);
+       spin_lock_irqsave(&pdc_lock, flags);
 
 /* BCJ-XXXX series boxes. E.G. "9000/785/C3000" */
 #define IS_SPROCKETS() (strlen(boot_cpu_data.pdc.sys_model_name) == 14 && \
@@ -776,7 +802,8 @@ int pdc_get_initiator(struct hardware_path *hwpath, struct pdc_initiator *initia
        }
 
  out:
-       spin_unlock_irq(&pdc_lock);
+       spin_unlock_irqrestore(&pdc_lock, flags);
+
        return (retval >= PDC_OK);
 }
 EXPORT_SYMBOL(pdc_get_initiator);
@@ -794,13 +821,14 @@ EXPORT_SYMBOL(pdc_get_initiator);
 int pdc_pci_irt_size(unsigned long *num_entries, unsigned long hpa)
 {
        int retval;
+       unsigned long flags;
 
-       spin_lock_irq(&pdc_lock);
+       spin_lock_irqsave(&pdc_lock, flags);
        retval = mem_pdc_call(PDC_PCI_INDEX, PDC_PCI_GET_INT_TBL_SIZE, 
                              __pa(pdc_result), hpa);
        convert_to_wide(pdc_result);
        *num_entries = pdc_result[0];
-       spin_unlock_irq(&pdc_lock);
+       spin_unlock_irqrestore(&pdc_lock, flags);
 
        return retval;
 }
@@ -817,14 +845,15 @@ int pdc_pci_irt_size(unsigned long *num_entries, unsigned long hpa)
 int pdc_pci_irt(unsigned long num_entries, unsigned long hpa, void *tbl)
 {
        int retval;
+       unsigned long flags;
 
        BUG_ON((unsigned long)tbl & 0x7);
 
-       spin_lock_irq(&pdc_lock);
+       spin_lock_irqsave(&pdc_lock, flags);
        pdc_result[0] = num_entries;
        retval = mem_pdc_call(PDC_PCI_INDEX, PDC_PCI_GET_INT_TBL, 
                              __pa(pdc_result), hpa, __pa(tbl));
-       spin_unlock_irq(&pdc_lock);
+       spin_unlock_irqrestore(&pdc_lock, flags);
 
        return retval;
 }
@@ -842,12 +871,15 @@ int pdc_pci_irt(unsigned long num_entries, unsigned long hpa, void *tbl)
 unsigned int pdc_pci_config_read(void *hpa, unsigned long cfg_addr)
 {
        int retval;
-       spin_lock_irq(&pdc_lock);
+       unsigned long flags;
+
+       spin_lock_irqsave(&pdc_lock, flags);
        pdc_result[0] = 0;
        pdc_result[1] = 0;
        retval = mem_pdc_call(PDC_PCI_INDEX, PDC_PCI_READ_CONFIG, 
                              __pa(pdc_result), hpa, cfg_addr&~3UL, 4UL);
-       spin_unlock_irq(&pdc_lock);
+       spin_unlock_irqrestore(&pdc_lock, flags);
+
        return retval ? ~0 : (unsigned int) pdc_result[0];
 }
 
@@ -863,12 +895,15 @@ unsigned int pdc_pci_config_read(void *hpa, unsigned long cfg_addr)
 void pdc_pci_config_write(void *hpa, unsigned long cfg_addr, unsigned int val)
 {
        int retval;
-       spin_lock_irq(&pdc_lock);
+       unsigned long flags;
+
+       spin_lock_irqsave(&pdc_lock, flags);
        pdc_result[0] = 0;
        retval = mem_pdc_call(PDC_PCI_INDEX, PDC_PCI_WRITE_CONFIG, 
                              __pa(pdc_result), hpa,
                              cfg_addr&~3UL, 4UL, (unsigned long) val);
-       spin_unlock_irq(&pdc_lock);
+       spin_unlock_irqrestore(&pdc_lock, flags);
+
        return retval;
 }
 #endif /* UNTESTED CODE */
@@ -882,12 +917,13 @@ void pdc_pci_config_write(void *hpa, unsigned long cfg_addr, unsigned int val)
 int pdc_tod_read(struct pdc_tod *tod)
 {
         int retval;
+       unsigned long flags;
 
-        spin_lock_irq(&pdc_lock);
+        spin_lock_irqsave(&pdc_lock, flags);
         retval = mem_pdc_call(PDC_TOD, PDC_TOD_READ, __pa(pdc_result), 0);
         convert_to_wide(pdc_result);
         memcpy(tod, pdc_result, sizeof(*tod));
-        spin_unlock_irq(&pdc_lock);
+        spin_unlock_irqrestore(&pdc_lock, flags);
 
         return retval;
 }
@@ -903,10 +939,11 @@ EXPORT_SYMBOL(pdc_tod_read);
 int pdc_tod_set(unsigned long sec, unsigned long usec)
 {
         int retval;
+       unsigned long flags;
 
-        spin_lock_irq(&pdc_lock);
+        spin_lock_irqsave(&pdc_lock, flags);
         retval = mem_pdc_call(PDC_TOD, PDC_TOD_WRITE, sec, usec);
-        spin_unlock_irq(&pdc_lock);
+        spin_unlock_irqrestore(&pdc_lock, flags);
 
         return retval;
 }
@@ -917,13 +954,14 @@ int pdc_mem_mem_table(struct pdc_memory_table_raddr *r_addr,
                struct pdc_memory_table *tbl, unsigned long entries)
 {
        int retval;
+       unsigned long flags;
 
-       spin_lock_irq(&pdc_lock);
+       spin_lock_irqsave(&pdc_lock, flags);
        retval = mem_pdc_call(PDC_MEM, PDC_MEM_TABLE, __pa(pdc_result), __pa(pdc_result2), entries);
        convert_to_wide(pdc_result);
        memcpy(r_addr, pdc_result, sizeof(*r_addr));
        memcpy(tbl, pdc_result2, entries * sizeof(*tbl));
-       spin_unlock_irq(&pdc_lock);
+       spin_unlock_irqrestore(&pdc_lock, flags);
 
        return retval;
 }
@@ -936,11 +974,12 @@ int pdc_mem_mem_table(struct pdc_memory_table_raddr *r_addr,
 int pdc_do_firm_test_reset(unsigned long ftc_bitmap)
 {
         int retval;
+       unsigned long flags;
 
-        spin_lock_irq(&pdc_lock);
+        spin_lock_irqsave(&pdc_lock, flags);
         retval = mem_pdc_call(PDC_BROADCAST_RESET, PDC_DO_FIRM_TEST_RESET,
                               PDC_FIRM_TEST_MAGIC, ftc_bitmap);
-        spin_unlock_irq(&pdc_lock);
+        spin_unlock_irqrestore(&pdc_lock, flags);
 
         return retval;
 }
@@ -953,10 +992,11 @@ int pdc_do_firm_test_reset(unsigned long ftc_bitmap)
 int pdc_do_reset(void)
 {
         int retval;
+       unsigned long flags;
 
-        spin_lock_irq(&pdc_lock);
+        spin_lock_irqsave(&pdc_lock, flags);
         retval = mem_pdc_call(PDC_BROADCAST_RESET, PDC_DO_RESET);
-        spin_unlock_irq(&pdc_lock);
+        spin_unlock_irqrestore(&pdc_lock, flags);
 
         return retval;
 }
@@ -970,16 +1010,17 @@ int pdc_do_reset(void)
 int __init pdc_soft_power_info(unsigned long *power_reg)
 {
        int retval;
+       unsigned long flags;
 
        *power_reg = (unsigned long) (-1);
        
-       spin_lock_irq(&pdc_lock);
+       spin_lock_irqsave(&pdc_lock, flags);
        retval = mem_pdc_call(PDC_SOFT_POWER, PDC_SOFT_POWER_INFO, __pa(pdc_result), 0);
        if (retval == PDC_OK) {
                 convert_to_wide(pdc_result);
                 *power_reg = f_extend(pdc_result[0]);
        }
-       spin_unlock_irq(&pdc_lock);
+       spin_unlock_irqrestore(&pdc_lock, flags);
 
        return retval;
 }
@@ -998,9 +1039,12 @@ int __init pdc_soft_power_info(unsigned long *power_reg)
 int pdc_soft_power_button(int sw_control)
 {
        int retval;
-       spin_lock_irq(&pdc_lock);
+       unsigned long flags;
+
+       spin_lock_irqsave(&pdc_lock, flags);
        retval = mem_pdc_call(PDC_SOFT_POWER, PDC_SOFT_POWER_ENABLE, __pa(pdc_result), sw_control);
-       spin_unlock_irq(&pdc_lock);
+       spin_unlock_irqrestore(&pdc_lock, flags);
+
        return retval;
 }
 
@@ -1011,9 +1055,11 @@ int pdc_soft_power_button(int sw_control)
  */
 void pdc_io_reset(void)
 {
-       spin_lock_irq(&pdc_lock);  
+       unsigned long flags;
+
+       spin_lock_irqsave(&pdc_lock, flags);
        mem_pdc_call(PDC_IO, PDC_IO_RESET, 0);
-       spin_unlock_irq(&pdc_lock);
+       spin_unlock_irqrestore(&pdc_lock, flags);
 }
 
 /*
@@ -1027,9 +1073,11 @@ void pdc_io_reset(void)
  */
 void pdc_io_reset_devices(void)
 {
-       spin_lock_irq(&pdc_lock);  
+       unsigned long flags;
+
+       spin_lock_irqsave(&pdc_lock, flags);
        mem_pdc_call(PDC_IO, PDC_IO_RESET_DEVICES, 0);
-       spin_unlock_irq(&pdc_lock);
+       spin_unlock_irqrestore(&pdc_lock, flags);
 }
 
 
@@ -1146,10 +1194,11 @@ int pdc_sti_call(unsigned long func, unsigned long flags,
                  unsigned long glob_cfg)
 {
         int retval;
+       unsigned long irqflags;
 
-        spin_lock_irq(&pdc_lock);  
+        spin_lock_irqsave(&pdc_lock, irqflags);  
         retval = real32_call(func, flags, inptr, outputr, glob_cfg);
-        spin_unlock_irq(&pdc_lock);
+        spin_unlock_irqrestore(&pdc_lock, irqflags);
 
         return retval;
 }
@@ -1166,11 +1215,12 @@ EXPORT_SYMBOL(pdc_sti_call);
 int pdc_pat_cell_get_number(struct pdc_pat_cell_num *cell_info)
 {
        int retval;
+       unsigned long flags;
 
-       spin_lock_irq(&pdc_lock);
+       spin_lock_irqsave(&pdc_lock, flags);
        retval = mem_pdc_call(PDC_PAT_CELL, PDC_PAT_CELL_GET_NUMBER, __pa(pdc_result));
        memcpy(cell_info, pdc_result, sizeof(*cell_info));
-       spin_unlock_irq(&pdc_lock);
+       spin_unlock_irqrestore(&pdc_lock, flags);
 
        return retval;
 }
@@ -1190,16 +1240,17 @@ int pdc_pat_cell_module(unsigned long *actcnt, unsigned long ploc, unsigned long
                        unsigned long view_type, void *mem_addr)
 {
        int retval;
+       unsigned long flags;
        static struct pdc_pat_cell_mod_maddr_block result __attribute__ ((aligned (8)));
 
-       spin_lock_irq(&pdc_lock);
+       spin_lock_irqsave(&pdc_lock, flags);
        retval = mem_pdc_call(PDC_PAT_CELL, PDC_PAT_CELL_MODULE, __pa(pdc_result), 
                              ploc, mod, view_type, __pa(&result));
        if(!retval) {
                *actcnt = pdc_result[0];
                memcpy(mem_addr, &result, *actcnt);
        }
-       spin_unlock_irq(&pdc_lock);
+       spin_unlock_irqrestore(&pdc_lock, flags);
 
        return retval;
 }
@@ -1214,12 +1265,13 @@ int pdc_pat_cell_module(unsigned long *actcnt, unsigned long ploc, unsigned long
 int pdc_pat_cpu_get_number(struct pdc_pat_cpu_num *cpu_info, void *hpa)
 {
        int retval;
+       unsigned long flags;
 
-       spin_lock_irq(&pdc_lock);
+       spin_lock_irqsave(&pdc_lock, flags);
        retval = mem_pdc_call(PDC_PAT_CPU, PDC_PAT_CPU_GET_NUMBER,
                              __pa(&pdc_result), hpa);
        memcpy(cpu_info, pdc_result, sizeof(*cpu_info));
-       spin_unlock_irq(&pdc_lock);
+       spin_unlock_irqrestore(&pdc_lock, flags);
 
        return retval;
 }
@@ -1235,12 +1287,13 @@ int pdc_pat_cpu_get_number(struct pdc_pat_cpu_num *cpu_info, void *hpa)
 int pdc_pat_get_irt_size(unsigned long *num_entries, unsigned long cell_num)
 {
        int retval;
+       unsigned long flags;
 
-       spin_lock_irq(&pdc_lock);
+       spin_lock_irqsave(&pdc_lock, flags);
        retval = mem_pdc_call(PDC_PAT_IO, PDC_PAT_IO_GET_PCI_ROUTING_TABLE_SIZE,
                              __pa(pdc_result), cell_num);
        *num_entries = pdc_result[0];
-       spin_unlock_irq(&pdc_lock);
+       spin_unlock_irqrestore(&pdc_lock, flags);
 
        return retval;
 }
@@ -1255,11 +1308,12 @@ int pdc_pat_get_irt_size(unsigned long *num_entries, unsigned long cell_num)
 int pdc_pat_get_irt(void *r_addr, unsigned long cell_num)
 {
        int retval;
+       unsigned long flags;
 
-       spin_lock_irq(&pdc_lock);
+       spin_lock_irqsave(&pdc_lock, flags);
        retval = mem_pdc_call(PDC_PAT_IO, PDC_PAT_IO_GET_PCI_ROUTING_TABLE,
                              __pa(r_addr), cell_num);
-       spin_unlock_irq(&pdc_lock);
+       spin_unlock_irqrestore(&pdc_lock, flags);
 
        return retval;
 }
@@ -1276,13 +1330,14 @@ int pdc_pat_pd_get_addr_map(unsigned long *actual_len, void *mem_addr,
                            unsigned long count, unsigned long offset)
 {
        int retval;
+       unsigned long flags;
 
-       spin_lock_irq(&pdc_lock);
+       spin_lock_irqsave(&pdc_lock, flags);
        retval = mem_pdc_call(PDC_PAT_PD, PDC_PAT_PD_GET_ADDR_MAP, __pa(pdc_result), 
                              __pa(pdc_result2), count, offset);
        *actual_len = pdc_result[0];
        memcpy(mem_addr, pdc_result2, *actual_len);
-       spin_unlock_irq(&pdc_lock);
+       spin_unlock_irqrestore(&pdc_lock, flags);
 
        return retval;
 }
@@ -1297,7 +1352,9 @@ int pdc_pat_pd_get_addr_map(unsigned long *actual_len, void *mem_addr,
 int pdc_pat_io_pci_cfg_read(unsigned long pci_addr, int pci_size, u32 *mem_addr)
 {
        int retval;
-       spin_lock_irq(&pdc_lock);
+       unsigned long flags;
+
+       spin_lock_irqsave(&pdc_lock, flags);
        retval = mem_pdc_call(PDC_PAT_IO, PDC_PAT_IO_PCI_CONFIG_READ,
                                        __pa(pdc_result), pci_addr, pci_size);
        switch(pci_size) {
@@ -1305,7 +1362,7 @@ int pdc_pat_io_pci_cfg_read(unsigned long pci_addr, int pci_size, u32 *mem_addr)
                case 2: *(u16 *)mem_addr =  (u16) pdc_result[0];
                case 4: *(u32 *)mem_addr =  (u32) pdc_result[0];
        }
-       spin_unlock_irq(&pdc_lock);
+       spin_unlock_irqrestore(&pdc_lock, flags);
 
        return retval;
 }
@@ -1321,11 +1378,12 @@ int pdc_pat_io_pci_cfg_read(unsigned long pci_addr, int pci_size, u32 *mem_addr)
 int pdc_pat_io_pci_cfg_write(unsigned long pci_addr, int pci_size, u32 val)
 {
        int retval;
+       unsigned long flags;
 
-       spin_lock_irq(&pdc_lock);
+       spin_lock_irqsave(&pdc_lock, flags);
        retval = mem_pdc_call(PDC_PAT_IO, PDC_PAT_IO_PCI_CONFIG_WRITE,
                                pci_addr, pci_size, val);
-       spin_unlock_irq(&pdc_lock);
+       spin_unlock_irqrestore(&pdc_lock, flags);
 
        return retval;
 }
index 9bdd0197ceb777f555efc995e1581c17d2167938..b39c5b9aff463d5efcf41dda4fe2474b27b97052 100644 (file)
@@ -35,8 +35,8 @@
 
 #undef PARISC_IRQ_CR16_COUNTS
 
-extern irqreturn_t timer_interrupt(int, void *, struct pt_regs *);
-extern irqreturn_t ipi_interrupt(int, void *, struct pt_regs *);
+extern irqreturn_t timer_interrupt(int, void *);
+extern irqreturn_t ipi_interrupt(int, void *);
 
 #define EIEM_MASK(irq)       (1UL<<(CPU_IRQ_MAX - irq))
 
@@ -347,12 +347,14 @@ static inline int eirr_to_irq(unsigned long eirr)
 /* ONLY called from entry.S:intr_extint() */
 void do_cpu_irq_mask(struct pt_regs *regs)
 {
+       struct pt_regs *old_regs;
        unsigned long eirr_val;
        int irq, cpu = smp_processor_id();
 #ifdef CONFIG_SMP
        cpumask_t dest;
 #endif
 
+       old_regs = set_irq_regs(regs);
        local_irq_disable();
        irq_enter();
 
@@ -375,10 +377,11 @@ void do_cpu_irq_mask(struct pt_regs *regs)
                goto set_out;
        }
 #endif
-       __do_IRQ(irq, regs);
+       __do_IRQ(irq);
 
  out:
        irq_exit();
+       set_irq_regs(old_regs);
        return;
 
  set_out:
index 6d57553d8ef886890dc358247f85adc7fdb52e2d..8f6a0b312f7a025b97d9785be851f0fb748f4e85 100644 (file)
@@ -69,10 +69,6 @@ EXPORT_SYMBOL(memcpy_toio);
 EXPORT_SYMBOL(memcpy_fromio);
 EXPORT_SYMBOL(memset_io);
 
-#include <asm/unistd.h>
-EXPORT_SYMBOL(sys_lseek);
-EXPORT_SYMBOL(sys_write);
-
 #include <asm/semaphore.h>
 EXPORT_SYMBOL(__up);
 EXPORT_SYMBOL(__down_interruptible);
index d3b8fc52dfc1e130a2c9a6e621116c62ed8a74f7..199887a61c765dea150132dc9d870b9c14a0e9f6 100644 (file)
@@ -290,7 +290,7 @@ EXPORT_SYMBOL(pcibios_bus_to_resource);
 void pcibios_align_resource(void *data, struct resource *res,
                                resource_size_t size, resource_size_t alignment)
 {
-       unsigned long mask, align;
+       resource_size_t mask, align;
 
        DBG_RES("pcibios_align_resource(%s, (%p) [%lx,%lx]/%x, 0x%lx, 0x%lx)\n",
                pci_name(((struct pci_dev *) data)),
index faad338f310ed12f8dddc4f4824b40c61edde298..4a23a97b06cd7484a172bce26a2803149abdeabd 100644 (file)
@@ -154,7 +154,7 @@ halt_processor(void)
 
 
 irqreturn_t
-ipi_interrupt(int irq, void *dev_id, struct pt_regs *regs
+ipi_interrupt(int irq, void *dev_id) 
 {
        int this_cpu = smp_processor_id();
        struct cpuinfo_parisc *p = &cpu_data[this_cpu];
@@ -414,19 +414,6 @@ smp_flush_tlb_all(void)
        on_each_cpu(flush_tlb_all_local, NULL, 1, 1);
 }
 
-
-void 
-smp_do_timer(struct pt_regs *regs)
-{
-       int cpu = smp_processor_id();
-       struct cpuinfo_parisc *data = &cpu_data[cpu];
-
-        if (!--data->prof_counter) {
-               data->prof_counter = data->prof_multiplier;
-               update_process_times(user_mode(regs));
-       }
-}
-
 /*
  * Called by secondaries to update state and initialize CPU registers.
  */
index 1db5588ceacf7474ebba8d947b6b7c31da09a906..512642d8f707ce7208a99b5c0e2136c02c065c5e 100644 (file)
@@ -266,30 +266,17 @@ long parisc_personality(unsigned long personality)
        return err;
 }
 
-static inline int override_machine(char __user *mach) {
-#ifdef CONFIG_COMPAT
-       if (personality(current->personality) == PER_LINUX32) {
-               if (__put_user(0, mach + 6) ||
-                   __put_user(0, mach + 7))
-                       return -EFAULT;
-       }
-
-       return 0;
-#else /*!CONFIG_COMPAT*/
-       return 0;
-#endif /*CONFIG_COMPAT*/
-}
-
-long parisc_newuname(struct new_utsname __user *utsname)
+long parisc_newuname(struct new_utsname __user *name)
 {
-       int err = 0;
+       int err = sys_newuname(name);
 
-       down_read(&uts_sem);
-       if (copy_to_user(utsname, &system_utsname, sizeof(*utsname)))
-               err = -EFAULT;
-       up_read(&uts_sem);
-
-       err = override_machine(utsname->machine);
+#ifdef CONFIG_COMPAT
+       if (!err && personality(current->personality) == PER_LINUX32) {
+               if (__put_user(0, name->machine + 6) ||
+                   __put_user(0, name->machine + 7))
+                       err = -EFAULT;
+       }
+#endif
 
-       return (long)err;
+       return err;
 }
index e3b30bc36453a0d05b830c3d9967de27112ab0c3..29be4377aca6c0fb1e2cebd00d4fba4556efdc01 100644 (file)
@@ -111,13 +111,14 @@ struct __sysctl_args32 {
 
 asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args)
 {
+#ifndef CONFIG_SYSCTL_SYSCALL
+       return -ENOSYS;
+#else
        struct __sysctl_args32 tmp;
        int error;
        unsigned int oldlen32;
-       size_t oldlen, *oldlenp = NULL;
+       size_t oldlen, __user *oldlenp = NULL;
        unsigned long addr = (((long __force)&args->__unused[0]) + 7) & ~7;
-       extern int do_sysctl(int *name, int nlen, void *oldval, size_t *oldlenp,
-              void *newval, size_t newlen);
 
        DBG(("sysctl32(%p)\n", args));
 
@@ -144,8 +145,9 @@ asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args)
        }
 
        lock_kernel();
-       error = do_sysctl((int *)(u64)tmp.name, tmp.nlen, (void *)(u64)tmp.oldval,
-                         oldlenp, (void *)(u64)tmp.newval, tmp.newlen);
+       error = do_sysctl((int __user *)(u64)tmp.name, tmp.nlen,
+                         (void __user *)(u64)tmp.oldval, oldlenp,
+                         (void __user *)(u64)tmp.newval, tmp.newlen);
        unlock_kernel();
        if (oldlenp) {
                if (!error) {
@@ -157,10 +159,11 @@ asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args)
                                        error = -EFAULT;
                        }
                }
-               if (copy_to_user(&args->__unused[0], tmp.__unused, sizeof(tmp.__unused)))
+               if (copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused)))
                        error = -EFAULT;
        }
        return error;
+#endif
 }
 
 #endif /* CONFIG_SYSCTL */
@@ -310,9 +313,8 @@ struct readdir32_callback {
 
 #define ROUND_UP(x,a)  ((__typeof__(x))(((unsigned long)(x) + ((a) - 1)) & ~((a) - 1)))
 #define NAME_OFFSET(de) ((int) ((de)->d_name - (char __user *) (de)))
-static int
-filldir32 (void *__buf, const char *name, int namlen, loff_t offset, ino_t ino,
-          unsigned int d_type)
+static int filldir32 (void *__buf, const char *name, int namlen,
+                       loff_t offset, u64 ino, unsigned int d_type)
 {
        struct linux32_dirent __user * dirent;
        struct getdents32_callback * buf = (struct getdents32_callback *) __buf;
@@ -374,9 +376,8 @@ out:
        return error;
 }
 
-static int
-fillonedir32 (void * __buf, const char * name, int namlen, loff_t offset, ino_t ino,
-             unsigned int d_type)
+static int fillonedir32(void * __buf, const char * name, int namlen,
+                       loff_t offset, u64 ino, unsigned int d_type)
 {
        struct readdir32_callback * buf = (struct readdir32_callback *) __buf;
        struct old_linux32_dirent __user * dirent;
index b3496b592a2d7db687793899388a4db9ce73f064..bad7d1eb62b975dff89921860ca30e816e948de3 100644 (file)
 
 static unsigned long clocktick __read_mostly;  /* timer cycles per tick */
 
-#ifdef CONFIG_SMP
-extern void smp_do_timer(struct pt_regs *regs);
-#endif
-
-irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+/*
+ * We keep time on PA-RISC Linux by using the Interval Timer which is
+ * a pair of registers; one is read-only and one is write-only; both
+ * accessed through CR16.  The read-only register is 32 or 64 bits wide,
+ * and increments by 1 every CPU clock tick.  The architecture only
+ * guarantees us a rate between 0.5 and 2, but all implementations use a
+ * rate of 1.  The write-only register is 32-bits wide.  When the lowest
+ * 32 bits of the read-only register compare equal to the write-only
+ * register, it raises a maskable external interrupt.  Each processor has
+ * an Interval Timer of its own and they are not synchronised.  
+ *
+ * We want to generate an interrupt every 1/HZ seconds.  So we program
+ * CR16 to interrupt every @clocktick cycles.  The it_value in cpu_data
+ * is programmed with the intended time of the next tick.  We can be
+ * held off for an arbitrarily long period of time by interrupts being
+ * disabled, so we may miss one or more ticks.
+ */
+irqreturn_t timer_interrupt(int irq, void *dev_id)
 {
        unsigned long now;
        unsigned long next_tick;
-       unsigned long cycles_elapsed;
+       unsigned long cycles_elapsed, ticks_elapsed;
        unsigned long cycles_remainder;
        unsigned int cpu = smp_processor_id();
+       struct cpuinfo_parisc *cpuinfo = &cpu_data[cpu];
 
        /* gcc can optimize for "read-only" case with a local clocktick */
        unsigned long cpt = clocktick;
 
-       profile_tick(CPU_PROFILING, regs);
+       profile_tick(CPU_PROFILING);
 
        /* Initialize next_tick to the expected tick time. */
-       next_tick = cpu_data[cpu].it_value;
+       next_tick = cpuinfo->it_value;
 
        /* Get current interval timer.
         * CR16 reads as 64 bits in CPU wide mode.
@@ -67,11 +81,14 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                 * of the more expensive div/mul method
                 */
                cycles_remainder = cycles_elapsed;
+               ticks_elapsed = 1;
                while (cycles_remainder > cpt) {
                        cycles_remainder -= cpt;
+                       ticks_elapsed++;
                }
        } else {
                cycles_remainder = cycles_elapsed % cpt;
+               ticks_elapsed = 1 + cycles_elapsed / cpt;
        }
 
        /* Can we differentiate between "early CR16" (aka Scenario 1) and
@@ -81,18 +98,7 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
         * cycles after the IT fires. But it's arbitrary how much time passes
         * before we call it "late". I've picked one second.
         */
-/* aproximate HZ with shifts. Intended math is "(elapsed/clocktick) > HZ" */
-#if HZ == 1000
-       if (cycles_elapsed > (cpt << 10) )
-#elif HZ == 250
-       if (cycles_elapsed > (cpt << 8) )
-#elif HZ == 100
-       if (cycles_elapsed > (cpt << 7) )
-#else
-#warn WTF is HZ set to anyway?
-       if (cycles_elapsed > (HZ * cpt) )
-#endif
-       {
+       if (ticks_elapsed > HZ) {
                /* Scenario 3: very long delay?  bad in any case */
                printk (KERN_CRIT "timer_interrupt(CPU %d): delayed!"
                        " cycles %lX rem %lX "
@@ -111,7 +117,7 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
         */
        next_tick = now + cycles_remainder;
 
-       cpu_data[cpu].it_value = next_tick;
+       cpuinfo->it_value = next_tick;
 
        /* Skip one clocktick on purpose if we are likely to miss next_tick.
         * We want to avoid the new next_tick being less than CR16.
@@ -122,21 +128,22 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                next_tick += cpt;
 
        /* Program the IT when to deliver the next interrupt. */
-        /* Only bottom 32-bits of next_tick are written to cr16.  */
+       /* Only bottom 32-bits of next_tick are written to cr16.  */
        mtctl(next_tick, 16);
 
 
        /* Done mucking with unreliable delivery of interrupts.
         * Go do system house keeping.
         */
-#ifdef CONFIG_SMP
-       smp_do_timer(regs);
-#else
-       update_process_times(user_mode(regs));
-#endif
+
+       if (!--cpuinfo->prof_counter) {
+               cpuinfo->prof_counter = cpuinfo->prof_multiplier;
+               update_process_times(user_mode(get_irq_regs()));
+       }
+
        if (cpu == 0) {
                write_seqlock(&xtime_lock);
-               do_timer(regs);
+               do_timer(ticks_elapsed);
                write_sequnlock(&xtime_lock);
        }
 
@@ -310,13 +317,15 @@ void __init time_init(void)
 
        start_cpu_itimer();     /* get CPU 0 started */
 
-       if(pdc_tod_read(&tod_data) == 0) {
-               write_seqlock_irq(&xtime_lock);
+       if (pdc_tod_read(&tod_data) == 0) {
+               unsigned long flags;
+
+               write_seqlock_irqsave(&xtime_lock, flags);
                xtime.tv_sec = tod_data.tod_sec;
                xtime.tv_nsec = tod_data.tod_usec * 1000;
                set_normalized_timespec(&wall_to_monotonic,
                                        -xtime.tv_sec, -xtime.tv_nsec);
-               write_sequnlock_irq(&xtime_lock);
+               write_sequnlock_irqrestore(&xtime_lock, flags);
        } else {
                printk(KERN_ERR "Error reading tod clock\n");
                xtime.tv_sec = 0;
index 8b6910465578b02cf8d00b9c9326f302d7ef5b5e..2bd9b7fb0f6c91cc7e35bdedf3bafed7f897e7a3 100644 (file)
@@ -751,6 +751,15 @@ config ARCH_MEMORY_PROBE
        def_bool y
        depends on MEMORY_HOTPLUG
 
+# Some NUMA nodes have memory ranges that span
+# other nodes.  Even though a pfn is valid and
+# between a node's start and end pfns, it may not
+# reside on that node.  See memmap_init_zone()
+# for details.
+config NODES_SPAN_OTHER_NODES
+       def_bool y
+       depends on NEED_MULTIPLE_NODES
+
 config PPC_64K_PAGES
        bool "64k page size"
        depends on PPC64
index 003520b56303e2f4e275d436827a6a6152c8f3a4..37ddfcab000330ab360e3a6727ee26d22ef638f1 100644 (file)
@@ -105,10 +105,10 @@ wrapperbits       := $(extra-y) $(addprefix $(obj)/,addnote hack-coff)
 # Bits for building various flavours of zImage
 
 ifneq ($(CROSS32_COMPILE),)
-CROSSWRAP := -C $(CROSS32_COMPILE)
+CROSSWRAP := -C "$(CROSS32_COMPILE)"
 else
 ifneq ($(CROSS_COMPILE),)
-CROSSWRAP := -C $(CROSS_COMPILE)
+CROSSWRAP := -C "$(CROSS_COMPILE)"
 endif
 endif
 
@@ -151,12 +151,12 @@ $(obj)/zImage.initrd.miboot: vmlinux $(wrapperbits)
 $(obj)/uImage: vmlinux $(wrapperbits)
        $(call cmd,wrap,uboot)
 
-image-$(CONFIG_PPC_PSERIES)    += zImage.pseries
-image-$(CONFIG_PPC_MAPLE)      += zImage.pseries
-image-$(CONFIG_PPC_CELL)       += zImage.pseries
-image-$(CONFIG_PPC_CHRP)       += zImage.chrp
-image-$(CONFIG_PPC_PMAC)       += zImage.pmac
-image-$(CONFIG_DEFAULT_UIMAGE) += uImage
+image-$(CONFIG_PPC_PSERIES)            += zImage.pseries
+image-$(CONFIG_PPC_MAPLE)              += zImage.pseries
+image-$(CONFIG_PPC_IBM_CELL_BLADE)     += zImage.pseries
+image-$(CONFIG_PPC_CHRP)               += zImage.chrp
+image-$(CONFIG_PPC_PMAC)               += zImage.pmac
+image-$(CONFIG_DEFAULT_UIMAGE)         += uImage
 
 # For 32-bit powermacs, build the COFF and miboot images
 # as well as the ELF images.
diff --git a/arch/powerpc/boot/dts/mpc8349emitx.dts b/arch/powerpc/boot/dts/mpc8349emitx.dts
new file mode 100644 (file)
index 0000000..27807fc
--- /dev/null
@@ -0,0 +1,246 @@
+/*
+ * MPC8349E-mITX Device Tree Source
+ *
+ * Copyright 2006 Freescale Semiconductor Inc.
+ *
+ * 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.
+ */
+/ {
+       model = "MPC8349EMITX";
+       compatible = "MPC834xMITX";
+       #address-cells = <1>;
+       #size-cells = <1>;
+
+       cpus {
+               #cpus = <1>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               PowerPC,8349@0 {
+                       device_type = "cpu";
+                       reg = <0>;
+                       d-cache-line-size = <20>;
+                       i-cache-line-size = <20>;
+                       d-cache-size = <8000>;
+                       i-cache-size = <8000>;
+                       timebase-frequency = <0>;       // from bootloader
+                       bus-frequency = <0>;            // from bootloader
+                       clock-frequency = <0>;          // from bootloader
+                       32-bit;
+               };
+       };
+
+       memory {
+               device_type = "memory";
+               reg = <00000000 10000000>;
+       };
+
+       soc8349@e0000000 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               #interrupt-cells = <2>;
+               device_type = "soc";
+               ranges = <0 e0000000 00100000>;
+               reg = <e0000000 00000200>;
+               bus-frequency = <0>;                    // from bootloader
+
+               wdt@200 {
+                       device_type = "watchdog";
+                       compatible = "mpc83xx_wdt";
+                       reg = <200 100>;
+               };
+
+               i2c@3000 {
+                       device_type = "i2c";
+                       compatible = "fsl-i2c";
+                       reg = <3000 100>;
+                       interrupts = <e 8>;
+                       interrupt-parent = <700>;
+                       dfsrr;
+               };
+
+               i2c@3100 {
+                       device_type = "i2c";
+                       compatible = "fsl-i2c";
+                       reg = <3100 100>;
+                       interrupts = <f 8>;
+                       interrupt-parent = <700>;
+                       dfsrr;
+               };
+
+               spi@7000 {
+                       device_type = "spi";
+                       compatible = "mpc83xx_spi";
+                       reg = <7000 1000>;
+                       interrupts = <10 8>;
+                       interrupt-parent = <700>;
+                       mode = <0>;
+               };
+
+               usb@22000 {
+                       device_type = "usb";
+                       compatible = "fsl-usb2-mph";
+                       reg = <22000 1000>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       interrupt-parent = <700>;
+                       interrupts = <27 2>;
+                       phy_type = "ulpi";
+                       port1;
+               };
+
+               usb@23000 {
+                       device_type = "usb";
+                       compatible = "fsl-usb2-dr";
+                       reg = <23000 1000>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       interrupt-parent = <700>;
+                       interrupts = <26 2>;
+                       phy_type = "ulpi";
+               };
+
+               mdio@24520 {
+                       device_type = "mdio";
+                       compatible = "gianfar";
+                       reg = <24520 20>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       linux,phandle = <24520>;
+
+                       /* Vitesse 8201 */
+                       ethernet-phy@1c {
+                               linux,phandle = <245201c>;
+                               interrupt-parent = <700>;
+                               interrupts = <12 2>;
+                               reg = <1c>;
+                               device_type = "ethernet-phy";
+                       };
+
+                       /* Vitesse 7385 */
+                       ethernet-phy@1f {
+                               linux,phandle = <245201f>;
+                               interrupt-parent = <700>;
+                               interrupts = <12 2>;
+                               reg = <1f>;
+                               device_type = "ethernet-phy";
+                       };
+               };
+
+               ethernet@24000 {
+                       device_type = "network";
+                       model = "TSEC";
+                       compatible = "gianfar";
+                       reg = <24000 1000>;
+                       address = [ 00 00 00 00 00 00 ];
+                       local-mac-address = [ 00 00 00 00 00 00 ];
+                       interrupts = <20 8 21 8 22 8>;
+                       interrupt-parent = <700>;
+                       phy-handle = <245201c>;
+               };
+
+               ethernet@25000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       device_type = "network";
+                       model = "TSEC";
+                       compatible = "gianfar";
+                       reg = <25000 1000>;
+                       address = [ 00 00 00 00 00 00 ];
+                       local-mac-address = [ 00 00 00 00 00 00 ];
+                       interrupts = <23 8 24 8 25 8>;
+                       interrupt-parent = <700>;
+                       phy-handle = <245201f>;
+               };
+
+               serial@4500 {
+                       device_type = "serial";
+                       compatible = "ns16550";
+                       reg = <4500 100>;
+                       clock-frequency = <0>;          // from bootloader
+                       interrupts = <9 8>;
+                       interrupt-parent = <700>;
+               };
+
+               serial@4600 {
+                       device_type = "serial";
+                       compatible = "ns16550";
+                       reg = <4600 100>;
+                       clock-frequency = <0>;          // from bootloader
+                       interrupts = <a 8>;
+                       interrupt-parent = <700>;
+               };
+
+               pci@8500 {
+                       interrupt-map-mask = <f800 0 0 7>;
+                       interrupt-map = <
+                                       /* IDSEL 0x10 - SATA */
+                                       8000 0 0 1 700 16 8 /* SATA_INTA */
+                                       >;
+                       interrupt-parent = <700>;
+                       interrupts = <42 8>;
+                       bus-range = <0 0>;
+                       ranges = <42000000 0 80000000 80000000 0 10000000
+                                 02000000 0 90000000 90000000 0 10000000
+                                 01000000 0 00000000 e2000000 0 01000000>;
+                       clock-frequency = <3f940aa>;
+                       #interrupt-cells = <1>;
+                       #size-cells = <2>;
+                       #address-cells = <3>;
+                       reg = <8500 100>;
+                       compatible = "83xx";
+                       device_type = "pci";
+               };
+
+               pci@8600 {
+                       interrupt-map-mask = <f800 0 0 7>;
+                       interrupt-map = <
+                                       /* IDSEL 0x0E - MiniPCI Slot */
+                                       7000 0 0 1 700 15 8 /* PCI_INTA */
+
+                                       /* IDSEL 0x0F - PCI Slot */
+                                       7800 0 0 1 700 14 8 /* PCI_INTA */
+                                       7800 0 0 2 700 15 8 /* PCI_INTB */
+                                        >;
+                       interrupt-parent = <700>;
+                       interrupts = <43 8>;
+                       bus-range = <1 1>;
+                       ranges = <42000000 0 a0000000 a0000000 0 10000000
+                                 02000000 0 b0000000 b0000000 0 10000000
+                                 01000000 0 00000000 e3000000 0 01000000>;
+                       clock-frequency = <3f940aa>;
+                       #interrupt-cells = <1>;
+                       #size-cells = <2>;
+                       #address-cells = <3>;
+                       reg = <8600 100>;
+                       compatible = "83xx";
+                       device_type = "pci";
+               };
+
+               crypto@30000 {
+                       device_type = "crypto";
+                       model = "SEC2";
+                       compatible = "talitos";
+                       reg = <30000 10000>;
+                       interrupts = <b 8>;
+                       interrupt-parent = <700>;
+                       num-channels = <4>;
+                       channel-fifo-len = <18>;
+                       exec-units-mask = <0000007e>;
+                       descriptor-types-mask = <01010ebf>;
+               };
+
+               pic@700 {
+                       linux,phandle = <700>;
+                       interrupt-controller;
+                       #address-cells = <0>;
+                       #interrupt-cells = <2>;
+                       reg = <700 100>;
+                       built-in;
+                       device_type = "ipic";
+               };
+       };
+};
index fd99f789a37bbdd32a1507cca72191ef5e1f37af..3a71845afc6c584670075fbc9a152febcf7819de 100644 (file)
@@ -176,12 +176,9 @@ static void *claim(unsigned long virt, unsigned long size, unsigned long align)
 static void *of_try_claim(u32 size)
 {
        unsigned long addr = 0;
-       static u8 first_time = 1;
 
-       if (first_time) {
+       if (claim_base == 0)
                claim_base = _ALIGN_UP((unsigned long)_end, ONE_MB);
-               first_time = 0;
-       }
 
        for(; claim_base < RAM_END; claim_base += ONE_MB) {
 #ifdef DEBUG
index 6fd9e7acec2912927c7faac2facd459ff4e07d67..892d5dd3254e3dc1ced10e570f7e478599e7eb7f 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc6
-# Sun Sep 10 10:20:32 2006
+# Linux kernel version: 2.6.18
+# Wed Oct  4 15:30:50 2006
 #
 CONFIG_PPC64=y
 CONFIG_64BIT=y
@@ -22,6 +22,7 @@ CONFIG_ARCH_MAY_HAVE_PC_FDC=y
 CONFIG_PPC_OF=y
 CONFIG_PPC_UDBG_16550=y
 # CONFIG_GENERIC_TBSYNC is not set
+CONFIG_AUDIT_ARCH=y
 # CONFIG_DEFAULT_UIMAGE is not set
 
 #
@@ -52,10 +53,11 @@ CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
-CONFIG_SYSCTL=y
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
@@ -63,7 +65,9 @@ CONFIG_CPUSETS=y
 # CONFIG_RELAY is not set
 CONFIG_INITRAMFS_SOURCE=""
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
 # CONFIG_EMBEDDED is not set
+# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -72,12 +76,12 @@ CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
 CONFIG_SLAB=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -96,6 +100,7 @@ CONFIG_STOP_MACHINE=y
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_BLK_DEV_IO_TRACE is not set
 
 #
@@ -115,12 +120,13 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 # Platform support
 #
 CONFIG_PPC_MULTIPLATFORM=y
-# CONFIG_PPC_ISERIES is not set
 # CONFIG_EMBEDDED6xx is not set
 # CONFIG_APUS is not set
 # CONFIG_PPC_PSERIES is not set
+# CONFIG_PPC_ISERIES is not set
 # CONFIG_PPC_PMAC is not set
 # CONFIG_PPC_MAPLE is not set
+# CONFIG_PPC_PASEMI is not set
 CONFIG_PPC_CELL=y
 CONFIG_PPC_CELL_NATIVE=y
 CONFIG_PPC_IBM_CELL_BLADE=y
@@ -142,7 +148,6 @@ CONFIG_MMIO_NVRAM=y
 #
 CONFIG_SPU_FS=m
 CONFIG_SPU_BASE=y
-CONFIG_SPUFS_MMAP=y
 CONFIG_CBE_RAS=y
 
 #
@@ -158,7 +163,7 @@ CONFIG_PREEMPT_NONE=y
 CONFIG_PREEMPT_BKL=y
 CONFIG_BINFMT_ELF=y
 CONFIG_BINFMT_MISC=m
-CONFIG_FORCE_MAX_ZONEORDER=13
+CONFIG_FORCE_MAX_ZONEORDER=9
 # CONFIG_IOMMU_VMERGE is not set
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_KEXEC=y
@@ -168,6 +173,7 @@ CONFIG_NUMA=y
 CONFIG_NODES_SHIFT=4
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
 CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_SELECT_MEMORY_MODEL=y
 # CONFIG_FLATMEM_MANUAL is not set
 # CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -178,12 +184,12 @@ CONFIG_HAVE_MEMORY_PRESENT=y
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPARSEMEM_EXTREME=y
 CONFIG_MEMORY_HOTPLUG=y
+CONFIG_MEMORY_HOTPLUG_SPARSE=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_MIGRATION=y
 CONFIG_RESOURCES_64BIT=y
-CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y
 CONFIG_ARCH_MEMORY_PROBE=y
-# CONFIG_PPC_64K_PAGES is not set
+CONFIG_PPC_64K_PAGES=y
 CONFIG_SCHED_SMT=y
 CONFIG_PROC_DEVICETREE=y
 # CONFIG_CMDLINE_BOOL is not set
@@ -201,6 +207,7 @@ CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PCI=y
 CONFIG_PCI_DOMAINS=y
 CONFIG_PCIEPORTBUS=y
+# CONFIG_PCI_MULTITHREAD_PROBE is not set
 # CONFIG_PCI_DEBUG is not set
 
 #
@@ -228,6 +235,7 @@ CONFIG_PACKET=y
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
@@ -249,7 +257,8 @@ CONFIG_INET_XFRM_MODE_TUNNEL=y
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
 
 #
 # IP: Virtual Server Configuration
@@ -261,11 +270,15 @@ CONFIG_IPV6=y
 CONFIG_INET6_AH=m
 CONFIG_INET6_ESP=m
 CONFIG_INET6_IPCOMP=m
+# CONFIG_IPV6_MIP6 is not set
 CONFIG_INET6_XFRM_TUNNEL=m
 CONFIG_INET6_TUNNEL=m
 CONFIG_INET6_XFRM_MODE_TRANSPORT=y
 CONFIG_INET6_XFRM_MODE_TUNNEL=y
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
 CONFIG_IPV6_TUNNEL=m
+# CONFIG_IPV6_SUBTREES is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
 # CONFIG_NETWORK_SECMARK is not set
 CONFIG_NETFILTER=y
 # CONFIG_NETFILTER_DEBUG is not set
@@ -322,7 +335,6 @@ CONFIG_IP_NF_QUEUE=m
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -434,6 +446,7 @@ CONFIG_BLK_DEV_AEC62XX=y
 # CONFIG_BLK_DEV_CS5530 is not set
 # CONFIG_BLK_DEV_HPT34X is not set
 # CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_JMICRON is not set
 # CONFIG_BLK_DEV_SC1200 is not set
 # CONFIG_BLK_DEV_PIIX is not set
 # CONFIG_BLK_DEV_IT821X is not set
@@ -456,6 +469,12 @@ CONFIG_IDEDMA_AUTO=y
 #
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -470,6 +489,7 @@ CONFIG_MD_RAID1=m
 # CONFIG_MD_MULTIPATH is not set
 # CONFIG_MD_FAULTY is not set
 CONFIG_BLK_DEV_DM=m
+# CONFIG_DM_DEBUG is not set
 CONFIG_DM_CRYPT=m
 CONFIG_DM_SNAPSHOT=m
 CONFIG_DM_MIRROR=m
@@ -504,7 +524,7 @@ CONFIG_NETDEVICES=y
 # CONFIG_DUMMY is not set
 CONFIG_BONDING=y
 # CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
+CONFIG_TUN=y
 
 #
 # ARCnet devices
@@ -552,7 +572,7 @@ CONFIG_SKGE=m
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
 CONFIG_SPIDER_NET=m
-# CONFIG_MV643XX_ETH is not set
+# CONFIG_QLA3XXX is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -599,6 +619,7 @@ CONFIG_SPIDER_NET=m
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -865,6 +886,7 @@ CONFIG_INFINIBAND_USER_ACCESS=m
 CONFIG_INFINIBAND_ADDR_TRANS=y
 CONFIG_INFINIBAND_MTHCA=m
 CONFIG_INFINIBAND_MTHCA_DEBUG=y
+# CONFIG_INFINIBAND_AMSO1100 is not set
 CONFIG_INFINIBAND_IPOIB=m
 CONFIG_INFINIBAND_IPOIB_DEBUG=y
 CONFIG_INFINIBAND_IPOIB_DEBUG_DATA=y
@@ -916,7 +938,7 @@ CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
 CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
+CONFIG_AUTOFS4_FS=m
 # CONFIG_FUSE_FS is not set
 
 #
@@ -943,8 +965,10 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
 CONFIG_HUGETLBFS=y
 CONFIG_HUGETLB_PAGE=y
 CONFIG_RAMFS=y
@@ -1084,6 +1108,7 @@ CONFIG_PLIST=y
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
 CONFIG_MAGIC_SYSRQ=y
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_KERNEL=y
@@ -1102,6 +1127,7 @@ CONFIG_DEBUG_SPINLOCK_SLEEP=y
 # CONFIG_DEBUG_INFO is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
 # CONFIG_FORCED_INLINING is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_DEBUG_STACKOVERFLOW is not set
@@ -1123,6 +1149,10 @@ CONFIG_IRQSTACKS=y
 # Cryptographic options
 #
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_HASH=y
+# CONFIG_CRYPTO_MANAGER is not set
 CONFIG_CRYPTO_HMAC=y
 # CONFIG_CRYPTO_NULL is not set
 # CONFIG_CRYPTO_MD4 is not set
@@ -1132,6 +1162,8 @@ CONFIG_CRYPTO_SHA1=m
 # CONFIG_CRYPTO_SHA512 is not set
 # CONFIG_CRYPTO_WP512 is not set
 # CONFIG_CRYPTO_TGR192 is not set
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
 CONFIG_CRYPTO_DES=m
 # CONFIG_CRYPTO_BLOWFISH is not set
 # CONFIG_CRYPTO_TWOFISH is not set
index d58f82f836f82553e9c5b98bd0dce39f55afda38..b5005506c2f80c2ed0ff0bfd39628321c311076a 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc6
-# Sun Sep 10 10:22:57 2006
+# Linux kernel version: 2.6.19-rc1
+# Fri Oct  6 13:25:04 2006
 #
 CONFIG_PPC64=y
 CONFIG_64BIT=y
@@ -22,6 +22,7 @@ CONFIG_ARCH_MAY_HAVE_PC_FDC=y
 CONFIG_PPC_OF=y
 # CONFIG_PPC_UDBG_16550 is not set
 # CONFIG_GENERIC_TBSYNC is not set
+CONFIG_AUDIT_ARCH=y
 # CONFIG_DEFAULT_UIMAGE is not set
 
 #
@@ -52,10 +53,11 @@ CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
 CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
-CONFIG_SYSCTL=y
+# CONFIG_UTS_NS is not set
 CONFIG_AUDIT=y
 CONFIG_AUDITSYSCALL=y
 CONFIG_IKCONFIG=y
@@ -64,7 +66,9 @@ CONFIG_IKCONFIG_PROC=y
 # CONFIG_RELAY is not set
 CONFIG_INITRAMFS_SOURCE=""
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
 # CONFIG_EMBEDDED is not set
+# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -73,12 +77,12 @@ CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
 CONFIG_SLAB=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -97,6 +101,7 @@ CONFIG_STOP_MACHINE=y
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_BLK_DEV_IO_TRACE is not set
 
 #
@@ -115,13 +120,18 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 #
 # Platform support
 #
-# CONFIG_PPC_MULTIPLATFORM is not set
-CONFIG_PPC_ISERIES=y
+CONFIG_PPC_MULTIPLATFORM=y
 # CONFIG_EMBEDDED6xx is not set
 # CONFIG_APUS is not set
+# CONFIG_PPC_PSERIES is not set
+CONFIG_PPC_ISERIES=y
+# CONFIG_PPC_PMAC is not set
+# CONFIG_PPC_MAPLE is not set
+# CONFIG_PPC_PASEMI is not set
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
-# CONFIG_UDBG_RTAS_CONSOLE is not set
+# CONFIG_PPC_IBM_CELL_BLADE is not set
+# CONFIG_U3_DART is not set
 # CONFIG_PPC_RTAS is not set
 # CONFIG_MMIO_NVRAM is not set
 CONFIG_IBMVIO=y
@@ -147,12 +157,15 @@ CONFIG_BINFMT_ELF=y
 CONFIG_FORCE_MAX_ZONEORDER=13
 CONFIG_IOMMU_VMERGE=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+# CONFIG_KEXEC is not set
+# CONFIG_CRASH_DUMP is not set
 CONFIG_IRQ_ALL_CPUS=y
 CONFIG_LPARCFG=y
 # CONFIG_NUMA is not set
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_FLATMEM_MANUAL=y
 # CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -179,6 +192,7 @@ CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PCI=y
 CONFIG_PCI_DOMAINS=y
 # CONFIG_PCIEPORTBUS is not set
+# CONFIG_PCI_MULTITHREAD_PROBE is not set
 # CONFIG_PCI_DEBUG is not set
 
 #
@@ -206,6 +220,7 @@ CONFIG_PACKET=y
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
+CONFIG_XFRM_SUB_POLICY=y
 CONFIG_NET_KEY=m
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
@@ -224,10 +239,12 @@ CONFIG_INET_XFRM_TUNNEL=m
 CONFIG_INET_TUNNEL=y
 CONFIG_INET_XFRM_MODE_TRANSPORT=y
 CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=m
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
 
 #
 # IP: Virtual Server Configuration
@@ -247,6 +264,7 @@ CONFIG_NETFILTER=y
 CONFIG_NETFILTER_XTABLES=m
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
 CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+CONFIG_NETFILTER_XT_TARGET_DSCP=m
 CONFIG_NETFILTER_XT_TARGET_MARK=m
 CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
 CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
@@ -255,6 +273,7 @@ CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
 CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
 CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
 # CONFIG_NETFILTER_XT_MATCH_DCCP is not set
+CONFIG_NETFILTER_XT_MATCH_DSCP=m
 # CONFIG_NETFILTER_XT_MATCH_ESP is not set
 CONFIG_NETFILTER_XT_MATCH_HELPER=m
 CONFIG_NETFILTER_XT_MATCH_LENGTH=m
@@ -294,7 +313,6 @@ CONFIG_IP_NF_MATCH_IPRANGE=m
 CONFIG_IP_NF_MATCH_TOS=m
 CONFIG_IP_NF_MATCH_RECENT=m
 CONFIG_IP_NF_MATCH_ECN=m
-CONFIG_IP_NF_MATCH_DSCP=m
 # CONFIG_IP_NF_MATCH_AH is not set
 CONFIG_IP_NF_MATCH_TTL=m
 CONFIG_IP_NF_MATCH_OWNER=m
@@ -319,7 +337,6 @@ CONFIG_IP_NF_NAT_AMANDA=m
 CONFIG_IP_NF_MANGLE=m
 CONFIG_IP_NF_TARGET_TOS=m
 CONFIG_IP_NF_TARGET_ECN=m
-CONFIG_IP_NF_TARGET_DSCP=m
 CONFIG_IP_NF_TARGET_TTL=m
 CONFIG_IP_NF_TARGET_CLUSTERIP=m
 CONFIG_IP_NF_RAW=m
@@ -351,7 +368,6 @@ CONFIG_LLC=y
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -433,6 +449,7 @@ CONFIG_BLK_DEV_INITRD=y
 #
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
+CONFIG_SCSI_NETLINK=y
 CONFIG_SCSI_PROC_FS=y
 
 #
@@ -454,12 +471,14 @@ CONFIG_SCSI_CONSTANTS=y
 # CONFIG_SCSI_LOGGING is not set
 
 #
-# SCSI Transport Attributes
+# SCSI Transports
 #
 CONFIG_SCSI_SPI_ATTRS=y
 CONFIG_SCSI_FC_ATTRS=y
 # CONFIG_SCSI_ISCSI_ATTRS is not set
-# CONFIG_SCSI_SAS_ATTRS is not set
+CONFIG_SCSI_SAS_ATTRS=m
+CONFIG_SCSI_SAS_LIBSAS=m
+CONFIG_SCSI_SAS_LIBSAS_DEBUG=y
 
 #
 # SCSI low-level drivers
@@ -472,10 +491,11 @@ CONFIG_SCSI_FC_ATTRS=y
 # CONFIG_SCSI_AIC7XXX is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
+# CONFIG_SCSI_ARCMSR is not set
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
-# CONFIG_ATA is not set
 # CONFIG_SCSI_HPTIOP is not set
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_DMX3191D is not set
@@ -486,15 +506,21 @@ CONFIG_SCSI_FC_ATTRS=y
 CONFIG_SCSI_IBMVSCSI=m
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
 # CONFIG_SCSI_SYM53C8XX_2 is not set
-# CONFIG_SCSI_IPR is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
 # CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
 # CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_DEBUG is not set
 
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
+
 #
 # Multi-device support (RAID and LVM)
 #
@@ -508,6 +534,7 @@ CONFIG_MD_RAID10=m
 CONFIG_MD_MULTIPATH=m
 CONFIG_MD_FAULTY=m
 CONFIG_BLK_DEV_DM=y
+# CONFIG_DM_DEBUG is not set
 CONFIG_DM_CRYPT=m
 CONFIG_DM_SNAPSHOT=m
 CONFIG_DM_MIRROR=m
@@ -573,6 +600,7 @@ CONFIG_MII=y
 # CONFIG_HP100 is not set
 CONFIG_NET_PCI=y
 CONFIG_PCNET32=y
+CONFIG_PCNET32_NAPI=y
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
 # CONFIG_B44 is not set
@@ -610,6 +638,7 @@ CONFIG_E1000=m
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -649,6 +678,7 @@ CONFIG_PPP_BSDCOMP=m
 # CONFIG_PPP_MPPE is not set
 CONFIG_PPPOE=m
 # CONFIG_SLIP is not set
+CONFIG_SLHC=m
 # CONFIG_NET_FC is not set
 # CONFIG_SHAPER is not set
 CONFIG_NETCONSOLE=y
@@ -671,6 +701,7 @@ CONFIG_NET_POLL_CONTROLLER=y
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -774,12 +805,12 @@ CONFIG_MAX_RAW_DEVS=256
 #
 # Misc devices
 #
+# CONFIG_TIFM_CORE is not set
 
 #
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -893,6 +924,9 @@ CONFIG_XFS_FS=m
 CONFIG_XFS_SECURITY=y
 CONFIG_XFS_POSIX_ACL=y
 # CONFIG_XFS_RT is not set
+CONFIG_GFS2_FS=m
+CONFIG_GFS2_FS_LOCKING_NOLOCK=m
+CONFIG_GFS2_FS_LOCKING_DLM=m
 # CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -929,12 +963,14 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
 # CONFIG_HUGETLBFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-# CONFIG_CONFIGFS_FS is not set
+CONFIG_CONFIGFS_FS=m
 
 #
 # Miscellaneous filesystems
@@ -988,6 +1024,7 @@ CONFIG_CIFS_POSIX=y
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
 # CONFIG_9P_FS is not set
+CONFIG_GENERIC_ACL=y
 
 #
 # Partition Types
@@ -1039,6 +1076,12 @@ CONFIG_NLS_ISO8859_1=y
 # CONFIG_NLS_KOI8_U is not set
 # CONFIG_NLS_UTF8 is not set
 
+#
+# Distributed Lock Manager
+#
+CONFIG_DLM=m
+# CONFIG_DLM_DEBUG is not set
+
 #
 # iSeries device drivers
 #
@@ -1073,6 +1116,7 @@ CONFIG_PLIST=y
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_MAGIC_SYSRQ=y
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_KERNEL=y
@@ -1091,6 +1135,7 @@ CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_DEBUG_INFO is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
 # CONFIG_FORCED_INLINING is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 CONFIG_DEBUG_STACKOVERFLOW=y
@@ -1109,6 +1154,10 @@ CONFIG_IRQSTACKS=y
 # Cryptographic options
 #
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=m
 CONFIG_CRYPTO_HMAC=y
 CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_MD4=m
@@ -1118,9 +1167,12 @@ CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_WP512=m
 CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
 CONFIG_CRYPTO_DES=y
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
 CONFIG_CRYPTO_SERPENT=m
 CONFIG_CRYPTO_AES=m
 CONFIG_CRYPTO_CAST5=m
index 62ba66091a13e212147fa3241f06eb7e0c3917b7..ae96a5b2f00dbd8ec53af5d94009b6c08770e0ef 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-rc6
-# Sun Sep 10 10:24:55 2006
+# Linux kernel version: 2.6.18
+# Mon Oct  9 11:59:34 2006
 #
 CONFIG_PPC64=y
 CONFIG_64BIT=y
@@ -22,6 +22,7 @@ CONFIG_ARCH_MAY_HAVE_PC_FDC=y
 CONFIG_PPC_OF=y
 CONFIG_PPC_UDBG_16550=y
 CONFIG_GENERIC_TBSYNC=y
+CONFIG_AUDIT_ARCH=y
 # CONFIG_DEFAULT_UIMAGE is not set
 
 #
@@ -34,7 +35,7 @@ CONFIG_PPC_FPU=y
 CONFIG_PPC_STD_MMU=y
 CONFIG_VIRT_CPU_ACCOUNTING=y
 CONFIG_SMP=y
-CONFIG_NR_CPUS=2
+CONFIG_NR_CPUS=4
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -51,10 +52,11 @@ CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
 CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
-CONFIG_SYSCTL=y
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
@@ -62,7 +64,9 @@ CONFIG_IKCONFIG_PROC=y
 # CONFIG_RELAY is not set
 CONFIG_INITRAMFS_SOURCE=""
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
 # CONFIG_EMBEDDED is not set
+# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -71,12 +75,12 @@ CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
-CONFIG_RT_MUTEXES=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
 CONFIG_SLAB=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -95,6 +99,7 @@ CONFIG_STOP_MACHINE=y
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 # CONFIG_BLK_DEV_IO_TRACE is not set
 
 #
@@ -114,16 +119,16 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 # Platform support
 #
 CONFIG_PPC_MULTIPLATFORM=y
-# CONFIG_PPC_ISERIES is not set
 # CONFIG_EMBEDDED6xx is not set
 # CONFIG_APUS is not set
 # CONFIG_PPC_PSERIES is not set
+# CONFIG_PPC_ISERIES is not set
 # CONFIG_PPC_PMAC is not set
 CONFIG_PPC_MAPLE=y
+# CONFIG_PPC_PASEMI is not set
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
 # CONFIG_PPC_IBM_CELL_BLADE is not set
-# CONFIG_UDBG_RTAS_CONSOLE is not set
 CONFIG_U3_DART=y
 # CONFIG_PPC_RTAS is not set
 # CONFIG_MMIO_NVRAM is not set
@@ -157,6 +162,7 @@ CONFIG_IRQ_ALL_CPUS=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_FLATMEM_MANUAL=y
 # CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -184,6 +190,7 @@ CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PCI=y
 CONFIG_PCI_DOMAINS=y
 # CONFIG_PCIEPORTBUS is not set
+# CONFIG_PCI_MULTITHREAD_PROBE is not set
 # CONFIG_PCI_DEBUG is not set
 
 #
@@ -211,6 +218,7 @@ CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
+# CONFIG_XFRM_SUB_POLICY is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
@@ -232,10 +240,12 @@ CONFIG_IP_PNP_DHCP=y
 # CONFIG_INET_TUNNEL is not set
 CONFIG_INET_XFRM_MODE_TRANSPORT=y
 CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IPV6 is not set
 # CONFIG_INET6_XFRM_TUNNEL is not set
 # CONFIG_INET6_TUNNEL is not set
@@ -265,7 +275,6 @@ CONFIG_TCP_CONG_BIC=y
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -377,6 +386,7 @@ CONFIG_BLK_DEV_AMD74XX=y
 # CONFIG_BLK_DEV_CS5530 is not set
 # CONFIG_BLK_DEV_HPT34X is not set
 # CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_JMICRON is not set
 # CONFIG_BLK_DEV_SC1200 is not set
 # CONFIG_BLK_DEV_PIIX is not set
 # CONFIG_BLK_DEV_IT821X is not set
@@ -399,6 +409,12 @@ CONFIG_IDEDMA_AUTO=y
 #
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -498,7 +514,7 @@ CONFIG_E1000=y
 # CONFIG_VIA_VELOCITY is not set
 CONFIG_TIGON3=y
 # CONFIG_BNX2 is not set
-# CONFIG_MV643XX_ETH is not set
+# CONFIG_QLA3XXX is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -545,6 +561,7 @@ CONFIG_TIGON3=y
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -704,6 +721,7 @@ CONFIG_I2C_AMD8111=y
 #
 # Misc devices
 #
+# CONFIG_TIFM_CORE is not set
 
 #
 # Multimedia devices
@@ -779,7 +797,6 @@ CONFIG_USB_UHCI_HCD=y
 #
 # may also be needed; see USB_STORAGE Help for more information
 #
-# CONFIG_USB_STORAGE is not set
 # CONFIG_USB_LIBUSUAL is not set
 
 #
@@ -802,6 +819,7 @@ CONFIG_USB_HIDINPUT=y
 # CONFIG_USB_ATI_REMOTE2 is not set
 # CONFIG_USB_KEYSPAN_REMOTE is not set
 # CONFIG_USB_APPLETOUCH is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
 
 #
 # USB Imaging devices
@@ -828,6 +846,7 @@ CONFIG_USB_MON=y
 CONFIG_USB_SERIAL=y
 # CONFIG_USB_SERIAL_CONSOLE is not set
 CONFIG_USB_SERIAL_GENERIC=y
+# CONFIG_USB_SERIAL_AIRCABLE is not set
 # CONFIG_USB_SERIAL_AIRPRIME is not set
 # CONFIG_USB_SERIAL_ARK3116 is not set
 # CONFIG_USB_SERIAL_BELKIN is not set
@@ -862,6 +881,7 @@ CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
 # CONFIG_USB_SERIAL_KLSI is not set
 # CONFIG_USB_SERIAL_KOBIL_SCT is not set
 # CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_MOS7840 is not set
 # CONFIG_USB_SERIAL_NAVMAN is not set
 # CONFIG_USB_SERIAL_PL2303 is not set
 # CONFIG_USB_SERIAL_HP4X is not set
@@ -879,6 +899,7 @@ CONFIG_USB_EZUSB=y
 #
 # CONFIG_USB_EMI62 is not set
 # CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
 # CONFIG_USB_AUERSWALD is not set
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
@@ -886,9 +907,9 @@ CONFIG_USB_EZUSB=y
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGETKIT is not set
-# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_PHIDGET is not set
 # CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
 # CONFIG_USB_APPLEDISPLAY is not set
 # CONFIG_USB_SISUSBVGA is not set
 # CONFIG_USB_LD is not set
@@ -995,8 +1016,10 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
 CONFIG_HUGETLBFS=y
 CONFIG_HUGETLB_PAGE=y
 CONFIG_RAMFS=y
@@ -1129,6 +1152,7 @@ CONFIG_PLIST=y
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_MAGIC_SYSRQ=y
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_KERNEL=y
@@ -1148,6 +1172,7 @@ CONFIG_DEBUG_SPINLOCK_SLEEP=y
 # CONFIG_DEBUG_INFO is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
 # CONFIG_FORCED_INLINING is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 CONFIG_DEBUG_STACKOVERFLOW=y
@@ -1169,6 +1194,9 @@ CONFIG_BOOTX_TEXT=y
 # Cryptographic options
 #
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_MANAGER=m
 # CONFIG_CRYPTO_HMAC is not set
 # CONFIG_CRYPTO_NULL is not set
 # CONFIG_CRYPTO_MD4 is not set
@@ -1178,6 +1206,8 @@ CONFIG_CRYPTO_MD5=y
 # CONFIG_CRYPTO_SHA512 is not set
 # CONFIG_CRYPTO_WP512 is not set
 # CONFIG_CRYPTO_TGR192 is not set
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
 CONFIG_CRYPTO_DES=y
 # CONFIG_CRYPTO_BLOWFISH is not set
 # CONFIG_CRYPTO_TWOFISH is not set
index cd3535e1a09558d323b351fd52b87c7c2831c692..0561b73a918f5c3545f7850e40f1fed7dbea2795 100644 (file)
@@ -1248,7 +1248,7 @@ CONFIG_PARTITION_ADVANCED=y
 # CONFIG_AMIGA_PARTITION is not set
 # CONFIG_ATARI_PARTITION is not set
 # CONFIG_MAC_PARTITION is not set
-# CONFIG_MSDOS_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
 # CONFIG_LDM_PARTITION is not set
 # CONFIG_SGI_PARTITION is not set
 # CONFIG_ULTRIX_PARTITION is not set
index 44175fb7adecc7822dab452201833373eaffddcf..d2833c1a1f3d784f7b0b37302fb9728a64516dea 100644 (file)
@@ -184,6 +184,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_MIGRATION=y
 CONFIG_RESOURCES_64BIT=y
 CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y
+CONFIG_NODES_SPAN_OTHER_NODES=y
 # CONFIG_PPC_64K_PAGES is not set
 CONFIG_SCHED_SMT=y
 CONFIG_PROC_DEVICETREE=y
@@ -506,7 +507,7 @@ CONFIG_SCSI_SAS_ATTRS=m
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
-# CONFIG_ATA is not set
+CONFIG_ATA=y
 # CONFIG_SCSI_HPTIOP is not set
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_DMX3191D is not set
index 47a613cdd775ce11535dbc214886bb446f9437f3..95382f99440475b097420a322031b5293858492a 100644 (file)
@@ -268,7 +268,7 @@ struct cpu_spec     cpu_specs[] = {
                .cpu_user_features      = COMMON_USER_POWER6,
                .icache_bsize           = 128,
                .dcache_bsize           = 128,
-               .num_pmcs               = 8,
+               .num_pmcs               = 6,
                .oprofile_cpu_type      = "ppc64/power6",
                .oprofile_type          = PPC_OPROFILE_POWER4,
                .oprofile_mmcra_sihv    = POWER6_MMCRA_SIHV,
index 124dbcba94a879a96bbe7728a9526172bc691a0d..39db7a3affe11e37f90c310aab469f1f0686827e 100644 (file)
@@ -319,7 +319,7 @@ EXPORT_SYMBOL(ibmebus_unregister_driver);
 
 int ibmebus_request_irq(struct ibmebus_dev *dev,
                        u32 ist, 
-                       irqreturn_t (*handler)(int, void*, struct pt_regs *),
+                       irq_handler_t handler,
                        unsigned long irq_flags, const char * devname,
                        void *dev_id)
 {
index ba0694071728f0fcd2a7af1ce0f27a03b4a68de1..f88a2a675d90f0d63f202e54c8ddafb4e476ebe1 100644 (file)
@@ -75,7 +75,7 @@ static unsigned long iommu_range_alloc(struct iommu_table *tbl,
        /* This allocator was derived from x86_64's bit string search */
 
        /* Sanity check */
-       if (unlikely(npages) == 0) {
+       if (unlikely(npages == 0)) {
                if (printk_ratelimit())
                        WARN_ON(1);
                return DMA_ERROR_CODE;
index c3f58f2f9f525d15fcb12466c6d7321218b2fc80..5e37bf14ef2dba4dd6094923b85bbed7591bbb7f 100644 (file)
@@ -187,6 +187,7 @@ void fixup_irqs(cpumask_t map)
 
 void do_IRQ(struct pt_regs *regs)
 {
+       struct pt_regs *old_regs = set_irq_regs(regs);
        unsigned int irq;
 #ifdef CONFIG_IRQSTACKS
        struct thread_info *curtp, *irqtp;
@@ -216,7 +217,7 @@ void do_IRQ(struct pt_regs *regs)
         * The value -2 is for buggy hardware and means that this IRQ
         * has already been handled. -- Tom
         */
-       irq = ppc_md.get_irq(regs);
+       irq = ppc_md.get_irq();
 
        if (irq != NO_IRQ && irq != NO_IRQ_IGNORE) {
 #ifdef CONFIG_IRQSTACKS
@@ -230,18 +231,19 @@ void do_IRQ(struct pt_regs *regs)
                                handler = &__do_IRQ;
                        irqtp->task = curtp->task;
                        irqtp->flags = 0;
-                       call_handle_irq(irq, desc, regs, irqtp, handler);
+                       call_handle_irq(irq, desc, irqtp, handler);
                        irqtp->task = NULL;
                        if (irqtp->flags)
                                set_bits(irqtp->flags, &curtp->flags);
                } else
 #endif
-                       generic_handle_irq(irq, regs);
+                       generic_handle_irq(irq);
        } else if (irq != NO_IRQ_IGNORE)
                /* That's not SMP safe ... but who cares ? */
                ppc_spurious_interrupts++;
 
         irq_exit();
+       set_irq_regs(old_regs);
 
 #ifdef CONFIG_PPC_ISERIES
        if (get_lppaca()->int_dword.fields.decr_int) {
@@ -570,8 +572,8 @@ unsigned int irq_create_mapping(struct irq_host *host,
 }
 EXPORT_SYMBOL_GPL(irq_create_mapping);
 
-extern unsigned int irq_create_of_mapping(struct device_node *controller,
-                                         u32 *intspec, unsigned int intsize)
+unsigned int irq_create_of_mapping(struct device_node *controller,
+                                  u32 *intspec, unsigned int intsize)
 {
        struct irq_host *host;
        irq_hw_number_t hwirq;
index 41521b30c3cdd36f3a369bf9c8b902b4cb6b22b3..c70e20708a1f625347139f9a7caec7410544266f 100644 (file)
@@ -52,12 +52,12 @@ _GLOBAL(call_do_softirq)
        blr
 
 _GLOBAL(call_handle_irq)
-       ld      r8,0(r7)
+       ld      r8,0(r6)
        mflr    r0
        std     r0,16(r1)
        mtctr   r8
-       stdu    r1,THREAD_SIZE-112(r6)
-       mr      r1,r6
+       stdu    r1,THREAD_SIZE-112(r5)
+       mr      r1,r5
        bctrl
        ld      r1,0(r1)
        ld      r0,16(r1)
index 9b49f8691d29d8a28451e8b4d6d6e858c7cb693f..0d9ff72e28526a7d2f2990388354a5fd37be13ef 100644 (file)
@@ -441,14 +441,14 @@ update_bridge_base(struct pci_bus *bus, int i)
                end = res->end - off;
                io_base_lo = (start >> 8) & PCI_IO_RANGE_MASK;
                io_limit_lo = (end >> 8) & PCI_IO_RANGE_MASK;
-               if (end > 0xffff) {
-                       pci_write_config_word(dev, PCI_IO_BASE_UPPER16,
-                                             start >> 16);
-                       pci_write_config_word(dev, PCI_IO_LIMIT_UPPER16,
-                                             end >> 16);
+               if (end > 0xffff)
                        io_base_lo |= PCI_IO_RANGE_TYPE_32;
-               else
+               else
                        io_base_lo |= PCI_IO_RANGE_TYPE_16;
+               pci_write_config_word(dev, PCI_IO_BASE_UPPER16,
+                               start >> 16);
+               pci_write_config_word(dev, PCI_IO_LIMIT_UPPER16,
+                               end >> 16);
                pci_write_config_byte(dev, PCI_IO_BASE, io_base_lo);
                pci_write_config_byte(dev, PCI_IO_LIMIT, io_limit_lo);
 
index 78d3c0fc8dfbfd1254f77fa44d680c4cdcc27b56..9bae8a5bf671344a6c5dce261272a6159a64a181 100644 (file)
@@ -199,8 +199,14 @@ struct pci_controller * pcibios_alloc_controller(struct device_node *dev)
        pci_setup_pci_controller(phb);
        phb->arch_data = dev;
        phb->is_dynamic = mem_init_done;
-       if (dev)
-               PHB_SET_NODE(phb, of_node_to_nid(dev));
+       if (dev) {
+               int nid = of_node_to_nid(dev);
+
+               if (nid < 0 || !node_online(nid))
+                       nid = -1;
+
+               PHB_SET_NODE(phb, nid);
+       }
        return phb;
 }
 
index 7b2f6452ba7252caa11c377553392446d44c02e0..f3d4dd580dd69fe20a04dd4762866ad0f82d51ea 100644 (file)
@@ -341,13 +341,6 @@ struct task_struct *__switch_to(struct task_struct *prev,
 
 static int instructions_to_print = 16;
 
-#ifdef CONFIG_PPC64
-#define BAD_PC(pc)     ((REGION_ID(pc) != KERNEL_REGION_ID) && \
-                        (REGION_ID(pc) != VMALLOC_REGION_ID))
-#else
-#define BAD_PC(pc)     ((pc) < KERNELBASE)
-#endif
-
 static void show_instructions(struct pt_regs *regs)
 {
        int i;
@@ -366,7 +359,8 @@ static void show_instructions(struct pt_regs *regs)
                 * bad address because the pc *should* only be a
                 * kernel address.
                 */
-               if (BAD_PC(pc) || __get_user(instr, (unsigned int __user *)pc)) {
+               if (!__kernel_text_address(pc) ||
+                    __get_user(instr, (unsigned int __user *)pc)) {
                        printk("XXXXXXXX ");
                } else {
                        if (regs->nip == pc)
index eb913f80bfb1f6540aaad75d584fc2af2646b95f..865b9648d0d57057fe1af797d67d6faea5345459 100644 (file)
@@ -724,7 +724,7 @@ static int __init early_init_dt_scan_chosen(unsigned long node,
                strlcpy(cmd_line, p, min((int)l, COMMAND_LINE_SIZE));
 
 #ifdef CONFIG_CMDLINE
-       if (l == 0 || (l == 1 && (*p) == 0))
+       if (p == NULL || l == 0 || (l == 1 && (*p) == 0))
                strlcpy(cmd_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
 #endif /* CONFIG_CMDLINE */
 
index 6a9bc9ce54e0a2304d5a590659822f95e4aad98a..35c6309bdb76a4dbb97616dbb08f94c2bccb8168 100644 (file)
@@ -115,7 +115,7 @@ void __devinit smp_generic_kick_cpu(int nr)
 }
 #endif
 
-void smp_message_recv(int msg, struct pt_regs *regs)
+void smp_message_recv(int msg)
 {
        switch(msg) {
        case PPC_MSG_CALL_FUNCTION:
@@ -127,11 +127,11 @@ void smp_message_recv(int msg, struct pt_regs *regs)
                break;
        case PPC_MSG_DEBUGGER_BREAK:
                if (crash_ipi_function_ptr) {
-                       crash_ipi_function_ptr(regs);
+                       crash_ipi_function_ptr(get_irq_regs());
                        break;
                }
 #ifdef CONFIG_DEBUGGER
-               debugger_ipi(regs);
+               debugger_ipi(get_irq_regs());
                break;
 #endif /* CONFIG_DEBUGGER */
                /* FALLTHROUGH */
index 85b9244a098c79d76373e4d75eef1cbe54a8a395..5b59bc18dfe7b76586cf10449c120a3e6e8e7f2c 100644 (file)
@@ -51,6 +51,7 @@
 #include <linux/rtc.h>
 #include <linux/jiffies.h>
 #include <linux/posix-timers.h>
+#include <linux/irq.h>
 
 #include <asm/io.h>
 #include <asm/processor.h>
@@ -643,6 +644,7 @@ static void iSeries_tb_recal(void)
  */
 void timer_interrupt(struct pt_regs * regs)
 {
+       struct pt_regs *old_regs;
        int next_dec;
        int cpu = smp_processor_id();
        unsigned long ticks;
@@ -653,9 +655,10 @@ void timer_interrupt(struct pt_regs * regs)
                do_IRQ(regs);
 #endif
 
+       old_regs = set_irq_regs(regs);
        irq_enter();
 
-       profile_tick(CPU_PROFILING, regs);
+       profile_tick(CPU_PROFILING);
        calculate_steal_time();
 
 #ifdef CONFIG_PPC_ISERIES
@@ -703,7 +706,7 @@ void timer_interrupt(struct pt_regs * regs)
 
 #ifdef CONFIG_PPC_ISERIES
        if (hvlpevent_is_pending())
-               process_hvlpevents(regs);
+               process_hvlpevents();
 #endif
 
 #ifdef CONFIG_PPC64
@@ -715,6 +718,7 @@ void timer_interrupt(struct pt_regs * regs)
 #endif
 
        irq_exit();
+       set_irq_regs(old_regs);
 }
 
 void wakeup_decrementer(void)
index d9f10f2fc372b2ebde2bb24dbbb82267383295d7..5ed4c2ceb5caa8632c11f229193afe0596893650 100644 (file)
@@ -900,14 +900,13 @@ void kernel_fp_unavailable_exception(struct pt_regs *regs)
 
 void altivec_unavailable_exception(struct pt_regs *regs)
 {
-#if !defined(CONFIG_ALTIVEC)
        if (user_mode(regs)) {
                /* A user program has executed an altivec instruction,
                   but this kernel doesn't support altivec. */
                _exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
                return;
        }
-#endif
+
        printk(KERN_EMERG "Unrecoverable VMX/Altivec Unavailable Exception "
                        "%lx at %lx\n", regs->trap, regs->nip);
        die("Unrecoverable VMX/Altivec Unavailable Exception", regs, SIGABRT);
index 16fe027bbc12ffb873222dbbdc170d474028ca91..d1c0758c56110628e5cc691263f48d1eda36bbb9 100644 (file)
@@ -307,11 +307,12 @@ void __init paging_init(void)
               top_of_ram, total_ram);
        printk(KERN_DEBUG "Memory hole size: %ldMB\n",
               (top_of_ram - total_ram) >> 20);
+       memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
 #ifdef CONFIG_HIGHMEM
-       max_zone_pfns[0] = total_lowmem >> PAGE_SHIFT;
-       max_zone_pfns[1] = top_of_ram >> PAGE_SHIFT;
+       max_zone_pfns[ZONE_DMA] = total_lowmem >> PAGE_SHIFT;
+       max_zone_pfns[ZONE_HIGHMEM] = top_of_ram >> PAGE_SHIFT;
 #else
-       max_zone_pfns[0] = top_of_ram >> PAGE_SHIFT;
+       max_zone_pfns[ZONE_DMA] = top_of_ram >> PAGE_SHIFT;
 #endif
        free_area_init_nodes(max_zone_pfns);
 }
index 43c272075e1ae8408baa35c8e78a2d831e24312c..9da01dc8cfd9d3fc0722de803d7cfbfb9e0ab573 100644 (file)
@@ -617,9 +617,9 @@ void __init do_init_bootmem(void)
 
 void __init paging_init(void)
 {
-       unsigned long max_zone_pfns[MAX_NR_ZONES] = {
-                               lmb_end_of_DRAM() >> PAGE_SHIFT
-       };
+       unsigned long max_zone_pfns[MAX_NR_ZONES];
+       memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
+       max_zone_pfns[ZONE_DMA] = lmb_end_of_DRAM() >> PAGE_SHIFT;
        free_area_init_nodes(max_zone_pfns);
 }
 
index 89d702de48639182b62544ccddf1d2c6c835f44c..0f5b30dc60da92b097f3e875069ab29281ed22b2 100644 (file)
@@ -11,7 +11,6 @@
  * option) any later version.
  */
 
-#include <linux/config.h>
 #include <linux/stddef.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
index 4276f087f26ef8e8e3f187ddeb8848f9848c1001..bb9acbb98176049545240b81ddf8c70ee2ff68c7 100644 (file)
@@ -12,8 +12,6 @@
  * option) any later version.
  */
 
-
-#include <linux/config.h>
 #include <linux/stddef.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
@@ -384,8 +382,7 @@ struct hw_interrupt_type m82xx_pci_ic = {
 };
 
 static void
-m82xx_pci_irq_demux(unsigned int irq, struct irq_desc *desc,
-                   struct pt_regs *regs)
+m82xx_pci_irq_demux(unsigned int irq, struct irq_desc *desc)
 {
        unsigned long stat, mask, pend;
        int bit;
@@ -398,7 +395,7 @@ m82xx_pci_irq_demux(unsigned int irq, struct irq_desc *desc,
                        break;
                for (bit = 0; pend != 0; ++bit, pend <<= 1) {
                        if (pend & 0x80000000)
-                               __do_IRQ(pci_int_base + bit, regs);
+                               __do_IRQ(pci_int_base + bit);
                }
        }
 }
index a7348213508f0f6251ba0d143740dbf3fad612e3..fb2f92bcd7700d88e22e4c9ab9a5369c5663263c 100644 (file)
@@ -22,8 +22,6 @@
 #ifndef __MACH_ADS8260_DEFS
 #define __MACH_ADS8260_DEFS
 
-#include <linux/config.h>
-
 #include <asm/ppcboot.h>
 
 /* For our show_cpuinfo hooks. */
index 0975e94ac7c469bc416b0f9fab57de41e4ff0a52..7edb6b461382b407203b5c1929ae0fd7e4ba2487 100644 (file)
@@ -32,6 +32,13 @@ config MPC834x_ITX
          Be aware that PCI initialization is the bootloader's
          responsiblilty.
 
+config MPC8360E_PB
+       bool "Freescale MPC8360E PB"
+       select DEFAULT_UIMAGE
+       select QUICC_ENGINE
+       help
+         This option enables support for the MPC836x EMDS Processor Board.
+
 endchoice
 
 config PPC_MPC832x
@@ -46,4 +53,10 @@ config MPC834x
        select PPC_INDIRECT_PCI
        default y if MPC834x_SYS || MPC834x_ITX
 
+config PPC_MPC836x
+       bool
+       select PPC_UDBG_16550
+       select PPC_INDIRECT_PCI
+       default y if MPC8360E_PB
+
 endmenu
index 9387a110d28aa4f410b9f226648c9277e0ca9b07..f1aa7e24a9382de1f18153dca7ce5a4da2c305fe 100644 (file)
@@ -5,3 +5,5 @@ obj-y                           := misc.o
 obj-$(CONFIG_PCI)              += pci.o
 obj-$(CONFIG_MPC834x_SYS)      += mpc834x_sys.o
 obj-$(CONFIG_MPC834x_ITX)      += mpc834x_itx.o
+obj-$(CONFIG_MPC8360E_PB)      += mpc8360e_pb.o
+obj-$(CONFIG_MPC832x_MDS)      += mpc832x_mds.o
index c0191900fc251b974cac3a2b7735768d915a8caa..1a523c81c06e528de4ac67bfe05d384ff054d6f5 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/root_dev.h>
 #include <linux/initrd.h>
 
+#include <asm/of_device.h>
 #include <asm/system.h>
 #include <asm/atomic.h>
 #include <asm/time.h>
@@ -141,6 +142,24 @@ static void __init mpc8360_sys_setup_arch(void)
 #endif
 }
 
+static int __init mpc8360_declare_of_platform_devices(void)
+{
+       struct device_node *np;
+
+       for (np = NULL; (np = of_find_compatible_node(np, "network",
+                                       "ucc_geth")) != NULL;) {
+               int ucc_num;
+               char bus_id[BUS_ID_SIZE];
+
+               ucc_num = *((uint *) get_property(np, "device-id", NULL)) - 1;
+               snprintf(bus_id, BUS_ID_SIZE, "ucc_geth.%u", ucc_num);
+               of_platform_device_create(np, bus_id, NULL);
+       }
+
+       return 0;
+}
+device_initcall(mpc8360_declare_of_platform_devices);
+
 void __init mpc8360_sys_init_IRQ(void)
 {
 
index 28070e7ae5074fc36ee52929358b831ddcc8affd..d3e669d69c735c2f0dfbfed753784378942129d5 100644 (file)
@@ -66,13 +66,12 @@ mpc85xx_pcibios_fixup(void)
 
 #ifdef CONFIG_CPM2
 
-static void cpm2_cascade(unsigned int irq, struct irq_desc *desc,
-                        struct pt_regs *regs)
+static void cpm2_cascade(unsigned int irq, struct irq_desc *desc)
 {
        int cascade_irq;
 
-       while ((cascade_irq = cpm2_get_irq(regs)) >= 0) {
-               generic_handle_irq(cascade_irq, regs);
+       while ((cascade_irq = cpm2_get_irq()) >= 0) {
+               generic_handle_irq(cascade_irq);
        }
        desc->chip->eoi(irq);
 }
index 193a5d7921b5fc85be01ae26b61db84a34bc50c4..953cd5dd3f54df1fff74edd4c5253e7ec40182b4 100644 (file)
@@ -132,13 +132,12 @@ mpc85xx_cds_pcibios_fixup(void)
 
 #ifdef CONFIG_PPC_I8259
 #warning The i8259 PIC support is currently broken
-static void mpc85xx_8259_cascade(unsigned int irq, struct
-               irq_desc *desc, struct pt_regs *regs)
+static void mpc85xx_8259_cascade(unsigned int irq, struct irq_desc *desc)
 {
-       unsigned int cascade_irq = i8259_irq(regs);
+       unsigned int cascade_irq = i8259_irq();
 
        if (cascade_irq != NO_IRQ)
-               generic_handle_irq(cascade_irq, regs);
+               generic_handle_irq(cascade_irq);
 
        desc->chip->eoi(irq);
 }
@@ -150,8 +149,10 @@ void __init mpc85xx_cds_pic_init(void)
        struct mpic *mpic;
        struct resource r;
        struct device_node *np = NULL;
+#ifdef CONFIG_PPC_I8259
        struct device_node *cascade_node = NULL;
        int cascade_irq;
+#endif
 
        np = of_find_node_by_type(np, "open-pic");
 
index b637e8157f7b8c8df596b793831a9397d859e14a..1a1c226ad4d960a76ddc076224b5944f99370938 100644 (file)
@@ -53,12 +53,11 @@ unsigned long pci_dram_offset = 0;
 
 
 #ifdef CONFIG_PCI
-static void mpc86xx_8259_cascade(unsigned int irq, struct irq_desc *desc,
-                                struct pt_regs *regs)
+static void mpc86xx_8259_cascade(unsigned int irq, struct irq_desc *desc)
 {
-       unsigned int cascade_irq = i8259_irq(regs);
+       unsigned int cascade_irq = i8259_irq();
        if (cascade_irq != NO_IRQ)
-               generic_handle_irq(cascade_irq, regs);
+               generic_handle_irq(cascade_irq);
        desc->chip->eoi(irq);
 }
 #endif /* CONFIG_PCI */
index 0c8c7b6ab897657866c37212195f87acba59a860..3e430b489bb7540414022caee7099771357f5ccf 100644 (file)
@@ -16,11 +16,6 @@ config SPU_BASE
        bool
        default n
 
-config SPUFS_MMAP
-       bool
-       depends on SPU_FS && SPARSEMEM
-       default y
-
 config CBE_RAS
        bool "RAS features for bare metal Cell BE"
        default y
index 6cc59e0b458221575d6af8fbcf10b2da71cf8c6d..a914c12b4060a2072d77a7bfc08e7c18c3265467 100644 (file)
@@ -98,10 +98,9 @@ static void iic_ioexc_eoi(unsigned int irq)
 {
 }
 
-static void iic_ioexc_cascade(unsigned int irq, struct irq_desc *desc,
-                           struct pt_regs *regs)
+static void iic_ioexc_cascade(unsigned int irq, struct irq_desc *desc)
 {
-       struct cbe_iic_regs *node_iic = desc->handler_data;
+       struct cbe_iic_regs __iomem *node_iic = (void __iomem *)desc->handler_data;
        unsigned int base = (irq & 0xffffff00) | IIC_IRQ_TYPE_IOEXC;
        unsigned long bits, ack;
        int cascade;
@@ -121,7 +120,7 @@ static void iic_ioexc_cascade(unsigned int irq, struct irq_desc *desc,
                                        irq_linear_revmap(iic_host,
                                                          base | cascade);
                                if (cirq != NO_IRQ)
-                                       generic_handle_irq(cirq, regs);
+                                       generic_handle_irq(cirq);
                        }
                /* post-ack level interrupts */
                ack = bits & ~IIC_ISR_EDGE_MASK;
@@ -140,7 +139,7 @@ static struct irq_chip iic_ioexc_chip = {
 };
 
 /* Get an IRQ number from the pending state register of the IIC */
-static unsigned int iic_get_irq(struct pt_regs *regs)
+static unsigned int iic_get_irq(void)
 {
        struct cbe_iic_pending_bits pending;
        struct iic *iic;
@@ -190,11 +189,11 @@ struct irq_host *iic_get_irq_host(int node)
 EXPORT_SYMBOL_GPL(iic_get_irq_host);
 
 
-static irqreturn_t iic_ipi_action(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t iic_ipi_action(int irq, void *dev_id)
 {
        int ipi = (int)(long)dev_id;
 
-       smp_message_recv(ipi, regs);
+       smp_message_recv(ipi);
 
        return IRQ_HANDLED;
 }
@@ -320,7 +319,7 @@ static int __init setup_iic(void)
        struct device_node *dn;
        struct resource r0, r1;
        unsigned int node, cascade, found = 0;
-       struct cbe_iic_regs *node_iic;
+       struct cbe_iic_regs __iomem *node_iic;
        const u32 *np;
 
        for (dn = NULL;
@@ -357,7 +356,11 @@ static int __init setup_iic(void)
                cascade = irq_create_mapping(iic_host, cascade);
                if (cascade == NO_IRQ)
                        continue;
-               set_irq_data(cascade, node_iic);
+               /*
+                * irq_data is a generic pointer that gets passed back
+                * to us later, so the forced cast is fine.
+                */
+               set_irq_data(cascade, (void __force *)node_iic);
                set_irq_chained_handler(cascade , iic_ioexc_cascade);
                out_be64(&node_iic->iic_ir,
                         (1 << 12)              /* priority */ |
index d2b20eba5b87270d21ca78ea2b892bbf361c8aff..aca4c3db0dde3431b3ff96eb0567442641a42f65 100644 (file)
@@ -345,8 +345,8 @@ static int cell_map_iommu_hardcoded(int num_nodes)
 
        /* node 0 */
        iommu = &cell_iommus[0];
-       iommu->mapped_base = ioremap(0x20000511000, 0x1000);
-       iommu->mapped_mmio_base = ioremap(0x20000510000, 0x1000);
+       iommu->mapped_base = ioremap(0x20000511000ul, 0x1000);
+       iommu->mapped_mmio_base = ioremap(0x20000510000ul, 0x1000);
 
        enable_mapping(iommu->mapped_base, iommu->mapped_mmio_base);
 
@@ -358,8 +358,8 @@ static int cell_map_iommu_hardcoded(int num_nodes)
 
        /* node 1 */
        iommu = &cell_iommus[1];
-       iommu->mapped_base = ioremap(0x30000511000, 0x1000);
-       iommu->mapped_mmio_base = ioremap(0x30000510000, 0x1000);
+       iommu->mapped_base = ioremap(0x30000511000ul, 0x1000);
+       iommu->mapped_mmio_base = ioremap(0x30000510000ul, 0x1000);
 
        enable_mapping(iommu->mapped_base, iommu->mapped_mmio_base);
 
index 608b1ebc56b28e142a170e22eabe0c8c22a41f14..21a9ebd4978e332cfc9218760877059eb6235766 100644 (file)
@@ -213,8 +213,7 @@ static struct irq_host_ops spider_host_ops = {
        .xlate = spider_host_xlate,
 };
 
-static void spider_irq_cascade(unsigned int irq, struct irq_desc *desc,
-                              struct pt_regs *regs)
+static void spider_irq_cascade(unsigned int irq, struct irq_desc *desc)
 {
        struct spider_pic *pic = desc->handler_data;
        unsigned int cs, virq;
@@ -225,7 +224,7 @@ static void spider_irq_cascade(unsigned int irq, struct irq_desc *desc,
        else
                virq = irq_linear_revmap(pic->host, cs);
        if (virq != NO_IRQ)
-               generic_handle_irq(virq, regs);
+               generic_handle_irq(virq);
        desc->chip->eoi(irq);
 }
 
@@ -244,7 +243,6 @@ static unsigned int __init spider_find_cascade_and_node(struct spider_pic *pic)
        int imaplen, intsize, unit;
        struct device_node *iic;
 
-#if 0 /* Enable that when we have a way to retreive the node as well */
        /* First, we check wether we have a real "interrupts" in the device
         * tree in case the device-tree is ever fixed
         */
@@ -252,9 +250,8 @@ static unsigned int __init spider_find_cascade_and_node(struct spider_pic *pic)
        if (of_irq_map_one(pic->of_node, 0, &oirq) == 0) {
                virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
                                             oirq.size);
-               goto bail;
+               return virq;
        }
-#endif
 
        /* Now do the horrible hacks */
        tmp = get_property(pic->of_node, "#interrupt-cells", NULL);
@@ -369,7 +366,7 @@ void __init spider_init_IRQ(void)
                } else if (device_is_compatible(dn, "sti,platform-spider-pic")
                           && (chip < 2)) {
                        static long hard_coded_pics[] =
-                               { 0x24000008000, 0x34000008000 };
+                               { 0x24000008000ul, 0x34000008000ul};
                        r.start = hard_coded_pics[chip];
                } else
                        continue;
index f78680346e5fe0dc72fbe4ba70dd2c4152332da1..d0fb959e3ef113b117d4972c373067baab96aa29 100644 (file)
 #include <linux/interrupt.h>
 #include <linux/list.h>
 #include <linux/module.h>
+#include <linux/pci.h>
 #include <linux/poll.h>
 #include <linux/ptrace.h>
 #include <linux/slab.h>
 #include <linux/wait.h>
 
+#include <asm/firmware.h>
 #include <asm/io.h>
 #include <asm/prom.h>
 #include <linux/mutex.h>
@@ -46,21 +48,21 @@ EXPORT_SYMBOL_GPL(spu_priv1_ops);
 static int __spu_trap_invalid_dma(struct spu *spu)
 {
        pr_debug("%s\n", __FUNCTION__);
-       force_sig(SIGBUS, /* info, */ current);
+       spu->dma_callback(spu, SPE_EVENT_INVALID_DMA);
        return 0;
 }
 
 static int __spu_trap_dma_align(struct spu *spu)
 {
        pr_debug("%s\n", __FUNCTION__);
-       force_sig(SIGBUS, /* info, */ current);
+       spu->dma_callback(spu, SPE_EVENT_DMA_ALIGNMENT);
        return 0;
 }
 
 static int __spu_trap_error(struct spu *spu)
 {
        pr_debug("%s\n", __FUNCTION__);
-       force_sig(SIGILL, /* info, */ current);
+       spu->dma_callback(spu, SPE_EVENT_SPE_ERROR);
        return 0;
 }
 
@@ -145,7 +147,7 @@ static int __spu_trap_data_map(struct spu *spu, unsigned long ea, u64 dsisr)
 }
 
 static irqreturn_t
-spu_irq_class_0(int irq, void *data, struct pt_regs *regs)
+spu_irq_class_0(int irq, void *data)
 {
        struct spu *spu;
 
@@ -184,7 +186,7 @@ spu_irq_class_0_bottom(struct spu *spu)
 EXPORT_SYMBOL_GPL(spu_irq_class_0_bottom);
 
 static irqreturn_t
-spu_irq_class_1(int irq, void *data, struct pt_regs *regs)
+spu_irq_class_1(int irq, void *data)
 {
        struct spu *spu;
        unsigned long stat, mask, dar, dsisr;
@@ -222,7 +224,7 @@ spu_irq_class_1(int irq, void *data, struct pt_regs *regs)
 EXPORT_SYMBOL_GPL(spu_irq_class_1_bottom);
 
 static irqreturn_t
-spu_irq_class_2(int irq, void *data, struct pt_regs *regs)
+spu_irq_class_2(int irq, void *data)
 {
        struct spu *spu;
        unsigned long stat;
@@ -317,7 +319,7 @@ static void spu_free_irqs(struct spu *spu)
                free_irq(spu->irqs[2], spu);
 }
 
-static LIST_HEAD(spu_list);
+static struct list_head spu_list[MAX_NUMNODES];
 static DEFINE_MUTEX(spu_mutex);
 
 static void spu_init_channels(struct spu *spu)
@@ -354,32 +356,42 @@ static void spu_init_channels(struct spu *spu)
        }
 }
 
-struct spu *spu_alloc(void)
+struct spu *spu_alloc_node(int node)
 {
-       struct spu *spu;
+       struct spu *spu = NULL;
 
        mutex_lock(&spu_mutex);
-       if (!list_empty(&spu_list)) {
-               spu = list_entry(spu_list.next, struct spu, list);
+       if (!list_empty(&spu_list[node])) {
+               spu = list_entry(spu_list[node].next, struct spu, list);
                list_del_init(&spu->list);
-               pr_debug("Got SPU %x %d\n", spu->isrc, spu->number);
-       } else {
-               pr_debug("No SPU left\n");
-               spu = NULL;
+               pr_debug("Got SPU %x %d %d\n",
+                        spu->isrc, spu->number, spu->node);
+               spu_init_channels(spu);
        }
        mutex_unlock(&spu_mutex);
 
-       if (spu)
-               spu_init_channels(spu);
+       return spu;
+}
+EXPORT_SYMBOL_GPL(spu_alloc_node);
+
+struct spu *spu_alloc(void)
+{
+       struct spu *spu = NULL;
+       int node;
+
+       for (node = 0; node < MAX_NUMNODES; node++) {
+               spu = spu_alloc_node(node);
+               if (spu)
+                       break;
+       }
 
        return spu;
 }
-EXPORT_SYMBOL_GPL(spu_alloc);
 
 void spu_free(struct spu *spu)
 {
        mutex_lock(&spu_mutex);
-       list_add_tail(&spu->list, &spu_list);
+       list_add_tail(&spu->list, &spu_list[spu->node]);
        mutex_unlock(&spu_mutex);
 }
 EXPORT_SYMBOL_GPL(spu_free);
@@ -566,7 +578,7 @@ static void spu_unmap(struct spu *spu)
 }
 
 /* This function shall be abstracted for HV platforms */
-static int __init spu_map_interrupts(struct spu *spu, struct device_node *np)
+static int __init spu_map_interrupts_old(struct spu *spu, struct device_node *np)
 {
        unsigned int isrc;
        const u32 *tmp;
@@ -590,7 +602,7 @@ static int __init spu_map_interrupts(struct spu *spu, struct device_node *np)
        return spu->irqs[2] == NO_IRQ ? -EINVAL : 0;
 }
 
-static int __init spu_map_device(struct spu *spu, struct device_node *node)
+static int __init spu_map_device_old(struct spu *spu, struct device_node *node)
 {
        const char *prop;
        int ret;
@@ -635,6 +647,88 @@ out:
        return ret;
 }
 
+static int __init spu_map_interrupts(struct spu *spu, struct device_node *np)
+{
+       struct of_irq oirq;
+       int ret;
+       int i;
+
+       for (i=0; i < 3; i++) {
+               ret = of_irq_map_one(np, i, &oirq);
+               if (ret)
+                       goto err;
+
+               ret = -EINVAL;
+               spu->irqs[i] = irq_create_of_mapping(oirq.controller,
+                                       oirq.specifier, oirq.size);
+               if (spu->irqs[i] == NO_IRQ)
+                       goto err;
+       }
+       return 0;
+
+err:
+       pr_debug("failed to map irq %x for spu %s\n", *oirq.specifier, spu->name);
+       for (; i >= 0; i--) {
+               if (spu->irqs[i] != NO_IRQ)
+                       irq_dispose_mapping(spu->irqs[i]);
+       }
+       return ret;
+}
+
+static int spu_map_resource(struct device_node *node, int nr,
+               void __iomem** virt, unsigned long *phys)
+{
+       struct resource resource = { };
+       int ret;
+
+       ret = of_address_to_resource(node, 0, &resource);
+       if (ret)
+               goto out;
+
+       if (phys)
+               *phys = resource.start;
+       *virt = ioremap(resource.start, resource.end - resource.start);
+       if (!*virt)
+               ret = -EINVAL;
+
+out:
+       return ret;
+}
+
+static int __init spu_map_device(struct spu *spu, struct device_node *node)
+{
+       int ret = -ENODEV;
+       spu->name = get_property(node, "name", NULL);
+       if (!spu->name)
+               goto out;
+
+       ret = spu_map_resource(node, 0, (void __iomem**)&spu->local_store,
+                                       &spu->local_store_phys);
+       if (ret)
+               goto out;
+       ret = spu_map_resource(node, 1, (void __iomem**)&spu->problem,
+                                       &spu->problem_phys);
+       if (ret)
+               goto out_unmap;
+       ret = spu_map_resource(node, 2, (void __iomem**)&spu->priv2,
+                                       NULL);
+       if (ret)
+               goto out_unmap;
+
+       if (!firmware_has_feature(FW_FEATURE_LPAR))
+               ret = spu_map_resource(node, 3, (void __iomem**)&spu->priv1,
+                                       NULL);
+       if (ret)
+               goto out_unmap;
+       return 0;
+
+out_unmap:
+       spu_unmap(spu);
+out:
+       pr_debug("failed to map spe %s: %d\n", spu->name, ret);
+       return ret;
+}
+
 struct sysdev_class spu_sysdev_class = {
        set_kset_name("spu")
 };
@@ -687,15 +781,27 @@ static int __init create_spu(struct device_node *spe)
        if (!spu)
                goto out;
 
-       ret = spu_map_device(spu, spe);
-       if (ret)
-               goto out_free;
-
        spu->node = find_spu_node_id(spe);
+       if (spu->node >= MAX_NUMNODES) {
+               printk(KERN_WARNING "SPE %s on node %d ignored,"
+                      " node number too big\n", spe->full_name, spu->node);
+               printk(KERN_WARNING "Check if CONFIG_NUMA is enabled.\n");
+               return -ENODEV;
+       }
        spu->nid = of_node_to_nid(spe);
        if (spu->nid == -1)
                spu->nid = 0;
+
+       ret = spu_map_device(spu, spe);
+       /* try old method */
+       if (ret)
+               ret = spu_map_device_old(spu, spe);
+       if (ret)
+               goto out_free;
+
        ret = spu_map_interrupts(spu, spe);
+       if (ret)
+               ret = spu_map_interrupts_old(spu, spe);
        if (ret)
                goto out_unmap;
        spin_lock_init(&spu->register_lock);
@@ -706,13 +812,13 @@ static int __init create_spu(struct device_node *spe)
        spu->number = number++;
        ret = spu_request_irqs(spu);
        if (ret)
-               goto out_unmap;
+               goto out_unlock;
 
        ret = spu_create_sysdev(spu);
        if (ret)
                goto out_free_irqs;
 
-       list_add(&spu->list, &spu_list);
+       list_add(&spu->list, &spu_list[spu->node]);
        mutex_unlock(&spu_mutex);
 
        pr_debug(KERN_DEBUG "Using SPE %s %02x %p %p %p %p %d\n",
@@ -722,9 +828,9 @@ static int __init create_spu(struct device_node *spe)
 
 out_free_irqs:
        spu_free_irqs(spu);
-
-out_unmap:
+out_unlock:
        mutex_unlock(&spu_mutex);
+out_unmap:
        spu_unmap(spu);
 out_free:
        kfree(spu);
@@ -745,9 +851,13 @@ static void destroy_spu(struct spu *spu)
 static void cleanup_spu_base(void)
 {
        struct spu *spu, *tmp;
+       int node;
+
        mutex_lock(&spu_mutex);
-       list_for_each_entry_safe(spu, tmp, &spu_list, list)
-               destroy_spu(spu);
+       for (node = 0; node < MAX_NUMNODES; node++) {
+               list_for_each_entry_safe(spu, tmp, &spu_list[node], list)
+                       destroy_spu(spu);
+       }
        mutex_unlock(&spu_mutex);
        sysdev_class_unregister(&spu_sysdev_class);
 }
@@ -756,13 +866,16 @@ module_exit(cleanup_spu_base);
 static int __init init_spu_base(void)
 {
        struct device_node *node;
-       int ret;
+       int i, ret;
 
        /* create sysdev class for spus */
        ret = sysdev_class_register(&spu_sysdev_class);
        if (ret)
                return ret;
 
+       for (i = 0; i < MAX_NUMNODES; i++)
+               INIT_LIST_HEAD(&spu_list[i]);
+
        ret = -ENODEV;
        for (node = of_find_node_by_type(NULL, "spe");
                        node; node = of_find_node_by_type(node, "spe")) {
@@ -774,18 +887,6 @@ static int __init init_spu_base(void)
                        break;
                }
        }
-       /* in some old firmware versions, the spe is called 'spc', so we
-          look for that as well */
-       for (node = of_find_node_by_type(NULL, "spc");
-                       node; node = of_find_node_by_type(node, "spc")) {
-               ret = create_spu(node);
-               if (ret) {
-                       printk(KERN_WARNING "%s: Error initializing %s\n",
-                               __FUNCTION__, node->name);
-                       cleanup_spu_base();
-                       break;
-               }
-       }
        return ret;
 }
 module_init(init_spu_base);
index bb5dc634272cd7de994afa3f01b4de756ae19e7b..ecdfbb35f82e9ab6af69ba850edfd53268e53139 100644 (file)
@@ -2,7 +2,7 @@ obj-y += switch.o
 
 obj-$(CONFIG_SPU_FS) += spufs.o
 spufs-y += inode.o file.o context.o syscalls.o
-spufs-y += sched.o backing_ops.o hw_ops.o run.o
+spufs-y += sched.o backing_ops.o hw_ops.o run.o gang.o
 
 # Rules to build switch.o with the help of SPU tool chain
 SPU_CROSS      := spu-
index 36439c5e9f2d80ba0c27415cae29dbb1d0af34ee..034cf6af53a2f6df6783710d74bbefeeca863fe1 100644 (file)
@@ -27,7 +27,7 @@
 #include <asm/spu_csa.h>
 #include "spufs.h"
 
-struct spu_context *alloc_spu_context(void)
+struct spu_context *alloc_spu_context(struct spu_gang *gang)
 {
        struct spu_context *ctx;
        ctx = kzalloc(sizeof *ctx, GFP_KERNEL);
@@ -51,6 +51,8 @@ struct spu_context *alloc_spu_context(void)
        ctx->state = SPU_STATE_SAVED;
        ctx->ops = &spu_backing_ops;
        ctx->owner = get_task_mm(current);
+       if (gang)
+               spu_gang_add_ctx(gang, ctx);
        goto out;
 out_free:
        kfree(ctx);
@@ -67,6 +69,8 @@ void destroy_spu_context(struct kref *kref)
        spu_deactivate(ctx);
        up_write(&ctx->state_sema);
        spu_fini_csa(&ctx->csa);
+       if (ctx->gang)
+               spu_gang_remove_ctx(ctx->gang, ctx);
        kfree(ctx);
 }
 
index 51fd197ab5dd1f98ac9f1bfbab25ef7b6f839ad4..0de8e114e6b68355b26c2f2ef4de546367792dbc 100644 (file)
@@ -36,6 +36,8 @@
 
 #include "spufs.h"
 
+#define SPUFS_MMAP_4K (PAGE_SIZE == 0x1000)
+
 
 static int
 spufs_mem_open(struct inode *inode, struct file *file)
@@ -88,7 +90,6 @@ spufs_mem_write(struct file *file, const char __user *buffer,
        return ret;
 }
 
-#ifdef CONFIG_SPUFS_MMAP
 static struct page *
 spufs_mem_mmap_nopage(struct vm_area_struct *vma,
                      unsigned long address, int *type)
@@ -101,12 +102,16 @@ spufs_mem_mmap_nopage(struct vm_area_struct *vma,
 
        spu_acquire(ctx);
 
-       if (ctx->state == SPU_STATE_SAVED)
+       if (ctx->state == SPU_STATE_SAVED) {
+               vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot)
+                                       & ~(_PAGE_NO_CACHE | _PAGE_GUARDED));
                page = vmalloc_to_page(ctx->csa.lscsa->ls + offset);
-       else
+       } else {
+               vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot)
+                                       | _PAGE_NO_CACHE | _PAGE_GUARDED);
                page = pfn_to_page((ctx->spu->local_store_phys + offset)
                                   >> PAGE_SHIFT);
-
+       }
        spu_release(ctx);
 
        if (type)
@@ -133,22 +138,19 @@ spufs_mem_mmap(struct file *file, struct vm_area_struct *vma)
        vma->vm_ops = &spufs_mem_mmap_vmops;
        return 0;
 }
-#endif
 
 static struct file_operations spufs_mem_fops = {
        .open    = spufs_mem_open,
        .read    = spufs_mem_read,
        .write   = spufs_mem_write,
        .llseek  = generic_file_llseek,
-#ifdef CONFIG_SPUFS_MMAP
        .mmap    = spufs_mem_mmap,
-#endif
 };
 
-#ifdef CONFIG_SPUFS_MMAP
 static struct page *spufs_ps_nopage(struct vm_area_struct *vma,
                                    unsigned long address,
-                                   int *type, unsigned long ps_offs)
+                                   int *type, unsigned long ps_offs,
+                                   unsigned long ps_size)
 {
        struct page *page = NOPAGE_SIGBUS;
        int fault_type = VM_FAULT_SIGBUS;
@@ -158,7 +160,7 @@ static struct page *spufs_ps_nopage(struct vm_area_struct *vma,
        int ret;
 
        offset += vma->vm_pgoff << PAGE_SHIFT;
-       if (offset >= 0x4000)
+       if (offset >= ps_size)
                goto out;
 
        ret = spu_acquire_runnable(ctx);
@@ -179,10 +181,11 @@ static struct page *spufs_ps_nopage(struct vm_area_struct *vma,
        return page;
 }
 
+#if SPUFS_MMAP_4K
 static struct page *spufs_cntl_mmap_nopage(struct vm_area_struct *vma,
                                           unsigned long address, int *type)
 {
-       return spufs_ps_nopage(vma, address, type, 0x4000);
+       return spufs_ps_nopage(vma, address, type, 0x4000, 0x1000);
 }
 
 static struct vm_operations_struct spufs_cntl_mmap_vmops = {
@@ -191,17 +194,12 @@ static struct vm_operations_struct spufs_cntl_mmap_vmops = {
 
 /*
  * mmap support for problem state control area [0x4000 - 0x4fff].
- * Mapping this area requires that the application have CAP_SYS_RAWIO,
- * as these registers require special care when read/writing.
  */
 static int spufs_cntl_mmap(struct file *file, struct vm_area_struct *vma)
 {
        if (!(vma->vm_flags & VM_SHARED))
                return -EINVAL;
 
-       if (!capable(CAP_SYS_RAWIO))
-               return -EPERM;
-
        vma->vm_flags |= VM_RESERVED;
        vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot)
                                     | _PAGE_NO_CACHE | _PAGE_GUARDED);
@@ -209,42 +207,49 @@ static int spufs_cntl_mmap(struct file *file, struct vm_area_struct *vma)
        vma->vm_ops = &spufs_cntl_mmap_vmops;
        return 0;
 }
-#endif
+#else /* SPUFS_MMAP_4K */
+#define spufs_cntl_mmap NULL
+#endif /* !SPUFS_MMAP_4K */
 
-static int spufs_cntl_open(struct inode *inode, struct file *file)
+static u64 spufs_cntl_get(void *data)
 {
-       struct spufs_inode_info *i = SPUFS_I(inode);
-       struct spu_context *ctx = i->i_ctx;
+       struct spu_context *ctx = data;
+       u64 val;
 
-       file->private_data = ctx;
-       file->f_mapping = inode->i_mapping;
-       ctx->cntl = inode->i_mapping;
-       return 0;
+       spu_acquire(ctx);
+       val = ctx->ops->status_read(ctx);
+       spu_release(ctx);
+
+       return val;
 }
 
-static ssize_t
-spufs_cntl_read(struct file *file, char __user *buffer,
-               size_t size, loff_t *pos)
+static void spufs_cntl_set(void *data, u64 val)
 {
-       /* FIXME: read from spu status */
-       return -EINVAL;
+       struct spu_context *ctx = data;
+
+       spu_acquire(ctx);
+       ctx->ops->runcntl_write(ctx, val);
+       spu_release(ctx);
 }
 
-static ssize_t
-spufs_cntl_write(struct file *file, const char __user *buffer,
-                size_t size, loff_t *pos)
+static int spufs_cntl_open(struct inode *inode, struct file *file)
 {
-       /* FIXME: write to runctl bit */
-       return -EINVAL;
+       struct spufs_inode_info *i = SPUFS_I(inode);
+       struct spu_context *ctx = i->i_ctx;
+
+       file->private_data = ctx;
+       file->f_mapping = inode->i_mapping;
+       ctx->cntl = inode->i_mapping;
+       return simple_attr_open(inode, file, spufs_cntl_get,
+                                       spufs_cntl_set, "0x%08lx");
 }
 
 static struct file_operations spufs_cntl_fops = {
        .open = spufs_cntl_open,
-       .read = spufs_cntl_read,
-       .write = spufs_cntl_write,
-#ifdef CONFIG_SPUFS_MMAP
+       .release = simple_attr_close,
+       .read = simple_attr_read,
+       .write = simple_attr_write,
        .mmap = spufs_cntl_mmap,
-#endif
 };
 
 static int
@@ -356,27 +361,54 @@ static int spufs_pipe_open(struct inode *inode, struct file *file)
        return nonseekable_open(inode, file);
 }
 
+/*
+ * Read as many bytes from the mailbox as possible, until
+ * one of the conditions becomes true:
+ *
+ * - no more data available in the mailbox
+ * - end of the user provided buffer
+ * - end of the mapped area
+ */
 static ssize_t spufs_mbox_read(struct file *file, char __user *buf,
                        size_t len, loff_t *pos)
 {
        struct spu_context *ctx = file->private_data;
-       u32 mbox_data;
-       int ret;
+       u32 mbox_data, __user *udata;
+       ssize_t count;
 
        if (len < 4)
                return -EINVAL;
 
+       if (!access_ok(VERIFY_WRITE, buf, len))
+               return -EFAULT;
+
+       udata = (void __user *)buf;
+
        spu_acquire(ctx);
-       ret = ctx->ops->mbox_read(ctx, &mbox_data);
+       for (count = 0; count <= len; count += 4, udata++) {
+               int ret;
+               ret = ctx->ops->mbox_read(ctx, &mbox_data);
+               if (ret == 0)
+                       break;
+
+               /*
+                * at the end of the mapped area, we can fault
+                * but still need to return the data we have
+                * read successfully so far.
+                */
+               ret = __put_user(mbox_data, udata);
+               if (ret) {
+                       if (!count)
+                               count = -EFAULT;
+                       break;
+               }
+       }
        spu_release(ctx);
 
-       if (!ret)
-               return -EAGAIN;
-
-       if (copy_to_user(buf, &mbox_data, sizeof mbox_data))
-               return -EFAULT;
+       if (!count)
+               count = -EAGAIN;
 
-       return 4;
+       return count;
 }
 
 static struct file_operations spufs_mbox_fops = {
@@ -432,36 +464,70 @@ void spufs_ibox_callback(struct spu *spu)
        kill_fasync(&ctx->ibox_fasync, SIGIO, POLLIN);
 }
 
+/*
+ * Read as many bytes from the interrupt mailbox as possible, until
+ * one of the conditions becomes true:
+ *
+ * - no more data available in the mailbox
+ * - end of the user provided buffer
+ * - end of the mapped area
+ *
+ * If the file is opened without O_NONBLOCK, we wait here until
+ * any data is available, but return when we have been able to
+ * read something.
+ */
 static ssize_t spufs_ibox_read(struct file *file, char __user *buf,
                        size_t len, loff_t *pos)
 {
        struct spu_context *ctx = file->private_data;
-       u32 ibox_data;
-       ssize_t ret;
+       u32 ibox_data, __user *udata;
+       ssize_t count;
 
        if (len < 4)
                return -EINVAL;
 
+       if (!access_ok(VERIFY_WRITE, buf, len))
+               return -EFAULT;
+
+       udata = (void __user *)buf;
+
        spu_acquire(ctx);
 
-       ret = 0;
+       /* wait only for the first element */
+       count = 0;
        if (file->f_flags & O_NONBLOCK) {
                if (!spu_ibox_read(ctx, &ibox_data))
-                       ret = -EAGAIN;
+                       count = -EAGAIN;
        } else {
-               ret = spufs_wait(ctx->ibox_wq, spu_ibox_read(ctx, &ibox_data));
+               count = spufs_wait(ctx->ibox_wq, spu_ibox_read(ctx, &ibox_data));
        }
+       if (count)
+               goto out;
 
-       spu_release(ctx);
+       /* if we can't write at all, return -EFAULT */
+       count = __put_user(ibox_data, udata);
+       if (count)
+               goto out;
 
-       if (ret)
-               return ret;
+       for (count = 4, udata++; (count + 4) <= len; count += 4, udata++) {
+               int ret;
+               ret = ctx->ops->ibox_read(ctx, &ibox_data);
+               if (ret == 0)
+                       break;
+               /*
+                * at the end of the mapped area, we can fault
+                * but still need to return the data we have
+                * read successfully so far.
+                */
+               ret = __put_user(ibox_data, udata);
+               if (ret)
+                       break;
+       }
 
-       ret = 4;
-       if (copy_to_user(buf, &ibox_data, sizeof ibox_data))
-               ret = -EFAULT;
+out:
+       spu_release(ctx);
 
-       return ret;
+       return count;
 }
 
 static unsigned int spufs_ibox_poll(struct file *file, poll_table *wait)
@@ -534,32 +600,67 @@ void spufs_wbox_callback(struct spu *spu)
        kill_fasync(&ctx->wbox_fasync, SIGIO, POLLOUT);
 }
 
+/*
+ * Write as many bytes to the interrupt mailbox as possible, until
+ * one of the conditions becomes true:
+ *
+ * - the mailbox is full
+ * - end of the user provided buffer
+ * - end of the mapped area
+ *
+ * If the file is opened without O_NONBLOCK, we wait here until
+ * space is availabyl, but return when we have been able to
+ * write something.
+ */
 static ssize_t spufs_wbox_write(struct file *file, const char __user *buf,
                        size_t len, loff_t *pos)
 {
        struct spu_context *ctx = file->private_data;
-       u32 wbox_data;
-       int ret;
+       u32 wbox_data, __user *udata;
+       ssize_t count;
 
        if (len < 4)
                return -EINVAL;
 
-       if (copy_from_user(&wbox_data, buf, sizeof wbox_data))
+       udata = (void __user *)buf;
+       if (!access_ok(VERIFY_READ, buf, len))
+               return -EFAULT;
+
+       if (__get_user(wbox_data, udata))
                return -EFAULT;
 
        spu_acquire(ctx);
 
-       ret = 0;
+       /*
+        * make sure we can at least write one element, by waiting
+        * in case of !O_NONBLOCK
+        */
+       count = 0;
        if (file->f_flags & O_NONBLOCK) {
                if (!spu_wbox_write(ctx, wbox_data))
-                       ret = -EAGAIN;
+                       count = -EAGAIN;
        } else {
-               ret = spufs_wait(ctx->wbox_wq, spu_wbox_write(ctx, wbox_data));
+               count = spufs_wait(ctx->wbox_wq, spu_wbox_write(ctx, wbox_data));
        }
 
-       spu_release(ctx);
+       if (count)
+               goto out;
+
+       /* write aÑ• much as possible */
+       for (count = 4, udata++; (count + 4) <= len; count += 4, udata++) {
+               int ret;
+               ret = __get_user(wbox_data, udata);
+               if (ret)
+                       break;
+
+               ret = spu_wbox_write(ctx, wbox_data);
+               if (ret == 0)
+                       break;
+       }
 
-       return ret ? ret : sizeof wbox_data;
+out:
+       spu_release(ctx);
+       return count;
 }
 
 static unsigned int spufs_wbox_poll(struct file *file, poll_table *wait)
@@ -657,11 +758,19 @@ static ssize_t spufs_signal1_write(struct file *file, const char __user *buf,
        return 4;
 }
 
-#ifdef CONFIG_SPUFS_MMAP
 static struct page *spufs_signal1_mmap_nopage(struct vm_area_struct *vma,
                                              unsigned long address, int *type)
 {
-       return spufs_ps_nopage(vma, address, type, 0x14000);
+#if PAGE_SIZE == 0x1000
+       return spufs_ps_nopage(vma, address, type, 0x14000, 0x1000);
+#elif PAGE_SIZE == 0x10000
+       /* For 64k pages, both signal1 and signal2 can be used to mmap the whole
+        * signal 1 and 2 area
+        */
+       return spufs_ps_nopage(vma, address, type, 0x10000, 0x10000);
+#else
+#error unsupported page size
+#endif
 }
 
 static struct vm_operations_struct spufs_signal1_mmap_vmops = {
@@ -680,15 +789,12 @@ static int spufs_signal1_mmap(struct file *file, struct vm_area_struct *vma)
        vma->vm_ops = &spufs_signal1_mmap_vmops;
        return 0;
 }
-#endif
 
 static struct file_operations spufs_signal1_fops = {
        .open = spufs_signal1_open,
        .read = spufs_signal1_read,
        .write = spufs_signal1_write,
-#ifdef CONFIG_SPUFS_MMAP
        .mmap = spufs_signal1_mmap,
-#endif
 };
 
 static int spufs_signal2_open(struct inode *inode, struct file *file)
@@ -743,11 +849,20 @@ static ssize_t spufs_signal2_write(struct file *file, const char __user *buf,
        return 4;
 }
 
-#ifdef CONFIG_SPUFS_MMAP
+#if SPUFS_MMAP_4K
 static struct page *spufs_signal2_mmap_nopage(struct vm_area_struct *vma,
                                              unsigned long address, int *type)
 {
-       return spufs_ps_nopage(vma, address, type, 0x1c000);
+#if PAGE_SIZE == 0x1000
+       return spufs_ps_nopage(vma, address, type, 0x1c000, 0x1000);
+#elif PAGE_SIZE == 0x10000
+       /* For 64k pages, both signal1 and signal2 can be used to mmap the whole
+        * signal 1 and 2 area
+        */
+       return spufs_ps_nopage(vma, address, type, 0x10000, 0x10000);
+#else
+#error unsupported page size
+#endif
 }
 
 static struct vm_operations_struct spufs_signal2_mmap_vmops = {
@@ -767,15 +882,15 @@ static int spufs_signal2_mmap(struct file *file, struct vm_area_struct *vma)
        vma->vm_ops = &spufs_signal2_mmap_vmops;
        return 0;
 }
-#endif
+#else /* SPUFS_MMAP_4K */
+#define spufs_signal2_mmap NULL
+#endif /* !SPUFS_MMAP_4K */
 
 static struct file_operations spufs_signal2_fops = {
        .open = spufs_signal2_open,
        .read = spufs_signal2_read,
        .write = spufs_signal2_write,
-#ifdef CONFIG_SPUFS_MMAP
        .mmap = spufs_signal2_mmap,
-#endif
 };
 
 static void spufs_signal1_type_set(void *data, u64 val)
@@ -824,11 +939,11 @@ static u64 spufs_signal2_type_get(void *data)
 DEFINE_SIMPLE_ATTRIBUTE(spufs_signal2_type, spufs_signal2_type_get,
                                        spufs_signal2_type_set, "%llu");
 
-#ifdef CONFIG_SPUFS_MMAP
+#if SPUFS_MMAP_4K
 static struct page *spufs_mss_mmap_nopage(struct vm_area_struct *vma,
                                           unsigned long address, int *type)
 {
-       return spufs_ps_nopage(vma, address, type, 0x0000);
+       return spufs_ps_nopage(vma, address, type, 0x0000, 0x1000);
 }
 
 static struct vm_operations_struct spufs_mss_mmap_vmops = {
@@ -837,17 +952,12 @@ static struct vm_operations_struct spufs_mss_mmap_vmops = {
 
 /*
  * mmap support for problem state MFC DMA area [0x0000 - 0x0fff].
- * Mapping this area requires that the application have CAP_SYS_RAWIO,
- * as these registers require special care when read/writing.
  */
 static int spufs_mss_mmap(struct file *file, struct vm_area_struct *vma)
 {
        if (!(vma->vm_flags & VM_SHARED))
                return -EINVAL;
 
-       if (!capable(CAP_SYS_RAWIO))
-               return -EPERM;
-
        vma->vm_flags |= VM_RESERVED;
        vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot)
                                     | _PAGE_NO_CACHE | _PAGE_GUARDED);
@@ -855,7 +965,9 @@ static int spufs_mss_mmap(struct file *file, struct vm_area_struct *vma)
        vma->vm_ops = &spufs_mss_mmap_vmops;
        return 0;
 }
-#endif
+#else /* SPUFS_MMAP_4K */
+#define spufs_mss_mmap NULL
+#endif /* !SPUFS_MMAP_4K */
 
 static int spufs_mss_open(struct inode *inode, struct file *file)
 {
@@ -867,17 +979,54 @@ static int spufs_mss_open(struct inode *inode, struct file *file)
 
 static struct file_operations spufs_mss_fops = {
        .open    = spufs_mss_open,
-#ifdef CONFIG_SPUFS_MMAP
        .mmap    = spufs_mss_mmap,
-#endif
+};
+
+static struct page *spufs_psmap_mmap_nopage(struct vm_area_struct *vma,
+                                          unsigned long address, int *type)
+{
+       return spufs_ps_nopage(vma, address, type, 0x0000, 0x20000);
+}
+
+static struct vm_operations_struct spufs_psmap_mmap_vmops = {
+       .nopage = spufs_psmap_mmap_nopage,
+};
+
+/*
+ * mmap support for full problem state area [0x00000 - 0x1ffff].
+ */
+static int spufs_psmap_mmap(struct file *file, struct vm_area_struct *vma)
+{
+       if (!(vma->vm_flags & VM_SHARED))
+               return -EINVAL;
+
+       vma->vm_flags |= VM_RESERVED;
+       vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot)
+                                    | _PAGE_NO_CACHE | _PAGE_GUARDED);
+
+       vma->vm_ops = &spufs_psmap_mmap_vmops;
+       return 0;
+}
+
+static int spufs_psmap_open(struct inode *inode, struct file *file)
+{
+       struct spufs_inode_info *i = SPUFS_I(inode);
+
+       file->private_data = i->i_ctx;
+       return nonseekable_open(inode, file);
+}
+
+static struct file_operations spufs_psmap_fops = {
+       .open    = spufs_psmap_open,
+       .mmap    = spufs_psmap_mmap,
 };
 
 
-#ifdef CONFIG_SPUFS_MMAP
+#if SPUFS_MMAP_4K
 static struct page *spufs_mfc_mmap_nopage(struct vm_area_struct *vma,
                                           unsigned long address, int *type)
 {
-       return spufs_ps_nopage(vma, address, type, 0x3000);
+       return spufs_ps_nopage(vma, address, type, 0x3000, 0x1000);
 }
 
 static struct vm_operations_struct spufs_mfc_mmap_vmops = {
@@ -886,17 +1035,12 @@ static struct vm_operations_struct spufs_mfc_mmap_vmops = {
 
 /*
  * mmap support for problem state MFC DMA area [0x0000 - 0x0fff].
- * Mapping this area requires that the application have CAP_SYS_RAWIO,
- * as these registers require special care when read/writing.
  */
 static int spufs_mfc_mmap(struct file *file, struct vm_area_struct *vma)
 {
        if (!(vma->vm_flags & VM_SHARED))
                return -EINVAL;
 
-       if (!capable(CAP_SYS_RAWIO))
-               return -EPERM;
-
        vma->vm_flags |= VM_RESERVED;
        vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot)
                                     | _PAGE_NO_CACHE | _PAGE_GUARDED);
@@ -904,7 +1048,9 @@ static int spufs_mfc_mmap(struct file *file, struct vm_area_struct *vma)
        vma->vm_ops = &spufs_mfc_mmap_vmops;
        return 0;
 }
-#endif
+#else /* SPUFS_MMAP_4K */
+#define spufs_mfc_mmap NULL
+#endif /* !SPUFS_MMAP_4K */
 
 static int spufs_mfc_open(struct inode *inode, struct file *file)
 {
@@ -1194,9 +1340,7 @@ static struct file_operations spufs_mfc_fops = {
        .flush   = spufs_mfc_flush,
        .fsync   = spufs_mfc_fsync,
        .fasync  = spufs_mfc_fasync,
-#ifdef CONFIG_SPUFS_MMAP
        .mmap    = spufs_mfc_mmap,
-#endif
 };
 
 static void spufs_npc_set(void *data, u64 val)
@@ -1344,6 +1488,21 @@ static u64 spufs_id_get(void *data)
 }
 DEFINE_SIMPLE_ATTRIBUTE(spufs_id_ops, spufs_id_get, NULL, "0x%llx\n")
 
+static u64 spufs_object_id_get(void *data)
+{
+       struct spu_context *ctx = data;
+       return ctx->object_id;
+}
+
+static void spufs_object_id_set(void *data, u64 id)
+{
+       struct spu_context *ctx = data;
+       ctx->object_id = id;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(spufs_object_id_ops, spufs_object_id_get,
+               spufs_object_id_set, "0x%llx\n");
+
 struct tree_descr spufs_dir_contents[] = {
        { "mem",  &spufs_mem_fops,  0666, },
        { "regs", &spufs_regs_fops,  0666, },
@@ -1367,6 +1526,8 @@ struct tree_descr spufs_dir_contents[] = {
        { "spu_tag_mask", &spufs_spu_tag_mask_ops, 0666, },
        { "event_mask", &spufs_event_mask_ops, 0666, },
        { "srr0", &spufs_srr0_ops, 0666, },
+       { "psmap", &spufs_psmap_fops, 0666, },
        { "phys-id", &spufs_id_ops, 0666, },
+       { "object-id", &spufs_object_id_ops, 0666, },
        {},
 };
diff --git a/arch/powerpc/platforms/cell/spufs/gang.c b/arch/powerpc/platforms/cell/spufs/gang.c
new file mode 100644 (file)
index 0000000..212ea78
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * SPU file system
+ *
+ * (C) Copyright IBM Deutschland Entwicklung GmbH 2005
+ *
+ * Author: Arnd Bergmann <arndb@de.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/list.h>
+#include <linux/slab.h>
+
+#include "spufs.h"
+
+struct spu_gang *alloc_spu_gang(void)
+{
+       struct spu_gang *gang;
+
+       gang = kzalloc(sizeof *gang, GFP_KERNEL);
+       if (!gang)
+               goto out;
+
+       kref_init(&gang->kref);
+       mutex_init(&gang->mutex);
+       INIT_LIST_HEAD(&gang->list);
+
+out:
+       return gang;
+}
+
+static void destroy_spu_gang(struct kref *kref)
+{
+       struct spu_gang *gang;
+       gang = container_of(kref, struct spu_gang, kref);
+       WARN_ON(gang->contexts || !list_empty(&gang->list));
+       kfree(gang);
+}
+
+struct spu_gang *get_spu_gang(struct spu_gang *gang)
+{
+       kref_get(&gang->kref);
+       return gang;
+}
+
+int put_spu_gang(struct spu_gang *gang)
+{
+       return kref_put(&gang->kref, &destroy_spu_gang);
+}
+
+void spu_gang_add_ctx(struct spu_gang *gang, struct spu_context *ctx)
+{
+       mutex_lock(&gang->mutex);
+       ctx->gang = get_spu_gang(gang);
+       list_add(&ctx->gang_list, &gang->list);
+       gang->contexts++;
+       mutex_unlock(&gang->mutex);
+}
+
+void spu_gang_remove_ctx(struct spu_gang *gang, struct spu_context *ctx)
+{
+       mutex_lock(&gang->mutex);
+       WARN_ON(ctx->gang != gang);
+       list_del_init(&ctx->gang_list);
+       gang->contexts--;
+       mutex_unlock(&gang->mutex);
+
+       put_spu_gang(gang);
+}
index 3950ddccb2c8531d451c8a188b86ae95371ec797..427d00a4f6a0884b22018d4f07929992f2370a7a 100644 (file)
@@ -50,6 +50,10 @@ spufs_alloc_inode(struct super_block *sb)
        ei = kmem_cache_alloc(spufs_inode_cache, SLAB_KERNEL);
        if (!ei)
                return NULL;
+
+       ei->i_gang = NULL;
+       ei->i_ctx = NULL;
+
        return &ei->vfs_inode;
 }
 
@@ -128,14 +132,19 @@ out:
 static void
 spufs_delete_inode(struct inode *inode)
 {
-       if (SPUFS_I(inode)->i_ctx)
-               put_spu_context(SPUFS_I(inode)->i_ctx);
+       struct spufs_inode_info *ei = SPUFS_I(inode);
+
+       if (ei->i_ctx)
+               put_spu_context(ei->i_ctx);
+       if (ei->i_gang)
+               put_spu_gang(ei->i_gang);
        clear_inode(inode);
 }
 
 static void spufs_prune_dir(struct dentry *dir)
 {
        struct dentry *dentry, *tmp;
+
        mutex_lock(&dir->d_inode->i_mutex);
        list_for_each_entry_safe(dentry, tmp, &dir->d_subdirs, d_u.d_child) {
                spin_lock(&dcache_lock);
@@ -156,13 +165,13 @@ static void spufs_prune_dir(struct dentry *dir)
        mutex_unlock(&dir->d_inode->i_mutex);
 }
 
-/* Caller must hold root->i_mutex */
-static int spufs_rmdir(struct inode *root, struct dentry *dir_dentry)
+/* Caller must hold parent->i_mutex */
+static int spufs_rmdir(struct inode *parent, struct dentry *dir)
 {
        /* remove all entries */
-       spufs_prune_dir(dir_dentry);
+       spufs_prune_dir(dir);
 
-       return simple_rmdir(root, dir_dentry);
+       return simple_rmdir(parent, dir);
 }
 
 static int spufs_fill_dir(struct dentry *dir, struct tree_descr *files,
@@ -191,17 +200,17 @@ out:
 static int spufs_dir_close(struct inode *inode, struct file *file)
 {
        struct spu_context *ctx;
-       struct inode *dir;
-       struct dentry *dentry;
+       struct inode *parent;
+       struct dentry *dir;
        int ret;
 
-       dentry = file->f_dentry;
-       dir = dentry->d_parent->d_inode;
-       ctx = SPUFS_I(dentry->d_inode)->i_ctx;
+       dir = file->f_dentry;
+       parent = dir->d_parent->d_inode;
+       ctx = SPUFS_I(dir->d_inode)->i_ctx;
 
-       mutex_lock(&dir->i_mutex);
-       ret = spufs_rmdir(dir, dentry);
-       mutex_unlock(&dir->i_mutex);
+       mutex_lock(&parent->i_mutex);
+       ret = spufs_rmdir(parent, dir);
+       mutex_unlock(&parent->i_mutex);
        WARN_ON(ret);
 
        /* We have to give up the mm_struct */
@@ -224,7 +233,8 @@ struct file_operations spufs_context_fops = {
 };
 
 static int
-spufs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
+spufs_mkdir(struct inode *dir, struct dentry *dentry, unsigned int flags,
+               int mode)
 {
        int ret;
        struct inode *inode;
@@ -239,11 +249,13 @@ spufs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
                inode->i_gid = dir->i_gid;
                inode->i_mode &= S_ISGID;
        }
-       ctx = alloc_spu_context();
+       ctx = alloc_spu_context(SPUFS_I(dir)->i_gang); /* XXX gang */
        SPUFS_I(inode)->i_ctx = ctx;
        if (!ctx)
                goto out_iput;
 
+       ctx->flags = flags;
+
        inode->i_op = &spufs_dir_inode_operations;
        inode->i_fop = &simple_dir_operations;
        ret = spufs_fill_dir(dentry, spufs_dir_contents, mode, ctx);
@@ -289,24 +301,177 @@ out:
        return ret;
 }
 
+static int spufs_create_context(struct inode *inode,
+                       struct dentry *dentry,
+                       struct vfsmount *mnt, int flags, int mode)
+{
+       int ret;
+
+       ret = spufs_mkdir(inode, dentry, flags, mode & S_IRWXUGO);
+       if (ret)
+               goto out_unlock;
+
+       /*
+        * get references for dget and mntget, will be released
+        * in error path of *_open().
+        */
+       ret = spufs_context_open(dget(dentry), mntget(mnt));
+       if (ret < 0) {
+               WARN_ON(spufs_rmdir(inode, dentry));
+               mutex_unlock(&inode->i_mutex);
+               spu_forget(SPUFS_I(dentry->d_inode)->i_ctx);
+               goto out;
+       }
+
+out_unlock:
+       mutex_unlock(&inode->i_mutex);
+out:
+       dput(dentry);
+       return ret;
+}
+
+static int spufs_rmgang(struct inode *root, struct dentry *dir)
+{
+       /* FIXME: this fails if the dir is not empty,
+                 which causes a leak of gangs. */
+       return simple_rmdir(root, dir);
+}
+
+static int spufs_gang_close(struct inode *inode, struct file *file)
+{
+       struct inode *parent;
+       struct dentry *dir;
+       int ret;
+
+       dir = file->f_dentry;
+       parent = dir->d_parent->d_inode;
+
+       ret = spufs_rmgang(parent, dir);
+       WARN_ON(ret);
+
+       return dcache_dir_close(inode, file);
+}
+
+struct file_operations spufs_gang_fops = {
+       .open           = dcache_dir_open,
+       .release        = spufs_gang_close,
+       .llseek         = dcache_dir_lseek,
+       .read           = generic_read_dir,
+       .readdir        = dcache_readdir,
+       .fsync          = simple_sync_file,
+};
+
+static int
+spufs_mkgang(struct inode *dir, struct dentry *dentry, int mode)
+{
+       int ret;
+       struct inode *inode;
+       struct spu_gang *gang;
+
+       ret = -ENOSPC;
+       inode = spufs_new_inode(dir->i_sb, mode | S_IFDIR);
+       if (!inode)
+               goto out;
+
+       ret = 0;
+       if (dir->i_mode & S_ISGID) {
+               inode->i_gid = dir->i_gid;
+               inode->i_mode &= S_ISGID;
+       }
+       gang = alloc_spu_gang();
+       SPUFS_I(inode)->i_ctx = NULL;
+       SPUFS_I(inode)->i_gang = gang;
+       if (!gang)
+               goto out_iput;
+
+       inode->i_op = &spufs_dir_inode_operations;
+       inode->i_fop = &simple_dir_operations;
+
+       d_instantiate(dentry, inode);
+       dget(dentry);
+       dir->i_nlink++;
+       dentry->d_inode->i_nlink++;
+       return ret;
+
+out_iput:
+       iput(inode);
+out:
+       return ret;
+}
+
+static int spufs_gang_open(struct dentry *dentry, struct vfsmount *mnt)
+{
+       int ret;
+       struct file *filp;
+
+       ret = get_unused_fd();
+       if (ret < 0) {
+               dput(dentry);
+               mntput(mnt);
+               goto out;
+       }
+
+       filp = dentry_open(dentry, mnt, O_RDONLY);
+       if (IS_ERR(filp)) {
+               put_unused_fd(ret);
+               ret = PTR_ERR(filp);
+               goto out;
+       }
+
+       filp->f_op = &spufs_gang_fops;
+       fd_install(ret, filp);
+out:
+       return ret;
+}
+
+static int spufs_create_gang(struct inode *inode,
+                       struct dentry *dentry,
+                       struct vfsmount *mnt, int mode)
+{
+       int ret;
+
+       ret = spufs_mkgang(inode, dentry, mode & S_IRWXUGO);
+       if (ret)
+               goto out;
+
+       /*
+        * get references for dget and mntget, will be released
+        * in error path of *_open().
+        */
+       ret = spufs_gang_open(dget(dentry), mntget(mnt));
+       if (ret < 0)
+               WARN_ON(spufs_rmgang(inode, dentry));
+
+out:
+       mutex_unlock(&inode->i_mutex);
+       dput(dentry);
+       return ret;
+}
+
+
 static struct file_system_type spufs_type;
 
-long spufs_create_thread(struct nameidata *nd,
-                        unsigned int flags, mode_t mode)
+long spufs_create(struct nameidata *nd, unsigned int flags, mode_t mode)
 {
        struct dentry *dentry;
        int ret;
 
-       /* need to be at the root of spufs */
        ret = -EINVAL;
-       if (nd->dentry->d_sb->s_type != &spufs_type ||
-           nd->dentry != nd->dentry->d_sb->s_root)
+       /* check if we are on spufs */
+       if (nd->dentry->d_sb->s_type != &spufs_type)
                goto out;
 
-       /* all flags are reserved */
-       if (flags)
+       /* don't accept undefined flags */
+       if (flags & (~SPU_CREATE_FLAG_ALL))
                goto out;
 
+       /* only threads can be underneath a gang */
+       if (nd->dentry != nd->dentry->d_sb->s_root) {
+               if ((flags & SPU_CREATE_GANG) ||
+                   !SPUFS_I(nd->dentry->d_inode)->i_gang)
+                       goto out;
+       }
+
        dentry = lookup_create(nd, 1);
        ret = PTR_ERR(dentry);
        if (IS_ERR(dentry))
@@ -317,22 +482,13 @@ long spufs_create_thread(struct nameidata *nd,
                goto out_dput;
 
        mode &= ~current->fs->umask;
-       ret = spufs_mkdir(nd->dentry->d_inode, dentry, mode & S_IRWXUGO);
-       if (ret)
-               goto out_dput;
 
-       /*
-        * get references for dget and mntget, will be released
-        * in error path of *_open().
-        */
-       ret = spufs_context_open(dget(dentry), mntget(nd->mnt));
-       if (ret < 0) {
-               WARN_ON(spufs_rmdir(nd->dentry->d_inode, dentry));
-               mutex_unlock(&nd->dentry->d_inode->i_mutex);
-               spu_forget(SPUFS_I(dentry->d_inode)->i_ctx);
-               dput(dentry);
-               goto out;
-       }
+       if (flags & SPU_CREATE_GANG)
+               return spufs_create_gang(nd->dentry->d_inode,
+                                       dentry, nd->mnt, mode);
+       else
+               return spufs_create_context(nd->dentry->d_inode,
+                                       dentry, nd->mnt, flags, mode);
 
 out_dput:
        dput(dentry);
index 483c8b76232c010de9b1f10e6fc1b88656eb98cf..63df8cf4ba1607e13ee8c01cdab8a392da12835b 100644 (file)
@@ -14,6 +14,26 @@ void spufs_stop_callback(struct spu *spu)
        wake_up_all(&ctx->stop_wq);
 }
 
+void spufs_dma_callback(struct spu *spu, int type)
+{
+       struct spu_context *ctx = spu->ctx;
+
+       if (ctx->flags & SPU_CREATE_EVENTS_ENABLED) {
+               ctx->event_return |= type;
+               wake_up_all(&ctx->stop_wq);
+       } else {
+               switch (type) {
+               case SPE_EVENT_DMA_ALIGNMENT:
+               case SPE_EVENT_INVALID_DMA:
+                       force_sig(SIGBUS, /* info, */ current);
+                       break;
+               case SPE_EVENT_SPE_ERROR:
+                       force_sig(SIGILL, /* info */ current);
+                       break;
+               }
+       }
+}
+
 static inline int spu_stopped(struct spu_context *ctx, u32 * stat)
 {
        struct spu *spu;
@@ -28,8 +48,7 @@ static inline int spu_stopped(struct spu_context *ctx, u32 * stat)
        return (!(*stat & 0x1) || pte_fault || spu->class_0_pending) ? 1 : 0;
 }
 
-static inline int spu_run_init(struct spu_context *ctx, u32 * npc,
-                              u32 * status)
+static inline int spu_run_init(struct spu_context *ctx, u32 * npc)
 {
        int ret;
 
@@ -72,7 +91,7 @@ static inline int spu_reacquire_runnable(struct spu_context *ctx, u32 *npc,
                       SPU_STATUS_STOPPED_BY_HALT)) {
                return *status;
        }
-       if ((ret = spu_run_init(ctx, npc, status)) != 0)
+       if ((ret = spu_run_init(ctx, npc)) != 0)
                return ret;
        return 0;
 }
@@ -177,46 +196,49 @@ static inline int spu_process_events(struct spu_context *ctx)
 }
 
 long spufs_run_spu(struct file *file, struct spu_context *ctx,
-                  u32 * npc, u32 * status)
+                  u32 *npc, u32 *event)
 {
        int ret;
+       u32 status;
 
        if (down_interruptible(&ctx->run_sema))
                return -ERESTARTSYS;
 
-       ret = spu_run_init(ctx, npc, status);
+       ctx->event_return = 0;
+       ret = spu_run_init(ctx, npc);
        if (ret)
                goto out;
 
        do {
-               ret = spufs_wait(ctx->stop_wq, spu_stopped(ctx, status));
+               ret = spufs_wait(ctx->stop_wq, spu_stopped(ctx, &status));
                if (unlikely(ret))
                        break;
-               if ((*status & SPU_STATUS_STOPPED_BY_STOP) &&
-                   (*status >> SPU_STOP_STATUS_SHIFT == 0x2104)) {
+               if ((status & SPU_STATUS_STOPPED_BY_STOP) &&
+                   (status >> SPU_STOP_STATUS_SHIFT == 0x2104)) {
                        ret = spu_process_callback(ctx);
                        if (ret)
                                break;
-                       *status &= ~SPU_STATUS_STOPPED_BY_STOP;
+                       status &= ~SPU_STATUS_STOPPED_BY_STOP;
                }
                if (unlikely(ctx->state != SPU_STATE_RUNNABLE)) {
-                       ret = spu_reacquire_runnable(ctx, npc, status);
+                       ret = spu_reacquire_runnable(ctx, npc, &status);
                        if (ret)
                                goto out;
                        continue;
                }
                ret = spu_process_events(ctx);
 
-       } while (!ret && !(*status & (SPU_STATUS_STOPPED_BY_STOP |
+       } while (!ret && !(status & (SPU_STATUS_STOPPED_BY_STOP |
                                      SPU_STATUS_STOPPED_BY_HALT)));
 
        ctx->ops->runcntl_stop(ctx);
-       ret = spu_run_fini(ctx, npc, status);
+       ret = spu_run_fini(ctx, npc, &status);
        if (!ret)
-               ret = *status;
+               ret = status;
        spu_yield(ctx);
 
 out:
+       *event = ctx->event_return;
        up(&ctx->run_sema);
        return ret;
 }
index 1350294484b62e191a131daa99dbd6f8de51aab2..bd6fe4b7a84baab84face56b2d8ca5f5c263db2e 100644 (file)
@@ -3,11 +3,7 @@
  * Copyright (C) IBM 2005
  * Author: Mark Nutter <mnutter@us.ibm.com>
  *
- * SPU scheduler, based on Linux thread priority.  For now use
- * a simple "cooperative" yield model with no preemption.  SPU
- * scheduling will eventually be preemptive: When a thread with
- * a higher static priority gets ready to run, then an active SPU
- * context will be preempted and returned to the waitq.
+ * 2006-03-31  NUMA domains added.
  *
  * 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
@@ -37,6 +33,9 @@
 #include <linux/smp_lock.h>
 #include <linux/stddef.h>
 #include <linux/unistd.h>
+#include <linux/numa.h>
+#include <linux/mutex.h>
+#include <linux/notifier.h>
 
 #include <asm/io.h>
 #include <asm/mmu_context.h>
 
 #define SPU_BITMAP_SIZE (((MAX_PRIO+BITS_PER_LONG)/BITS_PER_LONG)+1)
 struct spu_prio_array {
-       atomic_t nr_blocked;
        unsigned long bitmap[SPU_BITMAP_SIZE];
        wait_queue_head_t waitq[MAX_PRIO];
+       struct list_head active_list[MAX_NUMNODES];
+       struct mutex active_mutex[MAX_NUMNODES];
 };
 
-/* spu_runqueue - This is the main runqueue data structure for SPUs. */
-struct spu_runqueue {
-       struct semaphore sem;
-       unsigned long nr_active;
-       unsigned long nr_idle;
-       unsigned long nr_switches;
-       struct list_head active_list;
-       struct list_head idle_list;
-       struct spu_prio_array prio;
-};
-
-static struct spu_runqueue *spu_runqueues = NULL;
-
-static inline struct spu_runqueue *spu_rq(void)
-{
-       /* Future: make this a per-NODE array,
-        * and use cpu_to_node(smp_processor_id())
-        */
-       return spu_runqueues;
-}
+static struct spu_prio_array *spu_prio;
 
-static inline struct spu *del_idle(struct spu_runqueue *rq)
+static inline int node_allowed(int node)
 {
-       struct spu *spu;
+       cpumask_t mask;
 
-       BUG_ON(rq->nr_idle <= 0);
-       BUG_ON(list_empty(&rq->idle_list));
-       /* Future: Move SPU out of low-power SRI state. */
-       spu = list_entry(rq->idle_list.next, struct spu, sched_list);
-       list_del_init(&spu->sched_list);
-       rq->nr_idle--;
-       return spu;
+       if (!nr_cpus_node(node))
+               return 0;
+       mask = node_to_cpumask(node);
+       if (!cpus_intersects(mask, current->cpus_allowed))
+               return 0;
+       return 1;
 }
 
-static inline void del_active(struct spu_runqueue *rq, struct spu *spu)
+static inline void mm_needs_global_tlbie(struct mm_struct *mm)
 {
-       BUG_ON(rq->nr_active <= 0);
-       BUG_ON(list_empty(&rq->active_list));
-       list_del_init(&spu->sched_list);
-       rq->nr_active--;
-}
+       int nr = (NR_CPUS > 1) ? NR_CPUS : NR_CPUS + 1;
 
-static inline void add_idle(struct spu_runqueue *rq, struct spu *spu)
-{
-       /* Future: Put SPU into low-power SRI state. */
-       list_add_tail(&spu->sched_list, &rq->idle_list);
-       rq->nr_idle++;
+       /* Global TLBIE broadcast required with SPEs. */
+       __cpus_setall(&mm->cpu_vm_mask, nr);
 }
 
-static inline void add_active(struct spu_runqueue *rq, struct spu *spu)
-{
-       rq->nr_active++;
-       rq->nr_switches++;
-       list_add_tail(&spu->sched_list, &rq->active_list);
-}
+static BLOCKING_NOTIFIER_HEAD(spu_switch_notifier);
 
-static void prio_wakeup(struct spu_runqueue *rq)
+static void spu_switch_notify(struct spu *spu, struct spu_context *ctx)
 {
-       if (atomic_read(&rq->prio.nr_blocked) && rq->nr_idle) {
-               int best = sched_find_first_bit(rq->prio.bitmap);
-               if (best < MAX_PRIO) {
-                       wait_queue_head_t *wq = &rq->prio.waitq[best];
-                       wake_up_interruptible_nr(wq, 1);
-               }
-       }
+       blocking_notifier_call_chain(&spu_switch_notifier,
+                           ctx ? ctx->object_id : 0, spu);
 }
 
-static void prio_wait(struct spu_runqueue *rq, struct spu_context *ctx,
-                     u64 flags)
+int spu_switch_event_register(struct notifier_block * n)
 {
-       int prio = current->prio;
-       wait_queue_head_t *wq = &rq->prio.waitq[prio];
-       DEFINE_WAIT(wait);
-
-       __set_bit(prio, rq->prio.bitmap);
-       atomic_inc(&rq->prio.nr_blocked);
-       prepare_to_wait_exclusive(wq, &wait, TASK_INTERRUPTIBLE);
-       if (!signal_pending(current)) {
-               up(&rq->sem);
-               up_write(&ctx->state_sema);
-               pr_debug("%s: pid=%d prio=%d\n", __FUNCTION__,
-                        current->pid, current->prio);
-               schedule();
-               down_write(&ctx->state_sema);
-               down(&rq->sem);
-       }
-       finish_wait(wq, &wait);
-       atomic_dec(&rq->prio.nr_blocked);
-       if (!waitqueue_active(wq))
-               __clear_bit(prio, rq->prio.bitmap);
+       return blocking_notifier_chain_register(&spu_switch_notifier, n);
 }
 
-static inline int is_best_prio(struct spu_runqueue *rq)
+int spu_switch_event_unregister(struct notifier_block * n)
 {
-       int best_prio;
-
-       best_prio = sched_find_first_bit(rq->prio.bitmap);
-       return (current->prio < best_prio) ? 1 : 0;
+       return blocking_notifier_chain_unregister(&spu_switch_notifier, n);
 }
 
-static inline void mm_needs_global_tlbie(struct mm_struct *mm)
-{
-       /* Global TLBIE broadcast required with SPEs. */
-#if (NR_CPUS > 1)
-       __cpus_setall(&mm->cpu_vm_mask, NR_CPUS);
-#else
-       __cpus_setall(&mm->cpu_vm_mask, NR_CPUS+1); /* is this ok? */
-#endif
-}
 
 static inline void bind_context(struct spu *spu, struct spu_context *ctx)
 {
-       pr_debug("%s: pid=%d SPU=%d\n", __FUNCTION__, current->pid,
-                spu->number);
+       pr_debug("%s: pid=%d SPU=%d NODE=%d\n", __FUNCTION__, current->pid,
+                spu->number, spu->node);
        spu->ctx = ctx;
        spu->flags = 0;
-       ctx->flags = 0;
        ctx->spu = spu;
        ctx->ops = &spu_hw_ops;
        spu->pid = current->pid;
@@ -181,16 +111,20 @@ static inline void bind_context(struct spu *spu, struct spu_context *ctx)
        spu->wbox_callback = spufs_wbox_callback;
        spu->stop_callback = spufs_stop_callback;
        spu->mfc_callback = spufs_mfc_callback;
+       spu->dma_callback = spufs_dma_callback;
        mb();
        spu_unmap_mappings(ctx);
        spu_restore(&ctx->csa, spu);
        spu->timestamp = jiffies;
+       spu_cpu_affinity_set(spu, raw_smp_processor_id());
+       spu_switch_notify(spu, ctx);
 }
 
 static inline void unbind_context(struct spu *spu, struct spu_context *ctx)
 {
-       pr_debug("%s: unbind pid=%d SPU=%d\n", __FUNCTION__,
-                spu->pid, spu->number);
+       pr_debug("%s: unbind pid=%d SPU=%d NODE=%d\n", __FUNCTION__,
+                spu->pid, spu->number, spu->node);
+       spu_switch_notify(spu, NULL);
        spu_unmap_mappings(ctx);
        spu_save(&ctx->csa, spu);
        spu->timestamp = jiffies;
@@ -199,173 +133,158 @@ static inline void unbind_context(struct spu *spu, struct spu_context *ctx)
        spu->wbox_callback = NULL;
        spu->stop_callback = NULL;
        spu->mfc_callback = NULL;
+       spu->dma_callback = NULL;
        spu->mm = NULL;
        spu->pid = 0;
        spu->prio = MAX_PRIO;
        ctx->ops = &spu_backing_ops;
        ctx->spu = NULL;
-       ctx->flags = 0;
        spu->flags = 0;
        spu->ctx = NULL;
 }
 
-static void spu_reaper(void *data)
+static inline void spu_add_wq(wait_queue_head_t * wq, wait_queue_t * wait,
+                             int prio)
 {
-       struct spu_context *ctx = data;
-       struct spu *spu;
-
-       down_write(&ctx->state_sema);
-       spu = ctx->spu;
-       if (spu && test_bit(SPU_CONTEXT_PREEMPT, &ctx->flags)) {
-               if (atomic_read(&spu->rq->prio.nr_blocked)) {
-                       pr_debug("%s: spu=%d\n", __func__, spu->number);
-                       ctx->ops->runcntl_stop(ctx);
-                       spu_deactivate(ctx);
-                       wake_up_all(&ctx->stop_wq);
-               } else {
-                       clear_bit(SPU_CONTEXT_PREEMPT, &ctx->flags);
-               }
-       }
-       up_write(&ctx->state_sema);
-       put_spu_context(ctx);
+       prepare_to_wait_exclusive(wq, wait, TASK_INTERRUPTIBLE);
+       set_bit(prio, spu_prio->bitmap);
 }
 
-static void schedule_spu_reaper(struct spu_runqueue *rq, struct spu *spu)
+static inline void spu_del_wq(wait_queue_head_t * wq, wait_queue_t * wait,
+                             int prio)
 {
-       struct spu_context *ctx = get_spu_context(spu->ctx);
-       unsigned long now = jiffies;
-       unsigned long expire = spu->timestamp + SPU_MIN_TIMESLICE;
-
-       set_bit(SPU_CONTEXT_PREEMPT, &ctx->flags);
-       INIT_WORK(&ctx->reap_work, spu_reaper, ctx);
-       if (time_after(now, expire))
-               schedule_work(&ctx->reap_work);
-       else
-               schedule_delayed_work(&ctx->reap_work, expire - now);
-}
+       u64 flags;
 
-static void check_preempt_active(struct spu_runqueue *rq)
-{
-       struct list_head *p;
-       struct spu *worst = NULL;
-
-       list_for_each(p, &rq->active_list) {
-               struct spu *spu = list_entry(p, struct spu, sched_list);
-               struct spu_context *ctx = spu->ctx;
-               if (!test_bit(SPU_CONTEXT_PREEMPT, &ctx->flags)) {
-                       if (!worst || (spu->prio > worst->prio)) {
-                               worst = spu;
-                       }
-               }
-       }
-       if (worst && (current->prio < worst->prio))
-               schedule_spu_reaper(rq, worst);
+       __set_current_state(TASK_RUNNING);
+
+       spin_lock_irqsave(&wq->lock, flags);
+
+       remove_wait_queue_locked(wq, wait);
+       if (list_empty(&wq->task_list))
+               clear_bit(prio, spu_prio->bitmap);
+
+       spin_unlock_irqrestore(&wq->lock, flags);
 }
 
-static struct spu *get_idle_spu(struct spu_context *ctx, u64 flags)
+static void spu_prio_wait(struct spu_context *ctx, u64 flags)
 {
-       struct spu_runqueue *rq;
-       struct spu *spu = NULL;
+       int prio = current->prio;
+       wait_queue_head_t *wq = &spu_prio->waitq[prio];
+       DEFINE_WAIT(wait);
 
-       rq = spu_rq();
-       down(&rq->sem);
-       for (;;) {
-               if (rq->nr_idle > 0) {
-                       if (is_best_prio(rq)) {
-                               /* Fall through. */
-                               spu = del_idle(rq);
-                               break;
-                       } else {
-                               prio_wakeup(rq);
-                               up(&rq->sem);
-                               yield();
-                               if (signal_pending(current)) {
-                                       return NULL;
-                               }
-                               rq = spu_rq();
-                               down(&rq->sem);
-                               continue;
-                       }
-               } else {
-                       check_preempt_active(rq);
-                       prio_wait(rq, ctx, flags);
-                       if (signal_pending(current)) {
-                               prio_wakeup(rq);
-                               spu = NULL;
-                               break;
-                       }
-                       continue;
-               }
+       if (ctx->spu)
+               return;
+
+       spu_add_wq(wq, &wait, prio);
+
+       if (!signal_pending(current)) {
+               up_write(&ctx->state_sema);
+               pr_debug("%s: pid=%d prio=%d\n", __FUNCTION__,
+                        current->pid, current->prio);
+               schedule();
+               down_write(&ctx->state_sema);
        }
-       up(&rq->sem);
-       return spu;
+
+       spu_del_wq(wq, &wait, prio);
 }
 
-static void put_idle_spu(struct spu *spu)
+static void spu_prio_wakeup(void)
 {
-       struct spu_runqueue *rq = spu->rq;
-
-       down(&rq->sem);
-       add_idle(rq, spu);
-       prio_wakeup(rq);
-       up(&rq->sem);
+       int best = sched_find_first_bit(spu_prio->bitmap);
+       if (best < MAX_PRIO) {
+               wait_queue_head_t *wq = &spu_prio->waitq[best];
+               wake_up_interruptible_nr(wq, 1);
+       }
 }
 
 static int get_active_spu(struct spu *spu)
 {
-       struct spu_runqueue *rq = spu->rq;
-       struct list_head *p;
+       int node = spu->node;
        struct spu *tmp;
        int rc = 0;
 
-       down(&rq->sem);
-       list_for_each(p, &rq->active_list) {
-               tmp = list_entry(p, struct spu, sched_list);
+       mutex_lock(&spu_prio->active_mutex[node]);
+       list_for_each_entry(tmp, &spu_prio->active_list[node], list) {
                if (tmp == spu) {
-                       del_active(rq, spu);
+                       list_del_init(&spu->list);
                        rc = 1;
                        break;
                }
        }
-       up(&rq->sem);
+       mutex_unlock(&spu_prio->active_mutex[node]);
        return rc;
 }
 
 static void put_active_spu(struct spu *spu)
 {
-       struct spu_runqueue *rq = spu->rq;
+       int node = spu->node;
+
+       mutex_lock(&spu_prio->active_mutex[node]);
+       list_add_tail(&spu->list, &spu_prio->active_list[node]);
+       mutex_unlock(&spu_prio->active_mutex[node]);
+}
+
+static struct spu *spu_get_idle(struct spu_context *ctx, u64 flags)
+{
+       struct spu *spu = NULL;
+       int node = cpu_to_node(raw_smp_processor_id());
+       int n;
 
-       down(&rq->sem);
-       add_active(rq, spu);
-       up(&rq->sem);
+       for (n = 0; n < MAX_NUMNODES; n++, node++) {
+               node = (node < MAX_NUMNODES) ? node : 0;
+               if (!node_allowed(node))
+                       continue;
+               spu = spu_alloc_node(node);
+               if (spu)
+                       break;
+       }
+       return spu;
 }
 
-/* Lock order:
- *     spu_activate() & spu_deactivate() require the
- *     caller to have down_write(&ctx->state_sema).
+static inline struct spu *spu_get(struct spu_context *ctx, u64 flags)
+{
+       /* Future: spu_get_idle() if possible,
+        * otherwise try to preempt an active
+        * context.
+        */
+       return spu_get_idle(ctx, flags);
+}
+
+/* The three externally callable interfaces
+ * for the scheduler begin here.
  *
- *     The rq->sem is breifly held (inside or outside a
- *     given ctx lock) for list management, but is never
- *     held during save/restore.
+ *     spu_activate    - bind a context to SPU, waiting as needed.
+ *     spu_deactivate  - unbind a context from its SPU.
+ *     spu_yield       - yield an SPU if others are waiting.
  */
 
 int spu_activate(struct spu_context *ctx, u64 flags)
 {
        struct spu *spu;
+       int ret = 0;
 
-       if (ctx->spu)
-               return 0;
-       spu = get_idle_spu(ctx, flags);
-       if (!spu)
-               return (signal_pending(current)) ? -ERESTARTSYS : -EAGAIN;
-       bind_context(spu, ctx);
-       /*
-        * We're likely to wait for interrupts on the same
-        * CPU that we are now on, so send them here.
-        */
-       spu_cpu_affinity_set(spu, raw_smp_processor_id());
-       put_active_spu(spu);
-       return 0;
+       for (;;) {
+               if (ctx->spu)
+                       return 0;
+               spu = spu_get(ctx, flags);
+               if (spu != NULL) {
+                       if (ctx->spu != NULL) {
+                               spu_free(spu);
+                               spu_prio_wakeup();
+                               break;
+                       }
+                       bind_context(spu, ctx);
+                       put_active_spu(spu);
+                       break;
+               }
+               spu_prio_wait(ctx, flags);
+               if (signal_pending(current)) {
+                       ret = -ERESTARTSYS;
+                       spu_prio_wakeup();
+                       break;
+               }
+       }
+       return ret;
 }
 
 void spu_deactivate(struct spu_context *ctx)
@@ -378,8 +297,10 @@ void spu_deactivate(struct spu_context *ctx)
                return;
        needs_idle = get_active_spu(spu);
        unbind_context(spu, ctx);
-       if (needs_idle)
-               put_idle_spu(spu);
+       if (needs_idle) {
+               spu_free(spu);
+               spu_prio_wakeup();
+       }
 }
 
 void spu_yield(struct spu_context *ctx)
@@ -387,77 +308,60 @@ void spu_yield(struct spu_context *ctx)
        struct spu *spu;
        int need_yield = 0;
 
-       down_write(&ctx->state_sema);
-       spu = ctx->spu;
-       if (spu && (sched_find_first_bit(spu->rq->prio.bitmap) < MAX_PRIO)) {
-               pr_debug("%s: yielding SPU %d\n", __FUNCTION__, spu->number);
-               spu_deactivate(ctx);
-               ctx->state = SPU_STATE_SAVED;
-               need_yield = 1;
-       } else if (spu) {
-               spu->prio = MAX_PRIO;
+       if (down_write_trylock(&ctx->state_sema)) {
+               if ((spu = ctx->spu) != NULL) {
+                       int best = sched_find_first_bit(spu_prio->bitmap);
+                       if (best < MAX_PRIO) {
+                               pr_debug("%s: yielding SPU %d NODE %d\n",
+                                        __FUNCTION__, spu->number, spu->node);
+                               spu_deactivate(ctx);
+                               ctx->state = SPU_STATE_SAVED;
+                               need_yield = 1;
+                       } else {
+                               spu->prio = MAX_PRIO;
+                       }
+               }
+               up_write(&ctx->state_sema);
        }
-       up_write(&ctx->state_sema);
        if (unlikely(need_yield))
                yield();
 }
 
 int __init spu_sched_init(void)
 {
-       struct spu_runqueue *rq;
-       struct spu *spu;
        int i;
 
-       rq = spu_runqueues = kmalloc(sizeof(struct spu_runqueue), GFP_KERNEL);
-       if (!rq) {
-               printk(KERN_WARNING "%s: Unable to allocate runqueues.\n",
+       spu_prio = kzalloc(sizeof(struct spu_prio_array), GFP_KERNEL);
+       if (!spu_prio) {
+               printk(KERN_WARNING "%s: Unable to allocate priority queue.\n",
                       __FUNCTION__);
                return 1;
        }
-       memset(rq, 0, sizeof(struct spu_runqueue));
-       init_MUTEX(&rq->sem);
-       INIT_LIST_HEAD(&rq->active_list);
-       INIT_LIST_HEAD(&rq->idle_list);
-       rq->nr_active = 0;
-       rq->nr_idle = 0;
-       rq->nr_switches = 0;
-       atomic_set(&rq->prio.nr_blocked, 0);
        for (i = 0; i < MAX_PRIO; i++) {
-               init_waitqueue_head(&rq->prio.waitq[i]);
-               __clear_bit(i, rq->prio.bitmap);
+               init_waitqueue_head(&spu_prio->waitq[i]);
+               __clear_bit(i, spu_prio->bitmap);
        }
-       __set_bit(MAX_PRIO, rq->prio.bitmap);
-       for (;;) {
-               spu = spu_alloc();
-               if (!spu)
-                       break;
-               pr_debug("%s: adding SPU[%d]\n", __FUNCTION__, spu->number);
-               add_idle(rq, spu);
-               spu->rq = rq;
-               spu->timestamp = jiffies;
-       }
-       if (!rq->nr_idle) {
-               printk(KERN_WARNING "%s: No available SPUs.\n", __FUNCTION__);
-               kfree(rq);
-               return 1;
+       __set_bit(MAX_PRIO, spu_prio->bitmap);
+       for (i = 0; i < MAX_NUMNODES; i++) {
+               mutex_init(&spu_prio->active_mutex[i]);
+               INIT_LIST_HEAD(&spu_prio->active_list[i]);
        }
        return 0;
 }
 
 void __exit spu_sched_exit(void)
 {
-       struct spu_runqueue *rq = spu_rq();
-       struct spu *spu;
-
-       if (!rq) {
-               printk(KERN_WARNING "%s: no runqueues!\n", __FUNCTION__);
-               return;
-       }
-       while (rq->nr_idle > 0) {
-               spu = del_idle(rq);
-               if (!spu)
-                       break;
-               spu_free(spu);
+       struct spu *spu, *tmp;
+       int node;
+
+       for (node = 0; node < MAX_NUMNODES; node++) {
+               mutex_lock(&spu_prio->active_mutex[node]);
+               list_for_each_entry_safe(spu, tmp, &spu_prio->active_list[node],
+                                        list) {
+                       list_del_init(&spu->list);
+                       spu_free(spu);
+               }
+               mutex_unlock(&spu_prio->active_mutex[node]);
        }
-       kfree(rq);
+       kfree(spu_prio);
 }
index 4485738e2102d152899e44ad87a8ee683700abaa..a0f55ca2d488322c1165a82b647eb4196a13d872 100644 (file)
@@ -39,6 +39,8 @@ struct spu_context_ops;
 
 #define SPU_CONTEXT_PREEMPT          0UL
 
+struct spu_gang;
+
 struct spu_context {
        struct spu *spu;                  /* pointer to a physical SPU */
        struct spu_state csa;             /* SPU context save area. */
@@ -48,6 +50,7 @@ struct spu_context {
        struct address_space *cntl;        /* 'control' area mappings. */
        struct address_space *signal1;     /* 'signal1' area mappings. */
        struct address_space *signal2;     /* 'signal2' area mappings. */
+       u64 object_id;             /* user space pointer for oprofile */
 
        enum { SPU_STATE_RUNNABLE, SPU_STATE_SAVED } state;
        struct rw_semaphore state_sema;
@@ -66,7 +69,18 @@ struct spu_context {
        u32 tagwait;
        struct spu_context_ops *ops;
        struct work_struct reap_work;
-       u64 flags;
+       unsigned long flags;
+       unsigned long event_return;
+
+       struct list_head gang_list;
+       struct spu_gang *gang;
+};
+
+struct spu_gang {
+       struct list_head list;
+       struct mutex mutex;
+       struct kref kref;
+       int contexts;
 };
 
 struct mfc_dma_command {
@@ -114,6 +128,7 @@ extern struct spu_context_ops spu_backing_ops;
 
 struct spufs_inode_info {
        struct spu_context *i_ctx;
+       struct spu_gang *i_gang;
        struct inode vfs_inode;
 };
 #define SPUFS_I(inode) \
@@ -124,12 +139,19 @@ extern struct tree_descr spufs_dir_contents[];
 /* system call implementation */
 long spufs_run_spu(struct file *file,
                   struct spu_context *ctx, u32 *npc, u32 *status);
-long spufs_create_thread(struct nameidata *nd,
+long spufs_create(struct nameidata *nd,
                         unsigned int flags, mode_t mode);
 extern struct file_operations spufs_context_fops;
 
+/* gang management */
+struct spu_gang *alloc_spu_gang(void);
+struct spu_gang *get_spu_gang(struct spu_gang *gang);
+int put_spu_gang(struct spu_gang *gang);
+void spu_gang_remove_ctx(struct spu_gang *gang, struct spu_context *ctx);
+void spu_gang_add_ctx(struct spu_gang *gang, struct spu_context *ctx);
+
 /* context management */
-struct spu_context * alloc_spu_context(void);
+struct spu_context * alloc_spu_context(struct spu_gang *gang);
 void destroy_spu_context(struct kref *kref);
 struct spu_context * get_spu_context(struct spu_context *ctx);
 int put_spu_context(struct spu_context *ctx);
@@ -183,5 +205,6 @@ void spufs_ibox_callback(struct spu *spu);
 void spufs_wbox_callback(struct spu *spu);
 void spufs_stop_callback(struct spu *spu);
 void spufs_mfc_callback(struct spu *spu);
+void spufs_dma_callback(struct spu *spu, int type);
 
 #endif
index 9d9d82dd32ba8d466f5794e6dfaad2685ffb2f3c..0f782ca662ba2cb6a844a173a90cca825728b644 100644 (file)
@@ -1779,6 +1779,15 @@ static inline void restore_mfc_cntl(struct spu_state *csa, struct spu *spu)
         */
        out_be64(&priv2->mfc_control_RW, csa->priv2.mfc_control_RW);
        eieio();
+       /*
+        * FIXME: this is to restart a DMA that we were processing
+        *        before the save. better remember the fault information
+        *        in the csa instead.
+        */
+       if ((csa->priv2.mfc_control_RW & MFC_CNTL_SUSPEND_DMA_QUEUE_MASK)) {
+               out_be64(&priv2->mfc_control_RW, MFC_CNTL_RESTART_DMA_COMMAND);
+               eieio();
+       }
 }
 
 static inline void enable_user_access(struct spu_state *csa, struct spu *spu)
index e6565a949ddc727b11299b4374001ff70a67e326..a6d1ae4dc2a330797f7952008aef3495fd1cc67b 100644 (file)
@@ -38,7 +38,7 @@ static long do_spu_run(struct file *filp,
        u32 npc, status;
 
        ret = -EFAULT;
-       if (get_user(npc, unpc) || get_user(status, ustatus))
+       if (get_user(npc, unpc))
                goto out;
 
        /* check if this file was created by spu_create */
@@ -49,7 +49,10 @@ static long do_spu_run(struct file *filp,
        i = SPUFS_I(filp->f_dentry->d_inode);
        ret = spufs_run_spu(filp, i->i_ctx, &npc, &status);
 
-       if (put_user(npc, unpc) || put_user(status, ustatus))
+       if (put_user(npc, unpc))
+               ret = -EFAULT;
+
+       if (ustatus && put_user(status, ustatus))
                ret = -EFAULT;
 out:
        return ret;
@@ -87,7 +90,7 @@ asmlinkage long sys_spu_create(const char __user *pathname,
                ret = path_lookup(tmp, LOOKUP_PARENT|
                                LOOKUP_OPEN|LOOKUP_CREATE, &nd);
                if (!ret) {
-                       ret = spufs_create_thread(&nd, flags, mode);
+                       ret = spufs_create(&nd, flags, mode);
                        path_release(&nd);
                }
                putname(tmp);
index 488dbd9b51ae1e76aae82f59bd8ca59a81f6b7eb..cae3d13229b995f88374cf0021dac66577c37d30 100644 (file)
@@ -70,7 +70,7 @@ unsigned long event_scan_interval;
  * has to include <linux/interrupt.h> (to get irqreturn_t), which
  * causes all sorts of problems.  -- paulus
  */
-extern irqreturn_t xmon_irq(int, void *, struct pt_regs *);
+extern irqreturn_t xmon_irq(int, void *);
 
 extern unsigned long loops_per_jiffy;
 
@@ -335,12 +335,11 @@ chrp_event_scan(unsigned long unused)
                  jiffies + event_scan_interval);
 }
 
-static void chrp_8259_cascade(unsigned int irq, struct irq_desc *desc,
-                             struct pt_regs *regs)
+static void chrp_8259_cascade(unsigned int irq, struct irq_desc *desc)
 {
-       unsigned int cascade_irq = i8259_irq(regs);
+       unsigned int cascade_irq = i8259_irq();
        if (cascade_irq != NO_IRQ)
-               generic_handle_irq(cascade_irq, regs);
+               generic_handle_irq(cascade_irq);
        desc->chip->eoi(irq);
 }
 
index cb6f084844f2740800fe7a1b7dea14bc4cb9336d..bdb475c65cba267bc039bb8efc2b30368a284b21 100644 (file)
@@ -61,8 +61,7 @@ pci_dram_offset = MPC7448_HPC2_PCI_MEM_OFFSET;
 extern int tsi108_setup_pci(struct device_node *dev);
 extern void _nmask_and_or_msr(unsigned long nmask, unsigned long or_val);
 extern void tsi108_pci_int_init(void);
-extern void tsi108_irq_cascade(unsigned int irq, struct irq_desc *desc,
-                           struct pt_regs *regs);
+extern void tsi108_irq_cascade(unsigned int irq, struct irq_desc *desc);
 
 int mpc7448_hpc2_exclude_device(u_char bus, u_char devfn)
 {
@@ -200,7 +199,7 @@ static void __init mpc7448_hpc2_init_IRQ(void)
        tsi_pic = of_find_node_by_type(NULL, "open-pic");
        if (tsi_pic) {
                unsigned int size;
-               void *prop = get_property(tsi_pic, "reg", &size);
+               const void *prop = get_property(tsi_pic, "reg", &size);
                mpic_paddr = of_translate_address(tsi_pic, prop);
        }
 
index e32446877e78a2edc46e7e36d7da3574d220a084..5225abfafd9b8f44b1ec7e7aeac3cfe800e233a7 100644 (file)
 #include "irq.h"
 #include "pci.h"
 #include "call_pci.h"
-
-#if defined(CONFIG_SMP)
-extern void iSeries_smp_message_recv(struct pt_regs *);
-#endif
+#include "smp.h"
 
 #ifdef CONFIG_PCI
 
@@ -88,7 +85,7 @@ static DEFINE_SPINLOCK(pending_irqs_lock);
 static int num_pending_irqs;
 static int pending_irqs[NR_IRQS];
 
-static void int_received(struct pci_event *event, struct pt_regs *regs)
+static void int_received(struct pci_event *event)
 {
        int irq;
 
@@ -146,11 +143,11 @@ static void int_received(struct pci_event *event, struct pt_regs *regs)
        }
 }
 
-static void pci_event_handler(struct HvLpEvent *event, struct pt_regs *regs)
+static void pci_event_handler(struct HvLpEvent *event)
 {
        if (event && (event->xType == HvLpEvent_Type_PciIo)) {
                if (hvlpevent_is_int(event))
-                       int_received((struct pci_event *)event, regs);
+                       int_received((struct pci_event *)event);
                else
                        printk(KERN_ERR
                                "pci_event_handler: unexpected ack received\n");
@@ -308,18 +305,18 @@ int __init iSeries_allocate_IRQ(HvBusNumber bus,
 /*
  * Get the next pending IRQ.
  */
-unsigned int iSeries_get_irq(struct pt_regs *regs)
+unsigned int iSeries_get_irq(void)
 {
        int irq = NO_IRQ_IGNORE;
 
 #ifdef CONFIG_SMP
        if (get_lppaca()->int_dword.fields.ipi_cnt) {
                get_lppaca()->int_dword.fields.ipi_cnt = 0;
-               iSeries_smp_message_recv(regs);
+               iSeries_smp_message_recv();
        }
 #endif /* CONFIG_SMP */
        if (hvlpevent_is_pending())
-               process_hvlpevents(regs);
+               process_hvlpevents();
 
 #ifdef CONFIG_PCI
        if (num_pending_irqs) {
index 1ee8985140e565d336f0f7d2969952502c9b92ea..69f1b437fc7bb4b90708a6d1e79facc3864a9c39 100644 (file)
@@ -4,6 +4,6 @@
 extern void iSeries_init_IRQ(void);
 extern int  iSeries_allocate_IRQ(HvBusNumber, HvSubBusNumber, u32);
 extern void iSeries_activate_IRQs(void);
-extern unsigned int iSeries_get_irq(struct pt_regs *);
+extern unsigned int iSeries_get_irq(void);
 
 #endif /* _ISERIES_IRQ_H */
index 98c1c2440aad0f6927c11f318c5a56a89dc41a90..e3e929e1b4606cada11840a13f89aed3c5108805 100644 (file)
@@ -116,7 +116,7 @@ static void hvlpevent_clear_valid(struct HvLpEvent * event)
        hvlpevent_invalidate(event);
 }
 
-void process_hvlpevents(struct pt_regs *regs)
+void process_hvlpevents(void)
 {
        struct HvLpEvent * event;
 
@@ -144,7 +144,7 @@ void process_hvlpevents(struct pt_regs *regs)
                                __get_cpu_var(hvlpevent_counts)[event->xType]++;
                        if (event->xType < HvLpEvent_Type_NumTypes &&
                                        lpEventHandler[event->xType])
-                               lpEventHandler[event->xType](event, regs);
+                               lpEventHandler[event->xType](event);
                        else
                                printk(KERN_INFO "Unexpected Lp Event type=%d\n", event->xType );
 
index 1983b640bac117593c84cd42e197fbb9c9771ce3..b5737d68d6c4e41930ce2335456c24bcf82212df 100644 (file)
@@ -513,7 +513,7 @@ static void handle_ack(struct io_mf_lp_event *event)
  * parse it enough to know if it is an interrupt or an
  * acknowledge.
  */
-static void hv_handler(struct HvLpEvent *event, struct pt_regs *regs)
+static void hv_handler(struct HvLpEvent *event)
 {
        if ((event != NULL) && (event->xType == HvLpEvent_Type_MachineFac)) {
                if (hvlpevent_is_ack(event))
@@ -847,7 +847,7 @@ static int mf_get_boot_rtc(struct rtc_time *tm)
        /* We need to poll here as we are not yet taking interrupts */
        while (rtc_data.busy) {
                if (hvlpevent_is_pending())
-                       process_hvlpevents(NULL);
+                       process_hvlpevents();
        }
        return rtc_set_tm(rtc_data.rc, rtc_data.ce_msg.ce_msg, tm);
 }
index 2eb095edb472c213f0cf8a2589a5424913572952..aee5908df7008aecfaa105c5e3b2db2a2b334da5 100644 (file)
 #include <asm/cputable.h>
 #include <asm/system.h>
 
+#include "smp.h"
+
 static unsigned long iSeries_smp_message[NR_CPUS];
 
-void iSeries_smp_message_recv(struct pt_regs *regs)
+void iSeries_smp_message_recv(void)
 {
        int cpu = smp_processor_id();
        int msg;
@@ -55,7 +57,7 @@ void iSeries_smp_message_recv(struct pt_regs *regs)
 
        for (msg = 0; msg < 4; msg++)
                if (test_and_clear_bit(msg, &iSeries_smp_message[cpu]))
-                       smp_message_recv(msg, regs);
+                       smp_message_recv(msg);
 }
 
 static inline void smp_iSeries_do_message(int cpu, int msg)
diff --git a/arch/powerpc/platforms/iseries/smp.h b/arch/powerpc/platforms/iseries/smp.h
new file mode 100644 (file)
index 0000000..d501f7d
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef _PLATFORMS_ISERIES_SMP_H
+#define _PLATFORMS_ISERIES_SMP_H
+
+extern void iSeries_smp_message_recv(void);
+
+#endif /* _PLATFORMS_ISERIES_SMP_H */
index 9baa4ee82592eec2d9723aa045a8ecdd282f83e8..04e07e5da0c10010d7e2c458fc4adb9f921b6779 100644 (file)
@@ -378,7 +378,7 @@ void vio_set_hostlp(void)
 }
 EXPORT_SYMBOL(vio_set_hostlp);
 
-static void vio_handleEvent(struct HvLpEvent *event, struct pt_regs *regs)
+static void vio_handleEvent(struct HvLpEvent *event)
 {
        HvLpIndex remoteLp;
        int subtype = (event->xSubtype & VIOMAJOR_SUBTYPE_MASK)
index 1b827618e05f9f59f412896df8b0f61f5be06191..63b4d1bff359b226a4dd882efbe8757dfcdd2e07 100644 (file)
@@ -8,7 +8,7 @@
  * 2 of the License, or (at your option) any later version.
  */
 
-#define DEBUG
+#undef DEBUG
 
 #include <linux/kernel.h>
 #include <linux/pci.h>
@@ -16,6 +16,7 @@
 #include <linux/string.h>
 #include <linux/init.h>
 #include <linux/bootmem.h>
+#include <linux/irq.h>
 
 #include <asm/sections.h>
 #include <asm/io.h>
@@ -33,7 +34,7 @@
 #define DBG(x...)
 #endif
 
-static struct pci_controller *u3_agp, *u3_ht;
+static struct pci_controller *u3_agp, *u3_ht, *u4_pcie;
 
 static int __init fixup_one_level_bus_range(struct device_node *node, int higher)
 {
@@ -287,6 +288,114 @@ static struct pci_ops u3_ht_pci_ops =
        u3_ht_write_config
 };
 
+static unsigned int u4_pcie_cfa0(unsigned int devfn, unsigned int off)
+{
+       return (1 << PCI_SLOT(devfn))   |
+              (PCI_FUNC(devfn) << 8)   |
+              ((off >> 8) << 28)       |
+              (off & 0xfcu);
+}
+
+static unsigned int u4_pcie_cfa1(unsigned int bus, unsigned int devfn,
+                                unsigned int off)
+{
+        return (bus << 16)             |
+              (devfn << 8)             |
+              ((off >> 8) << 28)       |
+              (off & 0xfcu)            | 1u;
+}
+
+static volatile void __iomem *u4_pcie_cfg_access(struct pci_controller* hose,
+                                        u8 bus, u8 dev_fn, int offset)
+{
+        unsigned int caddr;
+
+        if (bus == hose->first_busno)
+                caddr = u4_pcie_cfa0(dev_fn, offset);
+        else
+                caddr = u4_pcie_cfa1(bus, dev_fn, offset);
+
+        /* Uninorth will return garbage if we don't read back the value ! */
+        do {
+                out_le32(hose->cfg_addr, caddr);
+        } while (in_le32(hose->cfg_addr) != caddr);
+
+        offset &= 0x03;
+        return hose->cfg_data + offset;
+}
+
+static int u4_pcie_read_config(struct pci_bus *bus, unsigned int devfn,
+                               int offset, int len, u32 *val)
+{
+        struct pci_controller *hose;
+        volatile void __iomem *addr;
+
+        hose = pci_bus_to_host(bus);
+        if (hose == NULL)
+                return PCIBIOS_DEVICE_NOT_FOUND;
+        if (offset >= 0x1000)
+                return  PCIBIOS_BAD_REGISTER_NUMBER;
+        addr = u4_pcie_cfg_access(hose, bus->number, devfn, offset);
+        if (!addr)
+                return PCIBIOS_DEVICE_NOT_FOUND;
+        /*
+         * Note: the caller has already checked that offset is
+         * suitably aligned and that len is 1, 2 or 4.
+         */
+        switch (len) {
+        case 1:
+                *val = in_8(addr);
+                break;
+        case 2:
+                *val = in_le16(addr);
+                break;
+        default:
+                *val = in_le32(addr);
+                break;
+        }
+        return PCIBIOS_SUCCESSFUL;
+}
+static int u4_pcie_write_config(struct pci_bus *bus, unsigned int devfn,
+                                int offset, int len, u32 val)
+{
+        struct pci_controller *hose;
+        volatile void __iomem *addr;
+
+        hose = pci_bus_to_host(bus);
+        if (hose == NULL)
+                return PCIBIOS_DEVICE_NOT_FOUND;
+        if (offset >= 0x1000)
+                return  PCIBIOS_BAD_REGISTER_NUMBER;
+        addr = u4_pcie_cfg_access(hose, bus->number, devfn, offset);
+        if (!addr)
+                return PCIBIOS_DEVICE_NOT_FOUND;
+        /*
+         * Note: the caller has already checked that offset is
+         * suitably aligned and that len is 1, 2 or 4.
+         */
+        switch (len) {
+        case 1:
+                out_8(addr, val);
+                (void) in_8(addr);
+                break;
+        case 2:
+                out_le16(addr, val);
+                (void) in_le16(addr);
+                break;
+        default:
+                out_le32(addr, val);
+                (void) in_le32(addr);
+                break;
+        }
+        return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops u4_pcie_pci_ops =
+{
+        u4_pcie_read_config,
+        u4_pcie_write_config
+};
+
 static void __init setup_u3_agp(struct pci_controller* hose)
 {
        /* On G5, we move AGP up to high bus number so we don't need
@@ -307,6 +416,26 @@ static void __init setup_u3_agp(struct pci_controller* hose)
        u3_agp = hose;
 }
 
+static void __init setup_u4_pcie(struct pci_controller* hose)
+{
+        /* We currently only implement the "non-atomic" config space, to
+         * be optimised later.
+         */
+        hose->ops = &u4_pcie_pci_ops;
+        hose->cfg_addr = ioremap(0xf0000000 + 0x800000, 0x1000);
+        hose->cfg_data = ioremap(0xf0000000 + 0xc00000, 0x1000);
+
+        /* The bus contains a bridge from root -> device, we need to
+         * make it visible on bus 0 so that we pick the right type
+         * of config cycles. If we didn't, we would have to force all
+         * config cycles to be type 1. So we override the "bus-range"
+         * property here
+         */
+        hose->first_busno = 0x00;
+        hose->last_busno = 0xff;
+        u4_pcie = hose;
+}
+
 static void __init setup_u3_ht(struct pci_controller* hose)
 {
        hose->ops = &u3_ht_pci_ops;
@@ -354,6 +483,10 @@ static int __init add_bridge(struct device_node *dev)
                setup_u3_ht(hose);
                disp_name = "U3-HT";
                primary = 1;
+        } else if (device_is_compatible(dev, "u4-pcie")) {
+                setup_u4_pcie(hose);
+                disp_name = "U4-PCIE";
+                primary = 0;
        }
        printk(KERN_INFO "Found %s PCI host bridge. Firmware bus number: %d->%d\n",
                disp_name, hose->first_busno, hose->last_busno);
@@ -361,7 +494,6 @@ static int __init add_bridge(struct device_node *dev)
        /* Interpret the "ranges" property */
        /* This also maps the I/O region and sets isa_io/mem_base */
        pci_process_bridge_OF_ranges(hose, dev, primary);
-       pci_setup_phb_io(hose, primary);
 
        /* Fixup "bus-range" OF property */
        fixup_bus_range(dev);
@@ -376,8 +508,30 @@ void __init maple_pcibios_fixup(void)
 
        DBG(" -> maple_pcibios_fixup\n");
 
-       for_each_pci_dev(dev)
+       for_each_pci_dev(dev) {
+               /* Fixup IRQ for PCIe host */
+               if (u4_pcie != NULL && dev->bus->number == 0 &&
+                   pci_bus_to_host(dev->bus) == u4_pcie) {
+                       printk(KERN_DEBUG "Fixup U4 PCIe IRQ\n");
+                       dev->irq = irq_create_mapping(NULL, 1);
+                       if (dev->irq != NO_IRQ)
+                               set_irq_type(dev->irq, IRQ_TYPE_LEVEL_LOW);
+                       continue;
+               }
+
+               /* Hide AMD8111 IDE interrupt when in legacy mode so
+                * the driver calls pci_get_legacy_ide_irq()
+                */
+               if (dev->vendor == PCI_VENDOR_ID_AMD &&
+                   dev->device == PCI_DEVICE_ID_AMD_8111_IDE &&
+                   (dev->class & 5) != 5) {
+                       dev->irq = NO_IRQ;
+                       continue;
+               }
+
+               /* For all others, map the interrupt from the device-tree */
                pci_read_irq_line(dev);
+       }
 
        DBG(" <- maple_pcibios_fixup\n");
 }
@@ -388,8 +542,10 @@ static void __init maple_fixup_phb_resources(void)
        
        list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
                unsigned long offset = (unsigned long)hose->io_base_virt - pci_io_base;
+
                hose->io_resource.start += offset;
                hose->io_resource.end += offset;
+
                printk(KERN_INFO "PCI Host %d, io start: %llx; io end: %llx\n",
                       hose->global_number,
                       (unsigned long long)hose->io_resource.start,
@@ -431,6 +587,19 @@ void __init maple_pci_init(void)
        if (ht && add_bridge(ht) != 0)
                of_node_put(ht);
 
+        /*
+         * We need to call pci_setup_phb_io for the HT bridge first
+         * so it gets the I/O port numbers starting at 0, and we
+         * need to call it for the AGP bridge after that so it gets
+         * small positive I/O port numbers.
+         */
+        if (u3_ht)
+                pci_setup_phb_io(u3_ht, 1);
+        if (u3_agp)
+                pci_setup_phb_io(u3_agp, 0);
+        if (u4_pcie)
+                pci_setup_phb_io(u4_pcie, 0);
+
        /* Fixup the IO resources on our host bridges as the common code
         * does it only for childs of the host bridges
         */
@@ -465,8 +634,11 @@ int maple_pci_get_legacy_ide_irq(struct pci_dev *pdev, int channel)
                return defirq;
 
        np = pci_device_to_OF_node(pdev);
-       if (np == NULL)
+       if (np == NULL) {
+               printk("Failed to locate OF node for IDE %s\n",
+                      pci_name(pdev));
                return defirq;
+       }
        irq = irq_of_parse_and_map(np, channel & 0x1);
        if (irq == NO_IRQ) {
                printk("Failed to map onboard IDE interrupt for channel %d\n",
@@ -479,6 +651,9 @@ int maple_pci_get_legacy_ide_irq(struct pci_dev *pdev, int channel)
 /* XXX: To remove once all firmwares are ok */
 static void fixup_maple_ide(struct pci_dev* dev)
 {
+       if (!machine_is(maple))
+               return;
+
 #if 0 /* Enable this to enable IDE port 0 */
        {
                u8 v;
@@ -495,7 +670,7 @@ static void fixup_maple_ide(struct pci_dev* dev)
        dev->resource[4].start = 0xcc00;
        dev->resource[4].end = 0xcc10;
 #endif
-#if 1 /* Enable this to fixup IDE sense/polarity of irqs in IO-APICs */
+#if 0 /* Enable this to fixup IDE sense/polarity of irqs in IO-APICs */
        {
                struct pci_dev *apicdev;
                u32 v;
index 4679c523041334365ff9ef3add371b0f04ce85bd..39020c1fa13db6f609035d4d5d96af59c047e3a9 100644 (file)
 
 #define CONFIG_OFFSET_VALID(off) ((off) < 4096)
 
-static unsigned long pa_pxp_cfg_addr(struct pci_controller *hose,
+static void volatile __iomem *pa_pxp_cfg_addr(struct pci_controller *hose,
                                       u8 bus, u8 devfn, int offset)
 {
-       return ((unsigned long)hose->cfg_data) + PA_PXP_CFA(bus, devfn, offset);
+       return hose->cfg_data + PA_PXP_CFA(bus, devfn, offset);
 }
 
 static int pa_pxp_read_config(struct pci_bus *bus, unsigned int devfn,
                              int offset, int len, u32 *val)
 {
        struct pci_controller *hose;
-       unsigned long addr;
+       void volatile __iomem *addr;
 
        hose = pci_bus_to_host(bus);
        if (!hose)
@@ -62,13 +62,13 @@ static int pa_pxp_read_config(struct pci_bus *bus, unsigned int devfn,
         */
        switch (len) {
        case 1:
-               *val = in_8((u8 *)addr);
+               *val = in_8(addr);
                break;
        case 2:
-               *val = in_le16((u16 *)addr);
+               *val = in_le16(addr);
                break;
        default:
-               *val = in_le32((u32 *)addr);
+               *val = in_le32(addr);
                break;
        }
 
@@ -79,7 +79,7 @@ static int pa_pxp_write_config(struct pci_bus *bus, unsigned int devfn,
                               int offset, int len, u32 val)
 {
        struct pci_controller *hose;
-       unsigned long addr;
+       void volatile __iomem *addr;
 
        hose = pci_bus_to_host(bus);
        if (!hose)
@@ -96,16 +96,16 @@ static int pa_pxp_write_config(struct pci_bus *bus, unsigned int devfn,
         */
        switch (len) {
        case 1:
-               out_8((u8 *)addr, val);
-               (void) in_8((u8 *)addr);
+               out_8(addr, val);
+               (void) in_8(addr);
                break;
        case 2:
-               out_le16((u16 *)addr, val);
-               (void) in_le16((u16 *)addr);
+               out_le16(addr, val);
+               (void) in_le16(addr);
                break;
        default:
-               out_le32((u32 *)addr, val);
-               (void) in_le32((u32 *)addr);
+               out_le32(addr, val);
+               (void) in_le32(addr);
                break;
        }
        return PCIBIOS_SUCCESSFUL;
index c2c7cf75dd5fa3a339b0b41351c96c25edc12b11..bfc4829162f1f2aba47aeca9b93df92ae3df01d0 100644 (file)
@@ -342,7 +342,7 @@ static void kw_i2c_handle_interrupt(struct pmac_i2c_host_kw *host, u8 isr)
 }
 
 /* Interrupt handler */
-static irqreturn_t kw_i2c_irq(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t kw_i2c_irq(int irq, void *dev_id)
 {
        struct pmac_i2c_host_kw *host = dev_id;
        unsigned long flags;
index ee3b223ab17aa5be88259af47dc33d923ba4437b..5c6c15c5f9a382fc529b636e270986b7825c88f8 100644 (file)
@@ -15,7 +15,7 @@
 #define DBG(fmt...)
 #endif
 
-static irqreturn_t macio_gpio_irq(int irq, void *data, struct pt_regs *regs)
+static irqreturn_t macio_gpio_irq(int irq, void *data)
 {
        pmf_do_irq(data);
 
index 39f7ddb554eaf084f079067f9180eeb69f4fe98c..39db12890214e5e905cb69b01bc0c9a6c4bf1ad0 100644 (file)
@@ -42,7 +42,7 @@
  * has to include <linux/interrupt.h> (to get irqreturn_t), which
  * causes all sorts of problems.  -- paulus
  */
-extern irqreturn_t xmon_irq(int, void *, struct pt_regs *);
+extern irqreturn_t xmon_irq(int, void *);
 
 #ifdef CONFIG_PPC32
 struct pmac_irq_hw {
@@ -210,7 +210,7 @@ static struct irq_chip pmac_pic = {
        .retrigger      = pmac_retrigger,
 };
 
-static irqreturn_t gatwick_action(int cpl, void *dev_id, struct pt_regs *regs)
+static irqreturn_t gatwick_action(int cpl, void *dev_id)
 {
        unsigned long flags;
        int irq, bits;
@@ -227,7 +227,7 @@ static irqreturn_t gatwick_action(int cpl, void *dev_id, struct pt_regs *regs)
                        continue;
                irq += __ilog2(bits);
                spin_unlock_irqrestore(&pmac_pic_lock, flags);
-               __do_IRQ(irq, regs);
+               __do_IRQ(irq);
                spin_lock_irqsave(&pmac_pic_lock, flags);
                rc = IRQ_HANDLED;
        }
@@ -235,18 +235,18 @@ static irqreturn_t gatwick_action(int cpl, void *dev_id, struct pt_regs *regs)
        return rc;
 }
 
-static unsigned int pmac_pic_get_irq(struct pt_regs *regs)
+static unsigned int pmac_pic_get_irq(void)
 {
        int irq;
        unsigned long bits = 0;
        unsigned long flags;
 
 #ifdef CONFIG_SMP
-       void psurge_smp_message_recv(struct pt_regs *);
+       void psurge_smp_message_recv(void);
 
                /* IPI's are a hack on the powersurge -- Cort */
                if ( smp_processor_id() != 0 ) {
-               psurge_smp_message_recv(regs);
+               psurge_smp_message_recv();
                return NO_IRQ_IGNORE;   /* ignore, already handled */
         }
 #endif /* CONFIG_SMP */
@@ -440,14 +440,13 @@ static void __init pmac_pic_probe_oldstyle(void)
 }
 #endif /* CONFIG_PPC32 */
 
-static void pmac_u3_cascade(unsigned int irq, struct irq_desc *desc,
-                           struct pt_regs *regs)
+static void pmac_u3_cascade(unsigned int irq, struct irq_desc *desc)
 {
        struct mpic *mpic = desc->handler_data;
 
-       unsigned int cascade_irq = mpic_get_one_irq(mpic, regs);
+       unsigned int cascade_irq = mpic_get_one_irq(mpic);
        if (cascade_irq != NO_IRQ)
-               generic_handle_irq(cascade_irq, regs);
+               generic_handle_irq(cascade_irq);
        desc->chip->eoi(irq);
 }
 
index 664103dfeef92edcc5f09ab033e723b94a96c0ca..c44c89f5e532177fb005a3a647bb0dd5574f33c5 100644 (file)
@@ -5,7 +5,7 @@
 
 extern struct hw_interrupt_type pmac_pic;
 
-void pmac_pic_init(void);
-int pmac_get_irq(struct pt_regs *regs);
+extern void pmac_pic_init(void);
+extern int pmac_get_irq(void);
 
 #endif /* __PPC_PLATFORMS_PMAC_PIC_H */
index 1949b657b0926158cf10fc2f226fc43b4600b695..eeb2ae5ffc581a1a0c33707365cf7ee45d6ede78 100644 (file)
@@ -160,7 +160,7 @@ static inline void psurge_clr_ipi(int cpu)
  */
 static unsigned long psurge_smp_message[NR_CPUS];
 
-void psurge_smp_message_recv(struct pt_regs *regs)
+void psurge_smp_message_recv(void)
 {
        int cpu = smp_processor_id();
        int msg;
@@ -174,12 +174,12 @@ void psurge_smp_message_recv(struct pt_regs *regs)
        /* make sure there is a message there */
        for (msg = 0; msg < 4; msg++)
                if (test_and_clear_bit(msg, &psurge_smp_message[cpu]))
-                       smp_message_recv(msg, regs);
+                       smp_message_recv(msg);
 }
 
-irqreturn_t psurge_primary_intr(int irq, void *d, struct pt_regs *regs)
+irqreturn_t psurge_primary_intr(int irq, void *d)
 {
-       psurge_smp_message_recv(regs);
+       psurge_smp_message_recv();
        return IRQ_HANDLED;
 }
 
@@ -328,6 +328,7 @@ static void __init smp_psurge_kick_cpu(int nr)
 {
        unsigned long start = __pa(__secondary_start_pmac_0) + nr * 8;
        unsigned long a;
+       int i;
 
        /* may need to flush here if secondary bats aren't setup */
        for (a = KERNELBASE; a < KERNELBASE + 0x800000; a += 32)
@@ -340,7 +341,11 @@ static void __init smp_psurge_kick_cpu(int nr)
        mb();
 
        psurge_set_ipi(nr);
-       udelay(10);
+       /*
+        * We can't use udelay here because the timebase is now frozen.
+        */
+       for (i = 0; i < 2000; ++i)
+               barrier();
        psurge_clr_ipi(nr);
 
        if (ppc_md.progress) ppc_md.progress("smp_psurge_kick_cpu - done", 0x354);
index bbf2e34dc3582442a9e65c2a404c4e7ddd31619e..d24ba547e53f162a9a95e47a474ddbfb17be4530 100644 (file)
@@ -267,7 +267,8 @@ static void iommu_table_setparms(struct pci_controller *phb,
                                 struct iommu_table *tbl)
 {
        struct device_node *node;
-       const unsigned long *basep, *sizep;
+       const unsigned long *basep;
+       const u32 *sizep;
 
        node = (struct device_node *)phb->arch_data;
 
index 311ed1993fc036de995f444bac92d1a327236c89..b1d3d161249ec4724a4b14a685ad38c8d9ba6009 100644 (file)
@@ -65,16 +65,14 @@ static int ras_check_exception_token;
 #define EPOW_SENSOR_INDEX      0
 #define RAS_VECTOR_OFFSET      0x500
 
-static irqreturn_t ras_epow_interrupt(int irq, void *dev_id,
-                                       struct pt_regs * regs);
-static irqreturn_t ras_error_interrupt(int irq, void *dev_id,
-                                       struct pt_regs * regs);
+static irqreturn_t ras_epow_interrupt(int irq, void *dev_id);
+static irqreturn_t ras_error_interrupt(int irq, void *dev_id);
 
 /* #define DEBUG */
 
 
 static void request_ras_irqs(struct device_node *np,
-                       irqreturn_t (*handler)(int, void *, struct pt_regs *),
+                       irq_handler_t handler,
                        const char *name)
 {
        int i, index, count = 0;
@@ -166,8 +164,7 @@ __initcall(init_ras_IRQ);
  * to examine the type of power failure and take appropriate action where
  * the time horizon permits something useful to be done.
  */
-static irqreturn_t
-ras_epow_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+static irqreturn_t ras_epow_interrupt(int irq, void *dev_id)
 {
        int status = 0xdeadbeef;
        int state = 0;
@@ -210,8 +207,7 @@ ras_epow_interrupt(int irq, void *dev_id, struct pt_regs * regs)
  * For nonrecoverable errors, an error is logged and we stop all processing
  * as quickly as possible in order to prevent propagation of the failure.
  */
-static irqreturn_t
-ras_error_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+static irqreturn_t ras_error_interrupt(int irq, void *dev_id)
 {
        struct rtas_error_log *rtas_elog;
        int status = 0xdeadbeef;
index f82b13e531a3d8a06c600e646103045f57b065b3..89a8119f988d697f0c7fa0b8edfdf3f3feb3240a 100644 (file)
@@ -121,12 +121,11 @@ static void __init fwnmi_init(void)
                fwnmi_active = 1;
 }
 
-void pseries_8259_cascade(unsigned int irq, struct irq_desc *desc,
-                         struct pt_regs *regs)
+void pseries_8259_cascade(unsigned int irq, struct irq_desc *desc)
 {
-       unsigned int cascade_irq = i8259_irq(regs);
+       unsigned int cascade_irq = i8259_irq();
        if (cascade_irq != NO_IRQ)
-               generic_handle_irq(cascade_irq, regs);
+               generic_handle_irq(cascade_irq);
        desc->chip->eoi(irq);
 }
 
index 253972e5479fc8dc5252de72f217be11f1b69255..d071abe78ab196943a56b8ee9ce097650a34cb00 100644 (file)
@@ -308,14 +308,14 @@ static inline unsigned int xics_remap_irq(unsigned int vec)
        return NO_IRQ;
 }
 
-static unsigned int xics_get_irq_direct(struct pt_regs *regs)
+static unsigned int xics_get_irq_direct(void)
 {
        unsigned int cpu = smp_processor_id();
 
        return xics_remap_irq(direct_xirr_info_get(cpu));
 }
 
-static unsigned int xics_get_irq_lpar(struct pt_regs *regs)
+static unsigned int xics_get_irq_lpar(void)
 {
        unsigned int cpu = smp_processor_id();
 
@@ -324,7 +324,7 @@ static unsigned int xics_get_irq_lpar(struct pt_regs *regs)
 
 #ifdef CONFIG_SMP
 
-static irqreturn_t xics_ipi_dispatch(int cpu, struct pt_regs *regs)
+static irqreturn_t xics_ipi_dispatch(int cpu)
 {
        WARN_ON(cpu_is_offline(cpu));
 
@@ -332,47 +332,47 @@ static irqreturn_t xics_ipi_dispatch(int cpu, struct pt_regs *regs)
                if (test_and_clear_bit(PPC_MSG_CALL_FUNCTION,
                                       &xics_ipi_message[cpu].value)) {
                        mb();
-                       smp_message_recv(PPC_MSG_CALL_FUNCTION, regs);
+                       smp_message_recv(PPC_MSG_CALL_FUNCTION);
                }
                if (test_and_clear_bit(PPC_MSG_RESCHEDULE,
                                       &xics_ipi_message[cpu].value)) {
                        mb();
-                       smp_message_recv(PPC_MSG_RESCHEDULE, regs);
+                       smp_message_recv(PPC_MSG_RESCHEDULE);
                }
 #if 0
                if (test_and_clear_bit(PPC_MSG_MIGRATE_TASK,
                                       &xics_ipi_message[cpu].value)) {
                        mb();
-                       smp_message_recv(PPC_MSG_MIGRATE_TASK, regs);
+                       smp_message_recv(PPC_MSG_MIGRATE_TASK);
                }
 #endif
 #if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC)
                if (test_and_clear_bit(PPC_MSG_DEBUGGER_BREAK,
                                       &xics_ipi_message[cpu].value)) {
                        mb();
-                       smp_message_recv(PPC_MSG_DEBUGGER_BREAK, regs);
+                       smp_message_recv(PPC_MSG_DEBUGGER_BREAK);
                }
 #endif
        }
        return IRQ_HANDLED;
 }
 
-static irqreturn_t xics_ipi_action_direct(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t xics_ipi_action_direct(int irq, void *dev_id)
 {
        int cpu = smp_processor_id();
 
        direct_qirr_info(cpu, 0xff);
 
-       return xics_ipi_dispatch(cpu, regs);
+       return xics_ipi_dispatch(cpu);
 }
 
-static irqreturn_t xics_ipi_action_lpar(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t xics_ipi_action_lpar(int irq, void *dev_id)
 {
        int cpu = smp_processor_id();
 
        lpar_qirr_info(cpu, 0xff);
 
-       return xics_ipi_dispatch(cpu, regs);
+       return xics_ipi_dispatch(cpu);
 }
 
 void xics_cause_IPI(int cpu)
index 6ee1055b0ffb60ba3e8afd858442aad8b79d7110..db0ec3ba3ae2a96f1008544b50ea594280aefa29 100644 (file)
@@ -31,7 +31,6 @@ struct xics_ipi_struct {
 extern struct xics_ipi_struct xics_ipi_message[NR_CPUS] __cacheline_aligned;
 
 struct irq_desc;
-extern void pseries_8259_cascade(unsigned int irq, struct irq_desc *desc,
-                                struct pt_regs *regs);
+extern void pseries_8259_cascade(unsigned int irq, struct irq_desc *desc);
 
 #endif /* _POWERPC_KERNEL_XICS_H */
index 28b0189947463146fdbcd63e9b4ea931d31e33b7..767ee6651adc2be412c3c574b4f7026126c27c1f 100644 (file)
@@ -147,7 +147,7 @@ static struct irq_chip cpm2_pic = {
        .end = cpm2_end_irq,
 };
 
-unsigned int cpm2_get_irq(struct pt_regs *regs)
+unsigned int cpm2_get_irq(void)
 {
        int irq;
        unsigned long bits;
index 3c513e5a688e4681cd33276f878ae451454cb4be..2840616529e46af0b514f5fa9d22018224fed718 100644 (file)
@@ -3,7 +3,7 @@
 
 extern intctl_cpm2_t *cpm2_intctl;
 
-extern unsigned int cpm2_get_irq(struct pt_regs *regs);
+extern unsigned int cpm2_get_irq(void);
 
 extern void cpm2_pic_init(struct device_node*);
 
index 7d759f1c26b19fe61a5df4813861b18b3071d509..dbe92ae2033319d89ffff84ad9e559d5d72189a8 100644 (file)
@@ -567,7 +567,7 @@ static int __init fs_enet_of_init(void)
                struct resource r[4];
                struct device_node *phy, *mdio;
                struct fs_platform_info fs_enet_data;
-               const unsigned int *id, *phy_addr, phy_irq;
+               const unsigned int *id, *phy_addr, *phy_irq;
                const void *mac_addr;
                const phandle *ph;
                const char *model;
@@ -641,7 +641,7 @@ static int __init fs_enet_of_init(void)
 
                if (strstr(model, "FCC")) {
                        int fcc_index = *id - 1;
-                       unsigned char* mdio_bb_prop;
+                       const unsigned char *mdio_bb_prop;
 
                        fs_enet_data.dpram_offset = (u32)cpm_dpram_addr(0);
                        fs_enet_data.rx_ring = 32;
@@ -708,8 +708,9 @@ static int __init fs_enet_of_init(void)
                        ret = platform_device_add_data(fs_enet_dev, &fs_enet_data,
                                                     sizeof(struct
                                                            fs_platform_info));
-               if (ret)
-                       goto unreg;
+                       if (ret)
+                               goto unreg;
+               }
        }
        return 0;
 
index 26a6a3becd66eb61901831765d15f7986ec4d196..0450265d73bbe38e628829ea2f9219046c5d7f8e 100644 (file)
@@ -34,7 +34,7 @@ static struct irq_host *i8259_host;
  * which is called.  It should be noted that polling is broken on some
  * IBM and Motorola PReP boxes so we must use the int-ack feature on them.
  */
-unsigned int i8259_irq(struct pt_regs *regs)
+unsigned int i8259_irq(void)
 {
        int irq;
        int lock = 0;
index 6ebdae8e6f692a715cbcad22e7d4d70ab2a64944..bc4d4a7f9657d39c4ae037e39ac6a81d9d9a3444 100644 (file)
@@ -709,7 +709,7 @@ void ipic_clear_mcp_status(u32 mask)
 }
 
 /* Return an interrupt vector or NO_IRQ if no interrupt is pending. */
-unsigned int ipic_get_irq(struct pt_regs *regs)
+unsigned int ipic_get_irq(void)
 {
        int irq;
 
index 3ee03a9a98fa2bda05ca8859258901bc60279b19..ba4833f57d47e343b2433c14350f612d0beace03 100644 (file)
@@ -489,9 +489,9 @@ static inline void mpic_eoi(struct mpic *mpic)
 }
 
 #ifdef CONFIG_SMP
-static irqreturn_t mpic_ipi_action(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t mpic_ipi_action(int irq, void *dev_id)
 {
-       smp_message_recv(mpic_irq_to_hw(irq) - MPIC_VEC_IPI_0, regs);
+       smp_message_recv(mpic_irq_to_hw(irq) - MPIC_VEC_IPI_0);
        return IRQ_HANDLED;
 }
 #endif /* CONFIG_SMP */
@@ -1217,7 +1217,7 @@ void mpic_send_ipi(unsigned int ipi_no, unsigned int cpu_mask)
                       mpic_physmask(cpu_mask & cpus_addr(cpu_online_map)[0]));
 }
 
-unsigned int mpic_get_one_irq(struct mpic *mpic, struct pt_regs *regs)
+unsigned int mpic_get_one_irq(struct mpic *mpic)
 {
        u32 src;
 
@@ -1230,13 +1230,13 @@ unsigned int mpic_get_one_irq(struct mpic *mpic, struct pt_regs *regs)
        return irq_linear_revmap(mpic->irqhost, src);
 }
 
-unsigned int mpic_get_irq(struct pt_regs *regs)
+unsigned int mpic_get_irq(void)
 {
        struct mpic *mpic = mpic_primary;
 
        BUG_ON(mpic == NULL);
 
-       return mpic_get_one_irq(mpic, regs);
+       return mpic_get_one_irq(mpic);
 }
 
 
index c229d07d4957627ebc3735e4354cd6b1a8bb5c86..6995f51b94882bdcf55815572c305d42516e4771 100644 (file)
@@ -300,7 +300,7 @@ static struct irq_host_ops qe_ic_host_ops = {
 };
 
 /* Return an interrupt vector or NO_IRQ if no interrupt is pending. */
-unsigned int qe_ic_get_low_irq(struct qe_ic *qe_ic, struct pt_regs *regs)
+unsigned int qe_ic_get_low_irq(struct qe_ic *qe_ic)
 {
        int irq;
 
@@ -316,7 +316,7 @@ unsigned int qe_ic_get_low_irq(struct qe_ic *qe_ic, struct pt_regs *regs)
 }
 
 /* Return an interrupt vector or NO_IRQ if no interrupt is pending. */
-unsigned int qe_ic_get_high_irq(struct qe_ic *qe_ic, struct pt_regs *regs)
+unsigned int qe_ic_get_high_irq(struct qe_ic *qe_ic)
 {
        int irq;
 
@@ -333,33 +333,31 @@ unsigned int qe_ic_get_high_irq(struct qe_ic *qe_ic, struct pt_regs *regs)
 
 /* FIXME: We mask all the QE Low interrupts while handling.  We should
  * let other interrupt come in, but BAD interrupts are generated */
-void fastcall qe_ic_cascade_low(unsigned int irq, struct irq_desc *desc,
-                               struct pt_regs *regs)
+void fastcall qe_ic_cascade_low(unsigned int irq, struct irq_desc *desc)
 {
        struct qe_ic *qe_ic = desc->handler_data;
        struct irq_chip *chip = irq_desc[irq].chip;
 
-       unsigned int cascade_irq = qe_ic_get_low_irq(qe_ic, regs);
+       unsigned int cascade_irq = qe_ic_get_low_irq(qe_ic);
 
        chip->mask_ack(irq);
        if (cascade_irq != NO_IRQ)
-               generic_handle_irq(cascade_irq, regs);
+               generic_handle_irq(cascade_irq);
        chip->unmask(irq);
 }
 
 /* FIXME: We mask all the QE High interrupts while handling.  We should
  * let other interrupt come in, but BAD interrupts are generated */
-void fastcall qe_ic_cascade_high(unsigned int irq, struct irq_desc *desc,
-                                struct pt_regs *regs)
+void fastcall qe_ic_cascade_high(unsigned int irq, struct irq_desc *desc)
 {
        struct qe_ic *qe_ic = desc->handler_data;
        struct irq_chip *chip = irq_desc[irq].chip;
 
-       unsigned int cascade_irq = qe_ic_get_high_irq(qe_ic, regs);
+       unsigned int cascade_irq = qe_ic_get_high_irq(qe_ic);
 
        chip->mask_ack(irq);
        if (cascade_irq != NO_IRQ)
-               generic_handle_irq(cascade_irq, regs);
+               generic_handle_irq(cascade_irq);
        chip->unmask(irq);
 }
 
index aea4359703892b25de9d4b00ccd94083c8c73c3a..0afe6bfe371455d90ba665bfcc57b9422159c471 100644 (file)
@@ -14,7 +14,6 @@
  * option) any later version.
  */
 
-#include <linux/config.h>
 #include <linux/stddef.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
index c28f69bef8e2012a9429a759d60257d71bd0405a..322f86e93de5b43f677e7bbc7e26a2a80fcb417c 100644 (file)
@@ -405,11 +405,10 @@ void __init tsi108_pci_int_init(void)
        init_pci_source();
 }
 
-void tsi108_irq_cascade(unsigned int irq, struct irq_desc *desc,
-                           struct pt_regs *regs)
+void tsi108_irq_cascade(unsigned int irq, struct irq_desc *desc)
 {
        unsigned int cascade_irq = get_pci_source();
        if (cascade_irq != NO_IRQ)
-               generic_handle_irq(cascade_irq, regs);
+               generic_handle_irq(cascade_irq);
        desc->chip->eoi(irq);
 }
index 708236f3474612a2aad9fc252a458cf1d270e7fc..f56ffef4defa7f0b3724fea942afda436008d3a8 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/module.h>
 #include <linux/sysrq.h>
 #include <linux/interrupt.h>
+#include <linux/irq.h>
 
 #include <asm/ptrace.h>
 #include <asm/string.h>
@@ -35,6 +36,7 @@
 #include <asm/rtas.h>
 #include <asm/sstep.h>
 #include <asm/bug.h>
+#include <asm/irq_regs.h>
 
 #ifdef CONFIG_PPC64
 #include <asm/hvcall.h>
@@ -520,13 +522,12 @@ int xmon(struct pt_regs *excp)
 }
 EXPORT_SYMBOL(xmon);
 
-irqreturn_t
-xmon_irq(int irq, void *d, struct pt_regs *regs)
+irqreturn_t xmon_irq(int irq, void *d)
 {
        unsigned long flags;
        local_irq_save(flags);
        printf("Keyboard interrupt\n");
-       xmon(regs);
+       xmon(get_irq_regs());
        local_irq_restore(flags);
        return IRQ_HANDLED;
 }
@@ -2577,12 +2578,11 @@ void xmon_init(int enable)
 }
 
 #ifdef CONFIG_MAGIC_SYSRQ
-static void sysrq_handle_xmon(int key, struct pt_regs *pt_regs,
-                             struct tty_struct *tty) 
+static void sysrq_handle_xmon(int key, struct tty_struct *tty) 
 {
        /* ensure xmon is enabled */
        xmon_init(1);
-       debugger(pt_regs);
+       debugger(get_irq_regs());
 }
 
 static struct sysrq_key_op sysrq_xmon_op = 
index 87fe9a89dba710f1afd9d5c9f5b5ecb1a5a173f3..e35483961b9071af1f46643cd4b875bb2673d74e 100644 (file)
@@ -414,7 +414,7 @@ static void siccuart_event(struct SICC_info *info, int event)
 }
 
 static void
-siccuart_rx_chars(struct SICC_info *info, struct pt_regs *regs)
+siccuart_rx_chars(struct SICC_info *info)
 {
     struct tty_struct *tty = info->tty;
     unsigned int status, ch, rsr, flg, ignored = 0;
@@ -441,7 +441,7 @@ siccuart_rx_chars(struct SICC_info *info, struct pt_regs *regs)
 #ifdef SUPPORT_SYSRQ
         if (info->sysrq) {
             if (ch && time_before(jiffies, info->sysrq)) {
-                handle_sysrq(ch, regs, NULL);
+                handle_sysrq(ch, NULL);
                 info->sysrq = 0;
                 goto ignore_char;
             }
@@ -553,15 +553,15 @@ static void siccuart_tx_chars(struct SICC_info *info)
 }
 
 
-static irqreturn_t siccuart_int_rx(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t siccuart_int_rx(int irq, void *dev_id)
 {
     struct SICC_info *info = dev_id;
-    siccuart_rx_chars(info, regs);
+    siccuart_rx_chars(info)
     return IRQ_HANDLED;
 }
 
 
-static irqreturn_t siccuart_int_tx(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t siccuart_int_tx(int irq, void *dev_id)
 {
     struct SICC_info *info = dev_id;
     siccuart_tx_chars(info);
index ac6d55fe22359c3ab2cd7854d95d227f8d49117f..a6056c29cf007885d77a658445d81f49fda0b0f2 100644 (file)
@@ -122,7 +122,7 @@ struct scc_enet_private {
 static int scc_enet_open(struct net_device *dev);
 static int scc_enet_start_xmit(struct sk_buff *skb, struct net_device *dev);
 static int scc_enet_rx(struct net_device *dev);
-static irqreturn_t scc_enet_interrupt(int irq, void *dev_id, struct pt_regs *);
+static irqreturn_t scc_enet_interrupt(int irq, void *dev_id);
 static int scc_enet_close(struct net_device *dev);
 static struct net_device_stats *scc_enet_get_stats(struct net_device *dev);
 static void set_multicast_list(struct net_device *dev);
@@ -273,7 +273,7 @@ scc_enet_timeout(struct net_device *dev)
  * This is called from the CPM handler, not the MPC core interrupt.
  */
 static irqreturn_t
-scc_enet_interrupt(int irq, void * dev_id, struct pt_regs * regs)
+scc_enet_interrupt(int irq, void * dev_id)
 {
        struct  net_device *dev = dev_id;
        volatile struct scc_enet_private *cep;
index e347fe88316d4b375fd67a8bf4505da0ec8dda7d..2e1943e2781963886eda3a1b8ea2afdbb6850060 100644 (file)
@@ -140,7 +140,7 @@ typedef struct {
 static int fcc_enet_open(struct net_device *dev);
 static int fcc_enet_start_xmit(struct sk_buff *skb, struct net_device *dev);
 static int fcc_enet_rx(struct net_device *dev);
-static irqreturn_t fcc_enet_interrupt(int irq, void *dev_id, struct pt_regs *);
+static irqreturn_t fcc_enet_interrupt(int irq, void *dev_id);
 static int fcc_enet_close(struct net_device *dev);
 static struct net_device_stats *fcc_enet_get_stats(struct net_device *dev);
 /* static void set_multicast_list(struct net_device *dev); */
@@ -524,7 +524,7 @@ fcc_enet_timeout(struct net_device *dev)
 
 /* The interrupt handler. */
 static irqreturn_t
-fcc_enet_interrupt(int irq, void * dev_id, struct pt_regs * regs)
+fcc_enet_interrupt(int irq, void * dev_id)
 {
        struct  net_device *dev = dev_id;
        volatile struct fcc_enet_private *cep;
@@ -1563,7 +1563,7 @@ mii_discover_phy(uint mii_reg, struct net_device *dev)
 #ifdef PHY_INTERRUPT
 /* This interrupt occurs when the PHY detects a link change. */
 static irqreturn_t
-mii_link_interrupt(int irq, void * dev_id, struct pt_regs * regs)
+mii_link_interrupt(int irq, void * dev_id)
 {
        struct  net_device *dev = dev_id;
        struct fcc_enet_private *fep = dev->priv;
index 9b3ace26280cb85301fd2954492f6dcb47530750..3b23bcb35b7abf9f8b3bd1c2efc9373f53ac60db 100644 (file)
@@ -47,12 +47,12 @@ cpm8xx_t    *cpmp;          /* Pointer to comm processor space */
 /* CPM interrupt vector functions.
 */
 struct cpm_action {
-       void    (*handler)(void *, struct pt_regs * regs);
+       void    (*handler)(void *);
        void    *dev_id;
 };
 static struct  cpm_action cpm_vecs[CPMVEC_NR];
-static irqreturn_t cpm_interrupt(int irq, void * dev, struct pt_regs * regs);
-static irqreturn_t cpm_error_interrupt(int irq, void *dev, struct pt_regs * regs);
+static irqreturn_t cpm_interrupt(int irq, void * dev);
+static irqreturn_t cpm_error_interrupt(int irq, void *dev);
 static void    alloc_host_memory(void);
 /* Define a table of names to identify CPM interrupt handlers in
  * /proc/interrupts.
@@ -205,7 +205,7 @@ cpm_interrupt_init(void)
  * Get the CPM interrupt vector.
  */
 int
-cpm_get_irq(struct pt_regs *regs)
+cpm_get_irq(void)
 {
        int cpm_vec;
 
@@ -222,7 +222,7 @@ cpm_get_irq(struct pt_regs *regs)
 /* CPM interrupt controller cascade interrupt.
 */
 static irqreturn_t
-cpm_interrupt(int irq, void * dev, struct pt_regs * regs)
+cpm_interrupt(int irq, void * dev)
 {
        /* This interrupt handler never actually gets called.  It is
         * installed only to unmask the CPM cascade interrupt in the SIU
@@ -237,7 +237,7 @@ cpm_interrupt(int irq, void * dev, struct pt_regs * regs)
  * tests in the interrupt handler.
  */
 static irqreturn_t
-cpm_error_interrupt(int irq, void *dev, struct pt_regs *regs)
+cpm_error_interrupt(int irq, void *dev)
 {
        return IRQ_HANDLED;
 }
@@ -246,11 +246,11 @@ cpm_error_interrupt(int irq, void *dev, struct pt_regs *regs)
  * request_irq() to the handler prototype required by cpm_install_handler().
  */
 static irqreturn_t
-cpm_handler_helper(int irq, void *dev_id, struct pt_regs *regs)
+cpm_handler_helper(int irq, void *dev_id)
 {
        int cpm_vec = irq - CPM_IRQ_OFFSET;
 
-       (*cpm_vecs[cpm_vec].handler)(dev_id, regs);
+       (*cpm_vecs[cpm_vec].handler)(dev_id);
 
        return IRQ_HANDLED;
 }
@@ -267,8 +267,7 @@ cpm_handler_helper(int irq, void *dev_id, struct pt_regs *regs)
  * request_irq() or cpm_install_handler().
  */
 void
-cpm_install_handler(int cpm_vec, void (*handler)(void *, struct pt_regs *regs),
-                   void *dev_id)
+cpm_install_handler(int cpm_vec, void (*handler)(void *), void *dev_id)
 {
        int err;
 
index f5f300fc213de91631e135e1289d3887e38ef864..959d31c26cbb121836d2a56a3b39d8087defeba3 100644 (file)
@@ -331,7 +331,7 @@ static int CS_SetFormat(int format);
 static int CS_SetVolume(int volume);
 static void cs4218_tdm_tx_intr(void *devid);
 static void cs4218_tdm_rx_intr(void *devid);
-static void cs4218_intr(void *devid, struct pt_regs *regs);
+static void cs4218_intr(void *devid);
 static int cs_get_volume(uint reg);
 static int cs_volume_setter(int volume, int mute);
 static int cs_get_gain(uint reg);
@@ -2646,7 +2646,7 @@ int __init tdm8xx_sound_init(void)
  * full duplex operation.
  */
 static void
-cs4218_intr(void *dev_id, struct pt_regs *regs)
+cs4218_intr(void *dev_id)
 {
        volatile smc_t  *sp;
        volatile cpm8xx_t       *cp;
index a695375c3e4c58f37906657914aafc66c37d2f33..b23c45bc151a220471cb678c847fa914127e6dcc 100644 (file)
@@ -149,7 +149,7 @@ struct scc_enet_private {
 static int scc_enet_open(struct net_device *dev);
 static int scc_enet_start_xmit(struct sk_buff *skb, struct net_device *dev);
 static int scc_enet_rx(struct net_device *dev);
-static void scc_enet_interrupt(void *dev_id, struct pt_regs *regs);
+static void scc_enet_interrupt(void *dev_id);
 static int scc_enet_close(struct net_device *dev);
 static struct net_device_stats *scc_enet_get_stats(struct net_device *dev);
 static void set_multicast_list(struct net_device *dev);
@@ -305,7 +305,7 @@ scc_enet_timeout(struct net_device *dev)
  * This is called from the CPM handler, not the MPC core interrupt.
  */
 static void
-scc_enet_interrupt(void *dev_id, struct pt_regs *regs)
+scc_enet_interrupt(void *dev_id)
 {
        struct  net_device *dev = dev_id;
        volatile struct scc_enet_private *cep;
index 8b6295bbb564626ff5fab4466b0536bc94ec618a..2f9fa9e3d331fcdc903164068262156de075bb2c 100644 (file)
@@ -198,8 +198,7 @@ static int fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev);
 #ifdef CONFIG_USE_MDIO
 static void fec_enet_mii(struct net_device *dev);
 #endif /* CONFIG_USE_MDIO */
-static irqreturn_t fec_enet_interrupt(int irq, void * dev_id,
-                                                       struct pt_regs * regs);
+static irqreturn_t fec_enet_interrupt(int irq, void * dev_id);
 #ifdef CONFIG_FEC_PACKETHOOK
 static void  fec_enet_tx(struct net_device *dev, __u32 regval);
 static void  fec_enet_rx(struct net_device *dev, __u32 regval);
@@ -472,7 +471,7 @@ fec_timeout(struct net_device *dev)
  * This is called from the MPC core interrupt.
  */
 static irqreturn_t
-fec_enet_interrupt(int irq, void * dev_id, struct pt_regs * regs)
+fec_enet_interrupt(int irq, void * dev_id)
 {
        struct  net_device *dev = dev_id;
        volatile fec_t  *fecp;
@@ -1408,7 +1407,7 @@ static
 #ifdef CONFIG_RPXCLASSIC
 void mii_link_interrupt(void *dev_id)
 #else
-irqreturn_t mii_link_interrupt(int irq, void * dev_id, struct pt_regs * regs)
+irqreturn_t mii_link_interrupt(int irq, void * dev_id)
 #endif
 {
 #ifdef CONFIG_USE_MDIO
index ca57e896a36c339196a9e23b1e15f3e918670760..96a55972b986bd7103270ceeabd037e21edbb4bb 100644 (file)
@@ -84,7 +84,7 @@ smp_message_pass(int target, int msg)
 /*
  * Common functions
  */
-void smp_message_recv(int msg, struct pt_regs *regs)
+void smp_message_recv(int msg)
 {
        atomic_inc(&ipi_recv);
 
@@ -100,7 +100,7 @@ void smp_message_recv(int msg, struct pt_regs *regs)
                break;
 #ifdef CONFIG_XMON
        case PPC_MSG_XMON_BREAK:
-               xmon(regs);
+               xmon(get_irq_regs());
                break;
 #endif /* CONFIG_XMON */
        default:
index 187388625a768ed45a15d3bb68c0c93dc491e8af..18ee851e33e387675ae6d9e7ab5fb18091732247 100644 (file)
@@ -62,6 +62,7 @@
 #include <asm/cache.h>
 #include <asm/8xx_immap.h>
 #include <asm/machdep.h>
+#include <asm/irq_regs.h>
 
 #include <asm/time.h>
 
@@ -129,6 +130,7 @@ void wakeup_decrementer(void)
  */
 void timer_interrupt(struct pt_regs * regs)
 {
+       struct pt_regs *old_regs;
        int next_dec;
        unsigned long cpu = smp_processor_id();
        unsigned jiffy_stamp = last_jiffy_stamp(cpu);
@@ -137,12 +139,13 @@ void timer_interrupt(struct pt_regs * regs)
        if (atomic_read(&ppc_n_lost_interrupts) != 0)
                do_IRQ(regs);
 
+       old_regs = set_irq_regs(regs);
        irq_enter();
 
        while ((next_dec = tb_ticks_per_jiffy - tb_delta(&jiffy_stamp)) <= 0) {
                jiffy_stamp += tb_ticks_per_jiffy;
                
-               profile_tick(CPU_PROFILING, regs);
+               profile_tick(CPU_PROFILING);
                update_process_times(user_mode(regs));
 
                if (smp_processor_id())
@@ -188,6 +191,7 @@ void timer_interrupt(struct pt_regs * regs)
                ppc_md.heartbeat();
 
        irq_exit();
+       set_irq_regs(old_regs);
 }
 
 /*
index 410200046af120236e44fb35d656e57f65ceb0da..c374e53ae03a0971654d26b5670f0e670b65cf40 100644 (file)
@@ -374,11 +374,12 @@ void __init paging_init(void)
        end_pfn = start_pfn + (total_memory >> PAGE_SHIFT);
        add_active_range(0, start_pfn, end_pfn);
 
+       memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
 #ifdef CONFIG_HIGHMEM
-       max_zone_pfns[0] = total_lowmem >> PAGE_SHIFT;
-       max_zone_pfns[1] = total_memory >> PAGE_SHIFT;
+       max_zone_pfns[ZONE_DMA] = total_lowmem >> PAGE_SHIFT;
+       max_zone_pfns[ZONE_HIGHMEM] = total_memory >> PAGE_SHIFT;
 #else
-       max_zone_pfns[0] = total_memory >> PAGE_SHIFT;
+       max_zone_pfns[ZONE_DMA] = total_memory >> PAGE_SHIFT;
 #endif /* CONFIG_HIGHMEM */
        free_area_init_nodes(max_zone_pfns);
 }
index 94badafe4ef18478c5cb353ca39980c3cd1e6585..14ecec7bbed77d8d349bdf190d3789fc0e38c717 100644 (file)
@@ -211,10 +211,10 @@ mpc8560ads_setup_arch(void)
 #endif
 }
 
-static irqreturn_t cpm2_cascade(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t cpm2_cascade(int irq, void *dev_id)
 {
-       while ((irq = cpm2_get_irq(regs)) >= 0)
-               __do_IRQ(irq, regs);
+       while ((irq = cpm2_get_irq()) >= 0)
+               __do_IRQ(irq);
        return IRQ_HANDLED;
 }
 
index 75204588a3e75f6935ba4c622d39fdba383e82e2..5ce0f69c1db66ad4b11b4554d447587b4771ba4c 100644 (file)
@@ -127,10 +127,10 @@ mpc85xx_cds_show_cpuinfo(struct seq_file *m)
 }
 
 #ifdef CONFIG_CPM2
-static irqreturn_t cpm2_cascade(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t cpm2_cascade(int irq, void *dev_id)
 {
-       while((irq = cpm2_get_irq(regs)) >= 0)
-               __do_IRQ(irq, regs);
+       while((irq = cpm2_get_irq()) >= 0)
+               __do_IRQ(irq);
        return IRQ_HANDLED;
 }
 
index 495aa79bb3a1d90a0061c9eb9719a24eafea805d..4bb18ab27672f24fb78b76767f788e8a2892db0b 100644 (file)
@@ -156,10 +156,10 @@ gp3_setup_arch(void)
        printk ("bi_immr_base = %8.8lx\n", binfo->bi_immr_base);
 }
 
-static irqreturn_t cpm2_cascade(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t cpm2_cascade(int irq, void *dev_id)
 {
-       while ((irq = cpm2_get_irq(regs)) >= 0)
-               __do_IRQ(irq, regs);
+       while ((irq = cpm2_get_irq()) >= 0)
+               __do_IRQ(irq);
 
        return IRQ_HANDLED;
 }
index 189ed4175f9fb2dbb5bededc6e880fe9c0f2b71a..dd45f2e1844951c5416de4189406bf2ddd4ab123 100644 (file)
@@ -181,10 +181,10 @@ tqm85xx_setup_arch(void)
 }
 
 #ifdef CONFIG_MPC8560
-static irqreturn_t cpm2_cascade(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t cpm2_cascade(int irq, void *dev_id)
 {
-       while ((irq = cpm2_get_irq(regs)) >= 0)
-               __do_IRQ(irq, regs);
+       while ((irq = cpm2_get_irq()) >= 0)
+               __do_IRQ(irq);
        return IRQ_HANDLED;
 }
 
index 1d034ead2c9a645eb99181eecb124cf2b910fe83..063274d2c5037d323cb28f6d3e8e4cba7b525499 100644 (file)
@@ -492,7 +492,7 @@ apus_halt(void)
 
 static unsigned char last_ipl[8];
 
-int apus_get_irq(struct pt_regs* regs)
+int apus_get_irq(void)
 {
        unsigned char ipl_emu, mask;
        unsigned int level;
index e0f112a1fd0b4926675cfc1d4eae7421e341dba4..d809e17aa5361bbc25902bdd93e99b5e739e07d9 100644 (file)
@@ -659,8 +659,7 @@ static void __init hdpu_map_io(void)
 char hdpu_smp0[] = "SMP Cpu #0";
 char hdpu_smp1[] = "SMP Cpu #1";
 
-static irqreturn_t hdpu_smp_cpu0_int_handler(int irq, void *dev_id,
-                                            struct pt_regs *regs)
+static irqreturn_t hdpu_smp_cpu0_int_handler(int irq, void *dev_id)
 {
        volatile unsigned int doorbell;
 
@@ -670,22 +669,21 @@ static irqreturn_t hdpu_smp_cpu0_int_handler(int irq, void *dev_id,
        mv64x60_write(&bh, MV64360_CPU0_DOORBELL_CLR, doorbell);
 
        if (doorbell & 1) {
-               smp_message_recv(0, regs);
+               smp_message_recv(0);
        }
        if (doorbell & 2) {
-               smp_message_recv(1, regs);
+               smp_message_recv(1);
        }
        if (doorbell & 4) {
-               smp_message_recv(2, regs);
+               smp_message_recv(2);
        }
        if (doorbell & 8) {
-               smp_message_recv(3, regs);
+               smp_message_recv(3);
        }
        return IRQ_HANDLED;
 }
 
-static irqreturn_t hdpu_smp_cpu1_int_handler(int irq, void *dev_id,
-                                            struct pt_regs *regs)
+static irqreturn_t hdpu_smp_cpu1_int_handler(int irq, void *dev_id)
 {
        volatile unsigned int doorbell;
 
@@ -695,16 +693,16 @@ static irqreturn_t hdpu_smp_cpu1_int_handler(int irq, void *dev_id,
        mv64x60_write(&bh, MV64360_CPU1_DOORBELL_CLR, doorbell);
 
        if (doorbell & 1) {
-               smp_message_recv(0, regs);
+               smp_message_recv(0);
        }
        if (doorbell & 2) {
-               smp_message_recv(1, regs);
+               smp_message_recv(1);
        }
        if (doorbell & 4) {
-               smp_message_recv(2, regs);
+               smp_message_recv(2);
        }
        if (doorbell & 8) {
-               smp_message_recv(3, regs);
+               smp_message_recv(3);
        }
        return IRQ_HANDLED;
 }
index d7b3a6afa78f86dc4209f562f9ebdedb75da34b5..1f9ea36837b1aff30544607bbdd69bf4bdb1769a 100644 (file)
@@ -196,7 +196,7 @@ static void __init mpc8272ads_fixup_enet_pdata(struct platform_device *pdev,
        bd_t* bi = (void*)__res;
        int fs_no = fsid_fcc1+pdev->id-1;
 
-       if(fs_no > ARRAY_SIZE(mpc82xx_enet_pdata)) {
+       if(fs_no >= ARRAY_SIZE(mpc82xx_enet_pdata)) {
                return;
        }
 
@@ -222,7 +222,7 @@ static void mpc8272ads_fixup_uart_pdata(struct platform_device *pdev,
        int id = fs_uart_id_scc2fsid(idx);
 
        /* no need to alter anything if console */
-       if ((id <= num) && (!pdev->dev.platform_data)) {
+       if ((id < num) && (!pdev->dev.platform_data)) {
                pinfo = &mpc8272_uart_pdata[id];
                pinfo->uart_clk = bd->bi_intfreq;
                pdev->dev.platform_data = pinfo;
index 5f130dca377009cbe3d13d8294f9ce9ee62b025b..e95d2c1117476d35d09dcb0f699192b697353727 100644 (file)
@@ -259,7 +259,7 @@ static void mpc866ads_fixup_enet_pdata(struct platform_device *pdev, int fs_no)
        /* Get pointer to Communication Processor */
        cp = cpmp;
 
-       if(fs_no > ARRAY_SIZE(mpc8xx_enet_pdata)) {
+       if(fs_no >= ARRAY_SIZE(mpc8xx_enet_pdata)) {
                printk(KERN_ERR"No network-suitable #%d device on bus", fs_no);
                return;
        }
@@ -305,7 +305,7 @@ static void __init mpc866ads_fixup_uart_pdata(struct platform_device *pdev,
        int id = fs_uart_id_smc2fsid(idx);
 
        /* no need to alter anything if console */
-       if ((id <= num) && (!pdev->dev.platform_data)) {
+       if ((id < num) && (!pdev->dev.platform_data)) {
                pinfo = &mpc866_uart_pdata[id];
                pinfo->uart_clk = bd->bi_intfreq;
                pdev->dev.platform_data = pinfo;
index 02293141efb5871c26f788f3a57a04cb6240cf46..f8161f3557f5df414b79ff046b7d927f99fd03a8 100644 (file)
@@ -263,7 +263,7 @@ static void mpc885ads_fixup_enet_pdata(struct platform_device *pdev, int fs_no)
        char *e;
        int i;
 
-       if(fs_no > ARRAY_SIZE(mpc8xx_enet_pdata)) {
+       if(fs_no >= ARRAY_SIZE(mpc8xx_enet_pdata)) {
                printk(KERN_ERR"No network-suitable #%d device on bus", fs_no);
                return;
        }
@@ -371,7 +371,7 @@ static void __init mpc885ads_fixup_uart_pdata(struct platform_device *pdev,
        int id = fs_uart_id_smc2fsid(idx);
 
        /* no need to alter anything if console */
-       if ((id <= num) && (!pdev->dev.platform_data)) {
+       if ((id < num) && (!pdev->dev.platform_data)) {
                pinfo = &mpc885_uart_pdata[id];
                pinfo->uart_clk = bd->bi_intfreq;
                pdev->dev.platform_data = pinfo;
index 3bb530af029774b865849e24d5fee27c8fe83a11..13d70ab50bf15f246fc6eefa82656a98a8187350 100644 (file)
@@ -451,11 +451,11 @@ static void __init ppc7d_calibrate_decr(void)
  * Interrupt stuff
  *****************************************************************************/
 
-static irqreturn_t ppc7d_i8259_intr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t ppc7d_i8259_intr(int irq, void *dev_id)
 {
        u32 temp = mv64x60_read(&bh, MV64x60_GPP_INTR_CAUSE);
        if (temp & (1 << 28)) {
-               i8259_irq(regs);
+               i8259_irq();
                mv64x60_write(&bh, MV64x60_GPP_INTR_CAUSE, temp & (~(1 << 28)));
                return IRQ_HANDLED;
        }
@@ -536,13 +536,13 @@ static u32 ppc7d_irq_canonicalize(u32 irq)
        return irq;
 }
 
-static int ppc7d_get_irq(struct pt_regs *regs)
+static int ppc7d_get_irq(void)
 {
        int irq;
 
-       irq = mv64360_get_irq(regs);
+       irq = mv64360_get_irq();
        if (irq == (mv64360_irq_base + MV64x60_IRQ_GPP28))
-               irq = i8259_irq(regs);
+               irq = i8259_irq();
        return irq;
 }
 
index 60b769c7f3fc97eb6ec62c6b3ca670e16ae82e0f..cc0935ccab7a49f3770707c8ca23d7fde0c5050e 100644 (file)
@@ -121,7 +121,7 @@ struct hw_interrupt_type sbc82xx_i8259_ic = {
        .end = sbc82xx_i8259_end_irq,
 };
 
-static irqreturn_t sbc82xx_i8259_demux(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t sbc82xx_i8259_demux(int irq, void *dev_id)
 {
        spin_lock(&sbc82xx_i8259_lock);
 
@@ -139,7 +139,7 @@ static irqreturn_t sbc82xx_i8259_demux(int irq, void *dev_id, struct pt_regs *re
                        return IRQ_HANDLED;
                }
        }
-       __do_IRQ(NR_SIU_INTS + irq, regs);
+       __do_IRQ(NR_SIU_INTS + irq);
        return IRQ_HANDLED;
 }
 
index 0a8a5d84390fc9767fa9bc54e37289ee0e2b21f5..987e9aa0dd4596ab9c07ca8a88bf8fb0552d2926 100644 (file)
@@ -91,6 +91,6 @@ extern struct hw_interrupt_type cpc700_pic;
 extern unsigned int cpc700_irq_assigns[32][2];
 
 extern void __init cpc700_init_IRQ(void);
-extern int cpc700_get_irq(struct pt_regs *);
+extern int cpc700_get_irq(void);
 
 #endif /* __PPC_SYSLIB_CPC700_H__ */
index 172aa215fdb0d1ac059c725187f9afdc4f5aaaf7..d48e8f45c05058d4412843faa6967d7d58234cc3 100644 (file)
@@ -158,7 +158,7 @@ cpc700_init_IRQ(void)
  * Find the highest IRQ that generating an interrupt, if any.
  */
 int
-cpc700_get_irq(struct pt_regs *regs)
+cpc700_get_irq(void)
 {
        int irq = 0;
        u_int irq_status, irq_test = 1;
index c0fee0beb81503722a64053122be7fe90d017b4f..fb2d5842641a34c0806dac2d009971c77f263db6 100644 (file)
@@ -123,7 +123,7 @@ static struct hw_interrupt_type cpm2_pic = {
        .end = cpm2_end_irq,
 };
 
-int cpm2_get_irq(struct pt_regs *regs)
+int cpm2_get_irq(void)
 {
        int irq;
         unsigned long bits;
index 97cab8f13a1a0c412f866eadd7fe696c8e432e93..467339337a78f213be4cdf4c548a83ec69e6f809 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef _PPC_KERNEL_CPM2_H
 #define _PPC_KERNEL_CPM2_H
 
-extern int cpm2_get_irq(struct pt_regs *regs);
+extern int cpm2_get_irq(void);
 
 extern void cpm2_init_IRQ(void);
 
index 7fd550a7d586752ea456eba3a0110ee824cb15cc..e84d432c0657c9a022832b994317de363cf0ee4f 100644 (file)
@@ -110,9 +110,6 @@ gt64260_init_irq(void)
  *  This function returns the lowest interrupt number of all interrupts that
  *  are currently asserted.
  *
- * Input Variable(s):
- *  struct pt_regs*    not used
- *
  * Output Variable(s):
  *  None.
  *
@@ -120,7 +117,7 @@ gt64260_init_irq(void)
  *  int        <interrupt number> or -2 (bogus interrupt)
  */
 int
-gt64260_get_irq(struct pt_regs *regs)
+gt64260_get_irq(void)
 {
        int irq;
        int irq_gpp;
@@ -229,7 +226,7 @@ gt64260_mask_irq(unsigned int irq)
 }
 
 static irqreturn_t
-gt64260_cpu_error_int_handler(int irq, void *dev_id, struct pt_regs *regs)
+gt64260_cpu_error_int_handler(int irq, void *dev_id)
 {
        printk(KERN_ERR "gt64260_cpu_error_int_handler: %s 0x%08x\n",
                "Error on CPU interface - Cause regiser",
@@ -250,7 +247,7 @@ gt64260_cpu_error_int_handler(int irq, void *dev_id, struct pt_regs *regs)
 }
 
 static irqreturn_t
-gt64260_pci_error_int_handler(int irq, void *dev_id, struct pt_regs *regs)
+gt64260_pci_error_int_handler(int irq, void *dev_id)
 {
        u32 val;
        unsigned int pci_bus = (unsigned int)dev_id;
index eb35353af83702e7de9c90b744d3ba00f1f47d6e..a43dda5a83343a7cc39d5ea1ae6794e915ac871c 100644 (file)
@@ -28,7 +28,7 @@ static int i8259_pic_irq_offset;
  * which is called.  It should be noted that polling is broken on some
  * IBM and Motorola PReP boxes so we must use the int-ack feature on them.
  */
-int i8259_irq(struct pt_regs *regs)
+int i8259_irq(void)
 {
        int irq;
 
index 4b77e6c8c87f9430cf0bb7775d9911de97fa0784..6ad52f4a26e171dd4c586459375b71a08f0ad439 100644 (file)
@@ -119,7 +119,7 @@ static inline u32 l2c_diag(u32 addr)
        return mfdcr(DCRN_L2C0_DATA);
 }
 
-static irqreturn_t l2c_error_handler(int irq, void* dev, struct pt_regs* regs)
+static irqreturn_t l2c_error_handler(int irq, void* dev)
 {
        u32 sr = mfdcr(DCRN_L2C0_SR);
        if (sr & L2C_SR_CPE){
index 46801f5ec03f3883b424239e7a9c13b958ae9144..10659c24b1beb2c4369afe48868e2b86d719ec0d 100644 (file)
@@ -601,7 +601,7 @@ void ipic_clear_mcp_status(u32 mask)
 }
 
 /* Return an interrupt vector or -1 if no interrupt is pending. */
-int ipic_get_irq(struct pt_regs *regs)
+int ipic_get_irq(void)
 {
        int irq;
 
index d3fa264e179e345d1b0107606ec01b6adbfd107b..e3b586b1ede9c6cb122fbb721c9e293636092254 100644 (file)
@@ -117,7 +117,7 @@ struct hw_interrupt_type pq2pci_ic = {
 };
 
 static irqreturn_t
-pq2pci_irq_demux(int irq, void *dev_id, struct pt_regs *regs)
+pq2pci_irq_demux(int irq, void *dev_id)
 {
        unsigned long stat, mask, pend;
        int bit;
@@ -130,7 +130,7 @@ pq2pci_irq_demux(int irq, void *dev_id, struct pt_regs *regs)
                        break;
                for (bit = 0; pend != 0; ++bit, pend <<= 1) {
                        if (pend & 0x80000000)
-                               __do_IRQ(NR_CPM_INTS + bit, regs);
+                               __do_IRQ(NR_CPM_INTS + bit);
                }
        }
 
index 54303a7b4e6990d1662f9fe257fb35da2dc81648..d8d299bd1a123d37f2bda11f7e85f60f9f8c3830 100644 (file)
@@ -169,7 +169,7 @@ abort(void)
 }
 
 /* A place holder for time base interrupts, if they are ever enabled. */
-irqreturn_t timebase_interrupt(int irq, void * dev, struct pt_regs * regs)
+irqreturn_t timebase_interrupt(int irq, void * dev)
 {
        printk ("timebase_interrupt()\n");
 
index ac11d7bab443840c193a6b0c741a7ba31b3663b2..fffac8cbeb514e5ab4d733d81af6976efe0041a9 100644 (file)
@@ -21,7 +21,7 @@
 static int wdt_timeout;
 int m8xx_has_internal_rtc = 0;
 
-static irqreturn_t m8xx_wdt_interrupt(int, void *, struct pt_regs *);
+static irqreturn_t m8xx_wdt_interrupt(int, void *);
 static struct irqaction m8xx_wdt_irqaction = {
        .handler = m8xx_wdt_interrupt,
        .name = "watchdog",
@@ -35,7 +35,7 @@ void m8xx_wdt_reset(void)
        out_be16(&imap->im_siu_conf.sc_swsr, 0xaa39);   /* write magic2 */
 }
 
-static irqreturn_t m8xx_wdt_interrupt(int irq, void *dev, struct pt_regs *regs)
+static irqreturn_t m8xx_wdt_interrupt(int irq, void *dev)
 {
        volatile immap_t *imap = (volatile immap_t *)IMAP_ADDR;
 
index 6425b5cee7db2bc7c638c5c5faa41b07467af98b..af35a316544a1a3308ce1cccff538a806fb066fb 100644 (file)
@@ -220,7 +220,7 @@ mpc52xx_init_irq(void)
 }
 
 int
-mpc52xx_get_irq(struct pt_regs *regs)
+mpc52xx_get_irq(void)
 {
        u32 status;
        int irq = -1;
index 3f6d162f87cfa635b54263757f401127ee99b454..4b7a3338e12252cd8a264ec2c67a8e869df31d75 100644 (file)
 
 static void mv64360_unmask_irq(unsigned int);
 static void mv64360_mask_irq(unsigned int);
-static irqreturn_t mv64360_cpu_error_int_handler(int, void *, struct pt_regs *);
-static irqreturn_t mv64360_sram_error_int_handler(int, void *,
-                                                 struct pt_regs *);
-static irqreturn_t mv64360_pci_error_int_handler(int, void *, struct pt_regs *);
+static irqreturn_t mv64360_cpu_error_int_handler(int, void *);
+static irqreturn_t mv64360_sram_error_int_handler(int, void *);
+static irqreturn_t mv64360_pci_error_int_handler(int, void *);
 
 /* ========================== local declarations =========================== */
 
@@ -131,9 +130,6 @@ mv64360_init_irq(void)
  * This function returns the lowest interrupt number of all interrupts that
  * are currently asserted.
  *
- * Input Variable(s):
- *  struct pt_regs*    not used
- *
  * Output Variable(s):
  *  None.
  *
@@ -142,7 +138,7 @@ mv64360_init_irq(void)
  *
  */
 int
-mv64360_get_irq(struct pt_regs *regs)
+mv64360_get_irq(void)
 {
        int irq;
        int irq_gpp;
@@ -283,7 +279,7 @@ mv64360_mask_irq(unsigned int irq)
 }
 
 static irqreturn_t
-mv64360_cpu_error_int_handler(int irq, void *dev_id, struct pt_regs *regs)
+mv64360_cpu_error_int_handler(int irq, void *dev_id)
 {
        printk(KERN_ERR "mv64360_cpu_error_int_handler: %s 0x%08x\n",
                "Error on CPU interface - Cause regiser",
@@ -304,7 +300,7 @@ mv64360_cpu_error_int_handler(int irq, void *dev_id, struct pt_regs *regs)
 }
 
 static irqreturn_t
-mv64360_sram_error_int_handler(int irq, void *dev_id, struct pt_regs *regs)
+mv64360_sram_error_int_handler(int irq, void *dev_id)
 {
        printk(KERN_ERR "mv64360_sram_error_int_handler: %s 0x%08x\n",
                "Error in internal SRAM - Cause register",
@@ -325,7 +321,7 @@ mv64360_sram_error_int_handler(int irq, void *dev_id, struct pt_regs *regs)
 }
 
 static irqreturn_t
-mv64360_pci_error_int_handler(int irq, void *dev_id, struct pt_regs *regs)
+mv64360_pci_error_int_handler(int irq, void *dev_id)
 {
        u32 val;
        unsigned int pci_bus = (unsigned int)dev_id;
@@ -380,7 +376,7 @@ mv64360_register_hdlrs(void)
        /* Clear old errors and register CPU interface error intr handler */
        mv64x60_write(&bh, MV64x60_CPU_ERR_CAUSE, 0);
        if ((rc = request_irq(MV64x60_IRQ_CPU_ERR + mv64360_irq_base,
-               mv64360_cpu_error_int_handler, IRQF_DISABLED, CPU_INTR_STR, 0)))
+               mv64360_cpu_error_int_handler, IRQF_DISABLED, CPU_INTR_STR, NULL)))
                printk(KERN_WARNING "Can't register cpu error handler: %d", rc);
 
        mv64x60_write(&bh, MV64x60_CPU_ERR_MASK, 0);
@@ -389,7 +385,7 @@ mv64360_register_hdlrs(void)
        /* Clear old errors and register internal SRAM error intr handler */
        mv64x60_write(&bh, MV64360_SRAM_ERR_CAUSE, 0);
        if ((rc = request_irq(MV64360_IRQ_SRAM_PAR_ERR + mv64360_irq_base,
-               mv64360_sram_error_int_handler,IRQF_DISABLED,SRAM_INTR_STR, 0)))
+               mv64360_sram_error_int_handler,IRQF_DISABLED,SRAM_INTR_STR, NULL)))
                printk(KERN_WARNING "Can't register SRAM error handler: %d",rc);
 
        /* Clear old errors and register PCI 0 error intr handler */
index aa0b957887056a90a701cc192290c55f21f5dc1d..18ec94733293538228d97f311d9e50003f28540a 100644 (file)
@@ -45,7 +45,7 @@ static u_int NumSources;
 static int open_pic_irq_offset;
 static volatile OpenPIC_Source __iomem *ISR[NR_IRQS];
 static int openpic_cascade_irq = -1;
-static int (*openpic_cascade_fn)(struct pt_regs *);
+static int (*openpic_cascade_fn)(void);
 
 /* Global Operations */
 static void openpic_disable_8259_pass_through(void);
@@ -54,7 +54,7 @@ static void openpic_set_spurious(u_int vector);
 #ifdef CONFIG_SMP
 /* Interprocessor Interrupts */
 static void openpic_initipi(u_int ipi, u_int pri, u_int vector);
-static irqreturn_t openpic_ipi_action(int cpl, void *dev_id, struct pt_regs *);
+static irqreturn_t openpic_ipi_action(int cpl, void *dev_id);
 #endif
 
 /* Timer Interrupts */
@@ -700,7 +700,7 @@ static struct irqaction openpic_cascade_irqaction = {
 
 void __init
 openpic_hookup_cascade(u_int irq, char *name,
-       int (*cascade_fn)(struct pt_regs *))
+       int (*cascade_fn)(void))
 {
        openpic_cascade_irq = irq;
        openpic_cascade_fn = cascade_fn;
@@ -857,16 +857,16 @@ static void openpic_end_ipi(unsigned int irq_nr)
 {
 }
 
-static irqreturn_t openpic_ipi_action(int cpl, void *dev_id, struct pt_regs *regs)
+static irqreturn_t openpic_ipi_action(int cpl, void *dev_id)
 {
-       smp_message_recv(cpl-OPENPIC_VEC_IPI-open_pic_irq_offset, regs);
+       smp_message_recv(cpl-OPENPIC_VEC_IPI-open_pic_irq_offset);
        return IRQ_HANDLED;
 }
 
 #endif /* CONFIG_SMP */
 
 int
-openpic_get_irq(struct pt_regs *regs)
+openpic_get_irq(void)
 {
        int irq = openpic_irq();
 
@@ -876,7 +876,7 @@ openpic_get_irq(struct pt_regs *regs)
         * This should move to irq.c eventually.  -- paulus
         */
        if (irq == openpic_cascade_irq && openpic_cascade_fn != NULL) {
-               int cirq = openpic_cascade_fn(regs);
+               int cirq = openpic_cascade_fn();
 
                /* Allow for the cascade being shared with other devices */
                if (cirq != -1) {
index e1ff971539ea9f5f10a7fcc6a84701754c4c3c66..d585207f9f77855e0c8f126dfc52014fbc4328af 100644 (file)
@@ -529,7 +529,7 @@ static void openpic2_end_irq(unsigned int irq_nr)
 }
 
 int
-openpic2_get_irq(struct pt_regs *regs)
+openpic2_get_irq(void)
 {
        int irq = openpic2_irq();
 
index 1584c8b1229f76bac6627a939c4d3efd9b206d4d..607ebd111d44b6b0241b9e55acf6632ac198094c 100644 (file)
@@ -42,7 +42,7 @@ static struct hw_interrupt_type ppc403_aic = {
 };
 
 int
-ppc403_pic_get_irq(struct pt_regs *regs)
+ppc403_pic_get_irq(void)
 {
        int irq;
        unsigned long bits;
index 745685df59849f96d2f902b8cf883ac3c338d06b..ee0da4b4b993c41f81750facfc7a091b6a056b3d 100644 (file)
@@ -96,7 +96,7 @@ UIC_HANDLERS(1);
 UIC_HANDLERS(2);
 UIC_HANDLERS(3);
 
-static int ppc4xx_pic_get_irq(struct pt_regs *regs)
+static int ppc4xx_pic_get_irq(void)
 {
        u32 uic0 = mfdcr(DCRN_UIC_MSR(UIC0));
        if (uic0 & UIC0_UIC1NC)
@@ -125,7 +125,7 @@ UIC_HANDLERS(0);
 UIC_HANDLERS(1);
 UIC_HANDLERS(2);
 
-static int ppc4xx_pic_get_irq(struct pt_regs *regs)
+static int ppc4xx_pic_get_irq(void)
 {
        u32 uicb = mfdcr(DCRN_UIC_MSR(UICB));
        if (uicb & UICB_UIC0NC)
@@ -158,7 +158,7 @@ static void __init ppc4xx_pic_impl_init(void)
 UIC_HANDLERS(0);
 UIC_HANDLERS(1);
 
-static int ppc4xx_pic_get_irq(struct pt_regs *regs)
+static int ppc4xx_pic_get_irq(void)
 {
        u32 uic0 = mfdcr(DCRN_UIC_MSR(UIC0));
        if (uic0 & UIC0_UIC1NC)
@@ -179,7 +179,7 @@ static void __init ppc4xx_pic_impl_init(void)
 #define ACK_UIC0_PARENT
 UIC_HANDLERS(0);
 
-static int ppc4xx_pic_get_irq(struct pt_regs *regs)
+static int ppc4xx_pic_get_irq(void)
 {
        u32 uic0 = mfdcr(DCRN_UIC_MSR(UIC0));
        return uic0 ? 32 - ffs(uic0) : -1;
index d9b471b4d6954b175b4ff4a6e0b9342b1a014fd3..05b0e94150852e0d8189adf0d529a6667c48fac8 100644 (file)
@@ -349,13 +349,12 @@ EXPORT_SYMBOL_GPL(rio_hw_add_outb_message);
  * mpc85xx_rio_tx_handler - MPC85xx outbound message interrupt handler
  * @irq: Linux interrupt number
  * @dev_instance: Pointer to interrupt-specific data
- * @regs: Register context
  *
  * Handles outbound message interrupts. Executes a register outbound
  * mailbox event handler and acks the interrupt occurence.
  */
 static irqreturn_t
-mpc85xx_rio_tx_handler(int irq, void *dev_instance, struct pt_regs *regs)
+mpc85xx_rio_tx_handler(int irq, void *dev_instance)
 {
        int osr;
        struct rio_mport *port = (struct rio_mport *)dev_instance;
@@ -517,13 +516,12 @@ void rio_close_outb_mbox(struct rio_mport *mport, int mbox)
  * mpc85xx_rio_rx_handler - MPC85xx inbound message interrupt handler
  * @irq: Linux interrupt number
  * @dev_instance: Pointer to interrupt-specific data
- * @regs: Register context
  *
  * Handles inbound message interrupts. Executes a registered inbound
  * mailbox event handler and acks the interrupt occurence.
  */
 static irqreturn_t
-mpc85xx_rio_rx_handler(int irq, void *dev_instance, struct pt_regs *regs)
+mpc85xx_rio_rx_handler(int irq, void *dev_instance)
 {
        int isr;
        struct rio_mport *port = (struct rio_mport *)dev_instance;
@@ -736,13 +734,12 @@ EXPORT_SYMBOL_GPL(rio_hw_get_inb_message);
  * mpc85xx_rio_dbell_handler - MPC85xx doorbell interrupt handler
  * @irq: Linux interrupt number
  * @dev_instance: Pointer to interrupt-specific data
- * @regs: Register context
  *
  * Handles doorbell interrupts. Parses a list of registered
  * doorbell event handlers and executes a matching event handler.
  */
 static irqreturn_t
-mpc85xx_rio_dbell_handler(int irq, void *dev_instance, struct pt_regs *regs)
+mpc85xx_rio_dbell_handler(int irq, void *dev_instance)
 {
        int dsr;
        struct rio_mport *port = (struct rio_mport *)dev_instance;
index d6c25fe25011c7f52f4ce70c2191d20fe8349a1f..e8619c750732ccdc7b926b6e69fdd05aab0f0e30 100644 (file)
@@ -10,7 +10,7 @@
 #include <asm/mpc8xx.h>
 #include "ppc8xx_pic.h"
 
-extern int cpm_get_irq(struct pt_regs *regs);
+extern int cpm_get_irq(void);
 
 /* The 8xx internal interrupt controller.  It is usually
  * the only interrupt controller.  Some boards, like the MBX and
@@ -96,7 +96,7 @@ m8xx_get_irq(struct pt_regs *regs)
         * get back SIU_LEVEL7.  In this case, return -1
         */
         if (irq == CPM_INTERRUPT)
-               irq = CPM_IRQ_OFFSET + cpm_get_irq(regs);
+               irq = CPM_IRQ_OFFSET + cpm_get_irq();
 #if defined(CONFIG_PCI)
        else if (irq == ISA_BRIDGE_INT) {
                int isa_irq;
index 39a93dc6375b82a074aad29b9774865e27f001a5..6fd4cdbada72a3fb15ad0a19b1965724333a77e2 100644 (file)
@@ -86,7 +86,7 @@ static struct hw_interrupt_type xilinx_intc = {
 };
 
 int
-xilinx_pic_get_irq(struct pt_regs *regs)
+xilinx_pic_get_irq(void)
 {
        int irq;
 
index 51c2dfe89c62136525a8ecb6e3d2d8f96d5e5a2c..608193cfe43f13d488172caf7807c0e318ad9c31 100644 (file)
@@ -30,6 +30,9 @@ config GENERIC_CALIBRATE_DELAY
        bool
        default y
 
+config GENERIC_TIME
+       def_bool y
+
 config GENERIC_BUST_SPINLOCK
        bool
 
index 2b1e6c9a6e0e539826a3a8d45181ec5a7c72e76c..45c9fa7d7545465bd4c9bdc016b5c5cc925cf65e 100644 (file)
@@ -109,7 +109,7 @@ static LIST_HEAD(appldata_ops_list);
  *
  * schedule work and reschedule timer
  */
-static void appldata_timer_function(unsigned long data, struct pt_regs *regs)
+static void appldata_timer_function(unsigned long data)
 {
        P_DEBUG("   -= Timer =-\n");
        P_DEBUG("CPU: %i, expire_count: %i\n", smp_processor_id(),
index b6cad75fd1f43420c2307cd0c85b93dab4b2b60a..c313e9a9304f57a035807351eb5d09811e490e33 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18
-# Wed Oct  4 19:45:46 2006
+# Linux kernel version: 2.6.19-rc2
+# Wed Oct 18 17:11:10 2006
 #
 CONFIG_MMU=y
 CONFIG_LOCKDEP_SUPPORT=y
@@ -9,6 +9,7 @@ CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
 CONFIG_S390=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
@@ -210,6 +211,7 @@ CONFIG_INET6_XFRM_MODE_TRANSPORT=y
 CONFIG_INET6_XFRM_MODE_TUNNEL=y
 CONFIG_INET6_XFRM_MODE_BEET=y
 # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=y
 # CONFIG_IPV6_TUNNEL is not set
 # CONFIG_IPV6_SUBTREES is not set
 # CONFIG_IPV6_MULTIPLE_TABLES is not set
@@ -527,6 +529,7 @@ CONFIG_EXT3_FS=y
 CONFIG_EXT3_FS_XATTR=y
 # CONFIG_EXT3_FS_POSIX_ACL is not set
 # CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4DEV_FS is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 CONFIG_FS_MBCACHE=y
@@ -644,10 +647,6 @@ CONFIG_MSDOS_PARTITION=y
 #
 # CONFIG_NLS is not set
 
-#
-# Distributed Lock Manager
-#
-
 #
 # Instrumentation Support
 #
@@ -668,7 +667,6 @@ CONFIG_MAGIC_SYSRQ=y
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_KERNEL=y
 CONFIG_LOG_BUF_SHIFT=17
-# CONFIG_DETECT_SOFTLOCKUP is not set
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_DEBUG_SLAB is not set
 CONFIG_DEBUG_PREEMPT=y
@@ -689,6 +687,7 @@ CONFIG_DEBUG_FS=y
 # CONFIG_FRAME_POINTER is not set
 # CONFIG_UNWIND_INFO is not set
 CONFIG_FORCED_INLINING=y
+CONFIG_HEADERS_CHECK=y
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_LKDTM is not set
 
index e15e1489aef56b5c89b54f52822234ba84a64935..2001767e1dc7aa2fa40020f1874f84d3b7055173 100644 (file)
@@ -295,6 +295,7 @@ static inline long put_tv32(struct compat_timeval __user *o, struct timeval *i)
  *
  * This is really horribly ugly.
  */
+#ifdef CONFIG_SYSVIPC
 asmlinkage long sys32_ipc(u32 call, int first, int second, int third, u32 ptr)
 {
        if (call >> 16)         /* hack for backward compatibility */
@@ -338,6 +339,7 @@ asmlinkage long sys32_ipc(u32 call, int first, int second, int third, u32 ptr)
 
        return -ENOSYS;
 }
+#endif
 
 asmlinkage long sys32_truncate64(const char __user * path, unsigned long high, unsigned long low)
 {
index c1b383537fec2cbb3c0f4431c6a7faa80b83a73f..4faf96f8a83414ddf7f36eb46aa8bb21b4e50b90 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <asm/lowcore.h>
 #include <asm/s390_ext.h>
+#include <asm/irq_regs.h>
 #include <asm/irq.h>
 
 /*
@@ -114,7 +115,9 @@ void do_extint(struct pt_regs *regs, unsigned short code)
 {
         ext_int_info_t *p;
         int index;
+       struct pt_regs *old_regs;
 
+       old_regs = set_irq_regs(regs);
        irq_enter();
        asm volatile ("mc 0,0");
        if (S390_lowcore.int_clock >= S390_lowcore.jiffy_timer)
@@ -122,18 +125,18 @@ void do_extint(struct pt_regs *regs, unsigned short code)
                 * Make sure that the i/o interrupt did not "overtake"
                 * the last HZ timer interrupt.
                 */
-               account_ticks(regs);
+               account_ticks();
        kstat_cpu(smp_processor_id()).irqs[EXTERNAL_INTERRUPT]++;
         index = ext_hash(code);
        for (p = ext_int_hash[index]; p; p = p->next) {
                if (likely(p->code == code)) {
                        if (likely(p->handler))
-                               p->handler(regs, code);
+                               p->handler(code);
                }
        }
        irq_exit();
+       set_irq_regs(old_regs);
 }
 
 EXPORT_SYMBOL(register_external_interrupt);
 EXPORT_SYMBOL(unregister_external_interrupt);
-
index 9f19e833a56253535af44a1481284fffe9682360..90b5ef529eb7e881acf62b7a1e45386c8e074ba8 100644 (file)
@@ -51,4 +51,3 @@ EXPORT_SYMBOL(csum_fold);
 EXPORT_SYMBOL(console_mode);
 EXPORT_SYMBOL(console_devno);
 EXPORT_SYMBOL(console_irq);
-EXPORT_SYMBOL(sys_wait4);
index a8e6199755d4ecc86197aa0f95cfad26314df31b..62822245f9be95e25927ec5461f635d28df6efd7 100644 (file)
@@ -339,7 +339,7 @@ void machine_power_off_smp(void)
  * cpus are handled.
  */
 
-void do_ext_call_interrupt(struct pt_regs *regs, __u16 code)
+void do_ext_call_interrupt(__u16 code)
 {
         unsigned long bits;
 
index d9428a0fc8fb9ee3011f90f35f74a3be97bee70e..0d14a4789bf2e1a781e8ac98a42c3ef1e6eed09a 100644 (file)
@@ -62,27 +62,26 @@ static inline unsigned long save_context_stack(struct stack_trace *trace,
 void save_stack_trace(struct stack_trace *trace, struct task_struct *task)
 {
        register unsigned long sp asm ("15");
-       unsigned long orig_sp;
+       unsigned long orig_sp, new_sp;
 
-       sp &= PSW_ADDR_INSN;
-       orig_sp = sp;
+       orig_sp = sp & PSW_ADDR_INSN;
 
-       sp = save_context_stack(trace, &trace->skip, sp,
+       new_sp = save_context_stack(trace, &trace->skip, orig_sp,
                                S390_lowcore.panic_stack - PAGE_SIZE,
                                S390_lowcore.panic_stack);
-       if ((sp != orig_sp) && !trace->all_contexts)
+       if ((new_sp != orig_sp) && !trace->all_contexts)
                return;
-       sp = save_context_stack(trace, &trace->skip, sp,
+       new_sp = save_context_stack(trace, &trace->skip, new_sp,
                                S390_lowcore.async_stack - ASYNC_SIZE,
                                S390_lowcore.async_stack);
-       if ((sp != orig_sp) && !trace->all_contexts)
+       if ((new_sp != orig_sp) && !trace->all_contexts)
                return;
        if (task)
-               save_context_stack(trace, &trace->skip, sp,
+               save_context_stack(trace, &trace->skip, new_sp,
                                   (unsigned long) task_stack_page(task),
                                   (unsigned long) task_stack_page(task) + THREAD_SIZE);
        else
-               save_context_stack(trace, &trace->skip, sp,
+               save_context_stack(trace, &trace->skip, new_sp,
                                   S390_lowcore.thread_info,
                                   S390_lowcore.thread_info + THREAD_SIZE);
        return;
index e59baec565208e6dad4761365943c87bc5392a56..a4ceae3dbcf1b5fe8ed8ae27b931a56d8791b346 100644 (file)
@@ -320,3 +320,4 @@ SYSCALL(sys_tee,sys_tee,sys_tee_wrapper)
 SYSCALL(sys_vmsplice,sys_vmsplice,compat_sys_vmsplice_wrapper)
 NI_SYSCALL                                                     /* 310 sys_move_pages */
 SYSCALL(sys_getcpu,sys_getcpu,sys_getcpu_wrapper)
+SYSCALL(sys_epoll_pwait,sys_epoll_pwait,sys_ni_syscall)
index 4bf66cc4a267ee9d8fed39992e52a84c74b4dbd6..6cceed4df73ee40adf6f233d601ae511df9050bc 100644 (file)
 #include <linux/profile.h>
 #include <linux/timex.h>
 #include <linux/notifier.h>
+#include <linux/clocksource.h>
 
 #include <asm/uaccess.h>
 #include <asm/delay.h>
 #include <asm/s390_ext.h>
 #include <asm/div64.h>
 #include <asm/irq.h>
+#include <asm/irq_regs.h>
 #include <asm/timer.h>
 
 /* change this if you have some constant time drift */
@@ -81,78 +83,10 @@ void tod_to_timeval(__u64 todval, struct timespec *xtime)
        xtime->tv_nsec = ((todval * 1000) >> 12);
 }
 
-static inline unsigned long do_gettimeoffset(void) 
-{
-       __u64 now;
-
-       now = (get_clock() - jiffies_timer_cc) >> 12;
-       now -= (__u64) jiffies * USECS_PER_JIFFY;
-       return (unsigned long) now;
-}
-
-/*
- * This version of gettimeofday has microsecond resolution.
- */
-void do_gettimeofday(struct timeval *tv)
-{
-       unsigned long flags;
-       unsigned long seq;
-       unsigned long usec, sec;
-
-       do {
-               seq = read_seqbegin_irqsave(&xtime_lock, flags);
-
-               sec = xtime.tv_sec;
-               usec = xtime.tv_nsec / 1000 + do_gettimeoffset();
-       } while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
-
-       while (usec >= 1000000) {
-               usec -= 1000000;
-               sec++;
-       }
-
-       tv->tv_sec = sec;
-       tv->tv_usec = usec;
-}
-
-EXPORT_SYMBOL(do_gettimeofday);
-
-int do_settimeofday(struct timespec *tv)
-{
-       time_t wtm_sec, sec = tv->tv_sec;
-       long wtm_nsec, nsec = tv->tv_nsec;
-
-       if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
-               return -EINVAL;
-
-       write_seqlock_irq(&xtime_lock);
-       /* This is revolting. We need to set the xtime.tv_nsec
-        * correctly. However, the value in this location is
-        * is value at the last tick.
-        * Discover what correction gettimeofday
-        * would have done, and then undo it!
-        */
-       nsec -= do_gettimeoffset() * 1000;
-
-       wtm_sec  = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
-       wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
-
-       set_normalized_timespec(&xtime, sec, nsec);
-       set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
-
-       ntp_clear();
-       write_sequnlock_irq(&xtime_lock);
-       clock_was_set();
-       return 0;
-}
-
-EXPORT_SYMBOL(do_settimeofday);
-
-
 #ifdef CONFIG_PROFILING
-#define s390_do_profile(regs)  profile_tick(CPU_PROFILING, regs)
+#define s390_do_profile()      profile_tick(CPU_PROFILING)
 #else
-#define s390_do_profile(regs)  do { ; } while(0)
+#define s390_do_profile()      do { ; } while(0)
 #endif /* CONFIG_PROFILING */
 
 
@@ -160,7 +94,7 @@ EXPORT_SYMBOL(do_settimeofday);
  * timer_interrupt() needs to keep up the real-time clock,
  * as well as call the "do_timer()" routine every clocktick
  */
-void account_ticks(struct pt_regs *regs)
+void account_ticks(void)
 {
        __u64 tmp;
        __u32 ticks;
@@ -221,10 +155,10 @@ void account_ticks(struct pt_regs *regs)
        account_tick_vtime(current);
 #else
        while (ticks--)
-               update_process_times(user_mode(regs));
+               update_process_times(user_mode(get_irq_regs()));
 #endif
 
-       s390_do_profile(regs);
+       s390_do_profile();
 }
 
 #ifdef CONFIG_NO_IDLE_HZ
@@ -285,9 +219,11 @@ static inline void stop_hz_timer(void)
  */
 static inline void start_hz_timer(void)
 {
+       BUG_ON(!in_interrupt());
+
        if (!cpu_isset(smp_processor_id(), nohz_cpu_mask))
                return;
-       account_ticks(task_pt_regs(current));
+       account_ticks();
        cpu_clear(smp_processor_id(), nohz_cpu_mask);
 }
 
@@ -337,6 +273,22 @@ void init_cpu_timer(void)
 
 extern void vtime_init(void);
 
+static cycle_t read_tod_clock(void)
+{
+       return get_clock();
+}
+
+static struct clocksource clocksource_tod = {
+       .name           = "tod",
+       .rating         = 100,
+       .read           = read_tod_clock,
+       .mask           = -1ULL,
+       .mult           = 1000,
+       .shift          = 12,
+       .is_continuous  = 1,
+};
+
+
 /*
  * Initialize the TOD clock and the CPU timer of
  * the boot cpu.
@@ -381,6 +333,9 @@ void __init time_init(void)
                                              &ext_int_info_cc) != 0)
                 panic("Couldn't request external interrupt 0x1004");
 
+       if (clocksource_register(&clocksource_tod) != 0)
+               panic("Could not register TOD clock source");
+
         init_cpu_timer();
 
 #ifdef CONFIG_NO_IDLE_HZ
index 3eb4fab048b8c18f16c6327fb5bc4c096eb11579..66375a5e3d12f0d11020f4465afa97a7084452e8 100644 (file)
@@ -61,7 +61,7 @@ extern pgm_check_handler_t do_dat_exception;
 #ifdef CONFIG_PFAULT
 extern int pfault_init(void);
 extern void pfault_fini(void);
-extern void pfault_interrupt(struct pt_regs *regs, __u16 error_code);
+extern void pfault_interrupt(__u16 error_code);
 static ext_int_info_t ext_int_pfault;
 #endif
 extern pgm_check_handler_t do_monitor_call;
@@ -474,7 +474,7 @@ asmlinkage void illegal_op(struct pt_regs * regs, long interruption_code)
                        signal = math_emu_b3(opcode, regs);
                 } else if (opcode[0] == 0xed) {
                        get_user(*((__u32 *) (opcode+2)),
-                                (__u32 *)(location+1));
+                                (__u32 __user *)(location+1));
                        signal = math_emu_ed(opcode, regs);
                } else if (*((__u16 *) opcode) == 0xb299) {
                        get_user(*((__u16 *) (opcode+2)), location+1);
@@ -499,7 +499,7 @@ asmlinkage void illegal_op(struct pt_regs * regs, long interruption_code)
                info.si_signo = signal;
                info.si_errno = 0;
                info.si_code = SEGV_MAPERR;
-               info.si_addr = (void *) location;
+               info.si_addr = (void __user *) location;
                do_trap(interruption_code, signal,
                        "user address fault", regs, &info);
        } else
@@ -520,10 +520,10 @@ asmlinkage void
 specification_exception(struct pt_regs * regs, long interruption_code)
 {
         __u8 opcode[6];
-       __u16 *location = NULL;
+       __u16 __user *location = NULL;
        int signal = 0;
 
-       location = (__u16 *) get_check_address(regs);
+       location = (__u16 __user *) get_check_address(regs);
 
        /*
         * We got all needed information from the lowcore and can
@@ -632,7 +632,7 @@ asmlinkage void data_exception(struct pt_regs * regs, long interruption_code)
                        break;
                 case 0xed:
                        get_user(*((__u32 *) (opcode+2)),
-                                (__u32 *)(location+1));
+                                (__u32 __user *)(location+1));
                        signal = math_emu_ed(opcode, regs);
                        break;
                case 0xb2:
index 2306cd83fca125f2f995a482f51ac54297bd6e81..21baaf5496d61b02525a933c8139524710863cfb 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <asm/s390_ext.h>
 #include <asm/timer.h>
+#include <asm/irq_regs.h>
 
 static ext_int_info_t ext_int_info_timer;
 DEFINE_PER_CPU(struct vtimer_queue, virt_cpu_timer);
@@ -208,11 +209,11 @@ static void list_add_sorted(struct vtimer_list *timer, struct list_head *head)
  * Do the callback functions of expired vtimer events.
  * Called from within the interrupt handler.
  */
-static void do_callbacks(struct list_head *cb_list, struct pt_regs *regs)
+static void do_callbacks(struct list_head *cb_list)
 {
        struct vtimer_queue *vt_list;
        struct vtimer_list *event, *tmp;
-       void (*fn)(unsigned long, struct pt_regs*);
+       void (*fn)(unsigned long);
        unsigned long data;
 
        if (list_empty(cb_list))
@@ -223,7 +224,7 @@ static void do_callbacks(struct list_head *cb_list, struct pt_regs *regs)
        list_for_each_entry_safe(event, tmp, cb_list, entry) {
                fn = event->function;
                data = event->data;
-               fn(data, regs);
+               fn(data);
 
                if (!event->interval)
                        /* delete one shot timer */
@@ -241,7 +242,7 @@ static void do_callbacks(struct list_head *cb_list, struct pt_regs *regs)
 /*
  * Handler for the virtual CPU timer.
  */
-static void do_cpu_timer_interrupt(struct pt_regs *regs, __u16 error_code)
+static void do_cpu_timer_interrupt(__u16 error_code)
 {
        int cpu;
        __u64 next, delta;
@@ -274,7 +275,7 @@ static void do_cpu_timer_interrupt(struct pt_regs *regs, __u16 error_code)
                list_move_tail(&event->entry, &cb_list);
        }
        spin_unlock(&vt_list->lock);
-       do_callbacks(&cb_list, regs);
+       do_callbacks(&cb_list);
 
        /* next event is first in list */
        spin_lock(&vt_list->lock);
index 9c3c19fe62fcd99dfb3893730d7f54b354b731f5..1c323bbfda91cdfce7ae38e8d921533afebedbaf 100644 (file)
@@ -451,7 +451,7 @@ void pfault_fini(void)
 }
 
 asmlinkage void
-pfault_interrupt(struct pt_regs *regs, __u16 error_code)
+pfault_interrupt(__u16 error_code)
 {
        struct task_struct *tsk;
        __u16 subcode;
index f6a0c44361682de8e34fdc1eec8c57a2d7977f7e..6a461d4caeffc814e2f5968c178edc1de2569bcf 100644 (file)
@@ -45,6 +45,9 @@ config GENERIC_CALIBRATE_DELAY
 config GENERIC_IOMAP
        bool
 
+config GENERIC_TIME
+       def_bool n
+
 config ARCH_MAY_HAVE_PC_FDC
        bool
 
@@ -357,6 +360,7 @@ config CPU_HAS_SR_RB
 endmenu
 
 menu "Timer support"
+depends on !GENERIC_TIME
 
 config SH_TMU
        bool "TMU timer support"
index 75f91aaae0777ab373cd476da69bd9e6bf5620bf..d146cdaa0b8b03897b5f09e68aec42f2acd4abd4 100644 (file)
@@ -14,7 +14,7 @@
 #include <asm/io.h>
 #include <asm/apm.h>
 #include <asm/adc.h>
-#include <asm/hp6xx/hp6xx.h>
+#include <asm/hp6xx.h>
 
 #define SH7709_PGDR                    0xa400012c
 
@@ -83,7 +83,7 @@ static int hp6x0_apm_get_info(char *buf, char **start, off_t fpos, int length)
        return p - buf;
 }
 
-static irqreturn_t hp6x0_apm_interrupt(int irq, void *dev, struct pt_regs *regs)
+static irqreturn_t hp6x0_apm_interrupt(int irq, void *dev)
 {
        if (!apm_suspended)
                apm_queue_event(APM_USER_SUSPEND);
@@ -96,7 +96,7 @@ static int __init hp6x0_apm_init(void)
        int ret;
 
        ret = request_irq(HP680_BTN_IRQ, hp6x0_apm_interrupt,
-                         SA_INTERRUPT, MODNAME, 0);
+                         IRQF_DISABLED, MODNAME, 0);
        if (unlikely(ret < 0)) {
                printk(KERN_ERR MODNAME ": IRQ %d request failed\n",
                       HP680_BTN_IRQ);
index 83d3272120645d149c16965e46d0f90b2f5c1183..d1947732fb3e5013e0b8d00f6f8ce42bf31e090a 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/time.h>
 #include <asm/io.h>
 #include <asm/hd64461.h>
-#include <asm/hp6xx/hp6xx.h>
+#include <asm/hp6xx.h>
 #include <asm/cpu/dac.h>
 #include <asm/pm.h>
 
index 2d3a5b4faf585b5dedcc201234cbf2efdfc3481d..b5a96649ed2692fc9a8b591171376809b7c61193 100644 (file)
@@ -13,7 +13,7 @@
 #include <asm/hd64461.h>
 #include <asm/io.h>
 #include <asm/irq.h>
-#include <asm/hp6xx/hp6xx.h>
+#include <asm/hp6xx.h>
 #include <asm/cpu/dac.h>
 
 #define        SCPCR   0xa4000116
index 0b7bee1a9ca5af99c0c3bdeb33aa0a8370f39174..e62524978160ac3fbb79448ea7d0656764bd2ee1 100644 (file)
@@ -135,7 +135,7 @@ static int swdrv_write(struct file *filp, const char *buff, size_t count,
        return count;
 }
 
-static irqreturn_t sw_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t sw_interrupt(int irq, void *dev_id)
 {
        landisk_btn = (0x0ff & (~ctrl_inb(PA_STATUS)));
        disable_irq(IRQ_BUTTON);
index 01c10fa5c0589092677190289dd626120df7d20a..7c3d1d304157f48d70555fa4dc71bdc199aeb00d 100644 (file)
@@ -69,7 +69,6 @@ static void __init pci_write_config(unsigned long busNo,
 
 static unsigned char m_irq_mask = 0xfb;
 static unsigned char s_irq_mask = 0xff;
-volatile unsigned long irq_err_count;
 
 static void disable_mpc1211_irq(unsigned int irq)
 {
@@ -118,7 +117,7 @@ static void mask_and_ack_mpc1211(unsigned int irq)
        if(irq < 8) {
                if(m_irq_mask & (1<<irq)){
                  if(!mpc1211_irq_real(irq)){
-                   irq_err_count++;
+                   atomic_inc(&irq_err_count)
                    printk("spurious 8259A interrupt: IRQ %x\n",irq);
                   }
                } else {
@@ -131,7 +130,7 @@ static void mask_and_ack_mpc1211(unsigned int irq)
        } else {
                if(s_irq_mask & (1<<(irq - 8))){
                  if(!mpc1211_irq_real(irq)){
-                   irq_err_count++;
+                   atomic_inc(&irq_err_count);
                    printk("spurious 8259A interrupt: IRQ %x\n",irq);
                  }
                } else {
index 51f3f6574210c712fb98adbc1d7165977c8366d8..bb9aa0d62852379d05aefa16a327650c2721d815 100644 (file)
@@ -15,7 +15,7 @@
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <asm/io.h>
-#include <asm/hs7751rvoip/hs7751rvoip.h>
+#include <asm/hs7751rvoip.h>
 #include <asm/addrspace.h>
 
 extern void *area6_io8_base;   /* Area 6 8bit I/O Base address */
index c617b188258a0e4a27bbb731f4ec99e48c0cdad3..943f93aa6052cc8ddc5a3723c804819b52a84bd7 100644 (file)
@@ -14,7 +14,7 @@
 #include <linux/irq.h>
 #include <asm/io.h>
 #include <asm/irq.h>
-#include <asm/hs7751rvoip/hs7751rvoip.h>
+#include <asm/hs7751rvoip.h>
 
 static int mask_pos[] = {8, 9, 10, 11, 12, 13, 0, 1, 2, 3, 4, 5, 6, 7};
 
index 0414c15c3458da63969f97c7cf3ddb923646bbdb..1d997ffd7931d859053cbd30ed16efddd5524c79 100644 (file)
 #include <linux/init.h>
 #include <linux/irq.h>
 #include <linux/mm.h>
-#include <linux/vmalloc.h>
-#include <linux/hdreg.h>
-#include <linux/ide.h>
 #include <linux/pm.h>
+#include <asm/hs7751rvoip.h>
 #include <asm/io.h>
-#include <asm/hs7751rvoip/hs7751rvoip.h>
 #include <asm/machvec.h>
-#include <asm/rtc.h>
-#include <asm/irq.h>
 
 static void __init hs7751rvoip_init_irq(void)
 {
index db92d6e6ae9936cea200bcc6faee4adcb6fbf071..311ccccba718c48e7665403b6b1b722732c9a339 100644 (file)
@@ -11,7 +11,7 @@
 #include <linux/pci.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
-#include <asm/r7780rp/r7780rp.h>
+#include <asm/r7780rp.h>
 #include <asm/addrspace.h>
 #include <asm/io.h>
 
index 2d960e9a3143b5bae8c2061b0c0bd4e4dfd4915e..aa15ec5bc69ee42cf26b776f20562520277f1f46 100644 (file)
@@ -1,18 +1,17 @@
 /*
- * linux/arch/sh/boards/renesas/r7780rp/irq.c
- *
- * Copyright (C) 2000  Kazumoto Kojima
- *
  * Renesas Solutions Highlander R7780RP-1 Support.
  *
- * Modified for R7780RP-1 by
- * Atom Create Engineering Co., Ltd. 2002.
+ * Copyright (C) 2002  Atom Create Engineering Co., Ltd.
+ * Copyright (C) 2006  Paul Mundt
+ *
+ * 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 <linux/init.h>
 #include <linux/irq.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/r7780rp/r7780rp.h>
+#include <linux/io.h>
+#include <asm/r7780rp.h>
 
 #ifdef CONFIG_SH_R7780MP
 static int mask_pos[] = {12, 11, 9, 14, 15, 8, 13, 6, 5, 4, 3, 2, 0, 0, 1, 0};
@@ -20,71 +19,26 @@ static int mask_pos[] = {12, 11, 9, 14, 15, 8, 13, 6, 5, 4, 3, 2, 0, 0, 1, 0};
 static int mask_pos[] = {15, 14, 13, 12, 11, 10, 9, 8, 7, 5, 6, 4, 0, 1, 2, 0};
 #endif
 
-static void enable_r7780rp_irq(unsigned int irq);
-static void disable_r7780rp_irq(unsigned int irq);
-
-/* shutdown is same as "disable" */
-#define shutdown_r7780rp_irq disable_r7780rp_irq
-
-static void ack_r7780rp_irq(unsigned int irq);
-static void end_r7780rp_irq(unsigned int irq);
-
-static unsigned int startup_r7780rp_irq(unsigned int irq)
-{
-       enable_r7780rp_irq(irq);
-       return 0; /* never anything pending */
-}
-
-static void disable_r7780rp_irq(unsigned int irq)
-{
-       unsigned short val;
-       unsigned short mask = 0xffff ^ (0x0001 << mask_pos[irq]);
-
-       /* Set the priority in IPR to 0 */
-       val = ctrl_inw(IRLCNTR1);
-       val &= mask;
-       ctrl_outw(val, IRLCNTR1);
-}
-
 static void enable_r7780rp_irq(unsigned int irq)
 {
-       unsigned short val;
-       unsigned short value = (0x0001 << mask_pos[irq]);
-
        /* Set priority in IPR back to original value */
-       val = ctrl_inw(IRLCNTR1);
-       val |= value;
-       ctrl_outw(val, IRLCNTR1);
-}
-
-static void ack_r7780rp_irq(unsigned int irq)
-{
-       disable_r7780rp_irq(irq);
+       ctrl_outw(ctrl_inw(IRLCNTR1) | (1 << mask_pos[irq]), IRLCNTR1);
 }
 
-static void end_r7780rp_irq(unsigned int irq)
+static void disable_r7780rp_irq(unsigned int irq)
 {
-       if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-               enable_r7780rp_irq(irq);
+       /* Set the priority in IPR to 0 */
+       ctrl_outw(ctrl_inw(IRLCNTR1) & (0xffff ^ (1 << mask_pos[irq])),
+                 IRLCNTR1);
 }
 
-static struct hw_interrupt_type r7780rp_irq_type = {
-       .typename = "R7780RP-IRQ",
-       .startup = startup_r7780rp_irq,
-       .shutdown = shutdown_r7780rp_irq,
-       .enable = enable_r7780rp_irq,
-       .disable = disable_r7780rp_irq,
-       .ack = ack_r7780rp_irq,
-       .end = end_r7780rp_irq,
+static struct irq_chip r7780rp_irq_chip __read_mostly = {
+       .name           = "R7780RP",
+       .mask           = disable_r7780rp_irq,
+       .unmask         = enable_r7780rp_irq,
+       .mask_ack       = disable_r7780rp_irq,
 };
 
-static void make_r7780rp_irq(unsigned int irq)
-{
-       disable_irq_nosync(irq);
-       irq_desc[irq].chip = &r7780rp_irq_type;
-       disable_r7780rp_irq(irq);
-}
-
 /*
  * Initialize IRQ setting
  */
@@ -92,24 +46,10 @@ void __init init_r7780rp_IRQ(void)
 {
        int i;
 
-       /* IRL0=PCI Slot #A
-        * IRL1=PCI Slot #B
-        * IRL2=PCI Slot #C
-        * IRL3=PCI Slot #D
-        * IRL4=CF Card
-        * IRL5=CF Card Insert
-        * IRL6=M66596
-        * IRL7=SD Card
-        * IRL8=Touch Panel
-        * IRL9=SCI
-        * IRL10=Serial
-        * IRL11=Extention #A
-        * IRL11=Extention #B
-        * IRL12=Debug LAN
-        * IRL13=Push Switch
-        * IRL14=ZiggBee IO
-        */
-
-       for (i=0; i<15; i++)
-               make_r7780rp_irq(i);
+       for (i = 0; i < 15; i++) {
+               disable_irq_nosync(i);
+               set_irq_chip_and_handler_name(i, &r7780rp_irq_chip,
+                                             handle_level_irq, "level");
+               enable_r7780rp_irq(i);
+       }
 }
index b941aa0aa34e60b8397e235ed5260cd87e932516..c331caeb694b681658639d5a8e75a3f765afa36c 100644 (file)
@@ -13,7 +13,7 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <asm/machvec.h>
-#include <asm/r7780rp/r7780rp.h>
+#include <asm/r7780rp.h>
 #include <asm/clock.h>
 #include <asm/io.h>
 
index 135aa0b5e62dcc926d7df4f3c4996c70c1433c96..f2507a804979a35f0b3a2bedb696986c06d1a689 100644 (file)
@@ -11,8 +11,8 @@
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/pci.h>
-#include <asm/rts7751r2d/rts7751r2d.h>
-#include <asm/io.h>
+#include <linux/io.h>
+#include <asm/rts7751r2d.h>
 #include <asm/addrspace.h>
 
 /*
index c915e7a3693a0648b8f52e090cdc4add9b72ac09..cb0eb20d1b4348fbd58a81c54a88bf7be7973399 100644 (file)
@@ -8,12 +8,10 @@
  * Modified for RTS7751R2D by
  * Atom Create Engineering Co., Ltd. 2002.
  */
-
 #include <linux/init.h>
 #include <linux/irq.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/rts7751r2d/rts7751r2d.h>
+#include <linux/io.h>
+#include <asm/rts7751r2d.h>
 
 #if defined(CONFIG_RTS7751R2D_REV11)
 static int mask_pos[] = {11, 9, 8, 12, 10, 6, 5, 4, 7, 14, 13, 0, 0, 0, 0};
index a7ce66c1e4f04ceb5a39d0dbd1c95050bffe879f..509f548bdce037e12eebdb4a5179515ade7dce0b 100644 (file)
@@ -8,13 +8,9 @@
  *
  * This file contains Renesas Technology Sales RTS7751R2D specific LED code.
  */
-
-#include <asm/io.h>
-#include <asm/rts7751r2d/rts7751r2d.h>
-
-#ifdef CONFIG_HEARTBEAT
-
+#include <linux/io.h>
 #include <linux/sched.h>
+#include <asm/rts7751r2d.h>
 
 /* Cycle the LED's in the clasic Knightriger/Sun pattern */
 void heartbeat_rts7751r2d(void)
@@ -46,10 +42,3 @@ void heartbeat_rts7751r2d(void)
        else
                bit--;
 }
-#endif /* CONFIG_HEARTBEAT */
-
-void rts7751r2d_led(unsigned short value)
-{
-       ctrl_outw(value, PA_OUTPORT);
-}
-
index 20597a6e6702c40e76f5cab65a2b396f668b3c08..5c042d35ec91768d5255d2cba2ddf8c48f59fcb8 100644 (file)
@@ -12,9 +12,9 @@
 #include <linux/platform_device.h>
 #include <linux/serial_8250.h>
 #include <linux/pm.h>
-#include <asm/io.h>
 #include <asm/machvec.h>
 #include <asm/mach/rts7751r2d.h>
+#include <asm/io.h>
 #include <asm/voyagergx.h>
 
 extern void heartbeat_rts7751r2d(void);
index 2f0c19706cf9ad3e144b57fada06bbd83ac15eef..a31a1d1e2681f06e16dff61cf2eef069977949ab 100644 (file)
@@ -7,7 +7,7 @@
  */
 #include <linux/init.h>
 #include <asm/machvec.h>
-#include <asm/shmin/shmin.h>
+#include <asm/shmin.h>
 #include <asm/clock.h>
 #include <asm/irq.h>
 #include <asm/io.h>
index f5e98c56b530a7c23d3e43b77e2b063cf19a448f..540d0bf16446e6edf6f3375e99661d5712ded7ce 100644 (file)
@@ -33,7 +33,7 @@ extern void pcibios_init(void);
  * EraseConfig handling functions
  */
 
-static irqreturn_t eraseconfig_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t eraseconfig_interrupt(int irq, void *dev_id)
 {
        volatile char dummy __attribute__((unused)) = * (volatile char *) 0xb8000000;
 
index 38f1e8171a3abbf361ac628e2b1f63c24c4b9f92..4d49b5cbcc1333632c685adb64cef2b5e79210f7 100644 (file)
@@ -71,7 +71,7 @@ static struct hw_interrupt_type hd64461_irq_type = {
        .end            = end_hd64461_irq,
 };
 
-static irqreturn_t hd64461_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t hd64461_interrupt(int irq, void *dev_id)
 {
        printk(KERN_INFO
               "HD64461: spurious interrupt, nirr: 0x%x nimr: 0x%x\n",
index 72320d02d69af015a7996997945ebc93918960d5..43431855ec86976874a0b4cf2c76305d10b42d5a 100644 (file)
@@ -85,7 +85,7 @@ static struct {
     void *dev;
 } handlers[GPIO_NPORTS * 8];
 
-static irqreturn_t hd64465_gpio_interrupt(int irq, void *dev, struct pt_regs *regs)
+static irqreturn_t hd64465_gpio_interrupt(int irq, void *dev)
 {
        unsigned short port, pin, isr, mask, portpin;
        
index 30573d3e1966717c46c420703972166625cb785f..d126e1f30dee60b99f0f959bd8755516c3618086 100644 (file)
@@ -84,7 +84,7 @@ static struct hw_interrupt_type hd64465_irq_type = {
 };
 
 
-static irqreturn_t hd64465_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t hd64465_interrupt(int irq, void *dev_id)
 {
        printk(KERN_INFO
               "HD64465: spurious interrupt, nirr: 0x%x nimr: 0x%x\n",
index 392c8b12ce36789dea7dbe0b8b3a25084f49371b..f7ea700d05ae53c022493c791f601aa25266f7e5 100644 (file)
 
     Copyright 2003 (c) Lineo uSolutions,Inc.
 */
-/* -------------------------------------------------------------------- */
-
-#undef DEBUG
-
-#include <linux/sched.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/param.h>
-#include <linux/ioport.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
-#include <linux/irq.h>
-
-#include <asm/io.h>
-#include <asm/irq.h>
+#include <linux/io.h>
 #include <asm/voyagergx.h>
+#include <asm/rts7751r2d.h>
 
 static void disable_voyagergx_irq(unsigned int irq)
 {
        unsigned long val;
        unsigned long mask = 1 << (irq - VOYAGER_IRQ_BASE);
 
-       pr_debug("disable_voyagergx_irq(%d): mask=%x\n", irq, mask);
+       pr_debug("disable_voyagergx_irq(%d): mask=%lx\n", irq, mask);
         val = inl(VOYAGER_INT_MASK);
         val &= ~mask;
         outl(val, VOYAGER_INT_MASK);
@@ -50,7 +39,7 @@ static void enable_voyagergx_irq(unsigned int irq)
         unsigned long val;
         unsigned long mask = 1 << (irq - VOYAGER_IRQ_BASE);
 
-        pr_debug("disable_voyagergx_irq(%d): mask=%x\n", irq, mask);
+        pr_debug("disable_voyagergx_irq(%d): mask=%lx\n", irq, mask);
         val = inl(VOYAGER_INT_MASK);
         val |= mask;
         outl(val, VOYAGER_INT_MASK);
@@ -88,8 +77,7 @@ static struct hw_interrupt_type voyagergx_irq_type = {
        .end = end_voyagergx_irq,
 };
 
-static irqreturn_t voyagergx_interrupt(int irq, void *dev_id,
-                                     struct pt_regs *regs)
+static irqreturn_t voyagergx_interrupt(int irq, void *dev_id)
 {
        printk(KERN_INFO
               "VoyagerGX: spurious interrupt, status: 0x%x\n",
@@ -138,7 +126,7 @@ int voyagergx_irq_demux(int irq)
                } else {
                        printk("Unexpected IRQ irq = %d status = 0x%08lx\n", irq, val);
                }
-               pr_debug("voyagergx_irq_demux %\n", i);
+               pr_debug("voyagergx_irq_demux %ld\n", i);
 #else
                for (bit = 1, i = 0 ; i < VOYAGER_IRQ_NUM ; bit <<= 1, i++)
                        if (val & bit)
@@ -186,4 +174,3 @@ void __init setup_voyagergx_irq(void)
 
        setup_irq(IRQ_VOYAGER, &irq0);
 }
-
index 9cb0709241808b6365e1a024f048722cbffb8a94..0caf11bb7e27993ae65d6e0ae5ff1531514c931a 100644 (file)
@@ -51,7 +51,7 @@ static volatile struct g2_dma_info *g2_dma = (volatile struct g2_dma_info *)0xa0
        ((g2_dma->channel[i].size - \
          g2_dma->status[i].size) & 0x0fffffff)
 
-static irqreturn_t g2_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t g2_dma_interrupt(int irq, void *dev_id)
 {
        int i;
 
index c1b6bc23c107f3cfc0d39941fd9cff9e2c2b9529..838fad566eaf68f8e4282fa4f218c02915e15147 100644 (file)
@@ -21,7 +21,7 @@
 static unsigned int xfer_complete;
 static int count;
 
-static irqreturn_t pvr2_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t pvr2_dma_interrupt(int irq, void *dev_id)
 {
        if (get_dma_residue(PVR2_CASCADE_CHAN)) {
                printk(KERN_WARNING "DMA: SH DMAC did not complete transfer "
index cbbe8bce3d679fd7d5b77e4f40363fd314dc3dee..d8ece20bb2cf078fd913facab2fdc4def5d1f384 100644 (file)
@@ -60,9 +60,9 @@ static inline unsigned int calc_xmit_shift(struct dma_channel *chan)
  * Besides that it needs to waken any waiting process, which should handle
  * setting up the next transfer.
  */
-static irqreturn_t dma_tei(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t dma_tei(int irq, void *dev_id)
 {
-       struct dma_channel *chan = (struct dma_channel *)dev_id;
+       struct dma_channel *chan = dev_id;
        u32 chcr;
 
        chcr = ctrl_inl(CHCR[chan->chan]);
@@ -228,7 +228,7 @@ static inline int dmaor_reset(void)
 }
 
 #if defined(CONFIG_CPU_SH4)
-static irqreturn_t dma_err(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t dma_err(int irq, void *dummy)
 {
        dmaor_reset();
        disable_irq(irq);
index 6e3ba9c65b40534de3d65f3c9a358d52d3476853..eeea1577e112727d6afd32d018ced0681788e65f 100644 (file)
@@ -13,7 +13,7 @@
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/pci.h>
-#include <asm/r7780rp/r7780rp.h>
+#include <asm/r7780rp.h>
 #include <asm/io.h>
 #include "pci-sh4.h"
 
index b68824c8b81e72684946ac2f36628c70bd613a4c..4a518d948049b41ff150a82303b3b69ee58fa691 100644 (file)
  *
  * PCI initialization for the Renesas SH7751R RTS7751R2D board
  */
-
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/init.h>
-#include <linux/delay.h>
 #include <linux/pci.h>
-#include <linux/module.h>
-#include <asm/rts7751r2d/rts7751r2d.h>
-#include <asm/io.h>
+#include <linux/io.h>
+#include <asm/rts7751r2d.h>
 #include "pci-sh4.h"
 
+static u8 rts7751r2d_irq_tab[] __initdata = {
+       IRQ_PCISLOT1,
+       IRQ_PCISLOT2,
+       IRQ_PCMCIA,
+       IRQ_PCIETH,
+};
+
 int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin)
 {
-        switch (slot) {
-       case 0: return IRQ_PCISLOT1;    /* PCI Extend slot #1 */
-       case 1: return IRQ_PCISLOT2;    /* PCI Extend slot #2 */
-       case 2: return IRQ_PCMCIA;      /* PCI Cardbus Bridge */
-       case 3: return IRQ_PCIETH;      /* Realtek Ethernet controller */
-       default:
-               printk("PCI: Bad IRQ mapping request for slot %d\n", slot);
-               return -1;
-       }
+       return rts7751r2d_irq_tab[slot];
 }
 
 static struct resource sh7751_io_resource = {
index dbe837884983285c302cc60d64e900fbd7ccc94c..85e1ee2e2e7b47d6997304768bfbc25c5998d92b 100644 (file)
@@ -155,7 +155,7 @@ int __init sh7751_pcic_init(struct sh4_pci_address_map *map)
         */
        pr_debug("PCI: Mapping IO address 0x%x - 0x%x to base 0x%x\n",
                 PCIBIOS_MIN_IO, (64 << 10),
-                SH4_PCI_IO_BASE + PCIBIOS_MIN_IO);
+                SH7751_PCI_IO_BASE + PCIBIOS_MIN_IO);
 
        /*
         * XXX: For now, leave this board-specific. In the event we have other
@@ -163,7 +163,7 @@ int __init sh7751_pcic_init(struct sh4_pci_address_map *map)
         */
 #ifdef CONFIG_SH_BIGSUR
        bigsur_port_map(PCIBIOS_MIN_IO, (64 << 10),
-                       SH4_PCI_IO_BASE + PCIBIOS_MIN_IO, 0);
+                       SH7751_PCI_IO_BASE + PCIBIOS_MIN_IO, 0);
 #endif
 
        /* Make sure the MSB's of IO window are set to access PCI space
index 4ab5ea6b35fb5eeaf22fa5dd5889803f4d9555c1..efecb3d5995c24e8dd7221420b0205da06ab3d4a 100644 (file)
@@ -161,7 +161,7 @@ static char * pci_commands[16]={
        "Memory Write-and-Invalidate"
 };
 
-static irqreturn_t st40_pci_irq(int irq, void *dev_instance, struct pt_regs *regs)
+static irqreturn_t st40_pci_irq(int irq, void *dev_instance)
 {
        unsigned pci_int, pci_air, pci_cir, pci_aint;
        static int count=0;
index e30e4b7aa70e739be7ed77211b32d5cc04f1801f..74ca576a7ce502984e26cf8511a7808acaf65c03 100644 (file)
  * These are the "new Hitachi style" interrupts, as present on the
  * Hitachi 7751, the STM ST40 STB1, SH7760, and SH7780.
  */
-
 #include <linux/kernel.h>
-#include <linux/init.h>
 #include <linux/irq.h>
+#include <linux/io.h>
 #include <asm/system.h>
-#include <asm/io.h>
-#include <asm/machvec.h>
-
-struct intc2_data {
-       unsigned char msk_offset;
-       unsigned char msk_shift;
-
-       int (*clear_irq) (int);
-};
-
-static struct intc2_data intc2_data[NR_INTC2_IRQS];
-
-static void enable_intc2_irq(unsigned int irq);
-static void disable_intc2_irq(unsigned int irq);
-
-/* shutdown is same as "disable" */
-#define shutdown_intc2_irq disable_intc2_irq
-
-static void mask_and_ack_intc2(unsigned int);
-static void end_intc2_irq(unsigned int irq);
-
-static unsigned int startup_intc2_irq(unsigned int irq)
-{
-       enable_intc2_irq(irq);
-       return 0; /* never anything pending */
-}
-
-static struct hw_interrupt_type intc2_irq_type = {
-       .typename       = "INTC2-IRQ",
-       .startup        = startup_intc2_irq,
-       .shutdown       = shutdown_intc2_irq,
-       .enable         = enable_intc2_irq,
-       .disable        = disable_intc2_irq,
-       .ack            = mask_and_ack_intc2,
-       .end            = end_intc2_irq
-};
 
 static void disable_intc2_irq(unsigned int irq)
 {
-       int irq_offset = irq - INTC2_FIRST_IRQ;
-       int msk_shift, msk_offset;
-
-       /* Sanity check */
-       if (unlikely(irq_offset < 0 || irq_offset >= NR_INTC2_IRQS))
-               return;
-
-       msk_shift = intc2_data[irq_offset].msk_shift;
-       msk_offset = intc2_data[irq_offset].msk_offset;
-
-       ctrl_outl(1 << msk_shift,
-                 INTC2_BASE + INTC2_INTMSK_OFFSET + msk_offset);
+       struct intc2_data *p = get_irq_chip_data(irq);
+       ctrl_outl(1 << p->msk_shift,
+                 INTC2_BASE + INTC2_INTMSK_OFFSET + p->msk_offset);
 }
 
 static void enable_intc2_irq(unsigned int irq)
 {
-       int irq_offset = irq - INTC2_FIRST_IRQ;
-       int msk_shift, msk_offset;
-
-       /* Sanity check */
-       if (unlikely(irq_offset < 0 || irq_offset >= NR_INTC2_IRQS))
-               return;
-
-       msk_shift = intc2_data[irq_offset].msk_shift;
-       msk_offset = intc2_data[irq_offset].msk_offset;
-
-       ctrl_outl(1 << msk_shift,
-                 INTC2_BASE + INTC2_INTMSKCLR_OFFSET + msk_offset);
+       struct intc2_data *p = get_irq_chip_data(irq);
+       ctrl_outl(1 << p->msk_shift,
+                 INTC2_BASE + INTC2_INTMSKCLR_OFFSET + p->msk_offset);
 }
 
-static void mask_and_ack_intc2(unsigned int irq)
-{
-       disable_intc2_irq(irq);
-}
-
-static void end_intc2_irq(unsigned int irq)
-{
-       if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-               enable_intc2_irq(irq);
-
-       if (unlikely(intc2_data[irq - INTC2_FIRST_IRQ].clear_irq))
-               intc2_data[irq - INTC2_FIRST_IRQ].clear_irq(irq);
-}
+static struct irq_chip intc2_irq_chip = {
+       .name           = "INTC2",
+       .mask           = disable_intc2_irq,
+       .unmask         = enable_intc2_irq,
+       .mask_ack       = disable_intc2_irq,
+};
 
 /*
  * Setup an INTC2 style interrupt.
@@ -106,179 +44,36 @@ static void end_intc2_irq(unsigned int irq)
  *    PIO1 which is INTPRI00[19,16] and INTMSK00[13]
  * would be:               ^     ^             ^  ^
  *                         |     |             |  |
- *    make_intc2_irq(84,   0,   16,            0, 13);
+ *     { 84,              0,   16,            0, 13 },
+ *
+ * in the intc2_data table.
  */
-void make_intc2_irq(unsigned int irq,
-                   unsigned int ipr_offset, unsigned int ipr_shift,
-                   unsigned int msk_offset, unsigned int msk_shift,
-                   unsigned int priority)
+void make_intc2_irq(struct intc2_data *table, unsigned int nr_irqs)
 {
-       int irq_offset = irq - INTC2_FIRST_IRQ;
-       unsigned int flags;
-       unsigned long ipr;
-
-       if (unlikely(irq_offset < 0 || irq_offset >= NR_INTC2_IRQS))
-               return;
-
-       disable_irq_nosync(irq);
-
-       /* Fill the data we need */
-       intc2_data[irq_offset].msk_offset = msk_offset;
-       intc2_data[irq_offset].msk_shift  = msk_shift;
-       intc2_data[irq_offset].clear_irq = NULL;
-
-       /* Set the priority level */
-       local_irq_save(flags);
-
-       ipr = ctrl_inl(INTC2_BASE + INTC2_INTPRI_OFFSET + ipr_offset);
-       ipr &= ~(0xf << ipr_shift);
-       ipr |= priority << ipr_shift;
-       ctrl_outl(ipr, INTC2_BASE + INTC2_INTPRI_OFFSET + ipr_offset);
-
-       local_irq_restore(flags);
+       int i;
 
-       irq_desc[irq].chip = &intc2_irq_type;
+       for (i = 0; i < nr_irqs; i++) {
+               unsigned long ipr, flags;
+               struct intc2_data *p = table + i;
 
-       disable_intc2_irq(irq);
-}
+               disable_irq_nosync(p->irq);
 
-static struct intc2_init {
-       unsigned short irq;
-       unsigned char ipr_offset, ipr_shift;
-       unsigned char msk_offset, msk_shift;
-       unsigned char priority;
-} intc2_init_data[]  __initdata = {
-#if defined(CONFIG_CPU_SUBTYPE_ST40)
-       {64,  0,  0, 0,  0, 13},        /* PCI serr */
-       {65,  0,  4, 0,  1, 13},        /* PCI err */
-       {66,  0,  4, 0,  2, 13},        /* PCI ad */
-       {67,  0,  4, 0,  3, 13},        /* PCI pwd down */
-       {72,  0,  8, 0,  5, 13},        /* DMAC INT0 */
-       {73,  0,  8, 0,  6, 13},        /* DMAC INT1 */
-       {74,  0,  8, 0,  7, 13},        /* DMAC INT2 */
-       {75,  0,  8, 0,  8, 13},        /* DMAC INT3 */
-       {76,  0,  8, 0,  9, 13},        /* DMAC INT4 */
-       {78,  0,  8, 0, 11, 13},        /* DMAC ERR */
-       {80,  0, 12, 0, 12, 13},        /* PIO0 */
-       {84,  0, 16, 0, 13, 13},        /* PIO1 */
-       {88,  0, 20, 0, 14, 13},        /* PIO2 */
-       {112, 4,  0, 4,  0, 13},        /* Mailbox */
- #ifdef CONFIG_CPU_SUBTYPE_ST40GX1
-       {116, 4,  4, 4,  4, 13},        /* SSC0 */
-       {120, 4,  8, 4,  8, 13},        /* IR Blaster */
-       {124, 4, 12, 4, 12, 13},        /* USB host */
-       {128, 4, 16, 4, 16, 13},        /* Video processor BLITTER */
-       {132, 4, 20, 4, 20, 13},        /* UART0 */
-       {134, 4, 20, 4, 22, 13},        /* UART2 */
-       {136, 4, 24, 4, 24, 13},        /* IO_PIO0 */
-       {140, 4, 28, 4, 28, 13},        /* EMPI */
-       {144, 8,  0, 8,  0, 13},        /* MAFE */
-       {148, 8,  4, 8,  4, 13},        /* PWM */
-       {152, 8,  8, 8,  8, 13},        /* SSC1 */
-       {156, 8, 12, 8, 12, 13},        /* IO_PIO1 */
-       {160, 8, 16, 8, 16, 13},        /* USB target */
-       {164, 8, 20, 8, 20, 13},        /* UART1 */
-       {168, 8, 24, 8, 24, 13},        /* Teletext */
-       {172, 8, 28, 8, 28, 13},        /* VideoSync VTG */
-       {173, 8, 28, 8, 29, 13},        /* VideoSync DVP0 */
-       {174, 8, 28, 8, 30, 13},        /* VideoSync DVP1 */
-#endif
-#elif defined(CONFIG_CPU_SUBTYPE_SH7760)
-/*
- * SH7760 INTC2-Style interrupts, vectors IRQ48-111 INTEVT 0x800-0xFE0
- */
-       /* INTPRIO0 | INTMSK0 */
-       {48,  0, 28, 0, 31,  3},        /* IRQ 4 */
-       {49,  0, 24, 0, 30,  3},        /* IRQ 3 */
-       {50,  0, 20, 0, 29,  3},        /* IRQ 2 */
-       {51,  0, 16, 0, 28,  3},        /* IRQ 1 */
-       /* 52-55 (INTEVT 0x880-0x8E0) unused/reserved */
-       /* INTPRIO4 | INTMSK0 */
-       {56,  4, 28, 0, 25,  3},        /* HCAN2_CHAN0 */
-       {57,  4, 24, 0, 24,  3},        /* HCAN2_CHAN1 */
-       {58,  4, 20, 0, 23,  3},        /* I2S_CHAN0   */
-       {59,  4, 16, 0, 22,  3},        /* I2S_CHAN1   */
-       {60,  4, 12, 0, 21,  3},        /* AC97_CHAN0  */
-       {61,  4,  8, 0, 20,  3},        /* AC97_CHAN1  */
-       {62,  4,  4, 0, 19,  3},        /* I2C_CHAN0   */
-       {63,  4,  0, 0, 18,  3},        /* I2C_CHAN1   */
-       /* INTPRIO8 | INTMSK0 */
-       {52,  8, 16, 0, 11,  3},        /* SCIF0_ERI_IRQ */
-       {53,  8, 16, 0, 10,  3},        /* SCIF0_RXI_IRQ */
-       {54,  8, 16, 0,  9,  3},        /* SCIF0_BRI_IRQ */
-       {55,  8, 16, 0,  8,  3},        /* SCIF0_TXI_IRQ */
-       {64,  8, 28, 0, 17,  3},        /* USBHI_IRQ */
-       {65,  8, 24, 0, 16,  3},        /* LCDC      */
-       /* 66, 67 unused */
-       {68,  8, 20, 0, 14, 13},        /* DMABRGI0_IRQ */
-       {69,  8, 20, 0, 13, 13},        /* DMABRGI1_IRQ */
-       {70,  8, 20, 0, 12, 13},        /* DMABRGI2_IRQ */
-       /* 71 unused */
-       {72,  8, 12, 0,  7,  3},        /* SCIF1_ERI_IRQ */
-       {73,  8, 12, 0,  6,  3},        /* SCIF1_RXI_IRQ */
-       {74,  8, 12, 0,  5,  3},        /* SCIF1_BRI_IRQ */
-       {75,  8, 12, 0,  4,  3},        /* SCIF1_TXI_IRQ */
-       {76,  8,  8, 0,  3,  3},        /* SCIF2_ERI_IRQ */
-       {77,  8,  8, 0,  2,  3},        /* SCIF2_RXI_IRQ */
-       {78,  8,  8, 0,  1,  3},        /* SCIF2_BRI_IRQ */
-       {79,  8,  8, 0,  0,  3},        /* SCIF2_TXI_IRQ */
-       /*          | INTMSK4 */
-       {80,  8,  4, 4, 23,  3},        /* SIM_ERI */
-       {81,  8,  4, 4, 22,  3},        /* SIM_RXI */
-       {82,  8,  4, 4, 21,  3},        /* SIM_TXI */
-       {83,  8,  4, 4, 20,  3},        /* SIM_TEI */
-       {84,  8,  0, 4, 19,  3},        /* HSPII */
-       /* INTPRIOC | INTMSK4 */
-       /* 85-87 unused/reserved */
-       {88, 12, 20, 4, 18,  3},        /* MMCI0 */
-       {89, 12, 20, 4, 17,  3},        /* MMCI1 */
-       {90, 12, 20, 4, 16,  3},        /* MMCI2 */
-       {91, 12, 20, 4, 15,  3},        /* MMCI3 */
-       {92, 12, 12, 4,  6,  3},        /* MFI (unsure, bug? in my 7760 manual*/
-       /* 93-107 reserved/undocumented */
-       {108,12,  4, 4,  1,  3},        /* ADC  */
-       {109,12,  0, 4,  0,  3},        /* CMTI */
-       /* 110-111 reserved/unused */
-#elif defined(CONFIG_CPU_SUBTYPE_SH7780)
-       { TIMER_IRQ, 0, 24, 0, INTC_TMU0_MSK, 2},
-       { 21, 1, 0, 0, INTC_RTC_MSK, TIMER_PRIORITY },
-       { 22, 1, 1, 0, INTC_RTC_MSK, TIMER_PRIORITY },
-       { 23, 1, 2, 0, INTC_RTC_MSK, TIMER_PRIORITY },
-       { SCIF0_ERI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY },
-       { SCIF0_RXI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY },
-       { SCIF0_BRI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY },
-       { SCIF0_TXI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY },
+               /* Set the priority level */
+               local_irq_save(flags);
 
-       { SCIF1_ERI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY },
-       { SCIF1_RXI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY },
-       { SCIF1_BRI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY },
-       { SCIF1_TXI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY },
+               ipr = ctrl_inl(INTC2_BASE + INTC2_INTPRI_OFFSET +
+                              p->ipr_offset);
+               ipr &= ~(0xf << p->ipr_shift);
+               ipr |= p->priority << p->ipr_shift;
+               ctrl_outl(ipr, INTC2_BASE + INTC2_INTPRI_OFFSET +
+                         p->ipr_offset);
 
-       { PCIC0_IRQ, 0x10,  8, 0, INTC_PCIC0_MSK, PCIC0_PRIORITY },
-       { PCIC1_IRQ, 0x10,  0, 0, INTC_PCIC1_MSK, PCIC1_PRIORITY },
-       { PCIC2_IRQ, 0x14, 24, 0, INTC_PCIC2_MSK, PCIC2_PRIORITY },
-       { PCIC3_IRQ, 0x14, 16, 0, INTC_PCIC3_MSK, PCIC3_PRIORITY },
-       { PCIC4_IRQ, 0x14,  8, 0, INTC_PCIC4_MSK, PCIC4_PRIORITY },
-#endif
-};
+               local_irq_restore(flags);
 
-void __init init_IRQ_intc2(void)
-{
-       int i;
+               set_irq_chip_and_handler_name(p->irq, &intc2_irq_chip,
+                                             handle_level_irq, "level");
+               set_irq_chip_data(p->irq, p);
 
-       for (i = 0; i < ARRAY_SIZE(intc2_init_data); i++) {
-               struct intc2_init *p = intc2_init_data + i;
-               make_intc2_irq(p->irq, p->ipr_offset, p->ipr_shift,
-                              p-> msk_offset, p->msk_shift, p->priority);
+               enable_intc2_irq(p->irq);
        }
 }
-
-/* Adds a termination callback to the interrupt */
-void intc2_add_clear_irq(int irq, int (*fn)(int))
-{
-       if (unlikely(irq < INTC2_FIRST_IRQ))
-               return;
-
-       intc2_data[irq - INTC2_FIRST_IRQ].clear_irq = fn;
-}
-
index f785822cd5dea4fb32e908a93f328c00ec3ffa4d..f7997312ef988e4016aa72411494eae994c34af6 100644 (file)
@@ -1,11 +1,10 @@
 /*
- * arch/sh/kernel/cpu/irq/ipr.c
+ * Interrupt handling for IPR-based IRQ.
  *
  * Copyright (C) 1999  Niibe Yutaka & Takeshi Yaegashi
  * Copyright (C) 2000  Kazumoto Kojima
- * Copyright (C) 2003 Takashi Kusuda <kusuda-takashi@hitachi-ul.co.jp>
- *
- * Interrupt handling for IPR-based IRQ.
+ * Copyright (C) 2003  Takashi Kusuda <kusuda-takashi@hitachi-ul.co.jp>
+ * Copyright (C) 2006  Paul Mundt
  *
  * Supported system:
  *     On-chip supporting modules (TMU, RTC, etc.).
  *     Hitachi SolutionEngine external I/O:
  *             MS7709SE01, MS7709ASE01, and MS7750SE01
  *
+ * 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 <linux/init.h>
 #include <linux/irq.h>
 #include <linux/module.h>
-
 #include <asm/system.h>
 #include <asm/io.h>
 #include <asm/machvec.h>
@@ -28,93 +28,46 @@ struct ipr_data {
        int shift;              /* Shifts of the 16-bit data */
        int priority;           /* The priority */
 };
-static struct ipr_data ipr_data[NR_IRQS];
-
-static void enable_ipr_irq(unsigned int irq);
-static void disable_ipr_irq(unsigned int irq);
-
-/* shutdown is same as "disable" */
-#define shutdown_ipr_irq disable_ipr_irq
-
-static void mask_and_ack_ipr(unsigned int);
-static void end_ipr_irq(unsigned int irq);
-
-static unsigned int startup_ipr_irq(unsigned int irq)
-{
-       enable_ipr_irq(irq);
-       return 0; /* never anything pending */
-}
-
-static struct hw_interrupt_type ipr_irq_type = {
-       .typename = "IPR-IRQ",
-       .startup = startup_ipr_irq,
-       .shutdown = shutdown_ipr_irq,
-       .enable = enable_ipr_irq,
-       .disable = disable_ipr_irq,
-       .ack = mask_and_ack_ipr,
-       .end = end_ipr_irq
-};
 
 static void disable_ipr_irq(unsigned int irq)
 {
-       unsigned long val;
-       unsigned int addr = ipr_data[irq].addr;
-       unsigned short mask = 0xffff ^ (0x0f << ipr_data[irq].shift);
-
+       struct ipr_data *p = get_irq_chip_data(irq);
        /* Set the priority in IPR to 0 */
-       val = ctrl_inw(addr);
-       val &= mask;
-       ctrl_outw(val, addr);
+       ctrl_outw(ctrl_inw(p->addr) & (0xffff ^ (0xf << p->shift)), p->addr);
 }
 
 static void enable_ipr_irq(unsigned int irq)
 {
-       unsigned long val;
-       unsigned int addr = ipr_data[irq].addr;
-       int priority = ipr_data[irq].priority;
-       unsigned short value = (priority << ipr_data[irq].shift);
-
+       struct ipr_data *p = get_irq_chip_data(irq);
        /* Set priority in IPR back to original value */
-       val = ctrl_inw(addr);
-       val |= value;
-       ctrl_outw(val, addr);
+       ctrl_outw(ctrl_inw(p->addr) | (p->priority << p->shift), p->addr);
 }
 
-static void mask_and_ack_ipr(unsigned int irq)
-{
-       disable_ipr_irq(irq);
-
-#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \
-    defined(CONFIG_CPU_SUBTYPE_SH7706) || \
-    defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7705)
-       /* This is needed when we use edge triggered setting */
-       /* XXX: Is it really needed? */
-       if (IRQ0_IRQ <= irq && irq <= IRQ5_IRQ) {
-               /* Clear external interrupt request */
-               int a = ctrl_inb(INTC_IRR0);
-               a &= ~(1 << (irq - IRQ0_IRQ));
-               ctrl_outb(a, INTC_IRR0);
-       }
-#endif
-}
-
-static void end_ipr_irq(unsigned int irq)
-{
-       if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-               enable_ipr_irq(irq);
-}
+static struct irq_chip ipr_irq_chip = {
+       .name           = "IPR",
+       .mask           = disable_ipr_irq,
+       .unmask         = enable_ipr_irq,
+       .mask_ack       = disable_ipr_irq,
+};
 
 void make_ipr_irq(unsigned int irq, unsigned int addr, int pos, int priority)
 {
+       struct ipr_data ipr_data;
+
        disable_irq_nosync(irq);
-       ipr_data[irq].addr = addr;
-       ipr_data[irq].shift = pos*4; /* POSition (0-3) x 4 means shift */
-       ipr_data[irq].priority = priority;
 
-       irq_desc[irq].chip = &ipr_irq_type;
-       disable_ipr_irq(irq);
+       ipr_data.addr = addr;
+       ipr_data.shift = pos*4; /* POSition (0-3) x 4 means shift */
+       ipr_data.priority = priority;
+
+       set_irq_chip_and_handler_name(irq, &ipr_irq_chip,
+                                     handle_level_irq, "level");
+       set_irq_chip_data(irq, &ipr_data);
+
+       enable_ipr_irq(irq);
 }
 
+/* XXX: This needs to die a horrible death.. */
 void __init init_IRQ(void)
 {
 #ifndef CONFIG_CPU_SUBTYPE_SH7780
index 44daf44833f90852e0f39557784fab51e2fc8ae2..ba3082d640b5f1d06191a7cc9671ee62a4bb111e 100644 (file)
@@ -4,7 +4,7 @@
  *  The SH-3 exception vector table.
 
  *  Copyright (C) 1999, 2000, 2002  Niibe Yutaka
- *  Copyright (C) 2003  Paul Mundt
+ *  Copyright (C) 2003 - 2006  Paul Mundt
  *
  * 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
@@ -49,198 +49,10 @@ ENTRY(nmi_slot)
 #endif
 ENTRY(user_break_point_trap)
        .long   break_point_trap        /* 1E0 */
-ENTRY(interrupt_table)
-       ! external hardware
-       .long   do_IRQ  ! 0000          /* 200 */
-       .long   do_IRQ  ! 0001
-       .long   do_IRQ  ! 0010
-       .long   do_IRQ  ! 0011
-       .long   do_IRQ  ! 0100
-       .long   do_IRQ  ! 0101
-       .long   do_IRQ  ! 0110
-       .long   do_IRQ  ! 0111
-       .long   do_IRQ  ! 1000          /* 300 */
-       .long   do_IRQ  ! 1001
-       .long   do_IRQ  ! 1010
-       .long   do_IRQ  ! 1011
-       .long   do_IRQ  ! 1100
-       .long   do_IRQ  ! 1101
-       .long   do_IRQ  ! 1110
-       .long   exception_error         
-       ! Internal hardware
-       .long   do_IRQ  ! TMU0 tuni0    /* 400 */
-       .long   do_IRQ  ! TMU1 tuni1
-       .long   do_IRQ  ! TMU2 tuni2
-       .long   do_IRQ  !      ticpi2
-       .long   do_IRQ  ! RTC  ati
-       .long   do_IRQ  !      pri
-       .long   do_IRQ  !      cui
-       .long   do_IRQ  ! SCI  eri
-       .long   do_IRQ  !      rxi      /* 500 */
-       .long   do_IRQ  !      txi
-       .long   do_IRQ  !      tei
-       .long   do_IRQ  ! WDT  iti      /* 560 */
-       .long   do_IRQ  ! REF  rcmi
-       .long   do_IRQ  !      rovi
-       .long   do_IRQ                  
-       .long   do_IRQ                  /* 5E0 */
-#if  defined(CONFIG_CPU_SUBTYPE_SH7707) || \
-     defined(CONFIG_CPU_SUBTYPE_SH7709) || \
-     defined(CONFIG_CPU_SUBTYPE_SH7706) || \
-     defined(CONFIG_CPU_SUBTYPE_SH7300) || \
-     defined(CONFIG_CPU_SUBTYPE_SH7705) || \
-     defined(CONFIG_CPU_SUBTYPE_SH7710)
-       .long   do_IRQ  ! 32 IRQ  irq0  /* 600 */
-       .long   do_IRQ  ! 33      irq1
-       .long   do_IRQ  ! 34      irq2
-       .long   do_IRQ  ! 35      irq3
-       .long   do_IRQ  ! 36      irq4
-       .long   do_IRQ  ! 37      irq5
-       .long   do_IRQ  ! 38
-       .long   do_IRQ  ! 39
-       .long   do_IRQ  ! 40 PINT pint0-7       /* 700 */
-       .long   do_IRQ  ! 41      pint8-15
-       .long   do_IRQ  ! 42
-       .long   do_IRQ  ! 43
-       .long   do_IRQ  ! 44
-       .long   do_IRQ  ! 45    
-       .long   do_IRQ  ! 46
-       .long   do_IRQ  ! 47
-       .long   do_IRQ  ! 48 DMAC dei0  /* 800 */
-       .long   do_IRQ  ! 49      dei1
-       .long   do_IRQ  ! 50      dei2
-       .long   do_IRQ  ! 51      dei3
-       .long   do_IRQ  ! 52 IrDA eri1
-       .long   do_IRQ  ! 53      rxi1
-       .long   do_IRQ  ! 54      bri1
-       .long   do_IRQ  ! 55      txi1
-       .long   do_IRQ  ! 56 SCIF eri2
-       .long   do_IRQ  ! 57      rxi2
-       .long   do_IRQ  ! 58      bri2
-       .long   do_IRQ  ! 59      txi2
-       .long   do_IRQ  ! 60 ADC  adi   /* 980 */
-#if defined(CONFIG_CPU_SUBTYPE_SH7705)
-       .long   exception_none  ! 61    /* 9A0 */
-       .long   exception_none  ! 62
-       .long   exception_none  ! 63
-       .long   exception_none  ! 64    /* A00 */
-       .long   do_IRQ  ! 65 USB  usi0
-       .long   do_IRQ  ! 66      usi1
-       .long   exception_none  ! 67
-       .long   exception_none  ! 68
-       .long   exception_none  ! 69
-       .long   exception_none  ! 70
-       .long   exception_none  ! 71
-       .long   exception_none  ! 72    /* B00 */
-       .long   exception_none  ! 73
-       .long   exception_none  ! 74
-       .long   exception_none  ! 75
-       .long   exception_none  ! 76
-       .long   exception_none  ! 77
-       .long   exception_none  ! 78
-       .long   exception_none  ! 79
-       .long   do_IRQ  ! 80 TPU0 tpi0  /* C00 */
-       .long   do_IRQ  ! 81 TPU1 tpi1
-       .long   exception_none  ! 82
-       .long   exception_none  ! 83
-       .long   do_IRQ  ! 84 TPU2 tpi2
-       .long   do_IRQ  ! 85 TPU3 tpi3  /* CA0 */
-#endif
-#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7300)
-       .long   do_IRQ  ! 61 LCDC lcdi  /* 9A0 */
-       .long   do_IRQ  ! 62 PCC  pcc0i
-       .long   do_IRQ  ! 63      pcc1i /* 9E0 */
-#endif
-#if defined(CONFIG_CPU_SUBTYPE_SH7710)
-       .long   exception_none  ! 61    /* 9A0 */
-       .long   exception_none  ! 62
-       .long   exception_none  ! 63
-       .long   exception_none  ! 64    /* A00 */
-       .long   exception_none  ! 65
-       .long   exception_none  ! 66
-       .long   exception_none  ! 67
-       .long   exception_none  ! 68
-       .long   exception_none  ! 69
-       .long   exception_none  ! 70
-       .long   exception_none  ! 71
-       .long   exception_none  ! 72    /* B00 */
-       .long   exception_none  ! 73
-       .long   exception_none  ! 74
-       .long   exception_none  ! 75
-       .long   do_IRQ  ! 76 DMAC2 dei4 /* B80 */
-       .long   do_IRQ  ! 77 DMAC2 dei5
-       .long   exception_none  ! 78
-       .long   do_IRQ  ! 79 IPSEC ipseci /* BE0 */
-       .long   do_IRQ  ! 80 EDMAC eint0 /* C00 */
-       .long   do_IRQ  ! 81 EDMAC eint1
-       .long   do_IRQ  ! 82 EDMAC eint2
-       .long   exception_none  ! 83    /* C60 */
-       .long   exception_none  ! 84
-       .long   exception_none  ! 85
-       .long   exception_none  ! 86
-       .long   exception_none  ! 87
-       .long   exception_none  ! 88    /* D00 */
-       .long   exception_none  ! 89
-       .long   exception_none  ! 90
-       .long   exception_none  ! 91
-       .long   exception_none  ! 92
-       .long   exception_none  ! 93
-       .long   exception_none  ! 94
-       .long   exception_none  ! 95
-       .long   do_IRQ  ! 96 SIOF eri0  /* E00 */
-       .long   do_IRQ  ! 97      txi0
-       .long   do_IRQ  ! 98      rxi0
-       .long   do_IRQ  ! 99      cci0
-       .long   do_IRQ  ! 100     eri1  /* E80 */
-       .long   do_IRQ  ! 101     txi1
-       .long   do_IRQ  ! 102     rxi2
-       .long   do_IRQ  ! 103     cci3
-#endif
-#if defined(CONFIG_CPU_SUBTYPE_SH7300)
-       .long   do_IRQ  ! 64
-       .long   do_IRQ  ! 65
-       .long   do_IRQ  ! 66
-       .long   do_IRQ  ! 67
-       .long   do_IRQ  ! 68
-       .long   do_IRQ  ! 69
-       .long   do_IRQ  ! 70
-       .long   do_IRQ  ! 71
-       .long   do_IRQ  ! 72
-       .long   do_IRQ  ! 73
-       .long   do_IRQ  ! 74
-       .long   do_IRQ  ! 75
-       .long   do_IRQ  ! 76
-       .long   do_IRQ  ! 77
-       .long   do_IRQ  ! 78
-       .long   do_IRQ  ! 79
-       .long   do_IRQ  ! 80 SCIF0(SH7300)
-       .long   do_IRQ  ! 81
-       .long   do_IRQ  ! 82
-       .long   do_IRQ  ! 83
-       .long   do_IRQ  ! 84
-       .long   do_IRQ  ! 85
-       .long   do_IRQ  ! 86
-       .long   do_IRQ  ! 87
-       .long   do_IRQ  ! 88
-       .long   do_IRQ  ! 89
-       .long   do_IRQ  ! 90
-       .long   do_IRQ  ! 91
-       .long   do_IRQ  ! 92
-       .long   do_IRQ  ! 93
-       .long   do_IRQ  ! 94
-       .long   do_IRQ  ! 95
-       .long   do_IRQ  ! 96
-       .long   do_IRQ  ! 97
-       .long   do_IRQ  ! 98
-       .long   do_IRQ  ! 99
-       .long   do_IRQ  ! 100
-       .long   do_IRQ  ! 101
-       .long   do_IRQ  ! 102
-       .long   do_IRQ  ! 103
-       .long   do_IRQ  ! 104
-       .long   do_IRQ  ! 105
-       .long   do_IRQ  ! 106
-       .long   do_IRQ  ! 107
-       .long   do_IRQ  ! 108
-#endif
-#endif
+
+       /*
+        * Pad the remainder of the table out, exceptions residing in far
+        * away offsets can be manually inserted in to their appropriate
+        * location via set_exception_table_{evt,vec}().
+        */
+       .balign 4096,0,4096
index 7146893a6cca5c3ebf33b78565eb2144c2f2f188..ac8ab57413cced9e802c5f77485be6e4b844d299 100644 (file)
@@ -4,7 +4,7 @@
  *  The SH-4 exception vector table.
 
  *  Copyright (C) 1999, 2000, 2002  Niibe Yutaka
- *  Copyright (C) 2003  Paul Mundt
+ *  Copyright (C) 2003 - 2006  Paul Mundt
  *
  * 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
@@ -53,503 +53,10 @@ ENTRY(nmi_slot)
 #endif
 ENTRY(user_break_point_trap)
        .long   break_point_trap        /* 1E0 */
-ENTRY(interrupt_table)
-       ! external hardware
-       .long   do_IRQ  ! 0000          /* 200 */
-       .long   do_IRQ  ! 0001
-       .long   do_IRQ  ! 0010
-       .long   do_IRQ  ! 0011
-       .long   do_IRQ  ! 0100
-       .long   do_IRQ  ! 0101
-       .long   do_IRQ  ! 0110
-       .long   do_IRQ  ! 0111
-       .long   do_IRQ  ! 1000          /* 300 */
-       .long   do_IRQ  ! 1001
-       .long   do_IRQ  ! 1010
-       .long   do_IRQ  ! 1011
-       .long   do_IRQ  ! 1100
-       .long   do_IRQ  ! 1101
-       .long   do_IRQ  ! 1110
-       .long   exception_error         
-       ! Internal hardware
-#ifndef CONFIG_CPU_SUBTYPE_SH7780
-       .long   do_IRQ  ! TMU0 tuni0    /* 400 */
-       .long   do_IRQ  ! TMU1 tuni1
-       .long   do_IRQ  ! TMU2 tuni2
-       .long   do_IRQ  !      ticpi2
-#if  defined(CONFIG_CPU_SUBTYPE_SH7760)
-       .long   exception_error
-       .long   exception_error
-       .long   exception_error
-       .long   exception_error
-       .long   exception_error                 /* 500 */
-       .long   exception_error
-       .long   exception_error
-#else
-       .long   do_IRQ  ! RTC  ati
-       .long   do_IRQ  !      pri
-       .long   do_IRQ  !      cui
-       .long   do_IRQ  ! SCI  eri
-       .long   do_IRQ  !      rxi      /* 500 */
-       .long   do_IRQ  !      txi
-       .long   do_IRQ  !      tei
-#endif
-       .long   do_IRQ  ! WDT  iti      /* 560 */
-       .long   do_IRQ  ! REF  rcmi
-       .long   do_IRQ  !      rovi
-       .long   do_IRQ                  
-       .long   do_IRQ                  /* 5E0 */
-       .long   do_IRQ  ! 32 Hitachi UDI        /* 600 */
-       .long   do_IRQ  ! 33 GPIO
-       .long   do_IRQ  ! 34 DMAC dmte0
-       .long   do_IRQ  ! 35      dmte1
-       .long   do_IRQ  ! 36      dmte2
-       .long   do_IRQ  ! 37      dmte3
-       .long   do_IRQ  ! 38      dmae
-       .long   exception_error                 ! 39    /* 6E0 */
-#if defined(CONFIG_CPU_SUBTYPE_SH7760)
-       .long   exception_error                         /* 700 */
-       .long   exception_error
-       .long   exception_error
-       .long   exception_error                         /* 760 */
-#else
-       .long   do_IRQ  ! 40 SCIF eri           /* 700 */
-       .long   do_IRQ  ! 41      rxi
-       .long   do_IRQ  ! 42      bri
-       .long   do_IRQ  ! 43      txi
-#endif
-#if CONFIG_NR_ONCHIP_DMA_CHANNELS == 8
-       .long   do_IRQ  ! 44 DMAC dmte4         /* 780 */
-       .long   do_IRQ  ! 45      dmte5
-       .long   do_IRQ  ! 46      dmte6
-       .long   do_IRQ  ! 47      dmte7         /* 7E0 */
-#elif defined(CONFIG_CPU_SUBTYPE_SH7343)
-       .long   do_IRQ  ! 44 IIC1 ali           /* 780 */
-       .long   do_IRQ  ! 45      tacki
-       .long   do_IRQ  ! 46      waiti
-       .long   do_IRQ  ! 47      dtei          /* 7E0 */
-       .long   do_IRQ  ! 48 DMAC dei0          /* 800 */
-       .long   do_IRQ  ! 49      dei1          /* 820 */
-#else
-       .long   exception_error                 ! 44    /* 780 */
-       .long   exception_error                 ! 45
-       .long   exception_error                 ! 46
-       .long   exception_error                 ! 47
-#endif
-#if defined(CONFIG_SH_FPU)
-       .long   do_fpu_state_restore    ! 48    /* 800 */
-       .long   do_fpu_state_restore    ! 49    /* 820 */
-#elif !defined(CONFIG_CPU_SUBTYPE_SH7343) && \
-      !defined(CONFIG_CPU_SUBTYPE_SH73180)
-       .long   exception_error
-       .long   exception_error
-#endif
-#if defined(CONFIG_CPU_SUBTYPE_SH7751)
-       .long   exception_error                 /* 840 */
-       .long   exception_error
-       .long   exception_error
-       .long   exception_error
-       .long   exception_error
-       .long   exception_error
-       .long   exception_error                 /* 900 */
-       .long   exception_error
-       .long   exception_error
-       .long   exception_error
-       .long   exception_error
-       .long   exception_error
-       .long   exception_error
-       .long   exception_error
-       .long   do_IRQ  ! PCI serr      /* A00 */
-       .long   do_IRQ  !     dma3
-       .long   do_IRQ  !     dma2
-       .long   do_IRQ  !     dma1
-       .long   do_IRQ  !     dma0
-       .long   do_IRQ  !     pwon
-       .long   do_IRQ  !     pwdwn
-       .long   do_IRQ  !     err
-       .long   do_IRQ  ! TMU3 tuni3    /* B00 */
-       .long   exception_error
-       .long   exception_error
-       .long   exception_error
-       .long   do_IRQ  ! TMU4 tuni4    /* B80 */
-#elif defined(CONFIG_CPU_SUBTYPE_SH7760)
-       .long   do_IRQ  ! IRQ   irq6    /* 840 */
-       .long   do_IRQ  !       irq7
-       .long   do_IRQ  ! SCIF  eri0
-       .long   do_IRQ  !       rxi0
-       .long   do_IRQ  !       bri0
-       .long   do_IRQ  !       txi0
-       .long   do_IRQ  ! HCAN2 cani0   /* 900 */
-       .long   do_IRQ  !       cani1
-       .long   do_IRQ  ! SSI   ssii0
-       .long   do_IRQ  !       ssii1
-       .long   do_IRQ  ! HAC   haci0
-       .long   do_IRQ  !       haci1
-       .long   do_IRQ  ! IIC   iici0
-       .long   do_IRQ  !       iici1
-       .long   do_IRQ  ! USB   usbi    /* A00 */
-       .long   do_IRQ  ! LCDC  vint
-       .long   exception_error
-       .long   exception_error
-       .long   do_IRQ  ! DMABRG dmabrgi0
-       .long   do_IRQ  !        dmabrgi1
-       .long   do_IRQ  !        dmabrgi2
-       .long   exception_error
-       .long   do_IRQ  ! SCIF  eri1    /* B00 */
-       .long   do_IRQ  !       rxi1
-       .long   do_IRQ  !       bri1
-       .long   do_IRQ  !       txi1
-       .long   do_IRQ  !       eri2
-       .long   do_IRQ  !       rxi2
-       .long   do_IRQ  !       bri2
-       .long   do_IRQ  !       txi2
-       .long   do_IRQ  ! SIM   simeri  /* C00 */
-       .long   do_IRQ  !       simrxi
-       .long   do_IRQ  !       simtxi
-       .long   do_IRQ  !       simtei
-       .long   do_IRQ  ! HSPI  spii
-       .long   exception_error
-       .long   exception_error
-       .long   exception_error
-       .long   do_IRQ  ! MMCIF mmci0   /* D00 */
-       .long   do_IRQ  !       mmci1
-       .long   do_IRQ  !       mmci2
-       .long   do_IRQ  !       mmci3
-       .long   exception_error
-       .long   exception_error
-       .long   exception_error
-       .long   exception_error
-       .long   exception_error                 /* E00 */
-       .long   exception_error
-       .long   exception_error
-       .long   exception_error
-       .long   do_IRQ  ! MFI   mfii
-       .long   exception_error
-       .long   exception_error
-       .long   exception_error
-       .long   exception_error                 /* F00 */
-       .long   exception_error
-       .long   exception_error
-       .long   exception_error
-       .long   do_IRQ  ! ADC   adi
-       .long   do_IRQ  ! CMT   cmti    /* FA0 */
-#elif defined(CONFIG_CPU_SUBTYPE_SH73180) || defined(CONFIG_CPU_SUBTYPE_SH7343)
-       .long   do_IRQ  !  50 0x840
-       .long   do_IRQ  !  51 0x860
-       .long   do_IRQ  !  52 0x880
-       .long   do_IRQ  !  53 0x8a0
-       .long   do_IRQ  !  54 0x8c0
-       .long   do_IRQ  !  55 0x8e0
-       .long   do_IRQ  !  56 0x900
-       .long   do_IRQ  !  57 0x920
-       .long   do_IRQ  !  58 0x940
-       .long   do_IRQ  !  59 0x960
-       .long   do_IRQ  !  60 0x980
-       .long   do_IRQ  !  61 0x9a0
-       .long   do_IRQ  !  62 0x9c0
-       .long   do_IRQ  !  63 0x9e0
-       .long   do_IRQ  !  64 0xa00
-       .long   do_IRQ  !  65 0xa20
-       .long   do_IRQ  !  66 0xa40
-       .long   do_IRQ  !  67 0xa60
-       .long   do_IRQ  !  68 0xa80
-       .long   do_IRQ  !  69 0xaa0
-       .long   do_IRQ  !  70 0xac0
-       .long   do_IRQ  !  71 0xae0
-       .long   do_IRQ  !  72 0xb00
-       .long   do_IRQ  !  73 0xb20
-       .long   do_IRQ  !  74 0xb40
-       .long   do_IRQ  !  75 0xb60
-       .long   do_IRQ  !  76 0xb80
-       .long   do_IRQ  !  77 0xba0
-       .long   do_IRQ  !  78 0xbc0
-       .long   do_IRQ  !  79 0xbe0
-       .long   do_IRQ  !  80 0xc00
-       .long   do_IRQ  !  81 0xc20
-       .long   do_IRQ  !  82 0xc40
-       .long   do_IRQ  !  83 0xc60
-       .long   do_IRQ  !  84 0xc80
-       .long   do_IRQ  !  85 0xca0
-       .long   do_IRQ  !  86 0xcc0
-       .long   do_IRQ  !  87 0xce0
-       .long   do_IRQ  !  88 0xd00
-       .long   do_IRQ  !  89 0xd20
-       .long   do_IRQ  !  90 0xd40
-       .long   do_IRQ  !  91 0xd60
-       .long   do_IRQ  !  92 0xd80
-       .long   do_IRQ  !  93 0xda0
-       .long   do_IRQ  !  94 0xdc0
-       .long   do_IRQ  !  95 0xde0
-       .long   do_IRQ  !  96 0xe00
-       .long   do_IRQ  !  97 0xe20
-       .long   do_IRQ  !  98 0xe40
-       .long   do_IRQ  !  99 0xe60
-       .long   do_IRQ  ! 100 0xe80
-       .long   do_IRQ  ! 101 0xea0
-       .long   do_IRQ  ! 102 0xec0
-       .long   do_IRQ  ! 103 0xee0
-       .long   do_IRQ  ! 104 0xf00
-       .long   do_IRQ  ! 105 0xf20
-       .long   do_IRQ  ! 106 0xf40
-       .long   do_IRQ  ! 107 0xf60
-       .long   do_IRQ  ! 108 0xf80
-#elif defined(CONFIG_CPU_SUBTYPE_ST40STB1)
-       .long   exception_error                 !  50 0x840
-       .long   exception_error                 !  51 0x860
-       .long   exception_error                 !  52 0x880
-       .long   exception_error                 !  53 0x8a0
-       .long   exception_error                 !  54 0x8c0
-       .long   exception_error                 !  55 0x8e0
-       .long   exception_error                 !  56 0x900
-       .long   exception_error                 !  57 0x920
-       .long   exception_error                 !  58 0x940
-       .long   exception_error                 !  59 0x960
-       .long   exception_error                 !  60 0x980
-       .long   exception_error                 !  61 0x9a0
-       .long   exception_error                 !  62 0x9c0
-       .long   exception_error                 !  63 0x9e0
-       .long   do_IRQ  !  64 0xa00 PCI serr
-       .long   do_IRQ  !  65 0xa20     err
-       .long   do_IRQ  !  66 0xa40     ad
-       .long   do_IRQ  !  67 0xa60     pwr_dwn
-       .long   exception_error                 !  68 0xa80
-       .long   exception_error                 !  69 0xaa0
-       .long   exception_error                 !  70 0xac0
-       .long   exception_error                 !  71 0xae0
-       .long   do_IRQ  !  72 0xb00 DMA INT0
-       .long   do_IRQ  !  73 0xb20     INT1
-       .long   do_IRQ  !  74 0xb40     INT2
-       .long   do_IRQ  !  75 0xb60     INT3
-       .long   do_IRQ  !  76 0xb80     INT4
-       .long   exception_error                 !  77 0xba0
-       .long   do_IRQ  !  78 0xbc0 DMA ERR
-       .long   exception_error                 !  79 0xbe0
-       .long   do_IRQ  !  80 0xc00 PIO0
-       .long   do_IRQ  !  81 0xc20 PIO1
-       .long   do_IRQ  !  82 0xc40 PIO2
-       .long   exception_error                 !  83 0xc60
-       .long   exception_error                 !  84 0xc80
-       .long   exception_error                 !  85 0xca0
-       .long   exception_error                 !  86 0xcc0
-       .long   exception_error                 !  87 0xce0
-       .long   exception_error                 !  88 0xd00
-       .long   exception_error                 !  89 0xd20
-       .long   exception_error                 !  90 0xd40
-       .long   exception_error                 !  91 0xd60
-       .long   exception_error                 !  92 0xd80
-       .long   exception_error                 !  93 0xda0
-       .long   exception_error                 !  94 0xdc0
-       .long   exception_error                 !  95 0xde0
-       .long   exception_error                 !  96 0xe00
-       .long   exception_error                 !  97 0xe20
-       .long   exception_error                 !  98 0xe40
-       .long   exception_error                 !  99 0xe60
-       .long   exception_error                 ! 100 0xe80
-       .long   exception_error                 ! 101 0xea0
-       .long   exception_error                 ! 102 0xec0
-       .long   exception_error                 ! 103 0xee0
-       .long   exception_error                 ! 104 0xf00
-       .long   exception_error                 ! 105 0xf20
-       .long   exception_error                 ! 106 0xf40
-       .long   exception_error                 ! 107 0xf60
-       .long   exception_error                 ! 108 0xf80
-       .long   exception_error                 ! 109 0xfa0
-       .long   exception_error                 ! 110 0xfc0
-       .long   exception_error                 ! 111 0xfe0
-       .long   do_IRQ  ! 112 0x1000 Mailbox
-       .long   exception_error                 ! 113 0x1020
-       .long   exception_error                 ! 114 0x1040
-       .long   exception_error                 ! 115 0x1060
-       .long   exception_error                 ! 116 0x1080
-       .long   exception_error                 ! 117 0x10a0
-       .long   exception_error                 ! 118 0x10c0
-       .long   exception_error                 ! 119 0x10e0
-       .long   exception_error                 ! 120 0x1100
-       .long   exception_error                 ! 121 0x1120
-       .long   exception_error                 ! 122 0x1140
-       .long   exception_error                 ! 123 0x1160
-       .long   exception_error                 ! 124 0x1180
-       .long   exception_error                 ! 125 0x11a0
-       .long   exception_error                 ! 126 0x11c0
-       .long   exception_error                 ! 127 0x11e0
-       .long   exception_error                 ! 128 0x1200
-       .long   exception_error                 ! 129 0x1220
-       .long   exception_error                 ! 130 0x1240
-       .long   exception_error                 ! 131 0x1260
-       .long   exception_error                 ! 132 0x1280
-       .long   exception_error                 ! 133 0x12a0
-       .long   exception_error                 ! 134 0x12c0
-       .long   exception_error                 ! 135 0x12e0
-       .long   exception_error                 ! 136 0x1300
-       .long   exception_error                 ! 137 0x1320
-       .long   exception_error                 ! 138 0x1340
-       .long   exception_error                 ! 139 0x1360
-       .long   do_IRQ  ! 140 0x1380 EMPI INV_ADDR
-       .long   exception_error                 ! 141 0x13a0
-       .long   exception_error                 ! 142 0x13c0
-       .long   exception_error                 ! 143 0x13e0
-#elif defined(CONFIG_CPU_SUBTYPE_SH7770)
-       .long   do_IRQ  !  50 0x840
-       .long   do_IRQ  !  51 0x860
-       .long   do_IRQ  !  52 0x880
-       .long   do_IRQ  !  53 0x8a0
-       .long   do_IRQ  !  54 0x8c0
-       .long   do_IRQ  !  55 0x8e0
-       .long   do_IRQ  !  56 0x900
-       .long   do_IRQ  !  57 0x920
-       .long   do_IRQ  !  58 0x940
-       .long   do_IRQ  !  59 0x960
-       .long   do_IRQ  !  60 0x980
-       .long   do_IRQ  !  61 0x9a0
-       .long   do_IRQ  !  62 0x9c0
-       .long   do_IRQ  !  63 0x9e0
-       .long   do_IRQ  !  64 0xa00
-       .long   do_IRQ  !  65 0xa20
-       .long   do_IRQ  !  66 0xa4d
-       .long   do_IRQ  !  67 0xa60
-       .long   do_IRQ  !  68 0xa80
-       .long   do_IRQ  !  69 0xaa0
-       .long   do_IRQ  !  70 0xac0
-       .long   do_IRQ  !  71 0xae0
-       .long   do_IRQ  !  72 0xb00
-       .long   do_IRQ  !  73 0xb20
-       .long   do_IRQ  !  74 0xb40
-       .long   do_IRQ  !  75 0xb60
-       .long   do_IRQ  !  76 0xb80
-       .long   do_IRQ  !  77 0xba0
-       .long   do_IRQ  !  78 0xbc0
-       .long   do_IRQ  !  79 0xbe0
-       .long   do_IRQ  !  80 0xc00
-       .long   do_IRQ  !  81 0xc20
-       .long   do_IRQ  !  82 0xc40
-       .long   do_IRQ  !  83 0xc60
-       .long   do_IRQ  !  84 0xc80
-       .long   do_IRQ  !  85 0xca0
-       .long   do_IRQ  !  86 0xcc0
-       .long   do_IRQ  !  87 0xce0
-       .long   do_IRQ  !  88 0xd00
-       .long   do_IRQ  !  89 0xd20
-       .long   do_IRQ  !  90 0xd40
-       .long   do_IRQ  !  91 0xd60
-       .long   do_IRQ  !  92 0xd80
-       .long   do_IRQ  !  93 0xda0
-       .long   do_IRQ  !  94 0xdc0
-       .long   do_IRQ  !  95 0xde0
-       .long   do_IRQ  !  96 0xe00
-       .long   do_IRQ  !  97 0xe20
-       .long   do_IRQ  !  98 0xe40
-       .long   do_IRQ  !  99 0xe60
-       .long   do_IRQ  ! 100 0xe80
-       .long   do_IRQ  ! 101 0xea0
-       .long   do_IRQ  ! 102 0xec0
-       .long   do_IRQ  ! 103 0xee0
-       .long   do_IRQ  ! 104 0xf00
-       .long   do_IRQ  ! 105 0xf20
-       .long   do_IRQ  ! 106 0xf40
-       .long   do_IRQ  ! 107 0xf60
-       .long   do_IRQ  ! 108 0xf80
-#endif
-#else
-       .long   exception_error         /* 400 */
-       .long   exception_error
-       .long   exception_error
-       .long   exception_error
-       .long   do_IRQ  ! RTC   ati
-       .long   do_IRQ  !       pri
-       .long   do_IRQ  !       cui
-       .long   exception_error
-       .long   exception_error         /* 500 */
-       .long   exception_error
-       .long   exception_error
-       .long   do_IRQ  ! WDT   iti     /* 560 */
-       .long   do_IRQ  ! TMU-ch0
-       .long   do_IRQ  ! TMU-ch1
-       .long   do_IRQ  ! TMU-ch2
-       .long   do_IRQ  ! ticpi2        /* 5E0 */
-       .long   do_IRQ  ! 32 Hitachi UDI        /* 600 */
-       .long   exception_error
-       .long   do_IRQ  ! 34 DMAC dmte0
-       .long   do_IRQ  ! 35      dmte1
-       .long   do_IRQ  ! 36      dmte2
-       .long   do_IRQ  ! 37      dmte3
-       .long   do_IRQ  ! 38      dmae
-       .long   exception_error                 ! 39    /* 6E0 */
-       .long   do_IRQ  ! 40 SCIF-ch0 eri               /* 700 */
-       .long   do_IRQ  ! 41          rxi
-       .long   do_IRQ  ! 42          bri
-       .long   do_IRQ  ! 43          txi
-       .long   do_IRQ  ! 44 DMAC dmte4         /* 780 */
-       .long   do_IRQ  ! 45      dmte5
-       .long   do_IRQ  ! 46      dmte6
-       .long   do_IRQ  ! 47      dmte7         /* 7E0 */
-#if defined(CONFIG_SH_FPU)
-       .long   do_fpu_state_restore    ! 48    /* 800 */
-       .long   do_fpu_state_restore    ! 49    /* 820 */
-#else
-       .long   exception_error
-       .long   exception_error
-#endif
-       .long   exception_error                 /* 840 */
-       .long   exception_error
-       .long   exception_error
-       .long   exception_error
-       .long   exception_error
-       .long   exception_error
-       .long   do_IRQ  ! 56 CMT        /* 900 */
-       .long   exception_error
-       .long   exception_error
-       .long   exception_error
-       .long   do_IRQ  ! 60 HAC
-       .long   exception_error
-       .long   exception_error
-       .long   exception_error
-       .long   do_IRQ  ! PCI serr      /* A00 */
-       .long   do_IRQ  !     INTA
-       .long   do_IRQ  !     INTB
-       .long   do_IRQ  !     INTC
-       .long   do_IRQ  !     INTD
-       .long   do_IRQ  !     err
-       .long   do_IRQ  !     pwd3
-       .long   do_IRQ  !     pwd2
-       .long   do_IRQ  !     pwd1      /* B00 */
-       .long   do_IRQ  !     pwd0
-       .long   exception_error
-       .long   exception_error
-       .long   do_IRQ  ! SCIF-ch1 eri  /* B80 */
-       .long   do_IRQ  !          rxi
-       .long   do_IRQ  !          bri
-       .long   do_IRQ  !          txi
-       .long   do_IRQ  ! SIOF          /* C00 */
-       .long   exception_error
-       .long   exception_error
-       .long   exception_error
-       .long   do_IRQ  ! HSPI          /* C80 */
-       .long   exception_error
-       .long   exception_error
-       .long   exception_error
-       .long   do_IRQ  ! MMCIF fatat   /* D00 */
-       .long   do_IRQ  !       tran
-       .long   do_IRQ  !       err
-       .long   do_IRQ  !       frdy
-       .long   do_IRQ  ! DMAC dmint8   /* D80 */
-       .long   do_IRQ  !      dmint9
-       .long   do_IRQ  !      dmint10
-       .long   do_IRQ  !      dmint11
-       .long   do_IRQ  ! TMU-ch3       /* E00 */
-       .long   do_IRQ  ! TMU-ch4
-       .long   do_IRQ  ! TMU-ch5
-       .long   exception_error
-       .long   do_IRQ  ! SSI
-       .long   exception_error
-       .long   exception_error
-       .long   exception_error
-       .long   do_IRQ  ! FLCTL flste   /* F00 */
-       .long   do_IRQ  !       fltend
-       .long   do_IRQ  !       fltrq0
-       .long   do_IRQ  !       fltrq1
-       .long   do_IRQ  ! GPIO gpioi0   /* F80 */
-       .long   do_IRQ  !      gpioi1
-       .long   do_IRQ  !      gpioi2
-       .long   do_IRQ  !      gpioi3
-#endif
 
+       /*
+        * Pad the remainder of the table out, exceptions residing in far
+        * away offsets can be manually inserted in to their appropriate
+        * location via set_exception_table_{evt,vec}().
+        */
+       .balign 4096,0,4096
index 97f1c9af35d652b46bc06af385477724816aa8b9..07e5377bf55016edfb299b52a9a0e2896db386df 100644 (file)
@@ -51,3 +51,66 @@ static int __init sh7760_devices_setup(void)
                                    ARRAY_SIZE(sh7760_devices));
 }
 __initcall(sh7760_devices_setup);
+
+/*
+ * SH7760 INTC2-Style interrupts, vectors IRQ48-111 INTEVT 0x800-0xFE0
+ */
+static struct intc2_data intc2_irq_table[] = {
+       /* INTPRIO0 | INTMSK0 */
+       {48,  0, 28, 0, 31,  3},        /* IRQ 4 */
+       {49,  0, 24, 0, 30,  3},        /* IRQ 3 */
+       {50,  0, 20, 0, 29,  3},        /* IRQ 2 */
+       {51,  0, 16, 0, 28,  3},        /* IRQ 1 */
+       /* 52-55 (INTEVT 0x880-0x8E0) unused/reserved */
+       /* INTPRIO4 | INTMSK0 */
+       {56,  4, 28, 0, 25,  3},        /* HCAN2_CHAN0 */
+       {57,  4, 24, 0, 24,  3},        /* HCAN2_CHAN1 */
+       {58,  4, 20, 0, 23,  3},        /* I2S_CHAN0   */
+       {59,  4, 16, 0, 22,  3},        /* I2S_CHAN1   */
+       {60,  4, 12, 0, 21,  3},        /* AC97_CHAN0  */
+       {61,  4,  8, 0, 20,  3},        /* AC97_CHAN1  */
+       {62,  4,  4, 0, 19,  3},        /* I2C_CHAN0   */
+       {63,  4,  0, 0, 18,  3},        /* I2C_CHAN1   */
+       /* INTPRIO8 | INTMSK0 */
+       {52,  8, 16, 0, 11,  3},        /* SCIF0_ERI_IRQ */
+       {53,  8, 16, 0, 10,  3},        /* SCIF0_RXI_IRQ */
+       {54,  8, 16, 0,  9,  3},        /* SCIF0_BRI_IRQ */
+       {55,  8, 16, 0,  8,  3},        /* SCIF0_TXI_IRQ */
+       {64,  8, 28, 0, 17,  3},        /* USBHI_IRQ */
+       {65,  8, 24, 0, 16,  3},        /* LCDC      */
+       /* 66, 67 unused */
+       {68,  8, 20, 0, 14, 13},        /* DMABRGI0_IRQ */
+       {69,  8, 20, 0, 13, 13},        /* DMABRGI1_IRQ */
+       {70,  8, 20, 0, 12, 13},        /* DMABRGI2_IRQ */
+       /* 71 unused */
+       {72,  8, 12, 0,  7,  3},        /* SCIF1_ERI_IRQ */
+       {73,  8, 12, 0,  6,  3},        /* SCIF1_RXI_IRQ */
+       {74,  8, 12, 0,  5,  3},        /* SCIF1_BRI_IRQ */
+       {75,  8, 12, 0,  4,  3},        /* SCIF1_TXI_IRQ */
+       {76,  8,  8, 0,  3,  3},        /* SCIF2_ERI_IRQ */
+       {77,  8,  8, 0,  2,  3},        /* SCIF2_RXI_IRQ */
+       {78,  8,  8, 0,  1,  3},        /* SCIF2_BRI_IRQ */
+       {79,  8,  8, 0,  0,  3},        /* SCIF2_TXI_IRQ */
+       /*          | INTMSK4 */
+       {80,  8,  4, 4, 23,  3},        /* SIM_ERI */
+       {81,  8,  4, 4, 22,  3},        /* SIM_RXI */
+       {82,  8,  4, 4, 21,  3},        /* SIM_TXI */
+       {83,  8,  4, 4, 20,  3},        /* SIM_TEI */
+       {84,  8,  0, 4, 19,  3},        /* HSPII */
+       /* INTPRIOC | INTMSK4 */
+       /* 85-87 unused/reserved */
+       {88, 12, 20, 4, 18,  3},        /* MMCI0 */
+       {89, 12, 20, 4, 17,  3},        /* MMCI1 */
+       {90, 12, 20, 4, 16,  3},        /* MMCI2 */
+       {91, 12, 20, 4, 15,  3},        /* MMCI3 */
+       {92, 12, 12, 4,  6,  3},        /* MFI (unsure, bug? in my 7760 manual*/
+       /* 93-107 reserved/undocumented */
+       {108,12,  4, 4,  1,  3},        /* ADC  */
+       {109,12,  0, 4,  0,  3},        /* CMTI */
+       /* 110-111 reserved/unused */
+};
+
+void __init init_IRQ_intc2(void)
+{
+       make_intc2_irq(intc2_irq_table, ARRAY_SIZE(intc2_irq_table));
+}
index 72493f259edccf63e6e187328c6dd5270d481622..814ddb226531c26c92ed78efd27aea24b5cd98db 100644 (file)
@@ -77,3 +77,30 @@ static int __init sh7780_devices_setup(void)
                                    ARRAY_SIZE(sh7780_devices));
 }
 __initcall(sh7780_devices_setup);
+
+static struct intc2_data intc2_irq_table[] = {
+       { TIMER_IRQ, 0, 24, 0, INTC_TMU0_MSK, 2 },
+       { 21, 1, 0, 0, INTC_RTC_MSK, TIMER_PRIORITY },
+       { 22, 1, 1, 0, INTC_RTC_MSK, TIMER_PRIORITY },
+       { 23, 1, 2, 0, INTC_RTC_MSK, TIMER_PRIORITY },
+       { SCIF0_ERI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY },
+       { SCIF0_RXI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY },
+       { SCIF0_BRI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY },
+       { SCIF0_TXI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY },
+
+       { SCIF1_ERI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY },
+       { SCIF1_RXI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY },
+       { SCIF1_BRI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY },
+       { SCIF1_TXI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY },
+
+       { PCIC0_IRQ, 0x10,  8, 0, INTC_PCIC0_MSK, PCIC0_PRIORITY },
+       { PCIC1_IRQ, 0x10,  0, 0, INTC_PCIC1_MSK, PCIC1_PRIORITY },
+       { PCIC2_IRQ, 0x14, 24, 0, INTC_PCIC2_MSK, PCIC2_PRIORITY },
+       { PCIC3_IRQ, 0x14, 16, 0, INTC_PCIC3_MSK, PCIC3_PRIORITY },
+       { PCIC4_IRQ, 0x14,  8, 0, INTC_PCIC4_MSK, PCIC4_PRIORITY },
+};
+
+void __init init_IRQ_intc2(void)
+{
+       make_intc2_irq(intc2_irq_table, ARRAY_SIZE(intc2_irq_table));
+}
index 97c571fbcdf13a5e2922867c143bf55dcb432292..39aaefb2d83f427d58a0b05ad48a45868dfba2e2 100644 (file)
@@ -1,9 +1,8 @@
-/* $Id: entry.S,v 1.37 2004/06/11 13:02:46 doyu Exp $
- *
+/*
  *  linux/arch/sh/entry.S
  *
  *  Copyright (C) 1999, 2000, 2002  Niibe Yutaka
- *  Copyright (C) 2003  Paul Mundt
+ *  Copyright (C) 2003 - 2006  Paul Mundt
  *
  * 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
@@ -78,7 +77,6 @@ OFF_TRA       =  (16*4+6*4)
 #define k3     r3
 #define k4     r4
 
-#define k_ex_code      r2_bank /* r2_bank1 */
 #define g_imask                r6      /* r6_bank1 */
 #define k_g_imask      r6_bank /* r6_bank1 */
 #define current                r7      /* r7_bank1 */
@@ -691,7 +689,7 @@ interrupt:
 0:
 #endif /* defined(CONFIG_KGDB_NMI) */
        bra     handle_exception
-        mov.l  @k2, k2
+        mov    #-1, k2         ! interrupt exception marker
 
        .align  2
 1:     .long   EXPEVT
@@ -717,8 +715,7 @@ ENTRY(handle_exception)
        add     current, k1
        mov     k1, r15         ! change to kernel stack
        !
-1:     mov     #-1, k4
-       mov.l   2f, k1
+1:     mov.l   2f, k1
        !
 #ifdef CONFIG_SH_DSP
        mov.l   r2, @-r15               ! Save r2, we need another reg
@@ -763,6 +760,8 @@ skip_save:
 #endif
        ! Save the user registers on the stack.
        mov.l   k2, @-r15       ! EXPEVT
+
+       mov     #-1, k4
        mov.l   k4, @-r15       ! set TRA (default: -1)
        !
        sts.l   macl, @-r15
@@ -797,8 +796,21 @@ skip_save:
        mov.l   r2, @-r15
        mov.l   r1, @-r15
        mov.l   r0, @-r15
-       ! Then, dispatch to the handler, according to the exception code.
-       stc     k_ex_code, r8
+
+       /*
+        * This gets a bit tricky.. in the INTEVT case we don't want to use
+        * the VBR offset as a destination in the jump call table, since all
+        * of the destinations are the same. In this case, (interrupt) sets
+        * a marker in r2 (now r2_bank since SR.RB changed), which we check
+        * to determine the exception type. For all other exceptions, we
+        * forcibly read EXPEVT from memory and fix up the jump address, in
+        * the interrupt exception case we jump to do_IRQ() and defer the
+        * INTEVT read until there. As a bonus, we can also clean up the SR.RB
+        * checks that do_IRQ() was doing..
+        */
+       stc     r2_bank, r8
+       cmp/pz  r8
+       bf      interrupt_exception
        shlr2   r8
        shlr    r8
        mov.l   4f, r9
@@ -806,6 +818,8 @@ skip_save:
        mov.l   @r9, r9
        jmp     @r9
         nop
+       rts
+        nop
 
        .align  2
 1:     .long   0x00001000      ! DSP=1
@@ -813,8 +827,17 @@ skip_save:
 3:     .long   0xcfffffff      ! RB=0, BL=0
 4:     .long   exception_handling_table
 
+interrupt_exception:
+       mov.l   1f, r9
+       jmp     @r9
+        nop
+       rts
+        nop
+
+       .align 2
+1:     .long   do_IRQ
+
        .align  2
 ENTRY(exception_none)
        rts
         nop
-
index c7ebd6aec9514cdb4f16583a94a6570e01262440..944128ce97066ff46bc67cae6a5ce98a3717e9d6 100644 (file)
 #include <linux/module.h>
 #include <linux/kernel_stat.h>
 #include <linux/seq_file.h>
+#include <linux/io.h>
 #include <asm/irq.h>
 #include <asm/processor.h>
 #include <asm/uaccess.h>
 #include <asm/thread_info.h>
 #include <asm/cpu/mmu_context.h>
 
+atomic_t irq_err_count;
+
 /*
  * 'what should we do if we get a hw irq event on an illegal vector'.
  * each architecture has to answer this themselves, it doesn't deserve
@@ -24,6 +27,7 @@
  */
 void ack_bad_irq(unsigned int irq)
 {
+       atomic_inc(&irq_err_count);
        printk("unexpected IRQ trap at vector %02x\n", irq);
 }
 
@@ -47,8 +51,10 @@ int show_interrupts(struct seq_file *p, void *v)
                if (!action)
                        goto unlock;
                seq_printf(p, "%3d: ",i);
-               seq_printf(p, "%10u ", kstat_irqs(i));
-               seq_printf(p, " %14s", irq_desc[i].chip->typename);
+               for_each_online_cpu(j)
+                       seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+               seq_printf(p, " %14s", irq_desc[i].chip->name);
+               seq_printf(p, "-%-8s", irq_desc[i].name);
                seq_printf(p, "  %s", action->name);
 
                for (action=action->next; action; action = action->next)
@@ -56,7 +62,9 @@ int show_interrupts(struct seq_file *p, void *v)
                seq_putc(p, '\n');
 unlock:
                spin_unlock_irqrestore(&irq_desc[i].lock, flags);
-       }
+       } else if (i == NR_IRQS)
+               seq_printf(p, "Err: %10u\n", atomic_read(&irq_err_count));
+
        return 0;
 }
 #endif
@@ -78,7 +86,8 @@ asmlinkage int do_IRQ(unsigned long r4, unsigned long r5,
                      unsigned long r6, unsigned long r7,
                      struct pt_regs regs)
 {
-       int irq = r4;
+       struct pt_regs *old_regs = set_irq_regs(&regs);
+       int irq;
 #ifdef CONFIG_4KSTACKS
        union irq_ctx *curctx, *irqctx;
 #endif
@@ -102,20 +111,9 @@ asmlinkage int do_IRQ(unsigned long r4, unsigned long r5,
 #endif
 
 #ifdef CONFIG_CPU_HAS_INTEVT
-       __asm__ __volatile__ (
-#ifdef CONFIG_CPU_HAS_SR_RB
-               "stc    r2_bank, %0\n\t"
+       irq = (ctrl_inl(INTEVT) >> 5) - 16;
 #else
-               "mov.l  @%1, %0\n\t"
-#endif
-               "shlr2  %0\n\t"
-               "shlr2  %0\n\t"
-               "shlr   %0\n\t"
-               "add    #-16, %0\n\t"
-               : "=z" (irq), "=r" (r4)
-               : "1" (INTEVT)
-               : "memory"
-       );
+       irq = r4;
 #endif
 
        irq = irq_demux(irq);
@@ -139,25 +137,25 @@ asmlinkage int do_IRQ(unsigned long r4, unsigned long r5,
 
                __asm__ __volatile__ (
                        "mov    %0, r4          \n"
-                       "mov    %1, r5          \n"
                        "mov    r15, r9         \n"
-                       "jsr    @%2             \n"
+                       "jsr    @%1             \n"
                        /* swith to the irq stack */
-                       " mov   %3, r15         \n"
+                       " mov   %2, r15         \n"
                        /* restore the stack (ring zero) */
                        "mov    r9, r15         \n"
                        : /* no outputs */
-                       : "r" (irq), "r" (&regs), "r" (__do_IRQ), "r" (isp)
+                       : "r" (irq), "r" (generic_handle_irq), "r" (isp)
                        /* XXX: A somewhat excessive clobber list? -PFM */
                        : "memory", "r0", "r1", "r2", "r3", "r4",
                          "r5", "r6", "r7", "r8", "t", "pr"
                );
        } else
 #endif
-               __do_IRQ(irq, &regs);
+               generic_handle_irq(irq);
 
        irq_exit();
 
+       set_irq_regs(old_regs);
        return 1;
 }
 
index 0b1d5dd7a93b4237c70f3681d5745cac2296e3bd..a52b13ac6b7f80a32e81a5daeef04a115de406da 100644 (file)
@@ -5,6 +5,7 @@
  *  Copyright (C) 1995  Linus Torvalds
  *
  *  SuperH version:  Copyright (C) 1999, 2000  Niibe Yutaka & Kaz Kojima
+ *                  Copyright (C) 2006 Lineo Solutions Inc. support SH4A UBC
  */
 
 /*
@@ -104,7 +105,7 @@ void show_regs(struct pt_regs * regs)
 {
        printk("\n");
        printk("Pid : %d, Comm: %20s\n", current->pid, current->comm);
-       print_symbol("PC is at %s\n", regs->pc);
+       print_symbol("PC is at %s\n", instruction_pointer(regs));
        printk("PC  : %08lx SP  : %08lx SR  : %08lx ",
               regs->pc, regs->regs[15], regs->sr);
 #ifdef CONFIG_MMU
@@ -129,15 +130,7 @@ void show_regs(struct pt_regs * regs)
        printk("MACH: %08lx MACL: %08lx GBR : %08lx PR  : %08lx\n",
               regs->mach, regs->macl, regs->gbr, regs->pr);
 
-       /*
-        * If we're in kernel mode, dump the stack too..
-        */
-       if (!user_mode(regs)) {
-               extern void show_task(unsigned long *sp);
-               unsigned long sp = regs->regs[15];
-
-               show_task((unsigned long *)sp);
-       }
+       show_trace(NULL, (unsigned long *)regs->regs[15], regs);
 }
 
 /*
@@ -290,6 +283,24 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
 static void
 ubc_set_tracing(int asid, unsigned long pc)
 {
+#if defined(CONFIG_CPU_SH4A)
+       unsigned long val;
+
+       val = (UBC_CBR_ID_INST | UBC_CBR_RW_READ | UBC_CBR_CE);
+       val |= (UBC_CBR_AIE | UBC_CBR_AIV_SET(asid));
+
+       ctrl_outl(val, UBC_CBR0);
+       ctrl_outl(pc,  UBC_CAR0);
+       ctrl_outl(0x0, UBC_CAMR0);
+       ctrl_outl(0x0, UBC_CBCR);
+
+       val = (UBC_CRR_RES | UBC_CRR_PCB | UBC_CRR_BIE);
+       ctrl_outl(val, UBC_CRR0);
+
+       /* Read UBC register that we writed last. For chekking UBC Register changed */
+       val = ctrl_inl(UBC_CRR0);
+
+#else  /* CONFIG_CPU_SH4A */
        ctrl_outl(pc, UBC_BARA);
 
 #ifdef CONFIG_MMU
@@ -307,6 +318,7 @@ ubc_set_tracing(int asid, unsigned long pc)
                ctrl_outw(BBR_INST | BBR_READ, UBC_BBRA);
                ctrl_outw(BRCR_PCBA, UBC_BRCR);
        }
+#endif /* CONFIG_CPU_SH4A */
 }
 
 /*
@@ -359,8 +371,13 @@ struct task_struct *__switch_to(struct task_struct *prev, struct task_struct *ne
 #endif
                ubc_set_tracing(asid, next->thread.ubc_pc);
        } else {
+#if defined(CONFIG_CPU_SH4A)
+               ctrl_outl(UBC_CBR_INIT, UBC_CBR0);
+               ctrl_outl(UBC_CRR_INIT, UBC_CRR0);
+#else
                ctrl_outw(0, UBC_BBRA);
                ctrl_outw(0, UBC_BBRB);
+#endif
        }
 
        return prev;
@@ -460,8 +477,13 @@ asmlinkage void break_point_trap(unsigned long r4, unsigned long r5,
                                 struct pt_regs regs)
 {
        /* Clear tracing.  */
+#if defined(CONFIG_CPU_SH4A)
+       ctrl_outl(UBC_CBR_INIT, UBC_CBR0);
+       ctrl_outl(UBC_CRR_INIT, UBC_CRR0);
+#else
        ctrl_outw(0, UBC_BBRA);
        ctrl_outw(0, UBC_BBRB);
+#endif
        current->thread.ubc_pc = 0;
        ubc_usercnt -= 1;
 
index 450c68f1df052f5ccba2eaef9d0149a1bc2390bf..57e708d7b52df705cdf6ebcf48d1608485dc2abd 100644 (file)
@@ -47,6 +47,7 @@ unsigned long long __attribute__ ((weak)) sched_clock(void)
        return (unsigned long long)jiffies * (1000000000 / HZ);
 }
 
+#ifndef CONFIG_GENERIC_TIME
 void do_gettimeofday(struct timeval *tv)
 {
        unsigned long seq;
@@ -99,6 +100,7 @@ int do_settimeofday(struct timespec *tv)
        return 0;
 }
 EXPORT_SYMBOL(do_settimeofday);
+#endif /* !CONFIG_GENERIC_TIME */
 
 /* last time the RTC clock got updated */
 static long last_rtc_update;
@@ -107,13 +109,14 @@ static long last_rtc_update;
  * handle_timer_tick() needs to keep up the real-time clock,
  * as well as call the "do_timer()" routine every clocktick
  */
-void handle_timer_tick(struct pt_regs *regs)
+void handle_timer_tick(void)
 {
        do_timer(1);
 #ifndef CONFIG_SMP
-       update_process_times(user_mode(regs));
+       update_process_times(user_mode(get_irq_regs()));
 #endif
-       profile_tick(CPU_PROFILING, regs);
+       if (current->pid)
+               profile_tick(CPU_PROFILING);
 
 #ifdef CONFIG_HEARTBEAT
        if (sh_mv.mv_heartbeat != NULL)
index 205816fcf0da50d7fecdeecd5975c2fbaf6c0a9e..24927015dc31fc901153935e91eca80e32332c67 100644 (file)
@@ -80,8 +80,7 @@ static unsigned long tmu_timer_get_offset(void)
        return count;
 }
 
-static irqreturn_t tmu_timer_interrupt(int irq, void *dev_id,
-                                      struct pt_regs *regs)
+static irqreturn_t tmu_timer_interrupt(int irq, void *dummy)
 {
        unsigned long timer_status;
 
@@ -98,7 +97,7 @@ static irqreturn_t tmu_timer_interrupt(int irq, void *dev_id,
         * locally disabled. -arca
         */
        write_seqlock(&xtime_lock);
-       handle_timer_tick(regs);
+       handle_timer_tick();
        write_sequnlock(&xtime_lock);
 
        return IRQ_HANDLED;
@@ -111,60 +110,6 @@ static struct irqaction tmu_irq = {
        .mask           = CPU_MASK_NONE,
 };
 
-/*
- * Hah!  We'll see if this works (switching from usecs to nsecs).
- */
-static unsigned long tmu_timer_get_frequency(void)
-{
-       u32 freq;
-       struct timespec ts1, ts2;
-       unsigned long diff_nsec;
-       unsigned long factor;
-
-       /* Setup the timer:  We don't want to generate interrupts, just
-        * have it count down at its natural rate.
-        */
-       ctrl_outb(0, TMU_TSTR);
-#if !defined(CONFIG_CPU_SUBTYPE_SH7300) && !defined(CONFIG_CPU_SUBTYPE_SH7760)
-       ctrl_outb(TMU_TOCR_INIT, TMU_TOCR);
-#endif
-       ctrl_outw(TMU0_TCR_CALIB, TMU0_TCR);
-       ctrl_outl(0xffffffff, TMU0_TCOR);
-       ctrl_outl(0xffffffff, TMU0_TCNT);
-
-       rtc_sh_get_time(&ts2);
-
-       do {
-               rtc_sh_get_time(&ts1);
-       } while (ts1.tv_nsec == ts2.tv_nsec && ts1.tv_sec == ts2.tv_sec);
-
-       /* actually start the timer */
-       ctrl_outb(TMU_TSTR_INIT, TMU_TSTR);
-
-       do {
-               rtc_sh_get_time(&ts2);
-       } while (ts1.tv_nsec == ts2.tv_nsec && ts1.tv_sec == ts2.tv_sec);
-
-       freq = 0xffffffff - ctrl_inl(TMU0_TCNT);
-       if (ts2.tv_nsec < ts1.tv_nsec) {
-               ts2.tv_nsec += 1000000000;
-               ts2.tv_sec--;
-       }
-
-       diff_nsec = (ts2.tv_sec - ts1.tv_sec) * 1000000000 + (ts2.tv_nsec - ts1.tv_nsec);
-
-       /* this should work well if the RTC has a precision of n Hz, where
-        * n is an integer.  I don't think we have to worry about the other
-        * cases. */
-       factor = (1000000000 + diff_nsec/2) / diff_nsec;
-
-       if (factor * diff_nsec > 1100000000 ||
-           factor * diff_nsec <  900000000)
-               panic("weird RTC (diff_nsec %ld)", diff_nsec);
-
-       return freq * factor;
-}
-
 static void tmu_clk_init(struct clk *clk)
 {
        u8 divisor = TMU0_TCR_INIT & 0x7;
@@ -232,12 +177,12 @@ struct sys_timer_ops tmu_timer_ops = {
        .init           = tmu_timer_init,
        .start          = tmu_timer_start,
        .stop           = tmu_timer_stop,
-       .get_frequency  = tmu_timer_get_frequency,
+#ifndef CONFIG_GENERIC_TIME
        .get_offset     = tmu_timer_get_offset,
+#endif
 };
 
 struct sys_timer tmu_timer = {
        .name   = "tmu",
        .ops    = &tmu_timer_ops,
 };
-
index c2c597e0948242c780d4d369dff64c69dee14c59..53dfa55f3156b40327e977aef77d7fef08d5351e 100644 (file)
@@ -1,38 +1,25 @@
-/* $Id: traps.c,v 1.17 2004/05/02 01:46:30 sugioka Exp $
- *
- *  linux/arch/sh/traps.c
+/*
+ * 'traps.c' handles hardware traps and faults after we have saved some
+ * state in 'entry.S'.
  *
  *  SuperH version: Copyright (C) 1999 Niibe Yutaka
  *                  Copyright (C) 2000 Philipp Rumpf
  *                  Copyright (C) 2000 David Howells
- *                  Copyright (C) 2002, 2003 Paul Mundt
- */
-
-/*
- * 'Traps.c' handles hardware traps and faults after we have saved some
- * state in 'entry.S'.
+ *                  Copyright (C) 2002 - 2006 Paul Mundt
+ *
+ * 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 <linux/sched.h>
 #include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/errno.h>
 #include <linux/ptrace.h>
-#include <linux/timer.h>
-#include <linux/mm.h>
-#include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/init.h>
-#include <linux/delay.h>
 #include <linux/spinlock.h>
 #include <linux/module.h>
 #include <linux/kallsyms.h>
-
+#include <linux/io.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/atomic.h>
-#include <asm/processor.h>
-#include <asm/sections.h>
 
 #ifdef CONFIG_SH_KGDB
 #include <asm/kgdb.h>
 #define TRAP_ILLEGAL_SLOT_INST 13
 #endif
 
-/*
- * These constants are for searching for possible module text
- * segments.  VMALLOC_OFFSET comes from mm/vmalloc.c; MODULE_RANGE is
- * a guess of how much space is likely to be vmalloced.
- */
-#define VMALLOC_OFFSET (8*1024*1024)
-#define MODULE_RANGE (8*1024*1024)
+static void dump_mem(const char *str, unsigned long bottom, unsigned long top)
+{
+       unsigned long p;
+       int i;
+
+       printk("%s(0x%08lx to 0x%08lx)\n", str, bottom, top);
+
+       for (p = bottom & ~31; p < top; ) {
+               printk("%04lx: ", p & 0xffff);
+
+               for (i = 0; i < 8; i++, p += 4) {
+                       unsigned int val;
+
+                       if (p < bottom || p >= top)
+                               printk("         ");
+                       else {
+                               if (__get_user(val, (unsigned int __user *)p)) {
+                                       printk("\n");
+                                       return;
+                               }
+                               printk("%08x ", val);
+                       }
+               }
+               printk("\n");
+       }
+}
 
 DEFINE_SPINLOCK(die_lock);
 
@@ -69,14 +75,28 @@ void die(const char * str, struct pt_regs * regs, long err)
 
        console_verbose();
        spin_lock_irq(&die_lock);
+       bust_spinlocks(1);
+
        printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter);
+
        CHK_REMOTE_DEBUG(regs);
+       print_modules();
        show_regs(regs);
+
+       printk("Process: %s (pid: %d, stack limit = %p)\n",
+              current->comm, current->pid, task_stack_page(current) + 1);
+
+       if (!user_mode(regs) || in_interrupt())
+               dump_mem("Stack: ", regs->regs[15], THREAD_SIZE +
+                        (unsigned long)task_stack_page(current));
+
+       bust_spinlocks(0);
        spin_unlock_irq(&die_lock);
        do_exit(SIGSEGV);
 }
 
-static inline void die_if_kernel(const char * str, struct pt_regs * regs, long err)
+static inline void die_if_kernel(const char *str, struct pt_regs *regs,
+                                long err)
 {
        if (!user_mode(regs))
                die(str, regs, err);
@@ -93,8 +113,7 @@ static int handle_unaligned_notify_count = 10;
  */
 static int die_if_no_fixup(const char * str, struct pt_regs * regs, long err)
 {
-       if (!user_mode(regs))
-       {
+       if (!user_mode(regs)) {
                const struct exception_table_entry *fixup;
                fixup = search_exception_tables(regs->pc);
                if (fixup) {
@@ -550,7 +569,10 @@ int is_dsp_inst(struct pt_regs *regs)
 #define is_dsp_inst(regs)      (0)
 #endif /* CONFIG_SH_DSP */
 
-extern int do_fpu_inst(unsigned short, struct pt_regs*);
+/* arch/sh/kernel/cpu/sh4/fpu.c */
+extern int do_fpu_inst(unsigned short, struct pt_regs *);
+extern asmlinkage void do_fpu_state_restore(unsigned long r4, unsigned long r5,
+               unsigned long r6, unsigned long r7, struct pt_regs regs);
 
 asmlinkage void do_reserved_inst(unsigned long r4, unsigned long r5,
                                unsigned long r6, unsigned long r7,
@@ -709,14 +731,20 @@ void __init per_cpu_trap_init(void)
                     : "memory");
 }
 
-void __init trap_init(void)
+void *set_exception_table_vec(unsigned int vec, void *handler)
 {
        extern void *exception_handling_table[];
+       void *old_handler;
+       
+       old_handler = exception_handling_table[vec];
+       exception_handling_table[vec] = handler;
+       return old_handler;
+}
 
-       exception_handling_table[TRAP_RESERVED_INST]
-               = (void *)do_reserved_inst;
-       exception_handling_table[TRAP_ILLEGAL_SLOT_INST]
-               = (void *)do_illegal_slot_inst;
+void __init trap_init(void)
+{
+       set_exception_table_vec(TRAP_RESERVED_INST, do_reserved_inst);
+       set_exception_table_vec(TRAP_ILLEGAL_SLOT_INST, do_illegal_slot_inst);
 
 #if defined(CONFIG_CPU_SH4) && !defined(CONFIG_SH_FPU) || \
     defined(CONFIG_SH_FPU_EMU)
@@ -725,61 +753,54 @@ void __init trap_init(void)
         * reserved. They'll be handled in the math-emu case, or faulted on
         * otherwise.
         */
-       /* entry 64 corresponds to EXPEVT=0x800 */
-       exception_handling_table[64] = (void *)do_reserved_inst;
-       exception_handling_table[65] = (void *)do_illegal_slot_inst;
+       set_exception_table_evt(0x800, do_reserved_inst);
+       set_exception_table_evt(0x820, do_illegal_slot_inst);
+#elif defined(CONFIG_SH_FPU)
+       set_exception_table_evt(0x800, do_fpu_state_restore);
+       set_exception_table_evt(0x820, do_fpu_state_restore);
 #endif
                
        /* Setup VBR for boot cpu */
        per_cpu_trap_init();
 }
 
-void show_stack(struct task_struct *tsk, unsigned long *sp)
+void show_trace(struct task_struct *tsk, unsigned long *sp,
+               struct pt_regs *regs)
 {
-       unsigned long *stack, addr;
-       unsigned long module_start = VMALLOC_START;
-       unsigned long module_end = VMALLOC_END;
-       int i = 1;
-
-       if (!tsk)
-               tsk = current;
-       if (tsk == current)
-               sp = (unsigned long *)current_stack_pointer;
-       else
-               sp = (unsigned long *)tsk->thread.sp;
+       unsigned long addr;
 
-       stack = sp;
+       if (regs && user_mode(regs))
+               return;
 
        printk("\nCall trace: ");
 #ifdef CONFIG_KALLSYMS
        printk("\n");
 #endif
 
-       while (!kstack_end(stack)) {
-               addr = *stack++;
-               if (((addr >= (unsigned long)_text) &&
-                    (addr <= (unsigned long)_etext)) ||
-                   ((addr >= module_start) && (addr <= module_end))) {
-                       /*
-                        * For 80-columns display, 6 entry is maximum.
-                        * NOTE: '[<8c00abcd>] ' consumes 13 columns .
-                        */
-#ifndef CONFIG_KALLSYMS
-                       if (i && ((i % 6) == 0))
-                               printk("\n       ");
-#endif
-                       printk("[<%08lx>] ", addr);
-                       print_symbol("%s\n", addr);
-                       i++;
-               }
+       while (!kstack_end(sp)) {
+               addr = *sp++;
+               if (kernel_text_address(addr))
+                       print_ip_sym(addr);
        }
 
        printk("\n");
 }
 
-void show_task(unsigned long *sp)
+void show_stack(struct task_struct *tsk, unsigned long *sp)
 {
-       show_stack(NULL, sp);
+       unsigned long stack;
+
+       if (!tsk)
+               tsk = current;
+       if (tsk == current)
+               sp = (unsigned long *)current_stack_pointer;
+       else
+               sp = (unsigned long *)tsk->thread.sp;
+
+       stack = (unsigned long)sp;
+       dump_mem("Stack: ", stack, THREAD_SIZE +
+                (unsigned long)task_stack_page(tsk));
+       show_trace(tsk, sp, NULL);
 }
 
 void dump_stack(void)
index c81e6b67ad300e9e8b23c5adfc1658184d1ea59e..38c82d890ffda6a5cb332ad3b387bde0476dc551 100644 (file)
@@ -28,6 +28,7 @@ void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *handle)
        split_page(page, order);
 
        ret = page_address(page);
+       memset(ret, 0, size);
        *handle = virt_to_phys(ret);
 
        /*
index 9431e967aa455000e218dddc99681518418cebe8..2f96610a83e961fc3e6a539c09aac98e9e39bb56 100644 (file)
@@ -289,6 +289,13 @@ endmenu
 
 source "fs/Kconfig"
 
+menu "Instrumentation Support"
+       depends on EXPERIMENTAL
+
+source "arch/sparc/oprofile/Kconfig"
+
+endmenu
+
 source "arch/sparc/Kconfig.debug"
 
 source "security/Kconfig"
index 4cdbb2d59ed0a3e04c5e1d10a5bcf308c8ee7f22..f33c3817f01446810095d86727f79ad48eaa81ee 100644 (file)
@@ -30,6 +30,8 @@ HEAD_Y := $(head-y)
 core-y += arch/sparc/kernel/ arch/sparc/mm/ arch/sparc/math-emu/
 libs-y += arch/sparc/prom/ arch/sparc/lib/
 
+drivers-$(CONFIG_OPROFILE)     += arch/sparc/oprofile/
+
 # Export what is needed by arch/sparc/boot/Makefile
 # Renaming is done to avoid confusing pattern matching rules in 2.5.45 (multy-)
 INIT_Y         := $(patsubst %/, %/built-in.o, $(init-y))
index 72f0201051a0bd9fa0cff67c8a3792e5dbf3795c..c8cb211b90728741877f0326a96803c37ba07527 100644 (file)
@@ -46,6 +46,7 @@
 #include <asm/pgtable.h>
 #include <asm/pcic.h>
 #include <asm/cacheflush.h>
+#include <asm/irq_regs.h>
 
 #ifdef CONFIG_SMP
 #define SMP_NOP2 "nop; nop;\n\t"
@@ -133,8 +134,8 @@ static void irq_panic(void)
     prom_halt();
 }
 
-void (*sparc_init_timers)(irqreturn_t (*)(int, void *,struct pt_regs *)) =
-    (void (*)(irqreturn_t (*)(int, void *,struct pt_regs *))) irq_panic;
+void (*sparc_init_timers)(irq_handler_t ) =
+    (void (*)(irq_handler_t )) irq_panic;
 
 /*
  * Dave Redman (djhr@tadpole.co.uk)
@@ -319,12 +320,14 @@ void unexpected_irq(int irq, void *dev_id, struct pt_regs * regs)
 
 void handler_irq(int irq, struct pt_regs * regs)
 {
+       struct pt_regs *old_regs;
        struct irqaction * action;
        int cpu = smp_processor_id();
 #ifdef CONFIG_SMP
        extern void smp4m_irq_rotate(int cpu);
 #endif
 
+       old_regs = set_irq_regs(regs);
        irq_enter();
        disable_pil_irq(irq);
 #ifdef CONFIG_SMP
@@ -338,27 +341,31 @@ void handler_irq(int irq, struct pt_regs * regs)
        do {
                if (!action || !action->handler)
                        unexpected_irq(irq, NULL, regs);
-               action->handler(irq, action->dev_id, regs);
+               action->handler(irq, action->dev_id);
                action = action->next;
        } while (action);
        sparc_irq[irq].flags &= ~SPARC_IRQ_INPROGRESS;
        enable_pil_irq(irq);
        irq_exit();
+       set_irq_regs(old_regs);
 }
 
 #ifdef CONFIG_BLK_DEV_FD
-extern void floppy_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+extern void floppy_interrupt(int irq, void *dev_id);
 
 void sparc_floppy_irq(int irq, void *dev_id, struct pt_regs *regs)
 {
+       struct pt_regs *old_regs;
        int cpu = smp_processor_id();
 
+       old_regs = set_irq_regs(regs);
        disable_pil_irq(irq);
        irq_enter();
        kstat_cpu(cpu).irqs[irq]++;
-       floppy_interrupt(irq, dev_id, regs);
+       floppy_interrupt(irq, dev_id);
        irq_exit();
        enable_pil_irq(irq);
+       set_irq_regs(old_regs);
        // XXX Eek, it's totally changed with preempt_count() and such
        // if (softirq_pending(cpu))
        //      do_softirq();
@@ -369,7 +376,7 @@ void sparc_floppy_irq(int irq, void *dev_id, struct pt_regs *regs)
  * thus no sharing possible.
  */
 int request_fast_irq(unsigned int irq,
-                    irqreturn_t (*handler)(int, void *, struct pt_regs *),
+                    irq_handler_t handler,
                     unsigned long irqflags, const char *devname)
 {
        struct irqaction *action;
@@ -468,7 +475,7 @@ out:
 }
 
 int request_irq(unsigned int irq,
-               irqreturn_t (*handler)(int, void *, struct pt_regs *),
+               irq_handler_t handler,
                unsigned long irqflags, const char * devname, void *dev_id)
 {
        struct irqaction * action, **actionp;
@@ -478,7 +485,7 @@ int request_irq(unsigned int irq,
        
        if (sparc_cpu_model == sun4d) {
                extern int sun4d_request_irq(unsigned int, 
-                                            irqreturn_t (*)(int, void *, struct pt_regs *),
+                                            irq_handler_t ,
                                             unsigned long, const char *, void *);
                return sun4d_request_irq(irq, handler, irqflags, devname, dev_id);
        }
index edb6cc665f561652a7c3ef487166ad034c31f0df..207f1b6eef5317baee833ff636488ed6fcbd36bb 100644 (file)
@@ -34,6 +34,7 @@
 #include <asm/pcic.h>
 #include <asm/timer.h>
 #include <asm/uaccess.h>
+#include <asm/irq_regs.h>
 
 
 unsigned int pcic_pin_to_irq(unsigned int pin, char *name);
@@ -708,13 +709,13 @@ static void pcic_clear_clock_irq(void)
        pcic_timer_dummy = readl(pcic0.pcic_regs+PCI_SYS_LIMIT);
 }
 
-static irqreturn_t pcic_timer_handler (int irq, void *h, struct pt_regs *regs)
+static irqreturn_t pcic_timer_handler (int irq, void *h)
 {
        write_seqlock(&xtime_lock);     /* Dummy, to show that we remember */
        pcic_clear_clock_irq();
        do_timer(1);
 #ifndef CONFIG_SMP
-       update_process_times(user_mode(regs));
+       update_process_times(user_mode(get_irq_regs()));
 #endif
        write_sequnlock(&xtime_lock);
        return IRQ_HANDLED;
index 4ca9e5fc97f4d504c12b1dabbfd8ad2bbcf06dde..2cc302b6bec00798564873fe7d1b063b5170e17b 100644 (file)
@@ -243,7 +243,7 @@ int of_set_property(struct device_node *dp, const char *name, void *val, int len
                        void *old_val = prop->value;
                        int ret;
 
-                       ret = prom_setprop(dp->node, name, val, len);
+                       ret = prom_setprop(dp->node, (char *) name, val, len);
                        err = -EINVAL;
                        if (ret >= 0) {
                                prop->value = new_val;
@@ -477,7 +477,10 @@ static struct property * __init build_one_prop(phandle node, char *prev, char *s
                        p->length = 0;
                } else {
                        p->value = prom_early_alloc(p->length + 1);
-                       prom_getproperty(node, p->name, p->value, p->length);
+                       len = prom_getproperty(node, p->name, p->value,
+                                              p->length);
+                       if (len <= 0)
+                               p->length = 0;
                        ((unsigned char *)p->value)[p->length] = '\0';
                }
        }
index 0251cab4708bbcf31a23f93e6d942e08f54bfc9b..383526ad94fccb61f9176a51233bcce62d4c5d3a 100644 (file)
@@ -103,7 +103,6 @@ void prom_sync_me(void)
 
 unsigned int boot_flags __initdata = 0;
 #define BOOTME_DEBUG  0x1
-#define BOOTME_SINGLE 0x2
 
 /* Exported for mm/init.c:paging_init. */
 unsigned long cmdline_memory_size __initdata = 0;
@@ -121,16 +120,6 @@ static struct console prom_debug_console = {
        .index =        -1,
 };
 
-int obp_system_intr(void)
-{
-       if (boot_flags & BOOTME_DEBUG) {
-               printk("OBP: system interrupted\n");
-               prom_halt();
-               return 1;
-       }
-       return 0;
-}
-
 /* 
  * Process kernel command line switches that are specific to the
  * SPARC or that require special low-level processing.
@@ -142,7 +131,6 @@ static void __init process_switch(char c)
                boot_flags |= BOOTME_DEBUG;
                break;
        case 's':
-               boot_flags |= BOOTME_SINGLE;
                break;
        case 'h':
                prom_printf("boot_flags_init: Halt!\n");
index 4d441a554d35406da94a99ff9ac20bd3e035986c..33dadd9f28712a14fe964e56933acb3f80486bab 100644 (file)
@@ -87,6 +87,7 @@ extern void ___set_bit(void);
 extern void ___clear_bit(void);
 extern void ___change_bit(void);
 extern void ___rw_read_enter(void);
+extern void ___rw_read_try(void);
 extern void ___rw_read_exit(void);
 extern void ___rw_write_enter(void);
 
@@ -104,8 +105,9 @@ extern unsigned _Urem(unsigned, unsigned);
 EXPORT_SYMBOL(sparc_cpu_model);
 EXPORT_SYMBOL(kernel_thread);
 #ifdef CONFIG_SMP
-// XXX find what uses (or used) these.
+// XXX find what uses (or used) these.   AV: see asm/spinlock.h
 EXPORT_SYMBOL(___rw_read_enter);
+EXPORT_SYMBOL(___rw_read_try);
 EXPORT_SYMBOL(___rw_read_exit);
 EXPORT_SYMBOL(___rw_write_enter);
 #endif
index 4be2c86ea540a5918bc71460f1c49331c2bfb586..009e891a4329cd6e727dca78c3a00b3dc3862a35 100644 (file)
@@ -154,7 +154,7 @@ static void sun4c_load_profile_irq(int cpu, unsigned int limit)
        /* Errm.. not sure how to do this.. */
 }
 
-static void __init sun4c_init_timers(irqreturn_t (*counter_fn)(int, void *, struct pt_regs *))
+static void __init sun4c_init_timers(irq_handler_t counter_fn)
 {
        int irq;
 
index 74eed9775ac04f32a1d7fba2c387638a5485bacb..d4f9da8170c529c9f26c4d915fe3e37b85244f30 100644 (file)
@@ -38,6 +38,7 @@
 #include <asm/sbus.h>
 #include <asm/sbi.h>
 #include <asm/cacheflush.h>
+#include <asm/irq_regs.h>
 
 /* If you trust current SCSI layer to handle different SCSI IRQs, enable this. I don't trust it... -jj */
 /* #define DISTRIBUTE_IRQS */
@@ -198,6 +199,7 @@ extern void unexpected_irq(int, void *, struct pt_regs *);
 
 void sun4d_handler_irq(int irq, struct pt_regs * regs)
 {
+       struct pt_regs *old_regs;
        struct irqaction * action;
        int cpu = smp_processor_id();
        /* SBUS IRQ level (1 - 7) */
@@ -208,6 +210,7 @@ void sun4d_handler_irq(int irq, struct pt_regs * regs)
        
        cc_set_iclr(1 << irq);
        
+       old_regs = set_irq_regs(regs);
        irq_enter();
        kstat_cpu(cpu).irqs[irq]++;
        if (!sbusl) {
@@ -215,7 +218,7 @@ void sun4d_handler_irq(int irq, struct pt_regs * regs)
                if (!action)
                        unexpected_irq(irq, NULL, regs);
                do {
-                       action->handler(irq, action->dev_id, regs);
+                       action->handler(irq, action->dev_id);
                        action = action->next;
                } while (action);
        } else {
@@ -242,7 +245,7 @@ void sun4d_handler_irq(int irq, struct pt_regs * regs)
                                                if (!action)
                                                        unexpected_irq(irq, NULL, regs);
                                                do {
-                                                       action->handler(irq, action->dev_id, regs);
+                                                       action->handler(irq, action->dev_id);
                                                        action = action->next;
                                                } while (action);
                                                release_sbi(SBI2DEVID(sbino), slot);
@@ -250,6 +253,7 @@ void sun4d_handler_irq(int irq, struct pt_regs * regs)
                        }
        }
        irq_exit();
+       set_irq_regs(old_regs);
 }
 
 unsigned int sun4d_build_irq(struct sbus_dev *sdev, int irq)
@@ -272,7 +276,7 @@ unsigned int sun4d_sbint_to_irq(struct sbus_dev *sdev, unsigned int sbint)
 }
 
 int sun4d_request_irq(unsigned int irq,
-               irqreturn_t (*handler)(int, void *, struct pt_regs *),
+               irq_handler_t handler,
                unsigned long irqflags, const char * devname, void *dev_id)
 {
        struct irqaction *action, *tmp = NULL, **actionp;
@@ -466,7 +470,7 @@ static void sun4d_load_profile_irq(int cpu, unsigned int limit)
        bw_set_prof_limit(cpu, limit);
 }
 
-static void __init sun4d_init_timers(irqreturn_t (*counter_fn)(int, void *, struct pt_regs *))
+static void __init sun4d_init_timers(irq_handler_t counter_fn)
 {
        int irq;
        int cpu;
index 3ff4edd32815ca842c5ccd03d4e6909d094f938c..c80ea61e8ba0e84d8ca1c00fc9df0668477759d2 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <asm/ptrace.h>
 #include <asm/atomic.h>
+#include <asm/irq_regs.h>
 
 #include <asm/delay.h>
 #include <asm/irq.h>
@@ -369,10 +370,12 @@ void smp4d_message_pass(int target, int msg, unsigned long data, int wait)
 
 void smp4d_percpu_timer_interrupt(struct pt_regs *regs)
 {
+       struct pt_regs *old_regs;
        int cpu = hard_smp4d_processor_id();
        static int cpu_tick[NR_CPUS];
        static char led_mask[] = { 0xe, 0xd, 0xb, 0x7, 0xb, 0xd };
 
+       old_regs = set_irq_regs(regs);
        bw_get_prof_limit(cpu); 
        bw_clear_intr_mask(0, 1);       /* INTR_TABLE[0] & 1 is Profile IRQ */
 
@@ -384,7 +387,7 @@ void smp4d_percpu_timer_interrupt(struct pt_regs *regs)
                show_leds(cpu);
        }
 
-       profile_tick(CPU_PROFILING, regs);
+       profile_tick(CPU_PROFILING);
 
        if(!--prof_counter(cpu)) {
                int user = user_mode(regs);
@@ -395,6 +398,7 @@ void smp4d_percpu_timer_interrupt(struct pt_regs *regs)
 
                prof_counter(cpu) = prof_multiplier(cpu);
        }
+       set_irq_regs(old_regs);
 }
 
 extern unsigned int lvl14_resolution;
index 7cefa301efea61f3f0a84f5d12d074b2fc526a50..a654c16f4027941c3f1627e2f1dce461be17e1ce 100644 (file)
@@ -228,7 +228,7 @@ static void sun4m_load_profile_irq(int cpu, unsigned int limit)
        sun4m_timers->cpu_timers[cpu].l14_timer_limit = limit;
 }
 
-static void __init sun4m_init_timers(irqreturn_t (*counter_fn)(int, void *, struct pt_regs *))
+static void __init sun4m_init_timers(irq_handler_t counter_fn)
 {
        int reg_count, irq, cpu;
        struct linux_prom_registers cnt_regs[PROMREG_MAX];
index 7d4a649138f6bdd07f0e0a9a745bab156c505b1f..e2d9c018bd5697c7b26fce6ee15e4f9363813c45 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/profile.h>
 #include <asm/cacheflush.h>
 #include <asm/tlbflush.h>
+#include <asm/irq_regs.h>
 
 #include <asm/ptrace.h>
 #include <asm/atomic.h>
@@ -353,11 +354,14 @@ void smp4m_cross_call_irq(void)
 
 void smp4m_percpu_timer_interrupt(struct pt_regs *regs)
 {
+       struct pt_regs *old_regs;
        int cpu = smp_processor_id();
 
+       old_regs = set_irq_regs(regs);
+
        clear_profile_irq(cpu);
 
-       profile_tick(CPU_PROFILING, regs);
+       profile_tick(CPU_PROFILING);
 
        if(!--prof_counter(cpu)) {
                int user = user_mode(regs);
@@ -368,6 +372,7 @@ void smp4m_percpu_timer_interrupt(struct pt_regs *regs)
 
                prof_counter(cpu) = prof_multiplier(cpu);
        }
+       set_irq_regs(old_regs);
 }
 
 extern unsigned int lvl14_resolution;
index d3b4daac705f078420a63343617c1e6c98408d5f..f1a7bd19e04fd1acaec49d879676313756a7cfe9 100644 (file)
@@ -55,7 +55,7 @@ void install_obp_ticker(void)
        linux_lvl14[3] =  obp_lvl14[3]; 
 }
 
-void claim_ticker14(irqreturn_t (*handler)(int, void *, struct pt_regs *),
+void claim_ticker14(irq_handler_t handler,
                    int irq_nr, unsigned int timeout )
 {
        int cpu = smp_processor_id();
index e10dc831944d45c27f129038b1103306c15b567d..6c7aa51b590fd5c7d0d10d457698d9c9146a157b 100644 (file)
@@ -42,6 +42,7 @@
 #include <asm/page.h>
 #include <asm/pcic.h>
 #include <asm/of_device.h>
+#include <asm/irq_regs.h>
 
 DEFINE_SPINLOCK(rtc_lock);
 enum sparc_clock_type sp_clock_typ;
@@ -94,6 +95,8 @@ unsigned long profile_pc(struct pt_regs *regs)
        return pc;
 }
 
+EXPORT_SYMBOL(profile_pc);
+
 __volatile__ unsigned int *master_l10_counter;
 __volatile__ unsigned int *master_l10_limit;
 
@@ -104,13 +107,13 @@ __volatile__ unsigned int *master_l10_limit;
 
 #define TICK_SIZE (tick_nsec / 1000)
 
-irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+irqreturn_t timer_interrupt(int irq, void *dev_id)
 {
        /* last time the cmos clock got updated */
        static long last_rtc_update;
 
 #ifndef CONFIG_SMP
-       profile_tick(CPU_PROFILING, regs);
+       profile_tick(CPU_PROFILING);
 #endif
 
        /* Protect counter clear so that do_gettimeoffset works */
@@ -128,7 +131,7 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs * regs)
 
        do_timer(1);
 #ifndef CONFIG_SMP
-       update_process_times(user_mode(regs));
+       update_process_times(user_mode(get_irq_regs()));
 #endif
 
 
index 346c19a949fd0245c2ca29fe3d9f0f72e7a2219f..1dd78c84888a3e1556645537db9c3f549d62f92d 100644 (file)
@@ -36,11 +36,11 @@ SECTIONS
 
   . = ALIGN(4096);
   __init_begin = .;
+  _sinittext = .;
   .init.text : { 
-       _sinittext = .;
        *(.init.text)
-       _einittext = .;
   }
+  _einittext = .;
   __init_text_end = .;
   .init.data : { *(.init.data) }
   . = ALIGN(16);
index 95fa48424967b38bf3311fab599136ddf11d7fb2..b1df55cb2215df6c4858681c61129281e62c53d7 100644 (file)
@@ -25,6 +25,15 @@ ___rw_read_enter_spin_on_wlock:
         ldstub [%g1 + 3], %g2
        b       ___rw_read_enter_spin_on_wlock
         ldub   [%g1 + 3], %g2
+___rw_read_try_spin_on_wlock:
+       andcc   %g2, 0xff, %g0
+       be,a    ___rw_read_try
+        ldstub [%g1 + 3], %g2
+       xnorcc  %g2, 0x0, %o0   /* if g2 is ~0, set o0 to 0 and bugger off */
+       bne,a   ___rw_read_enter_spin_on_wlock
+        ld     [%g1], %g2
+       retl
+        mov    %g4, %o7
 ___rw_read_exit_spin_on_wlock:
        orcc    %g2, 0x0, %g0
        be,a    ___rw_read_exit
@@ -60,6 +69,17 @@ ___rw_read_exit:
        retl
         mov    %g4, %o7
 
+       .globl  ___rw_read_try
+___rw_read_try:
+       orcc    %g2, 0x0, %g0
+       bne     ___rw_read_try_spin_on_wlock
+        ld     [%g1], %g2
+       add     %g2, 1, %g2
+       st      %g2, [%g1]
+       set     1, %o1
+       retl
+        mov    %g4, %o7
+
        .globl  ___rw_write_enter
 ___rw_write_enter:
        orcc    %g2, 0x0, %g0
index b27a506309eed9608e0154be1398f0d257df2564..0df7121cef07b768d8fe0090609f994edcca3ac5 100644 (file)
@@ -402,7 +402,7 @@ void srmmu_nocache_calcsize(void)
        srmmu_nocache_end = SRMMU_NOCACHE_VADDR + srmmu_nocache_size;
 }
 
-void srmmu_nocache_init(void)
+void __init srmmu_nocache_init(void)
 {
        unsigned int bitmap_bits;
        pgd_t *pgd;
diff --git a/arch/sparc/oprofile/Kconfig b/arch/sparc/oprofile/Kconfig
new file mode 100644 (file)
index 0000000..d8a8408
--- /dev/null
@@ -0,0 +1,17 @@
+config PROFILING
+       bool "Profiling support (EXPERIMENTAL)"
+       help
+         Say Y here to enable the extended profiling support mechanisms used
+         by profilers such as OProfile.
+         
+
+config OPROFILE
+       tristate "OProfile system profiling (EXPERIMENTAL)"
+       depends on PROFILING
+       help
+         OProfile is a profiling system capable of profiling the
+         whole system, include the kernel, kernel modules, libraries,
+         and applications.
+
+         If unsure, say N.
+
diff --git a/arch/sparc/oprofile/Makefile b/arch/sparc/oprofile/Makefile
new file mode 100644 (file)
index 0000000..e9feca1
--- /dev/null
@@ -0,0 +1,9 @@
+obj-$(CONFIG_OPROFILE) += oprofile.o
+
+DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \
+               oprof.o cpu_buffer.o buffer_sync.o \
+               event_buffer.o oprofile_files.o \
+               oprofilefs.o oprofile_stats.o \
+               timer_int.o )
+
+oprofile-y                             := $(DRIVER_OBJS) init.o
diff --git a/arch/sparc/oprofile/init.c b/arch/sparc/oprofile/init.c
new file mode 100644 (file)
index 0000000..9ab815b
--- /dev/null
@@ -0,0 +1,23 @@
+/**
+ * @file init.c
+ *
+ * @remark Copyright 2002 OProfile authors
+ * @remark Read the file COPYING
+ *
+ * @author John Levon <levon@movementarian.org>
+ */
+
+#include <linux/kernel.h>
+#include <linux/oprofile.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+int __init oprofile_arch_init(struct oprofile_operations * ops)
+{
+       return -ENODEV;
+}
+
+
+void oprofile_arch_exit(void)
+{
+}
index f54ab375464b97ff4d1f8a515d597c5ad29121d4..2f4612fa81f274e5b61982c350c69f6654118bb7 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18
-# Mon Oct  2 14:24:40 2006
+# Linux kernel version: 2.6.19-rc2
+# Tue Oct 17 19:29:20 2006
 #
 CONFIG_SPARC=y
 CONFIG_SPARC64=y
@@ -197,6 +197,7 @@ CONFIG_INET_XFRM_TUNNEL=y
 CONFIG_INET_TUNNEL=y
 CONFIG_INET_XFRM_MODE_TRANSPORT=y
 CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
@@ -214,7 +215,9 @@ CONFIG_INET6_XFRM_TUNNEL=m
 CONFIG_INET6_TUNNEL=m
 CONFIG_INET6_XFRM_MODE_TRANSPORT=m
 CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
 # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=m
 CONFIG_IPV6_TUNNEL=m
 # CONFIG_IPV6_SUBTREES is not set
 # CONFIG_IPV6_MULTIPLE_TABLES is not set
@@ -331,6 +334,12 @@ CONFIG_CDROM_PKTCDVD_BUFFERS=8
 CONFIG_CDROM_PKTCDVD_WCACHE=y
 CONFIG_ATA_OVER_ETH=m
 
+#
+# Misc devices
+#
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+
 #
 # ATA/ATAPI/MFM/RLL support
 #
@@ -373,6 +382,7 @@ CONFIG_BLK_DEV_ALI15X3=y
 # CONFIG_BLK_DEV_CS5530 is not set
 # CONFIG_BLK_DEV_HPT34X is not set
 # CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_JMICRON is not set
 # CONFIG_BLK_DEV_SC1200 is not set
 # CONFIG_BLK_DEV_PIIX is not set
 # CONFIG_BLK_DEV_IT821X is not set
@@ -449,10 +459,10 @@ CONFIG_ISCSI_TCP=m
 # CONFIG_SCSI_INIA100 is not set
 # CONFIG_SCSI_STEX is not set
 # CONFIG_SCSI_SYM53C8XX_2 is not set
-# CONFIG_SCSI_IPR is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
 # CONFIG_SCSI_QLOGICPTI is not set
 # CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
 # CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
@@ -478,6 +488,7 @@ CONFIG_MD_RAID456=m
 CONFIG_MD_MULTIPATH=m
 # CONFIG_MD_FAULTY is not set
 CONFIG_BLK_DEV_DM=m
+# CONFIG_DM_DEBUG is not set
 CONFIG_DM_CRYPT=m
 CONFIG_DM_SNAPSHOT=m
 CONFIG_DM_MIRROR=m
@@ -724,7 +735,6 @@ CONFIG_RTC=y
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -837,15 +847,10 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_W83627EHF is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
 
-#
-# Misc devices
-#
-
 #
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -858,6 +863,7 @@ CONFIG_VIDEO_V4L2=y
 #
 # CONFIG_FIRMWARE_EDID is not set
 CONFIG_FB=y
+CONFIG_FB_DDC=y
 CONFIG_FB_CFB_FILLRECT=y
 CONFIG_FB_CFB_COPYAREA=y
 CONFIG_FB_CFB_IMAGEBLIT=y
@@ -1099,7 +1105,6 @@ CONFIG_USB_HIDDEV=y
 # CONFIG_USB_ATI_REMOTE2 is not set
 # CONFIG_USB_KEYSPAN_REMOTE is not set
 # CONFIG_USB_APPLETOUCH is not set
-# CONFIG_USB_TRANCEVIBRATOR is not set
 
 #
 # USB Imaging devices
@@ -1145,6 +1150,7 @@ CONFIG_USB_HIDDEV=y
 # CONFIG_USB_APPLEDISPLAY is not set
 # CONFIG_USB_SISUSBVGA is not set
 # CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
 # CONFIG_USB_TEST is not set
 
 #
@@ -1229,6 +1235,7 @@ CONFIG_EXT3_FS=y
 CONFIG_EXT3_FS_XATTR=y
 CONFIG_EXT3_FS_POSIX_ACL=y
 CONFIG_EXT3_FS_SECURITY=y
+# CONFIG_EXT4DEV_FS is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 CONFIG_FS_MBCACHE=y
@@ -1236,6 +1243,7 @@ CONFIG_FS_MBCACHE=y
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -1279,6 +1287,7 @@ CONFIG_RAMFS=y
 #
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
+# CONFIG_ECRYPT_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_HFSPLUS_FS is not set
 # CONFIG_BEFS_FS is not set
@@ -1388,6 +1397,7 @@ CONFIG_DEBUG_FS=y
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_UNWIND_INFO is not set
 CONFIG_FORCED_INLINING=y
+# CONFIG_HEADERS_CHECK is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_LKDTM is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
index 8a9b470e1b651883ca6023313295a94775d78566..2df25c2b4071e92b7dea55dd32d5e34f4c2413db 100644 (file)
@@ -79,7 +79,7 @@ static void __ebus_dma_reset(struct ebus_dma_info *p, int no_drain)
        }
 }
 
-static irqreturn_t ebus_dma_irq(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t ebus_dma_irq(int irq, void *dev_id)
 {
        struct ebus_dma_info *p = dev_id;
        unsigned long flags;
index 4e64724cb9ae119f2c583bd716d07eee0c5f19ce..d64b1ea848de0adc1ec1f5967cb86dcb725e47bd 100644 (file)
@@ -522,12 +522,13 @@ void ack_bad_irq(unsigned int virt_irq)
 }
 
 #ifndef CONFIG_SMP
-extern irqreturn_t timer_interrupt(int, void *, struct pt_regs *);
+extern irqreturn_t timer_interrupt(int, void *);
 
 void timer_irq(int irq, struct pt_regs *regs)
 {
        unsigned long clr_mask = 1 << irq;
        unsigned long tick_mask = tick_ops->softint_mask;
+       struct pt_regs *old_regs;
 
        if (get_softint() & tick_mask) {
                irq = 0;
@@ -535,21 +536,25 @@ void timer_irq(int irq, struct pt_regs *regs)
        }
        clear_softint(clr_mask);
 
+       old_regs = set_irq_regs(regs);
        irq_enter();
 
        kstat_this_cpu.irqs[0]++;
-       timer_interrupt(irq, NULL, regs);
+       timer_interrupt(irq, NULL);
 
        irq_exit();
+       set_irq_regs(old_regs);
 }
 #endif
 
 void handler_irq(int irq, struct pt_regs *regs)
 {
        struct ino_bucket *bucket;
+       struct pt_regs *old_regs;
 
        clear_softint(1 << irq);
 
+       old_regs = set_irq_regs(regs);
        irq_enter();
 
        /* Sliiiick... */
@@ -558,12 +563,13 @@ void handler_irq(int irq, struct pt_regs *regs)
                struct ino_bucket *next = __bucket(bucket->irq_chain);
 
                bucket->irq_chain = 0;
-               __do_IRQ(bucket->virt_irq, regs);
+               __do_IRQ(bucket->virt_irq);
 
                bucket = next;
        }
 
        irq_exit();
+       set_irq_regs(old_regs);
 }
 
 struct sun5_timer {
index 7f920453577085dcd02351d6d6be16e179a2c100..d3dfb2a36d477584d8722430e07f01f701f9f01a 100644 (file)
@@ -131,8 +131,13 @@ static int of_device_resume(struct device * dev)
 void __iomem *of_ioremap(struct resource *res, unsigned long offset, unsigned long size, char *name)
 {
        unsigned long ret = res->start + offset;
+       struct resource *r;
 
-       if (!request_region(ret, size, name))
+       if (res->flags & IORESOURCE_MEM)
+               r = request_mem_region(ret, size, name);
+       else
+               r = request_region(ret, size, name);
+       if (!r)
                ret = 0;
 
        return (void __iomem *) ret;
@@ -841,7 +846,7 @@ static struct of_device * __init scan_one_device(struct device_node *dp,
        if (!parent)
                strcpy(op->dev.bus_id, "root");
        else
-               strcpy(op->dev.bus_id, dp->path_component_name);
+               sprintf(op->dev.bus_id, "%s@%08x", dp->name, dp->node);
 
        if (of_device_register(op)) {
                printk("%s: Could not register of device.\n",
index 7a59cc72c844c438188f5fef41bb4adcc08ea523..827ae30aa4971e5306e1f8c0ed6db494e65b71ec 100644 (file)
@@ -330,19 +330,6 @@ __init get_device_resource(struct linux_prom_pci_registers *ap,
        return res;
 }
 
-static int __init pdev_resource_collisions_expected(struct pci_dev *pdev)
-{
-       if (pdev->vendor != PCI_VENDOR_ID_SUN)
-               return 0;
-
-       if (pdev->device == PCI_DEVICE_ID_SUN_RIO_EBUS ||
-           pdev->device == PCI_DEVICE_ID_SUN_RIO_1394 ||
-           pdev->device == PCI_DEVICE_ID_SUN_RIO_USB)
-               return 1;
-
-       return 0;
-}
-
 static void __init pdev_record_assignments(struct pci_pbm_info *pbm,
                                           struct pci_dev *pdev)
 {
@@ -400,19 +387,23 @@ static void __init pdev_record_assignments(struct pci_pbm_info *pbm,
                pbm->parent->resource_adjust(pdev, res, root);
 
                if (request_resource(root, res) < 0) {
+                       int rnum;
+
                        /* OK, there is some conflict.  But this is fine
                         * since we'll reassign it in the fixup pass.
                         *
-                        * We notify the user that OBP made an error if it
-                        * is a case we don't expect.
+                        * Do not print the warning for ROM resources
+                        * as such a conflict is quite common and
+                        * harmless as the ROM bar is disabled.
                         */
-                       if (!pdev_resource_collisions_expected(pdev)) {
-                               printk(KERN_ERR "PCI: Address space collision on region %ld "
+                       rnum = (res - &pdev->resource[0]);
+                       if (rnum != PCI_ROM_RESOURCE)
+                               printk(KERN_ERR "PCI: Resource collision, "
+                                      "region %d "
                                       "[%016lx:%016lx] of device %s\n",
-                                      (res - &pdev->resource[0]),
+                                      rnum,
                                       res->start, res->end,
                                       pci_name(pdev));
-                       }
                }
        }
 }
index 1ec0aab68c08079d5d7204c770496c019086c416..fda5db223d9692f344725664d686d6dd7bba997e 100644 (file)
@@ -533,7 +533,7 @@ static void psycho_check_iommu_error(struct pci_controller_info *p,
 #define  PSYCHO_UEAFSR_RESV2   0x00000000007fffffUL /* Reserved                     */
 #define PSYCHO_UE_AFAR 0x0038UL
 
-static irqreturn_t psycho_ue_intr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t psycho_ue_intr(int irq, void *dev_id)
 {
        struct pci_controller_info *p = dev_id;
        unsigned long afsr_reg = p->pbm_A.controller_regs + PSYCHO_UE_AFSR;
@@ -610,7 +610,7 @@ static irqreturn_t psycho_ue_intr(int irq, void *dev_id, struct pt_regs *regs)
 #define  PSYCHO_CEAFSR_RESV2   0x00000000007fffffUL /* Reserved                     */
 #define PSYCHO_CE_AFAR 0x0040UL
 
-static irqreturn_t psycho_ce_intr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t psycho_ce_intr(int irq, void *dev_id)
 {
        struct pci_controller_info *p = dev_id;
        unsigned long afsr_reg = p->pbm_A.controller_regs + PSYCHO_CE_AFSR;
@@ -735,7 +735,7 @@ static irqreturn_t psycho_pcierr_intr_other(struct pci_pbm_info *pbm, int is_pbm
        return ret;
 }
 
-static irqreturn_t psycho_pcierr_intr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t psycho_pcierr_intr(int irq, void *dev_id)
 {
        struct pci_pbm_info *pbm = dev_id;
        struct pci_controller_info *p = pbm->parent;
index 45891850b90d2def5de925dd801e75724753f80b..94bb681f232379bf05a77df690c4e9944369d8d5 100644 (file)
@@ -574,7 +574,7 @@ static void sabre_check_iommu_error(struct pci_controller_info *p,
        spin_unlock_irqrestore(&iommu->lock, flags);
 }
 
-static irqreturn_t sabre_ue_intr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t sabre_ue_intr(int irq, void *dev_id)
 {
        struct pci_controller_info *p = dev_id;
        unsigned long afsr_reg = p->pbm_A.controller_regs + SABRE_UE_AFSR;
@@ -634,7 +634,7 @@ static irqreturn_t sabre_ue_intr(int irq, void *dev_id, struct pt_regs *regs)
        return IRQ_HANDLED;
 }
 
-static irqreturn_t sabre_ce_intr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t sabre_ce_intr(int irq, void *dev_id)
 {
        struct pci_controller_info *p = dev_id;
        unsigned long afsr_reg = p->pbm_A.controller_regs + SABRE_CE_AFSR;
@@ -726,7 +726,7 @@ static irqreturn_t sabre_pcierr_intr_other(struct pci_controller_info *p)
        return ret;
 }
 
-static irqreturn_t sabre_pcierr_intr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t sabre_pcierr_intr(int irq, void *dev_id)
 {
        struct pci_controller_info *p = dev_id;
        unsigned long afsr_reg, afar_reg;
@@ -1196,7 +1196,7 @@ static void pbm_register_toplevel_resources(struct pci_controller_info *p,
                                            &pbm->mem_space);
 }
 
-static void sabre_pbm_init(struct pci_controller_info *p, struct device_node *dp, u32 dma_begin)
+static void sabre_pbm_init(struct pci_controller_info *p, struct device_node *dp, u32 dma_start, u32 dma_end)
 {
        struct pci_pbm_info *pbm;
        struct device_node *node;
@@ -1261,6 +1261,8 @@ static void sabre_pbm_init(struct pci_controller_info *p, struct device_node *dp
                node = node->sibling;
        }
        if (simbas_found == 0) {
+               struct resource *rp;
+
                /* No APBs underneath, probably this is a hummingbird
                 * system.
                 */
@@ -1302,8 +1304,10 @@ static void sabre_pbm_init(struct pci_controller_info *p, struct device_node *dp
                pbm->io_space.end   = pbm->io_space.start + (1UL << 24) - 1UL;
                pbm->io_space.flags = IORESOURCE_IO;
 
-               pbm->mem_space.start = p->pbm_A.controller_regs + SABRE_MEMSPACE;
-               pbm->mem_space.end   = pbm->mem_space.start + (unsigned long)dma_begin - 1UL;
+               pbm->mem_space.start =
+                       (p->pbm_A.controller_regs + SABRE_MEMSPACE);
+               pbm->mem_space.end =
+                       (pbm->mem_space.start + ((1UL << 32UL) - 1UL));
                pbm->mem_space.flags = IORESOURCE_MEM;
 
                if (request_resource(&ioport_resource, &pbm->io_space) < 0) {
@@ -1315,6 +1319,17 @@ static void sabre_pbm_init(struct pci_controller_info *p, struct device_node *dp
                        prom_halt();
                }
 
+               rp = kmalloc(sizeof(*rp), GFP_KERNEL);
+               if (!rp) {
+                       prom_printf("Cannot allocate IOMMU resource.\n");
+                       prom_halt();
+               }
+               rp->name = "IOMMU";
+               rp->start = pbm->mem_space.start + (unsigned long) dma_start;
+               rp->end = pbm->mem_space.start + (unsigned long) dma_end - 1UL;
+               rp->flags = IORESOURCE_BUSY;
+               request_resource(&pbm->mem_space, rp);
+
                pci_register_legacy_regions(&pbm->io_space,
                                            &pbm->mem_space);
        }
@@ -1450,5 +1465,5 @@ void sabre_init(struct device_node *dp, char *model_name)
        /*
         * Look for APB underneath.
         */
-       sabre_pbm_init(p, dp, vdma[0]);
+       sabre_pbm_init(p, dp, vdma[0], vdma[0] + vdma[1]);
 }
index 75ade83ecc651b2cff9222e278ac0986b3e69cac..66911b126aed65a723954c7d2b4e287938eff6b1 100644 (file)
@@ -515,7 +515,7 @@ static void schizo_check_iommu_error(struct pci_controller_info *p,
 #define SCHIZO_UEAFSR_MTAG     0x000000000000e000UL /* Safari */
 #define SCHIZO_UEAFSR_ECCSYND  0x00000000000001ffUL /* Safari */
 
-static irqreturn_t schizo_ue_intr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t schizo_ue_intr(int irq, void *dev_id)
 {
        struct pci_controller_info *p = dev_id;
        unsigned long afsr_reg = p->pbm_B.controller_regs + SCHIZO_UE_AFSR;
@@ -603,7 +603,7 @@ static irqreturn_t schizo_ue_intr(int irq, void *dev_id, struct pt_regs *regs)
 #define SCHIZO_CEAFSR_MTAG     0x000000000000e000UL
 #define SCHIZO_CEAFSR_ECCSYND  0x00000000000001ffUL
 
-static irqreturn_t schizo_ce_intr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t schizo_ce_intr(int irq, void *dev_id)
 {
        struct pci_controller_info *p = dev_id;
        unsigned long afsr_reg = p->pbm_B.controller_regs + SCHIZO_CE_AFSR;
@@ -778,7 +778,7 @@ static irqreturn_t schizo_pcierr_intr_other(struct pci_pbm_info *pbm)
        return ret;
 }
 
-static irqreturn_t schizo_pcierr_intr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t schizo_pcierr_intr(int irq, void *dev_id)
 {
        struct pci_pbm_info *pbm = dev_id;
        struct pci_controller_info *p = pbm->parent;
@@ -933,7 +933,7 @@ static irqreturn_t schizo_pcierr_intr(int irq, void *dev_id, struct pt_regs *reg
 /* We only expect UNMAP errors here.  The rest of the Safari errors
  * are marked fatal and thus cause a system reset.
  */
-static irqreturn_t schizo_safarierr_intr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t schizo_safarierr_intr(int irq, void *dev_id)
 {
        struct pci_controller_info *p = dev_id;
        u64 errlog;
index 0b9c70627ce4e7537d96422d62ff2ac5feb1ba1f..699b24b890dfc5dc398e6a04ade5bf9f3a8b67c7 100644 (file)
@@ -35,7 +35,7 @@ static void __iomem *power_reg;
 static DECLARE_WAIT_QUEUE_HEAD(powerd_wait);
 static int button_pressed;
 
-static irqreturn_t power_handler(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t power_handler(int irq, void *dev_id)
 {
        if (button_pressed == 0) {
                button_pressed = 1;
index c49a57795743bcf3616b07663c2b593532f85d21..01d6d869ea2b5e261110567220886d3c1b422359 100644 (file)
@@ -839,7 +839,7 @@ unsigned int sbus_build_irq(void *buscookie, unsigned int ino)
 #define  SYSIO_UEAFSR_SIZE  0x00001c0000000000UL /* Bad transfer size 2^SIZE  */
 #define  SYSIO_UEAFSR_MID   0x000003e000000000UL /* UPA MID causing the fault */
 #define  SYSIO_UEAFSR_RESV2 0x0000001fffffffffUL /* Reserved                  */
-static irqreturn_t sysio_ue_handler(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t sysio_ue_handler(int irq, void *dev_id)
 {
        struct sbus_bus *sbus = dev_id;
        struct sbus_iommu *iommu = sbus->iommu;
@@ -911,7 +911,7 @@ static irqreturn_t sysio_ue_handler(int irq, void *dev_id, struct pt_regs *regs)
 #define  SYSIO_CEAFSR_SIZE  0x00001c0000000000UL /* Bad transfer size 2^SIZE  */
 #define  SYSIO_CEAFSR_MID   0x000003e000000000UL /* UPA MID causing the fault */
 #define  SYSIO_CEAFSR_RESV2 0x0000001fffffffffUL /* Reserved                  */
-static irqreturn_t sysio_ce_handler(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t sysio_ce_handler(int irq, void *dev_id)
 {
        struct sbus_bus *sbus = dev_id;
        struct sbus_iommu *iommu = sbus->iommu;
@@ -988,7 +988,7 @@ static irqreturn_t sysio_ce_handler(int irq, void *dev_id, struct pt_regs *regs)
 #define  SYSIO_SBAFSR_SIZE  0x00001c0000000000UL /* Size of transfer          */
 #define  SYSIO_SBAFSR_MID   0x000003e000000000UL /* MID causing the error     */
 #define  SYSIO_SBAFSR_RESV3 0x0000001fffffffffUL /* Reserved                  */
-static irqreturn_t sysio_sbus_error_handler(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t sysio_sbus_error_handler(int irq, void *dev_id)
 {
        struct sbus_bus *sbus = dev_id;
        struct sbus_iommu *iommu = sbus->iommu;
index 958287448cfe89f1cec527fa93d15c4808bf5495..bf033b31d4376341a8cce56b9ec77e9127f6986b 100644 (file)
@@ -74,7 +74,6 @@ prom_console_write(struct console *con, const char *s, unsigned n)
 
 unsigned int boot_flags = 0;
 #define BOOTME_DEBUG  0x1
-#define BOOTME_SINGLE 0x2
 
 /* Exported for mm/init.c:paging_init. */
 unsigned long cmdline_memory_size = 0;
@@ -91,16 +90,6 @@ void kernel_enter_debugger(void)
 {
 }
 
-int obp_system_intr(void)
-{
-       if (boot_flags & BOOTME_DEBUG) {
-               printk("OBP: system interrupted\n");
-               prom_halt();
-               return 1;
-       }
-       return 0;
-}
-
 /* 
  * Process kernel command line switches that are specific to the
  * SPARC or that require special low-level processing.
@@ -112,7 +101,6 @@ static void __init process_switch(char c)
                boot_flags |= BOOTME_DEBUG;
                break;
        case 's':
-               boot_flags |= BOOTME_SINGLE;
                break;
        case 'h':
                prom_printf("boot_flags_init: Halt!\n");
index f62bf3a2de1a552f9b4bb5d46ab5037b9e53696b..cc09d826641452998efbaa2df0ee8bb359cac524 100644 (file)
@@ -31,6 +31,7 @@
 #include <asm/cpudata.h>
 
 #include <asm/irq.h>
+#include <asm/irq_regs.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
 #include <asm/oplib.h>
@@ -1187,6 +1188,7 @@ void smp_percpu_timer_interrupt(struct pt_regs *regs)
        unsigned long compare, tick, pstate;
        int cpu = smp_processor_id();
        int user = user_mode(regs);
+       struct pt_regs *old_regs;
 
        /*
         * Check for level 14 softint.
@@ -1203,8 +1205,9 @@ void smp_percpu_timer_interrupt(struct pt_regs *regs)
                clear_softint(tick_mask);
        }
 
+       old_regs = set_irq_regs(regs);
        do {
-               profile_tick(CPU_PROFILING, regs);
+               profile_tick(CPU_PROFILING);
                if (!--prof_counter(cpu)) {
                        irq_enter();
 
@@ -1236,6 +1239,7 @@ void smp_percpu_timer_interrupt(struct pt_regs *regs)
                                     : /* no outputs */
                                     : "r" (pstate));
        } while (time_after_eq(tick, compare));
+       set_irq_regs(old_regs);
 }
 
 static void __init smp_setup_percpu_timer(void)
index 00f6fc4aaaffc4182c0dec5af21f127d7e353493..061e1b1fa5838e24701f9b307527c2d9c7325ca4 100644 (file)
@@ -45,6 +45,7 @@
 #include <asm/cpudata.h>
 #include <asm/uaccess.h>
 #include <asm/prom.h>
+#include <asm/irq_regs.h>
 
 DEFINE_SPINLOCK(mostek_lock);
 DEFINE_SPINLOCK(rtc_lock);
@@ -452,7 +453,7 @@ static inline void timer_check_rtc(void)
        }
 }
 
-irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+irqreturn_t timer_interrupt(int irq, void *dev_id)
 {
        unsigned long ticks, compare, pstate;
 
@@ -460,8 +461,8 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs * regs)
 
        do {
 #ifndef CONFIG_SMP
-               profile_tick(CPU_PROFILING, regs);
-               update_process_times(user_mode(regs));
+               profile_tick(CPU_PROFILING);
+               update_process_times(user_mode(get_irq_regs()));
 #endif
                do_timer(1);
 
index d75307589d74c144f39d713fea8749242e36e29f..5ac1f2963ae383e391cb601c730ed645e0707b6a 100644 (file)
@@ -1,3 +1,8 @@
+config DEFCONFIG_LIST
+       string
+       option defconfig_list
+       default "arch/$ARCH/defconfig"
+
 # UML uses the generic IRQ sugsystem
 config GENERIC_HARDIRQS
        bool
@@ -25,6 +30,19 @@ config PCI
 config PCMCIA
        bool
 
+# Yet to do!
+config TRACE_IRQFLAGS_SUPPORT
+       bool
+       default n
+
+config LOCKDEP_SUPPORT
+       bool
+       default y
+
+config STACKTRACE_SUPPORT
+       bool
+       default y
+
 config GENERIC_CALIBRATE_DELAY
        bool
        default y
@@ -37,13 +55,16 @@ config IRQ_RELEASE_METHOD
 menu "UML-specific options"
 
 config MODE_TT
-       bool "Tracing thread support"
+       bool "Tracing thread support (DEPRECATED)"
        default n
+       depends on BROKEN
        help
        This option controls whether tracing thread support is compiled
-       into UML.  This option is largely obsolete, given that skas0 provides
+       into UML. This option is largely obsolete, given that skas0 provides
        skas security and performance without needing to patch the host.
-       It is safe to say 'N' here.
+       It is safe to say 'N' here; saying 'Y' may cause additional problems
+       with the resulting binary even if you run UML in SKAS mode, and running
+       in TT mode is strongly *NOT RECOMMENDED*.
 
 config STATIC_LINK
        bool "Force a static link"
@@ -56,6 +77,9 @@ config STATIC_LINK
        for use in a chroot jail.  So, if you intend to run UML inside a
        chroot, and you disable CONFIG_MODE_TT, you probably want to say Y
        here.
+       Additionally, this option enables using higher memory spaces (up to
+       2.75G) for UML - disabling CONFIG_MODE_TT and enabling this option leads
+       to best results for this.
 
 config KERNEL_HALF_GIGS
        int "Kernel address space size (in .5G units)"
@@ -72,10 +96,13 @@ config MODE_SKAS
        default y
        help
        This option controls whether skas (separate kernel address space)
-       support is compiled in.  If you have applied the skas patch to the
-       host, then you certainly want to say Y here (and consider saying N
-       to CONFIG_MODE_TT).  Otherwise, it is safe to say Y.  Disabling this
-       option will shrink the UML binary slightly.
+       support is compiled in.
+       Unless you have specific needs to use TT mode (which applies almost only
+       to developers), you should say Y here.
+       SKAS mode will make use of the SKAS3 patch if it is applied on the host
+       (and your UML will run in SKAS3 mode), but if no SKAS patch is applied
+       on the host it will run in SKAS0 mode, which is anyway faster than TT
+       mode.
 
 source "arch/um/Kconfig.arch"
 source "mm/Kconfig"
index 62d87b71179b5b63497d6183c6b2f3c66c994fc1..e03e40c7aac35472e5139152a2158b0285c76bd8 100644 (file)
@@ -190,6 +190,11 @@ config HOSTAUDIO
        tristate
        default UML_SOUND
 
+#It is selected elsewhere, so kconfig would warn without this.
+config HW_RANDOM
+       tristate
+       default n
+
 config UML_RANDOM
        tristate "Hardware random number generator"
        help
index f6eb72d117b9e182d059fc7013a3bc1b596ebaaa..f191a550a079cc0b8340f69a67dffa5e33dd85a6 100644 (file)
@@ -16,23 +16,42 @@ config SEMAPHORE_SLEEPERS
        bool
        default y
 
-config HOST_2G_2G
-       bool "2G/2G host address space split"
-       default n
-       help
-       This is needed when the host on which you run has a 2G/2G memory
-       split, instead of the customary 3G/1G.
-
-       Note that to enable such a host
-       configuration, which makes sense only in some cases, you need special
-       host patches.
-
-       So, if you do not know what to do here, say 'N'.
+choice
+       prompt "Host memory split"
+       default HOST_VMSPLIT_3G
+       ---help---
+          This is needed when the host kernel on which you run has a non-default
+          (like 2G/2G) memory split, instead of the customary 3G/1G. If you did
+          not recompile your own kernel but use the default distro's one, you can
+          safely accept the "Default split" option.
+
+          It can be enabled on recent (>=2.6.16-rc2) vanilla kernels via
+          CONFIG_VM_SPLIT_*, or on previous kernels with special patches (-ck
+          patchset by Con Kolivas, or other ones) - option names match closely the
+          host CONFIG_VM_SPLIT_* ones.
+
+          A lower setting (where 1G/3G is lowest and 3G/1G is higher) will
+          tolerate even more "normal" host kernels, but an higher setting will be
+          stricter.
+
+          So, if you do not know what to do here, say 'Default split'.
+
+       config HOST_VMSPLIT_3G
+               bool "Default split (3G/1G user/kernel host split)"
+       config HOST_VMSPLIT_3G_OPT
+               bool "3G/1G user/kernel host split (for full 1G low memory)"
+       config HOST_VMSPLIT_2G
+               bool "2G/2G user/kernel host split"
+       config HOST_VMSPLIT_1G
+               bool "1G/3G user/kernel host split"
+endchoice
 
 config TOP_ADDR
-       hex
-       default 0xc0000000 if !HOST_2G_2G
-       default 0x80000000 if HOST_2G_2G
+       hex
+       default 0xB0000000 if HOST_VMSPLIT_3G_OPT
+       default 0x78000000 if HOST_VMSPLIT_2G
+       default 0x40000000 if HOST_VMSPLIT_1G
+       default 0xC0000000
 
 config 3_LEVEL_PGTABLES
        bool "Three-level pagetables (EXPERIMENTAL)"
index 11154b6773ec230302341d8889e79601677b47c1..d278682dd799dc51e47cad1341c62f34bae58e19 100644 (file)
@@ -1,10 +1,10 @@
 # Copyright 2003 - 2004 Pathscale, Inc
 # Released under the GPL
 
-core-y += arch/um/sys-x86_64/
+core-y += arch/um/sys-x86_64/ arch/x86_64/crypto/
 START := 0x60000000
 
-_extra_flags_ = -fno-builtin -m64 -mcmodel=kernel
+_extra_flags_ = -fno-builtin -m64
 
 #We #undef __x86_64__ for kernelspace, not for userspace where
 #it's needed for headers to work!
index 7a5b4afde6929474f8422ab681076dd430ebaed1..c6a308464acb600f3705c4e3a6e0c9fa9c848430 100644 (file)
@@ -5,6 +5,7 @@
 #include "user_util.h"
 #include "os.h"
 #include "user.h"
+#include "um_malloc.h"
 
 static inline void *cow_malloc(int size)
 {
index 77954ea77043796217b22f83e3ef0d9d3b8c7c14..310af0f1e49e4a7fa2b78609ed5e46c200cba721 100644 (file)
@@ -17,6 +17,7 @@
 #include "user_util.h"
 #include "user.h"
 #include "os.h"
+#include "um_malloc.h"
 
 #define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
 
index 108b7dafbd0e99a6d0cf9a9d82ca26ed6d1ac5f1..218aa0e9b792b6f0351e084f8640e472ecdf5c9f 100644 (file)
@@ -12,6 +12,7 @@
 #include "user_util.h"
 #include "chan_user.h"
 #include "os.h"
+#include "um_malloc.h"
 
 struct fd_chan {
        int fd;
index cfd9f01fd46456dab0f1a37a742a83df1876282b..426633e5d6e387cc43604557751a6ca641dcbdc1 100644 (file)
@@ -20,7 +20,7 @@
 
 #define LINE_BUFSIZE 4096
 
-static irqreturn_t line_interrupt(int irq, void *data, struct pt_regs *unused)
+static irqreturn_t line_interrupt(int irq, void *data)
 {
        struct chan *chan = data;
        struct line *line = chan->line;
@@ -364,8 +364,7 @@ void line_unthrottle(struct tty_struct *tty)
                reactivate_chan(&line->chan_list, line->driver->read_irq);
 }
 
-static irqreturn_t line_write_interrupt(int irq, void *data,
-                                       struct pt_regs *unused)
+static irqreturn_t line_write_interrupt(int irq, void *data)
 {
        struct chan *chan = data;
        struct line *line = chan->line;
@@ -712,7 +711,7 @@ struct winch {
        struct tty_struct *tty;
 };
 
-static irqreturn_t winch_interrupt(int irq, void *data, struct pt_regs *unused)
+static irqreturn_t winch_interrupt(int irq, void *data)
 {
        struct winch *winch = data;
        struct tty_struct *tty;
index 4d2bd39a85bc16ff7dc685b908dad366fa82cac0..8138f5ea1bf7516272de7b086ead9ca8295306ea 100644 (file)
@@ -23,6 +23,7 @@
 #include "user_util.h"
 #include "user.h"
 #include "os.h"
+#include "um_malloc.h"
 
 #define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
 
index a67dcbd78de4765c7f7f54d7f907cfd01449c2c3..d08bd036ccb84268aaab9ad386849ab28b5ffc53 100644 (file)
@@ -74,8 +74,7 @@ static void mc_work_proc(void *unused)
 
 static DECLARE_WORK(mconsole_work, mc_work_proc, NULL);
 
-static irqreturn_t mconsole_interrupt(int irq, void *dev_id,
-                                     struct pt_regs *regs)
+static irqreturn_t mconsole_interrupt(int irq, void *dev_id)
 {
        /* long to avoid size mismatch warnings from gcc */
        long fd;
@@ -674,8 +673,9 @@ static void with_console(struct mc_request *req, void (*proc)(void *),
 static void sysrq_proc(void *arg)
 {
        char *op = arg;
-
-       handle_sysrq(*op, &current->thread.regs, NULL);
+       struct pt_regs *old_regs = set_irq_regs(&current->thread.regs);
+       handle_sysrq(*op, NULL);
+       set_irq_regs(old_regs);
 }
 
 void mconsole_sysrq(struct mc_request *req)
index 9a3b5daf6250784c1359f8997e115eac3ab8f29b..df3516e47d4d534bae0f10022717cff6bc541297 100644 (file)
@@ -95,7 +95,8 @@ static const struct file_operations mmapper_fops = {
        .release        = mmapper_release,
 };
 
-static const struct miscdevice mmapper_dev = {
+/* No locking needed - only used (and modified) by below initcall and exitcall. */
+static struct miscdevice mmapper_dev = {
        .minor          = MISC_DYNAMIC_MINOR,
        .name           = "mmapper",
        .fops           = &mmapper_fops
index c1c5604752fb20dada9f293393f3a8e32c4e0520..ec9eb8bd9432dd31a89827aaca985fd88d082668 100644 (file)
@@ -77,7 +77,7 @@ static void uml_dev_close(void* dev)
        dev_close( (struct net_device *) dev);
 }
 
-irqreturn_t uml_net_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t uml_net_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
        struct uml_net_private *lp = dev->priv;
index f3a3f8a29c7af877d327692f2f30f89a7ef6f081..0ffd7ac295d45e0fd5bdc0e4e8c36eab42c517cd 100644 (file)
@@ -18,6 +18,7 @@
 #include "kern_util.h"
 #include "net_user.h"
 #include "os.h"
+#include "um_malloc.h"
 
 int tap_open_common(void *dev, char *gate_addr)
 {
index 2ef641ded960a96670456b5d2f1b56914a689c42..11921a7baa7b14066d2c2f7d7f653063535e516e 100644 (file)
@@ -12,6 +12,7 @@
 #include "net_user.h"
 #include "pcap_user.h"
 #include "user.h"
+#include "um_malloc.h"
 
 #define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
 
index 58f9f6a1420feb34405642fd4c607c71647b0701..96b80b565eeb7950296d3633b85df8a8eeb7b16b 100644 (file)
@@ -15,7 +15,7 @@ struct pcap_data {
        void *dev;
 };
 
-extern struct net_user_info pcap_user_info;
+extern const struct net_user_info pcap_user_info;
 
 extern int pcap_user_read(int fd, void *buf, int len, struct pcap_data *pri);
 
index 73755f37a8a8409df2c43f0825ababd61a15c08d..ce9f3733f73ee1a5a3f5b5c5518a06d5af685218 100644 (file)
@@ -47,7 +47,7 @@ struct connection {
        struct port_list *port;
 };
 
-static irqreturn_t pipe_interrupt(int irq, void *data, struct pt_regs *regs)
+static irqreturn_t pipe_interrupt(int irq, void *data)
 {
        struct connection *conn = data;
        int fd;
@@ -152,7 +152,7 @@ void port_work_proc(void *unused)
 
 DECLARE_WORK(port_work, port_work_proc, NULL);
 
-static irqreturn_t port_interrupt(int irq, void *data, struct pt_regs *regs)
+static irqreturn_t port_interrupt(int irq, void *data)
 {
        struct port_list *port = data;
 
index f2e8fc42ecc2df4a2ec7bfe247ab7ec12fe1659c..bc6afaf74c1a8123ace69f94c5d2d9a340bc6347 100644 (file)
@@ -19,6 +19,7 @@
 #include "chan_user.h"
 #include "port.h"
 #include "os.h"
+#include "um_malloc.h"
 
 struct port_chan {
        int raw;
index abec620e838030d43e7a01626cb82c5c041ed63f..829a5eca8c07606b9b44ea393df4e4f32b94fd99 100644 (file)
@@ -13,6 +13,7 @@
 #include "user_util.h"
 #include "kern_util.h"
 #include "os.h"
+#include "um_malloc.h"
 
 struct pty_chan {
        void (*announce)(char *dev_name, int dev);
index 8460285c69a5cea3e0b842d0b5cd792d84c38aef..7eddacc53b6ec2168a581685b4e11bf6523eeedf 100644 (file)
@@ -15,6 +15,7 @@
 #include "slip.h"
 #include "slip_common.h"
 #include "os.h"
+#include "um_malloc.h"
 
 void slip_user_init(void *data, void *dev)
 {
index 11de3ac1eb5c787512b4c1a71f6ac1a16cd6725b..d95d64309eaf3defc373ba6195a0b5fc03cbea45 100644 (file)
@@ -11,6 +11,7 @@
 #include "user_util.h"
 #include "user.h"
 #include "os.h"
+#include "um_malloc.h"
 
 struct tty_chan {
        char *dev;
index f0b0668458b76e8967853c260a5aefb5385f13fd..bc458f57921b0f232d0f078bc5014424281e8617 100644 (file)
@@ -524,7 +524,7 @@ static void ubd_handler(void)
        do_ubd_request(ubd_queue);
 }
 
-static irqreturn_t ubd_intr(int irq, void *dev, struct pt_regs *unused)
+static irqreturn_t ubd_intr(int irq, void *dev)
 {
        ubd_handler();
        return(IRQ_HANDLED);
index 386f8b952982e4317f5254e4016a2e7ba18597d1..850221d9b4c953306d87817bfd455551dc4aee67 100644 (file)
@@ -136,8 +136,6 @@ int xterm_open(int input, int output, int primary, void *d,
                return(pid);
        }
 
-       if(data->stack == 0) free_stack(stack, 0);
-
        if (data->direct_rcv) {
                new = os_rcv_fd(fd, &data->helper_pid);
        } else {
index 6036ec85895aef434ca1bb615945aa268f528405..a4ce7058e10e7c360fd0f72f049d6183530dc4eb 100644 (file)
@@ -21,7 +21,7 @@ struct xterm_wait {
        int new_fd;
 };
 
-static irqreturn_t xterm_interrupt(int irq, void *data, struct pt_regs *regs)
+static irqreturn_t xterm_interrupt(int irq, void *data)
 {
        struct xterm_wait *xterm = data;
        int fd;
index 356390d1f8b945dbedbb3ce11475fdb309b95926..461175f8b1d9da4b4c14f21616ea4ec2016e1409 100644 (file)
@@ -1,9 +1,16 @@
 /* for use by sys-$SUBARCH/kernel-offsets.c */
 
+DEFINE(KERNEL_MADV_REMOVE, MADV_REMOVE);
+#ifdef CONFIG_MODE_TT
+OFFSET(HOST_TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid);
+#endif
+
 OFFSET(HOST_TASK_REGS, task_struct, thread.regs);
 OFFSET(HOST_TASK_PID, task_struct, pid);
+
 DEFINE(UM_KERN_PAGE_SIZE, PAGE_SIZE);
 DEFINE(UM_NSEC_PER_SEC, NSEC_PER_SEC);
+
 DEFINE_STR(UM_KERN_EMERG, KERN_EMERG);
 DEFINE_STR(UM_KERN_ALERT, KERN_ALERT);
 DEFINE_STR(UM_KERN_CRIT, KERN_CRIT);
@@ -12,6 +19,10 @@ DEFINE_STR(UM_KERN_WARNING, KERN_WARNING);
 DEFINE_STR(UM_KERN_NOTICE, KERN_NOTICE);
 DEFINE_STR(UM_KERN_INFO, KERN_INFO);
 DEFINE_STR(UM_KERN_DEBUG, KERN_DEBUG);
+
 DEFINE(UM_ELF_CLASS, ELF_CLASS);
 DEFINE(UM_ELFCLASS32, ELFCLASS32);
 DEFINE(UM_ELFCLASS64, ELFCLASS64);
+
+/* For crypto assembler code. */
+DEFINE(crypto_tfm_ctx_offset, offsetof(struct crypto_tfm, __crt_ctx));
index c222d56b14940192c9a1b8eb659e8c966a4fb656..4f775597fd5fa3bed63890a8b752f8705f265367 100644 (file)
 #include "asm/ptrace.h"
 
 extern int um_request_irq(unsigned int irq, int fd, int type,
-                         irqreturn_t (*handler)(int, void *,
-                                                struct pt_regs *),
+                         irq_handler_t handler,
                          unsigned long irqflags,  const char * devname,
                          void *dev_id);
 extern int init_aio_irq(int irq, char *name,
-                       irqreturn_t (*handler)(int, void *, struct pt_regs *));
+                       irq_handler_t handler);
 
 #endif
 
index 59cfa9e0cad034739c3add89720269c01f0177c2..cec9fcc57bf51f5169cbee6cf7fdc6f60555d5f8 100644 (file)
@@ -6,7 +6,6 @@
 #ifndef __KERN_UTIL_H__
 #define __KERN_UTIL_H__
 
-#include "linux/threads.h"
 #include "sysdep/ptrace.h"
 #include "sysdep/faultinfo.h"
 
index e93c6d3e893b05c3ca17a9ce78ad91334f2d55cd..e860bc5848e0aaff10b382f185aed8b5a4acd81e 100644 (file)
@@ -12,7 +12,8 @@ extern void longjmp(jmp_buf, int);
 } while(0)
 
 #define UML_SETJMP(buf) ({ \
-       int n, enable;     \
+       int n;     \
+       volatile int enable;    \
        enable = get_signals(); \
        n = setjmp(*buf); \
        if(n != 0) \
index 120ca21a513a03853a38abf2004a35a1d0b4b173..6516f6dca96d35b036a7632cc668418e44468bf2 100644 (file)
@@ -201,6 +201,7 @@ extern int os_getpgrp(void);
 
 #ifdef UML_CONFIG_MODE_TT
 extern void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int));
+extern void stop(void);
 #endif
 extern void init_new_thread_signals(void);
 extern int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr);
index 2c13de321f2fb330eb5dc162fe53bffca57f3bad..97ec9d894d7539a7ef61c08b4196b01b547d6e91 100644 (file)
@@ -1,6 +1,7 @@
 #include <linux/stddef.h>
 #include <linux/sched.h>
 #include <linux/elf.h>
+#include <linux/crypto.h>
 #include <asm/mman.h>
 
 #define DEFINE(sym, val) \
@@ -17,9 +18,5 @@
 void foo(void)
 {
        OFFSET(HOST_TASK_DEBUGREGS, task_struct, thread.arch.debugregs);
-       DEFINE(KERNEL_MADV_REMOVE, MADV_REMOVE);
-#ifdef CONFIG_MODE_TT
-       OFFSET(HOST_TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid);
-#endif
 #include <common-offsets.h>
 }
index 91d129fb39308cc57771ca71d2465ecc1a07553d..a307237b7964394189e220673c160bddf08a6227 100644 (file)
@@ -2,6 +2,7 @@
 #include <linux/sched.h>
 #include <linux/time.h>
 #include <linux/elf.h>
+#include <linux/crypto.h>
 #include <asm/page.h>
 #include <asm/mman.h>
 
@@ -18,9 +19,5 @@
 
 void foo(void)
 {
-       DEFINE(KERNEL_MADV_REMOVE, MADV_REMOVE);
-#ifdef CONFIG_MODE_TT
-       OFFSET(HOST_TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid);
-#endif
 #include <common-offsets.h>
 }
diff --git a/arch/um/include/um_malloc.h b/arch/um/include/um_malloc.h
new file mode 100644 (file)
index 0000000..0363a9b
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2005 Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
+ * Licensed under the GPL
+ */
+
+#ifndef __UM_MALLOC_H__
+#define __UM_MALLOC_H__
+
+extern void *um_kmalloc(int size);
+extern void *um_kmalloc_atomic(int size);
+extern void kfree(const void *ptr);
+
+extern void *um_vmalloc(int size);
+extern void *um_vmalloc_atomic(int size);
+extern void vfree(void *ptr);
+
+#endif /* __UM_MALLOC_H__ */
index 39f8c8801076351de6b0c2cfc3d7b070a2c7dba4..acadce3f271f05d2833790c82922140b539d4dc4 100644 (file)
@@ -11,17 +11,11 @@ extern void panic(const char *fmt, ...)
 extern int printk(const char *fmt, ...)
        __attribute__ ((format (printf, 1, 2)));
 extern void schedule(void);
-extern void *um_kmalloc(int size);
-extern void *um_kmalloc_atomic(int size);
-extern void kfree(void *ptr);
 extern int in_aton(char *str);
 extern int open_gdb_chan(void);
 /* These use size_t, however unsigned long is correct on both i386 and x86_64. */
 extern unsigned long strlcpy(char *, const char *, unsigned long);
 extern unsigned long strlcat(char *, const char *, unsigned long);
-extern void *um_vmalloc(int size);
-extern void *um_vmalloc_atomic(int size);
-extern void vfree(void *ptr);
 
 #endif
 
index 802d7842514d25ad63b5be204a573363a6992b60..06625fefef3387b2aac94471361cf59139042b34 100644 (file)
@@ -52,7 +52,6 @@ extern int linux_main(int argc, char **argv);
 extern void set_cmdline(char *cmd);
 extern void input_cb(void (*proc)(void *), void *arg, int arg_len);
 extern int get_pty(void);
-extern void *um_kmalloc(int size);
 extern int switcheroo(int fd, int prot, void *from, void *to, int size);
 extern void do_exec(int old_pid, int new_pid);
 extern void tracer_panic(char *msg, ...)
index eee97bb81ba54c3bd2d47acc5e94c17baf38ed95..5c1e611f628d548fed1716c75d5537c39d6b8cc4 100644 (file)
@@ -31,6 +31,7 @@
 #include "irq_kern.h"
 #include "os.h"
 #include "sigio.h"
+#include "um_malloc.h"
 #include "misc_constants.h"
 
 /*
@@ -355,14 +356,16 @@ void forward_interrupts(int pid)
  */
 unsigned int do_IRQ(int irq, union uml_pt_regs *regs)
 {
-       irq_enter();
-       __do_IRQ(irq, (struct pt_regs *)regs);
-       irq_exit();
-       return 1;
+       struct pt_regs *old_regs = set_irq_regs((struct pt_regs *)regs);
+       irq_enter();
+       __do_IRQ(irq);
+       irq_exit();
+       set_irq_regs(old_regs);
+       return 1;
 }
 
 int um_request_irq(unsigned int irq, int fd, int type,
-                  irqreturn_t (*handler)(int, void *, struct pt_regs *),
+                  irq_handler_t handler,
                   unsigned long irqflags, const char * devname,
                   void *dev_id)
 {
@@ -423,8 +426,7 @@ void __init init_IRQ(void)
        }
 }
 
-int init_aio_irq(int irq, char *name, irqreturn_t (*handler)(int, void *,
-                                                            struct pt_regs *))
+int init_aio_irq(int irq, char *name, irq_handler_t handler)
 {
        int fds[2], err;
 
index fe6c64abda5b029d3f3b1c2a2b891471cf52f3c2..348b272bb766a5305f54ba3d35874b5b3caa45e6 100644 (file)
@@ -46,6 +46,7 @@
 #include "mode.h"
 #include "mode_kern.h"
 #include "choose-mode.h"
+#include "um_malloc.h"
 
 /* This is a per-cpu array.  A processor only modifies its entry and it only
  * cares about its entry, so it's OK if another processor is modifying its
index 0ad755ceb212e80a0b6684f69e4b894ff15c39dd..2b0ab438301c8bae8f8f4c3a6fe951b71f72e1dd 100644 (file)
@@ -17,7 +17,7 @@
 /* Protected by sigio_lock() called from write_sigio_workaround */
 static int sigio_irq_fd = -1;
 
-static irqreturn_t sigio_interrupt(int irq, void *data, struct pt_regs *unused)
+static irqreturn_t sigio_interrupt(int irq, void *data)
 {
        char c;
 
index c17eddcf89b3ce8ab627cbdad0f2574cdd3035cb..2c6d090a2e872b11d891c2510a1e4f55ef52dd17 100644 (file)
@@ -60,10 +60,7 @@ static int init_stub_pte(struct mm_struct *mm, unsigned long proc,
 #endif
 
        *pte = mk_pte(virt_to_page(kernel), __pgprot(_PAGE_PRESENT));
-       /* This is wrong for the code page, but it doesn't matter since the
-        * stub is mapped by hand with the correct permissions.
-        */
-       *pte = pte_mkwrite(*pte);
+       *pte = pte_mkread(*pte);
        return(0);
 
  out_pmd:
index a92965f8f9cdd57d600e229e136dee8fafa64d5a..2e354b3ca060649bb0cbd8afef6633637dc357a8 100644 (file)
@@ -86,7 +86,7 @@ static inline unsigned long long get_time(void)
        return nsecs;
 }
 
-irqreturn_t um_timer(int irq, void *dev, struct pt_regs *regs)
+irqreturn_t um_timer(int irq, void *dev)
 {
        unsigned long long nsecs;
        unsigned long flags;
index 6c92bbccb49c30658295c9ea226258ce62c3b5af..ed1abcf4d0576584e78e9df965f803ef5030c054 100644 (file)
@@ -4,13 +4,13 @@
  * Licensed under the GPL
  */
 
-#include <setjmp.h>
 #include <string.h>
 #include "user_util.h"
 #include "uml_uaccess.h"
 #include "task.h"
 #include "kern_util.h"
 #include "os.h"
+#include "longjmp.h"
 
 int __do_copy_from_user(void *to, const void *from, int n,
                        void **fault_addr, void **fault_catcher)
@@ -80,10 +80,10 @@ int __do_strnlen_user(const char *str, unsigned long n,
        struct tt_regs save = TASK_REGS(get_current())->tt;
        int ret;
        unsigned long *faddrp = (unsigned long *)fault_addr;
-       sigjmp_buf jbuf;
+       jmp_buf jbuf;
 
        *fault_catcher = &jbuf;
-       if(sigsetjmp(jbuf, 1) == 0)
+       if(UML_SETJMP(&jbuf) == 0)
                ret = strlen(str) + 1;
        else ret = *faddrp - (unsigned long) str;
 
index f559bdf746e6099bfb7593215ded118626a899df..863981ba14687684ab8bcbae3d7606945468afeb 100644 (file)
@@ -20,6 +20,7 @@
 #include "net_user.h"
 #include "etap.h"
 #include "os.h"
+#include "um_malloc.h"
 
 #define MAX_PACKET ETH_MAX_PACKET
 
index cd15b9df5b5c1a195eae1f34439a0d4004636786..d13299cfa31878e6b725e3ad86d5ac9fdd50922d 100644 (file)
@@ -35,22 +35,23 @@ static int helper_child(void *arg)
        char **argv = data->argv;
        int errval;
 
-       if(helper_pause){
+       if (helper_pause){
                signal(SIGHUP, helper_hup);
                pause();
        }
-       if(data->pre_exec != NULL)
+       if (data->pre_exec != NULL)
                (*data->pre_exec)(data->pre_data);
        execvp(argv[0], argv);
        errval = -errno;
        printk("helper_child - execve of '%s' failed - errno = %d\n", argv[0], errno);
        os_write_file(data->fd, &errval, sizeof(errval));
        kill(os_getpid(), SIGKILL);
-       return(0);
+       return 0;
 }
 
 /* Returns either the pid of the child process we run or -E* on failure.
- * XXX The alloc_stack here breaks if this is called in the tracing thread */
+ * XXX The alloc_stack here breaks if this is called in the tracing thread, so
+ * we need to receive a preallocated stack (a local buffer is ok). */
 int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
               unsigned long *stack_out)
 {
@@ -58,20 +59,21 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
        unsigned long stack, sp;
        int pid, fds[2], ret, n;
 
-       if((stack_out != NULL) && (*stack_out != 0))
+       if ((stack_out != NULL) && (*stack_out != 0))
                stack = *stack_out;
-       else stack = alloc_stack(0, __cant_sleep());
-       if(stack == 0)
+       else
+               stack = alloc_stack(0, __cant_sleep());
+       if (stack == 0)
                return -ENOMEM;
 
        ret = os_pipe(fds, 1, 0);
-       if(ret < 0){
+       if (ret < 0) {
                printk("run_helper : pipe failed, ret = %d\n", -ret);
                goto out_free;
        }
 
        ret = os_set_exec_close(fds[1], 1);
-       if(ret < 0){
+       if (ret < 0) {
                printk("run_helper : setting FD_CLOEXEC failed, ret = %d\n",
                       -ret);
                goto out_close;
@@ -83,7 +85,7 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
        data.argv = argv;
        data.fd = fds[1];
        pid = clone(helper_child, (void *) sp, CLONE_VM | SIGCHLD, &data);
-       if(pid < 0){
+       if (pid < 0) {
                ret = -errno;
                printk("run_helper : clone failed, errno = %d\n", errno);
                goto out_close;
@@ -95,10 +97,10 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
        /* Read the errno value from the child, if the exec failed, or get 0 if
         * the exec succeeded because the pipe fd was set as close-on-exec. */
        n = os_read_file(fds[0], &ret, sizeof(ret));
-       if(n == 0)
+       if (n == 0) {
                ret = pid;
-       else {
-               if(n < 0){
+       else {
+               if (n < 0) {
                        printk("run_helper : read on pipe failed, ret = %d\n",
                               -n);
                        ret = n;
@@ -112,10 +114,9 @@ out_close:
                close(fds[1]);
        close(fds[0]);
 out_free:
-       if(stack_out == NULL)
+       if ((stack_out == NULL) || (*stack_out == 0))
                free_stack(stack, 0);
-       else *stack_out = stack;
-       return(ret);
+       return ret;
 }
 
 int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags,
@@ -125,31 +126,32 @@ int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags,
        int pid, status, err;
 
        stack = alloc_stack(stack_order, __cant_sleep());
-       if(stack == 0) return(-ENOMEM);
+       if (stack == 0)
+               return -ENOMEM;
 
        sp = stack + (page_size() << stack_order) - sizeof(void *);
        pid = clone(proc, (void *) sp, flags | SIGCHLD, arg);
-       if(pid < 0){
+       if (pid < 0) {
                err = -errno;
                printk("run_helper_thread : clone failed, errno = %d\n",
                       errno);
                return err;
        }
-       if(stack_out == NULL){
+       if (stack_out == NULL) {
                CATCH_EINTR(pid = waitpid(pid, &status, 0));
-               if(pid < 0){
+               if (pid < 0) {
                        err = -errno;
                        printk("run_helper_thread - wait failed, errno = %d\n",
                               errno);
                        pid = err;
                }
-               if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0))
+               if (!WIFEXITED(status) || (WEXITSTATUS(status) != 0))
                        printk("run_helper_thread - thread returned status "
                               "0x%x\n", status);
                free_stack(stack, stack_order);
-       }
-       else *stack_out = stack;
-       return(pid);
+       } else
+               *stack_out = stack;
+       return pid;
 }
 
 int helper_wait(int pid)
@@ -157,9 +159,9 @@ int helper_wait(int pid)
        int ret;
 
        CATCH_EINTR(ret = waitpid(pid, NULL, WNOHANG));
-       if(ret < 0){
+       if (ret < 0) {
                ret = -errno;
                printk("helper_wait : waitpid failed, errno = %d\n", errno);
        }
-       return(ret);
+       return ret;
 }
index a97206df5b52068ffe20b3b0979653c4e384d28b..d46b818c1311258934679b82fdd0685afeaecbca 100644 (file)
@@ -18,6 +18,7 @@
 #include "sigio.h"
 #include "irq_user.h"
 #include "os.h"
+#include "um_malloc.h"
 
 static struct pollfd *pollfds = NULL;
 static int pollfds_num = 0;
index d1c5670787dca8edb9ad9b6aede68e22c6e24cd4..685feaab65d239efa4931af9838e63b54f62d702 100644 (file)
@@ -23,6 +23,7 @@
 #include "choose-mode.h"
 #include "uml-config.h"
 #include "os.h"
+#include "um_malloc.h"
 
 /* Set in set_stklim, which is called from main and __wrap_malloc.
  * __wrap_malloc only calls it if main hasn't started.
index f6457765b17db86c7b03c3879e11e8f1da16934b..925a65240cfec96c0f6c424e6009bf24a2012f90 100644 (file)
@@ -19,6 +19,7 @@
 #include "user_util.h"
 #include "sigio.h"
 #include "os.h"
+#include "um_malloc.h"
 
 /* Protected by sigio_lock(), also used by sigio_cleanup, which is an
  * exitcall.
index 38be096e750f0ec98d4887275f9f48abc274be3b..2115b8beb54167ffe9c522a5fbe6727b1e547137 100644 (file)
@@ -16,6 +16,7 @@
 #include "process.h"
 #include "kern_constants.h"
 #include "os.h"
+#include "uml-config.h"
 
 int set_interval(int is_virtual)
 {
@@ -30,7 +31,7 @@ int set_interval(int is_virtual)
        return 0;
 }
 
-#ifdef CONFIG_MODE_TT
+#ifdef UML_CONFIG_MODE_TT
 void enable_timer(void)
 {
        set_interval(1);
index 5461a065bbb924104dbb395538a6675cbfd9f4e1..3dc3a02d626318ba0337c8471237387099df5729 100644 (file)
@@ -10,7 +10,6 @@
 #include <errno.h>
 #include <stdarg.h>
 #include <stdlib.h>
-#include <setjmp.h>
 #include <sys/time.h>
 #include <sys/ptrace.h>
 #include <linux/ptrace.h>
index 3f5b1514e8a71a33513ccf613643fcb2e33fed5c..56b8a50e8bc2e08c3bfa5b7661b954599f5c6cee 100644 (file)
@@ -80,11 +80,18 @@ void setup_machinename(char *machine_out)
        struct utsname host;
 
        uname(&host);
-#if defined(UML_CONFIG_UML_X86) && !defined(UML_CONFIG_64BIT)
+#ifdef UML_CONFIG_UML_X86
+# ifndef UML_CONFIG_64BIT
        if (!strcmp(host.machine, "x86_64")) {
                strcpy(machine_out, "i686");
                return;
        }
+# else
+       if (!strcmp(host.machine, "i686")) {
+               strcpy(machine_out, "x86_64");
+               return;
+       }
+# endif
 #endif
        strcpy(machine_out, host.machine);
 }
index 8592738082038b0b8d500408fcc0e616793e457e..12c593607c5943666b51d7c71e392299823aec48 100644 (file)
@@ -14,6 +14,3 @@ EXPORT_SYMBOL(__up_wakeup);
 
 /*XXX: we need them because they would be exported by x86_64 */
 EXPORT_SYMBOL(__memcpy);
-
-/* Networking helper routines. */
-EXPORT_SYMBOL(ip_compute_csum);
index 1c967026c957dd08e4b81406a82712b60ada8ee6..652fa34c2cd3d3f0a3f7a8074cfb4ca890e56488 100644 (file)
@@ -5,7 +5,6 @@
 
 #include <stddef.h>
 #include <signal.h>
-#include <linux/compiler.h>
 #include <asm/unistd.h>
 #include "uml-config.h"
 #include "sysdep/sigcontext.h"
index 1c0f18d4f887a574734df7b6302ef8c362b8533d..13972148058dac9cae6c7e2829bf4c5b73b78bd9 100644 (file)
@@ -54,6 +54,10 @@ endif
 cflags-y += $(call cc-option,-funit-at-a-time)
 # prevent gcc from generating any FP code by mistake
 cflags-y += $(call cc-option,-mno-sse -mno-mmx -mno-sse2 -mno-3dnow,)
+# this works around some issues with generating unwind tables in older gccs
+# newer gccs do it by default
+cflags-y += -maccumulate-outgoing-args
+
 # do binutils support CFI?
 cflags-y += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
 AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
index 4844b543bed0b8c4d697f64910ec7c550c922a11..0f5d44e86be56d8b3f61a2f204d24a720b6ef92d 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18-git7
-# Wed Sep 27 21:53:10 2006
+# Linux kernel version: 2.6.19-rc2-git4
+# Sat Oct 21 03:38:52 2006
 #
 CONFIG_X86_64=y
 CONFIG_64BIT=y
@@ -19,6 +19,7 @@ CONFIG_EARLY_PRINTK=y
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_GENERIC_IOMAP=y
 CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_DMI=y
 CONFIG_AUDIT_ARCH=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -37,9 +38,11 @@ CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
 CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
@@ -47,9 +50,10 @@ CONFIG_IKCONFIG_PROC=y
 # CONFIG_RELAY is not set
 CONFIG_INITRAMFS_SOURCE=""
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
 # CONFIG_EMBEDDED is not set
 CONFIG_UID16=y
-CONFIG_SYSCTL=y
+# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -82,6 +86,7 @@ CONFIG_STOP_MACHINE=y
 #
 # Block layer
 #
+CONFIG_BLOCK=y
 CONFIG_LBD=y
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
@@ -252,9 +257,11 @@ CONFIG_PCI=y
 CONFIG_PCI_DIRECT=y
 CONFIG_PCI_MMCONFIG=y
 CONFIG_PCIEPORTBUS=y
+CONFIG_PCIEAER=y
 CONFIG_PCI_MSI=y
 # CONFIG_PCI_MULTITHREAD_PROBE is not set
 # CONFIG_PCI_DEBUG is not set
+# CONFIG_HT_IRQ is not set
 
 #
 # PCCARD (PCMCIA/CardBus) support
@@ -309,6 +316,7 @@ CONFIG_IP_PNP_DHCP=y
 # CONFIG_INET_TUNNEL is not set
 # CONFIG_INET_XFRM_MODE_TRANSPORT is not set
 # CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
@@ -325,9 +333,10 @@ CONFIG_IPV6=y
 # CONFIG_INET6_TUNNEL is not set
 # CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
 # CONFIG_INET6_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_BEET is not set
 # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=y
 # CONFIG_IPV6_TUNNEL is not set
-# CONFIG_IPV6_SUBTREES is not set
 # CONFIG_IPV6_MULTIPLE_TABLES is not set
 # CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
@@ -428,6 +437,13 @@ CONFIG_BLK_DEV_INITRD=y
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
 
+#
+# Misc devices
+#
+# CONFIG_IBM_ASM is not set
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+
 #
 # ATA/ATAPI/MFM/RLL support
 #
@@ -473,6 +489,7 @@ CONFIG_BLK_DEV_ATIIXP=y
 # CONFIG_BLK_DEV_CS5530 is not set
 # CONFIG_BLK_DEV_HPT34X is not set
 # CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_JMICRON is not set
 # CONFIG_BLK_DEV_SC1200 is not set
 CONFIG_BLK_DEV_PIIX=y
 # CONFIG_BLK_DEV_IT821X is not set
@@ -564,6 +581,7 @@ CONFIG_MEGARAID_SAS=y
 # CONFIG_SCSI_IPR is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
 # CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
 # CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
@@ -605,7 +623,6 @@ CONFIG_SATA_INTEL_COMBINED=y
 # CONFIG_PATA_HPT3X3 is not set
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_JMICRON is not set
-# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MPIIX is not set
 # CONFIG_PATA_OLDPIIX is not set
@@ -614,7 +631,6 @@ CONFIG_SATA_INTEL_COMBINED=y
 # CONFIG_PATA_OPTI is not set
 # CONFIG_PATA_OPTIDMA is not set
 # CONFIG_PATA_PDC_OLD is not set
-# CONFIG_PATA_QDI is not set
 # CONFIG_PATA_RADISYS is not set
 # CONFIG_PATA_RZ1000 is not set
 # CONFIG_PATA_SC1200 is not set
@@ -631,6 +647,7 @@ CONFIG_SATA_INTEL_COMBINED=y
 CONFIG_MD=y
 # CONFIG_BLK_DEV_MD is not set
 CONFIG_BLK_DEV_DM=y
+# CONFIG_DM_DEBUG is not set
 # CONFIG_DM_CRYPT is not set
 # CONFIG_DM_SNAPSHOT is not set
 # CONFIG_DM_MIRROR is not set
@@ -819,6 +836,7 @@ CONFIG_NET_POLL_CONTROLLER=y
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -841,6 +859,7 @@ CONFIG_KEYBOARD_ATKBD=y
 # CONFIG_KEYBOARD_LKKBD is not set
 # CONFIG_KEYBOARD_XTKBD is not set
 # CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
 CONFIG_INPUT_MOUSE=y
 CONFIG_MOUSE_PS2=y
 # CONFIG_MOUSE_SERIAL is not set
@@ -996,6 +1015,7 @@ CONFIG_I2C_ISA=m
 #
 # Dallas's 1-wire bus
 #
+# CONFIG_W1 is not set
 
 #
 # Hardware Monitoring support
@@ -1008,6 +1028,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1026 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_K8TEMP is not set
 # CONFIG_SENSORS_ASB100 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
@@ -1034,6 +1055,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 CONFIG_SENSORS_SMSC47B397=m
 # CONFIG_SENSORS_VIA686A is not set
+# CONFIG_SENSORS_VT1211 is not set
 # CONFIG_SENSORS_VT8231 is not set
 # CONFIG_SENSORS_W83781D is not set
 # CONFIG_SENSORS_W83791D is not set
@@ -1044,16 +1066,10 @@ CONFIG_SENSORS_SMSC47B397=m
 # CONFIG_SENSORS_HDAPS is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
 
-#
-# Misc devices
-#
-# CONFIG_IBM_ASM is not set
-
 #
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -1159,6 +1175,7 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_STORAGE_SDDR55 is not set
 # CONFIG_USB_STORAGE_JUMPSHOT is not set
 # CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_KARMA is not set
 # CONFIG_USB_LIBUSUAL is not set
 
 #
@@ -1212,6 +1229,7 @@ CONFIG_USB_MON=y
 #
 # CONFIG_USB_EMI62 is not set
 # CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
 # CONFIG_USB_AUERSWALD is not set
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
@@ -1219,12 +1237,13 @@ CONFIG_USB_MON=y
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGETKIT is not set
-# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_PHIDGET is not set
 # CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
 # CONFIG_USB_APPLEDISPLAY is not set
 # CONFIG_USB_SISUSBVGA is not set
 # CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
 # CONFIG_USB_TEST is not set
 
 #
@@ -1301,6 +1320,7 @@ CONFIG_EXT3_FS=y
 CONFIG_EXT3_FS_XATTR=y
 CONFIG_EXT3_FS_POSIX_ACL=y
 # CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4DEV_FS is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 CONFIG_FS_MBCACHE=y
@@ -1313,6 +1333,7 @@ CONFIG_REISERFS_FS_POSIX_ACL=y
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -1323,6 +1344,7 @@ CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
 CONFIG_AUTOFS4_FS=y
 # CONFIG_FUSE_FS is not set
+CONFIG_GENERIC_ACL=y
 
 #
 # CD-ROM/DVD Filesystems
@@ -1347,8 +1369,10 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
 CONFIG_HUGETLBFS=y
 CONFIG_HUGETLB_PAGE=y
 CONFIG_RAMFS=y
@@ -1482,11 +1506,14 @@ CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_DEBUG_INFO is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
 # CONFIG_FRAME_POINTER is not set
 CONFIG_UNWIND_INFO=y
 CONFIG_STACK_UNWIND=y
 # CONFIG_FORCED_INLINING is not set
+# CONFIG_HEADERS_CHECK is not set
 # CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_LKDTM is not set
 # CONFIG_DEBUG_RODATA is not set
 # CONFIG_IOMMU_DEBUG is not set
 CONFIG_DEBUG_STACKOVERFLOW=y
index d18198ed636b59d006bb3b87e68ea0bc50e87ff7..3a7561d4703e6cbd3ff85bc9137b665bed383858 100644 (file)
@@ -205,9 +205,9 @@ static int getreg32(struct task_struct *child, unsigned regno, u32 *val)
 static long ptrace32_siginfo(unsigned request, u32 pid, u32 addr, u32 data)
 {
        int ret;
-       compat_siginfo_t *si32 = (compat_siginfo_t *)compat_ptr(data);
+       compat_siginfo_t __user *si32 = compat_ptr(data);
        siginfo_t ssi; 
-       siginfo_t *si = compat_alloc_user_space(sizeof(siginfo_t));
+       siginfo_t __user *si = compat_alloc_user_space(sizeof(siginfo_t));
        if (request == PTRACE_SETSIGINFO) {
                memset(&ssi, 0, sizeof(siginfo_t));
                ret = copy_siginfo_from_user32(&ssi, si32);
index 6472e321cad7d0d6d682cf8e846a7f48ea761086..4d9d5ed942b293f3383c42beb3418373143050ea 100644 (file)
@@ -885,14 +885,14 @@ void setup_APIC_extened_lvt(unsigned char lvt_off, unsigned char vector,
  * value into /proc/profile.
  */
 
-void smp_local_timer_interrupt(struct pt_regs *regs)
+void smp_local_timer_interrupt(void)
 {
-       profile_tick(CPU_PROFILING, regs);
+       profile_tick(CPU_PROFILING);
 #ifdef CONFIG_SMP
-       update_process_times(user_mode(regs));
+       update_process_times(user_mode(get_irq_regs()));
 #endif
        if (apic_runs_main_timer > 1 && smp_processor_id() == boot_cpu_id)
-               main_timer_handler(regs);
+               main_timer_handler();
        /*
         * We take the 'long' return path, and there every subsystem
         * grabs the appropriate locks (kernel lock/ irq lock).
@@ -915,6 +915,8 @@ void smp_local_timer_interrupt(struct pt_regs *regs)
  */
 void smp_apic_timer_interrupt(struct pt_regs *regs)
 {
+       struct pt_regs *old_regs = set_irq_regs(regs);
+
        /*
         * the NMI deadlock-detector uses this.
         */
@@ -932,8 +934,9 @@ void smp_apic_timer_interrupt(struct pt_regs *regs)
         */
        exit_idle();
        irq_enter();
-       smp_local_timer_interrupt(regs);
+       smp_local_timer_interrupt();
        irq_exit();
+       set_irq_regs(old_regs);
 }
 
 /*
index b3f0908668ece23c11fc4d42675f011aab808821..a75c829c2b02b16bf23ea495a326d0307cd9685b 100644 (file)
@@ -54,13 +54,13 @@ static inline int bad_addr(unsigned long *addrp, unsigned long size)
 
        /* various gunk below that needed for SMP startup */
        if (addr < 0x8000) { 
-               *addrp = 0x8000;
+               *addrp = PAGE_ALIGN(0x8000);
                return 1; 
        }
 
        /* direct mapping tables of the kernel */
        if (last >= table_start<<PAGE_SHIFT && addr < table_end<<PAGE_SHIFT) { 
-               *addrp = table_end << PAGE_SHIFT; 
+               *addrp = PAGE_ALIGN(table_end << PAGE_SHIFT);
                return 1;
        } 
 
@@ -68,18 +68,18 @@ static inline int bad_addr(unsigned long *addrp, unsigned long size)
 #ifdef CONFIG_BLK_DEV_INITRD
        if (LOADER_TYPE && INITRD_START && last >= INITRD_START && 
            addr < INITRD_START+INITRD_SIZE) { 
-               *addrp = INITRD_START + INITRD_SIZE; 
+               *addrp = PAGE_ALIGN(INITRD_START + INITRD_SIZE);
                return 1;
        } 
 #endif
        /* kernel code */
-       if (last >= __pa_symbol(&_text) && last < __pa_symbol(&_end)) {
-               *addrp = __pa_symbol(&_end);
+       if (last >= __pa_symbol(&_text) && addr < __pa_symbol(&_end)) {
+               *addrp = PAGE_ALIGN(__pa_symbol(&_end));
                return 1;
        }
 
        if (last >= ebda_addr && addr < ebda_addr + ebda_size) {
-               *addrp = ebda_addr + ebda_size;
+               *addrp = PAGE_ALIGN(ebda_addr + ebda_size);
                return 1;
        }
 
@@ -152,7 +152,7 @@ unsigned long __init find_e820_area(unsigned long start, unsigned long end, unsi
                        continue; 
                while (bad_addr(&addr, size) && addr+size <= ei->addr+ei->size)
                        ;
-               last = addr + size;
+               last = PAGE_ALIGN(addr) + size;
                if (last > ei->addr + ei->size)
                        continue;
                if (last > end) 
index 208e38a372c107f0704dd16e77f56437c404f1e4..2b1245d8625849de6033eda814ed72b860faf232 100644 (file)
@@ -61,10 +61,11 @@ static void nvidia_bugs(void)
 
 static void ati_bugs(void)
 {
-#if 1 /* for testing */
-       printk("ATI board detected\n");
-#endif
-       /* No bugs right now */
+       if (timer_over_8254 == 1) {
+               timer_over_8254 = 0;
+               printk(KERN_INFO
+               "ATI board detected. Disabling timer routing over 8254.\n");
+       }
 }
 
 struct chipset {
index b8285cf1a9c3b2780bdd53c499047856d378195d..7d401b00d8227dbd6182524259a402822a903db6 100644 (file)
@@ -315,6 +315,8 @@ tracesys:
        LOAD_ARGS ARGOFFSET  /* reload args from stack in case ptrace changed it */
        RESTORE_REST
        cmpq $__NR_syscall_max,%rax
+       movq $-ENOSYS,%rcx
+       cmova %rcx,%rax
        ja  1f
        movq %r10,%rcx  /* fixup for C */
        call *sys_call_table(,%rax,8)
index cdb90e671b88a7bc96064f6af8ca48afc4768dea..73d76308b9555f35004bcb97d2689d72e4e86642 100644 (file)
@@ -63,6 +63,13 @@ static cpumask_t cluster_target_cpus(void)
        return cpumask_of_cpu(0);
 }
 
+static cpumask_t cluster_vector_allocation_domain(int cpu)
+{
+       cpumask_t domain = CPU_MASK_NONE;
+       cpu_set(cpu, domain);
+       return domain;
+}
+
 static void cluster_send_IPI_mask(cpumask_t mask, int vector)
 {
        send_IPI_mask_sequence(mask, vector);
@@ -119,6 +126,7 @@ struct genapic apic_cluster = {
        .int_delivery_mode = dest_Fixed,
        .int_dest_mode = (APIC_DEST_PHYSICAL != 0),
        .target_cpus = cluster_target_cpus,
+       .vector_allocation_domain = cluster_vector_allocation_domain,
        .apic_id_registered = cluster_apic_id_registered,
        .init_apic_ldr = cluster_init_apic_ldr,
        .send_IPI_all = cluster_send_IPI_all,
index 50ad153eaac416f42d7d93f90b23e23a11df07c7..7c01db8fa9d122eaf2adcff1e0927ec98a2e17e3 100644 (file)
@@ -22,6 +22,20 @@ static cpumask_t flat_target_cpus(void)
        return cpu_online_map;
 }
 
+static cpumask_t flat_vector_allocation_domain(int cpu)
+{
+       /* Careful. Some cpus do not strictly honor the set of cpus
+        * specified in the interrupt destination when using lowest
+        * priority interrupt delivery mode.
+        *
+        * In particular there was a hyperthreading cpu observed to
+        * deliver interrupts to the wrong hyperthread when only one
+        * hyperthread was specified in the interrupt desitination.
+        */
+       cpumask_t domain = { { [0] = APIC_ALL_CPUS, } };
+       return domain;
+}
+
 /*
  * Set up the logical destination ID.
  *
@@ -121,6 +135,7 @@ struct genapic apic_flat =  {
        .int_delivery_mode = dest_LowestPrio,
        .int_dest_mode = (APIC_DEST_LOGICAL != 0),
        .target_cpus = flat_target_cpus,
+       .vector_allocation_domain = flat_vector_allocation_domain,
        .apic_id_registered = flat_apic_id_registered,
        .init_apic_ldr = flat_init_apic_ldr,
        .send_IPI_all = flat_send_IPI_all,
@@ -138,9 +153,17 @@ struct genapic apic_flat =  {
 
 static cpumask_t physflat_target_cpus(void)
 {
-       return cpumask_of_cpu(0);
+       return cpu_online_map;
 }
 
+static cpumask_t physflat_vector_allocation_domain(int cpu)
+{
+       cpumask_t domain = CPU_MASK_NONE;
+       cpu_set(cpu, domain);
+       return domain;
+}
+
+
 static void physflat_send_IPI_mask(cpumask_t cpumask, int vector)
 {
        send_IPI_mask_sequence(cpumask, vector);
@@ -179,6 +202,7 @@ struct genapic apic_physflat =  {
        .int_delivery_mode = dest_Fixed,
        .int_dest_mode = (APIC_DEST_PHYSICAL != 0),
        .target_cpus = physflat_target_cpus,
+       .vector_allocation_domain = physflat_vector_allocation_domain,
        .apic_id_registered = flat_apic_id_registered,
        .init_apic_ldr = flat_init_apic_ldr,/*not needed, but shouldn't hurt*/
        .send_IPI_all = physflat_send_IPI_all,
index 0612a33bb896bb818001d3229c6af6652332c1df..c4ef801b765b8004033c83d2f6b1ac94b822fb9f 100644 (file)
@@ -178,7 +178,8 @@ void make_8259A_irq(unsigned int irq)
 {
        disable_irq_nosync(irq);
        io_apic_irqs &= ~(1<<irq);
-       set_irq_chip_and_handler(irq, &i8259A_chip, handle_level_irq);
+       set_irq_chip_and_handler_name(irq, &i8259A_chip, handle_level_irq,
+                                     "XT");
        enable_irq(irq);
 }
 
@@ -431,8 +432,8 @@ void __init init_ISA_irqs (void)
                        /*
                         * 16 old-style INTA-cycle interrupts:
                         */
-                       set_irq_chip_and_handler(i, &i8259A_chip,
-                                                handle_level_irq);
+                       set_irq_chip_and_handler_name(i, &i8259A_chip,
+                                                     handle_level_irq, "XT");
                } else {
                        /*
                         * 'high' PCI IRQs filled in on demand
index 91728d9d34724fdcd175d83fce1c5d08290fe0dd..b000017e4b5da80f336588e321982217599cf848 100644 (file)
@@ -47,7 +47,7 @@
 #include <asm/msidef.h>
 #include <asm/hypertransport.h>
 
-static int assign_irq_vector(int irq, cpumask_t mask);
+static int assign_irq_vector(int irq, cpumask_t mask, cpumask_t *result);
 
 #define __apicdebuginit  __init
 
@@ -57,7 +57,7 @@ static int no_timer_check;
 
 static int disable_timer_pin_1 __initdata;
 
-int timer_over_8254 __initdata = 0;
+int timer_over_8254 __initdata = 1;
 
 /* Where if anywhere is the i8259 connect in external int mode */
 static struct { int pin, apic; } ioapic_i8259 = { -1, -1 };
@@ -174,12 +174,10 @@ static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t mask)
 
        cpus_and(mask, tmp, CPU_MASK_ALL);
 
-       vector = assign_irq_vector(irq, mask);
+       vector = assign_irq_vector(irq, mask, &tmp);
        if (vector < 0)
                return;
 
-       cpus_clear(tmp);
-       cpu_set(vector >> 8, tmp);
        dest = cpu_mask_to_apicid(tmp);
 
        /*
@@ -188,7 +186,7 @@ static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t mask)
        dest = SET_APIC_LOGICAL_ID(dest);
 
        spin_lock_irqsave(&ioapic_lock, flags);
-       __target_IO_APIC_irq(irq, dest, vector & 0xff);
+       __target_IO_APIC_irq(irq, dest, vector);
        set_native_irq_info(irq, mask);
        spin_unlock_irqrestore(&ioapic_lock, flags);
 }
@@ -563,9 +561,45 @@ static inline int IO_APIC_irq_trigger(int irq)
 }
 
 /* irq_vectors is indexed by the sum of all RTEs in all I/O APICs. */
-unsigned int irq_vector[NR_IRQ_VECTORS] __read_mostly = { FIRST_EXTERNAL_VECTOR, 0 };
+static u8 irq_vector[NR_IRQ_VECTORS] __read_mostly = {
+       [0] = FIRST_EXTERNAL_VECTOR + 0,
+       [1] = FIRST_EXTERNAL_VECTOR + 1,
+       [2] = FIRST_EXTERNAL_VECTOR + 2,
+       [3] = FIRST_EXTERNAL_VECTOR + 3,
+       [4] = FIRST_EXTERNAL_VECTOR + 4,
+       [5] = FIRST_EXTERNAL_VECTOR + 5,
+       [6] = FIRST_EXTERNAL_VECTOR + 6,
+       [7] = FIRST_EXTERNAL_VECTOR + 7,
+       [8] = FIRST_EXTERNAL_VECTOR + 8,
+       [9] = FIRST_EXTERNAL_VECTOR + 9,
+       [10] = FIRST_EXTERNAL_VECTOR + 10,
+       [11] = FIRST_EXTERNAL_VECTOR + 11,
+       [12] = FIRST_EXTERNAL_VECTOR + 12,
+       [13] = FIRST_EXTERNAL_VECTOR + 13,
+       [14] = FIRST_EXTERNAL_VECTOR + 14,
+       [15] = FIRST_EXTERNAL_VECTOR + 15,
+};
+
+static cpumask_t irq_domain[NR_IRQ_VECTORS] __read_mostly = {
+       [0] = CPU_MASK_ALL,
+       [1] = CPU_MASK_ALL,
+       [2] = CPU_MASK_ALL,
+       [3] = CPU_MASK_ALL,
+       [4] = CPU_MASK_ALL,
+       [5] = CPU_MASK_ALL,
+       [6] = CPU_MASK_ALL,
+       [7] = CPU_MASK_ALL,
+       [8] = CPU_MASK_ALL,
+       [9] = CPU_MASK_ALL,
+       [10] = CPU_MASK_ALL,
+       [11] = CPU_MASK_ALL,
+       [12] = CPU_MASK_ALL,
+       [13] = CPU_MASK_ALL,
+       [14] = CPU_MASK_ALL,
+       [15] = CPU_MASK_ALL,
+};
 
-static int __assign_irq_vector(int irq, cpumask_t mask)
+static int __assign_irq_vector(int irq, cpumask_t mask, cpumask_t *result)
 {
        /*
         * NOTE! The local APIC isn't very good at handling
@@ -587,16 +621,24 @@ static int __assign_irq_vector(int irq, cpumask_t mask)
 
        BUG_ON((unsigned)irq >= NR_IRQ_VECTORS);
 
-       if (IO_APIC_VECTOR(irq) > 0)
-               old_vector = IO_APIC_VECTOR(irq);
-       if ((old_vector > 0) && cpu_isset(old_vector >> 8, mask)) {
-               return old_vector;
+       if (irq_vector[irq] > 0)
+               old_vector = irq_vector[irq];
+       if (old_vector > 0) {
+               cpus_and(*result, irq_domain[irq], mask);
+               if (!cpus_empty(*result))
+                       return old_vector;
        }
 
        for_each_cpu_mask(cpu, mask) {
+               cpumask_t domain;
+               int first, new_cpu;
                int vector, offset;
-               vector = pos[cpu].vector;
-               offset = pos[cpu].offset;
+
+               domain = vector_allocation_domain(cpu);
+               first = first_cpu(domain);
+
+               vector = pos[first].vector;
+               offset = pos[first].offset;
 next:
                vector += 8;
                if (vector >= FIRST_SYSTEM_VECTOR) {
@@ -604,35 +646,40 @@ next:
                        offset = (offset + 1) % 8;
                        vector = FIRST_DEVICE_VECTOR + offset;
                }
-               if (unlikely(pos[cpu].vector == vector))
+               if (unlikely(pos[first].vector == vector))
                        continue;
                if (vector == IA32_SYSCALL_VECTOR)
                        goto next;
-               if (per_cpu(vector_irq, cpu)[vector] != -1)
-                       goto next;
+               for_each_cpu_mask(new_cpu, domain)
+                       if (per_cpu(vector_irq, new_cpu)[vector] != -1)
+                               goto next;
                /* Found one! */
-               pos[cpu].vector = vector;
-               pos[cpu].offset = offset;
+               for_each_cpu_mask(new_cpu, domain) {
+                       pos[new_cpu].vector = vector;
+                       pos[new_cpu].offset = offset;
+               }
                if (old_vector >= 0) {
-                       int old_cpu = old_vector >> 8;
-                       old_vector &= 0xff;
-                       per_cpu(vector_irq, old_cpu)[old_vector] = -1;
+                       int old_cpu;
+                       for_each_cpu_mask(old_cpu, irq_domain[irq])
+                               per_cpu(vector_irq, old_cpu)[old_vector] = -1;
                }
-               per_cpu(vector_irq, cpu)[vector] = irq;
-               vector |= cpu << 8;
-               IO_APIC_VECTOR(irq) = vector;
+               for_each_cpu_mask(new_cpu, domain)
+                       per_cpu(vector_irq, new_cpu)[vector] = irq;
+               irq_vector[irq] = vector;
+               irq_domain[irq] = domain;
+               cpus_and(*result, domain, mask);
                return vector;
        }
        return -ENOSPC;
 }
 
-static int assign_irq_vector(int irq, cpumask_t mask)
+static int assign_irq_vector(int irq, cpumask_t mask, cpumask_t *result)
 {
        int vector;
        unsigned long flags;
 
        spin_lock_irqsave(&vector_lock, flags);
-       vector = __assign_irq_vector(irq, mask);
+       vector = __assign_irq_vector(irq, mask, result);
        spin_unlock_irqrestore(&vector_lock, flags);
        return vector;
 }
@@ -649,11 +696,11 @@ static void ioapic_register_intr(int irq, int vector, unsigned long trigger)
 {
        if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) ||
                        trigger == IOAPIC_LEVEL)
-               set_irq_chip_and_handler(irq, &ioapic_chip,
-                                        handle_fasteoi_irq);
+               set_irq_chip_and_handler_name(irq, &ioapic_chip,
+                                             handle_fasteoi_irq, "fasteoi");
        else
-               set_irq_chip_and_handler(irq, &ioapic_chip,
-                                        handle_edge_irq);
+               set_irq_chip_and_handler_name(irq, &ioapic_chip,
+                                             handle_edge_irq, "edge");
 }
 
 static void __init setup_IO_APIC_irqs(void)
@@ -704,14 +751,12 @@ static void __init setup_IO_APIC_irqs(void)
 
                if (IO_APIC_IRQ(irq)) {
                        cpumask_t mask;
-                       vector = assign_irq_vector(irq, TARGET_CPUS);
+                       vector = assign_irq_vector(irq, TARGET_CPUS, &mask);
                        if (vector < 0)
                                continue;
 
-                       cpus_clear(mask);
-                       cpu_set(vector >> 8, mask);
                        entry.dest.logical.logical_dest = cpu_mask_to_apicid(mask);
-                       entry.vector = vector & 0xff;
+                       entry.vector = vector;
 
                        ioapic_register_intr(irq, vector, IOAPIC_AUTO);
                        if (!apic && (irq < 16))
@@ -761,7 +806,7 @@ static void __init setup_ExtINT_IRQ0_pin(unsigned int apic, unsigned int pin, in
         * The timer IRQ doesn't have to know that behind the
         * scene we have a 8259A-master in AEOI mode ...
         */
-       set_irq_chip_and_handler(0, &ioapic_chip, handle_edge_irq);
+       set_irq_chip_and_handler_name(0, &ioapic_chip, handle_edge_irq, "edge");
 
        /*
         * Add it to the IO-APIC irq-routing table:
@@ -1210,12 +1255,15 @@ static int ioapic_retrigger_irq(unsigned int irq)
 {
        cpumask_t mask;
        unsigned vector;
+       unsigned long flags;
 
+       spin_lock_irqsave(&vector_lock, flags);
        vector = irq_vector[irq];
        cpus_clear(mask);
-       cpu_set(vector >> 8, mask);
+       cpu_set(first_cpu(irq_domain[irq]), mask);
 
-       send_IPI_mask(mask, vector & 0xff);
+       send_IPI_mask(mask, vector);
+       spin_unlock_irqrestore(&vector_lock, flags);
 
        return 1;
 }
@@ -1289,7 +1337,7 @@ static inline void init_IO_APIC_traps(void)
         */
        for (irq = 0; irq < NR_IRQS ; irq++) {
                int tmp = irq;
-               if (IO_APIC_IRQ(tmp) && !IO_APIC_VECTOR(tmp)) {
+               if (IO_APIC_IRQ(tmp) && !irq_vector[tmp]) {
                        /*
                         * Hmm.. We don't have an entry for this,
                         * so default to an old-fashioned 8259
@@ -1430,12 +1478,13 @@ static inline void check_timer(void)
 {
        int apic1, pin1, apic2, pin2;
        int vector;
+       cpumask_t mask;
 
        /*
         * get/set the timer IRQ vector:
         */
        disable_8259A_irq(0);
-       vector = assign_irq_vector(0, TARGET_CPUS);
+       vector = assign_irq_vector(0, TARGET_CPUS, &mask);
 
        /*
         * Subtle, code in do_timer_interrupt() expects an AEOI
@@ -1667,6 +1716,7 @@ int create_irq(void)
        int new;
        int vector = 0;
        unsigned long flags;
+       cpumask_t mask;
 
        irq = -ENOSPC;
        spin_lock_irqsave(&vector_lock, flags);
@@ -1675,7 +1725,7 @@ int create_irq(void)
                        continue;
                if (irq_vector[new] != 0)
                        continue;
-               vector = __assign_irq_vector(new, TARGET_CPUS);
+               vector = __assign_irq_vector(new, TARGET_CPUS, &mask);
                if (likely(vector > 0))
                        irq = new;
                break;
@@ -1707,13 +1757,10 @@ static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, struct msi_ms
 {
        int vector;
        unsigned dest;
+       cpumask_t tmp;
 
-       vector = assign_irq_vector(irq, TARGET_CPUS);
+       vector = assign_irq_vector(irq, TARGET_CPUS, &tmp);
        if (vector >= 0) {
-               cpumask_t tmp;
-
-               cpus_clear(tmp);
-               cpu_set(vector >> 8, tmp);
                dest = cpu_mask_to_apicid(tmp);
 
                msg->address_hi = MSI_ADDR_BASE_HI;
@@ -1752,12 +1799,10 @@ static void set_msi_irq_affinity(unsigned int irq, cpumask_t mask)
 
        cpus_and(mask, tmp, CPU_MASK_ALL);
 
-       vector = assign_irq_vector(irq, mask);
+       vector = assign_irq_vector(irq, mask, &tmp);
        if (vector < 0)
                return;
 
-       cpus_clear(tmp);
-       cpu_set(vector >> 8, tmp);
        dest = cpu_mask_to_apicid(tmp);
 
        read_msi_msg(irq, &msg);
@@ -1797,7 +1842,7 @@ int arch_setup_msi_irq(unsigned int irq, struct pci_dev *dev)
 
        write_msi_msg(irq, &msg);
 
-       set_irq_chip_and_handler(irq, &msi_chip, handle_edge_irq);
+       set_irq_chip_and_handler_name(irq, &msi_chip, handle_edge_irq, "edge");
 
        return 0;
 }
@@ -1844,12 +1889,10 @@ static void set_ht_irq_affinity(unsigned int irq, cpumask_t mask)
 
        cpus_and(mask, tmp, CPU_MASK_ALL);
 
-       vector = assign_irq_vector(irq, mask);
+       vector = assign_irq_vector(irq, mask, &tmp);
        if (vector < 0)
                return;
 
-       cpus_clear(tmp);
-       cpu_set(vector >> 8, tmp);
        dest = cpu_mask_to_apicid(tmp);
 
        target_ht_irq(irq, dest, vector & 0xff);
@@ -1857,7 +1900,7 @@ static void set_ht_irq_affinity(unsigned int irq, cpumask_t mask)
 }
 #endif
 
-static struct hw_interrupt_type ht_irq_chip = {
+static struct irq_chip ht_irq_chip = {
        .name           = "PCI-HT",
        .mask           = mask_ht_irq,
        .unmask         = unmask_ht_irq,
@@ -1871,15 +1914,13 @@ static struct hw_interrupt_type ht_irq_chip = {
 int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev)
 {
        int vector;
+       cpumask_t tmp;
 
-       vector = assign_irq_vector(irq, TARGET_CPUS);
+       vector = assign_irq_vector(irq, TARGET_CPUS, &tmp);
        if (vector >= 0) {
                u32 low, high;
                unsigned dest;
-               cpumask_t tmp;
 
-               cpus_clear(tmp);
-               cpu_set(vector >> 8, tmp);
                dest = cpu_mask_to_apicid(tmp);
 
                high =  HT_IRQ_HIGH_DEST_ID(dest);
@@ -1898,7 +1939,8 @@ int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev)
                write_ht_irq_low(irq, low);
                write_ht_irq_high(irq, high);
 
-               set_irq_chip_and_handler(irq, &ht_irq_chip, handle_edge_irq);
+               set_irq_chip_and_handler_name(irq, &ht_irq_chip,
+                                             handle_edge_irq, "edge");
        }
        return vector;
 }
@@ -1945,13 +1987,10 @@ int io_apic_set_pci_routing (int ioapic, int pin, int irq, int triggering, int p
                add_pin_to_irq(irq, ioapic, pin);
 
 
-       vector = assign_irq_vector(irq, TARGET_CPUS);
+       vector = assign_irq_vector(irq, TARGET_CPUS, &mask);
        if (vector < 0)
                return vector;
 
-       cpus_clear(mask);
-       cpu_set(vector >> 8, mask);
-
        /*
         * Generate a PCI IRQ routing entry and program the IOAPIC accordingly.
         * Note that we mask (disable) IRQs now -- these get enabled when the
index 506f27c85ca5650cc214d3635291d0ffb8ecd661..e46c55856d40ae6fb85daf785ca438dccba1b042 100644 (file)
@@ -75,7 +75,7 @@ int show_interrupts(struct seq_file *p, void *v)
                        seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
 #endif
                seq_printf(p, " %8s", irq_desc[i].chip->name);
-               seq_printf(p, "-%s", handle_irq_name(irq_desc[i].handle_irq));
+               seq_printf(p, "-%-8s", irq_desc[i].name);
 
                seq_printf(p, "  %s", action->name);
                for (action=action->next; action; action = action->next)
@@ -103,7 +103,9 @@ skip:
  * handlers).
  */
 asmlinkage unsigned int do_IRQ(struct pt_regs *regs)
-{      
+{
+       struct pt_regs *old_regs = set_irq_regs(regs);
+
        /* high bit used in ret_from_ code  */
        unsigned vector = ~regs->orig_rax;
        unsigned irq;
@@ -112,18 +114,19 @@ asmlinkage unsigned int do_IRQ(struct pt_regs *regs)
        irq_enter();
        irq = __get_cpu_var(vector_irq)[vector];
 
-       if (unlikely(irq >= NR_IRQS)) {
-               printk(KERN_EMERG "%s: cannot handle IRQ %d\n",
-                                       __FUNCTION__, irq);
-               BUG();
-       }
-
 #ifdef CONFIG_DEBUG_STACKOVERFLOW
        stack_overflow_check(regs);
 #endif
-       generic_handle_irq(irq, regs);
+
+       if (likely(irq < NR_IRQS))
+               generic_handle_irq(irq);
+       else
+               printk(KERN_EMERG "%s: %d.%d No irq handler for vector\n",
+                       __func__, smp_processor_id(), vector);
+
        irq_exit();
 
+       set_irq_regs(old_regs);
        return 1;
 }
 
index f760045d6d35f0bf082f43d1322f32fe34c04680..37a770859e7180ae38e06c22d6064fbe1a4ebeab 100644 (file)
@@ -2,8 +2,9 @@
  * Derived from arch/powerpc/kernel/iommu.c
  *
  * Copyright (C) IBM Corporation, 2006
+ * Copyright (C) 2006  Jon Mason <jdmason@kudzu.us>
  *
- * Author: Jon Mason <jdmason@us.ibm.com>
+ * Author: Jon Mason <jdmason@kudzu.us>
  * Author: Muli Ben-Yehuda <muli@il.ibm.com>
 
  * This program is free software; you can redistribute it and/or modify
@@ -51,7 +52,8 @@
 #define ONE_BASED_CHASSIS_NUM   1
 
 /* register offsets inside the host bridge space */
-#define PHB_CSR_OFFSET         0x0110
+#define CALGARY_CONFIG_REG     0x0108
+#define PHB_CSR_OFFSET         0x0110 /* Channel Status */
 #define PHB_PLSSR_OFFSET       0x0120
 #define PHB_CONFIG_RW_OFFSET   0x0160
 #define PHB_IOBASE_BAR_LOW     0x0170
@@ -82,6 +84,8 @@
 #define TAR_VALID              0x0000000000000008UL
 /* CSR (Channel/DMA Status Register) */
 #define CSR_AGENT_MASK         0xffe0ffff
+/* CCR (Calgary Configuration Register) */
+#define CCR_2SEC_TIMEOUT        0x000000000000000EUL
 
 #define MAX_NUM_OF_PHBS                8 /* how many PHBs in total? */
 #define MAX_NUM_CHASSIS                8 /* max number of chassis */
@@ -714,7 +718,7 @@ static void calgary_watchdog(unsigned long data)
 
        /* If no error, the agent ID in the CSR is not valid */
        if (val32 & CSR_AGENT_MASK) {
-               printk(KERN_EMERG "calgary_watchdog: DMA error on bus %d, "
+               printk(KERN_EMERG "calgary_watchdog: DMA error on PHB %#x, "
                                  "CSR = %#x\n", dev->bus->number, val32);
                writel(0, target);
 
@@ -731,6 +735,38 @@ static void calgary_watchdog(unsigned long data)
        }
 }
 
+static void __init calgary_increase_split_completion_timeout(void __iomem *bbar,
+       unsigned char busnum)
+{
+       u64 val64;
+       void __iomem *target;
+       unsigned long phb_shift = -1;
+       u64 mask;
+
+       switch (busno_to_phbid(busnum)) {
+       case 0: phb_shift = (63 - 19);
+               break;
+       case 1: phb_shift = (63 - 23);
+               break;
+       case 2: phb_shift = (63 - 27);
+               break;
+       case 3: phb_shift = (63 - 35);
+               break;
+       default:
+               BUG_ON(busno_to_phbid(busnum));
+       }
+
+       target = calgary_reg(bbar, CALGARY_CONFIG_REG);
+       val64 = be64_to_cpu(readq(target));
+
+       /* zero out this PHB's timer bits */
+       mask = ~(0xFUL << phb_shift);
+       val64 &= mask;
+       val64 |= (CCR_2SEC_TIMEOUT << phb_shift);
+       writeq(cpu_to_be64(val64), target);
+       readq(target); /* flush */
+}
+
 static void __init calgary_enable_translation(struct pci_dev *dev)
 {
        u32 val32;
@@ -748,13 +784,20 @@ static void __init calgary_enable_translation(struct pci_dev *dev)
        val32 = be32_to_cpu(readl(target));
        val32 |= PHB_TCE_ENABLE | PHB_DAC_DISABLE | PHB_MCSR_ENABLE;
 
-       printk(KERN_INFO "Calgary: enabling translation on PHB %d\n", busnum);
+       printk(KERN_INFO "Calgary: enabling translation on PHB %#x\n", busnum);
        printk(KERN_INFO "Calgary: errant DMAs will now be prevented on this "
               "bus.\n");
 
        writel(cpu_to_be32(val32), target);
        readl(target); /* flush */
 
+       /*
+        * Give split completion a longer timeout on bus 1 for aic94xx
+        * http://bugzilla.kernel.org/show_bug.cgi?id=7180
+        */
+       if (busnum == 1)
+               calgary_increase_split_completion_timeout(bbar, busnum);
+
        init_timer(&tbl->watchdog_timer);
        tbl->watchdog_timer.function = &calgary_watchdog;
        tbl->watchdog_timer.data = (unsigned long)dev;
@@ -778,7 +821,7 @@ static void __init calgary_disable_translation(struct pci_dev *dev)
        val32 = be32_to_cpu(readl(target));
        val32 &= ~(PHB_TCE_ENABLE | PHB_DAC_DISABLE | PHB_MCSR_ENABLE);
 
-       printk(KERN_INFO "Calgary: disabling translation on PHB %d!\n", busnum);
+       printk(KERN_INFO "Calgary: disabling translation on PHB %#x!\n", busnum);
        writel(cpu_to_be32(val32), target);
        readl(target); /* flush */
 
@@ -790,7 +833,16 @@ static inline unsigned int __init locate_register_space(struct pci_dev *dev)
        int rionodeid;
        u32 address;
 
-       rionodeid = (dev->bus->number % 15 > 4) ? 3 : 2;
+       /*
+        * Each Calgary has four busses. The first four busses (first Calgary)
+        * have RIO node ID 2, then the next four (second Calgary) have RIO
+        * node ID 3, the next four (third Calgary) have node ID 2 again, etc.
+        * We use a gross hack - relying on the dev->bus->number ordering,
+        * modulo 14 - to decide which Calgary a given bus is on. Busses 0, 1,
+        * 2 and 4 are on the first Calgary (id 2), 6, 8, a and c are on the
+        * second (id 3), and then it repeats modulo 14.
+        */
+       rionodeid = (dev->bus->number % 14 > 4) ? 3 : 2;
        /*
         * register space address calculation as follows:
         * FE0MB-8MB*OneBasedChassisNumber+1MB*(RioNodeId-ChassisBase)
@@ -798,7 +850,7 @@ static inline unsigned int __init locate_register_space(struct pci_dev *dev)
         * RioNodeId is 2 for first Calgary, 3 for second Calgary
         */
        address = START_ADDRESS -
-               (0x800000 * (ONE_BASED_CHASSIS_NUM + dev->bus->number / 15)) +
+               (0x800000 * (ONE_BASED_CHASSIS_NUM + dev->bus->number / 14)) +
                (0x100000) * (rionodeid - CHASSIS_BASE);
        return address;
 }
@@ -816,6 +868,8 @@ static int __init calgary_init_one(struct pci_dev *dev)
        void __iomem *bbar;
        int ret;
 
+       BUG_ON(dev->bus->number >= MAX_PHB_BUS_NUM);
+
        address = locate_register_space(dev);
        /* map entire 1MB of Calgary config space */
        bbar = ioremap_nocache(address, 1024 * 1024);
@@ -842,10 +896,10 @@ done:
 
 static int __init calgary_init(void)
 {
-       int i, ret = -ENODEV;
+       int ret = -ENODEV;
        struct pci_dev *dev = NULL;
 
-       for (i = 0; i < MAX_PHB_BUS_NUM; i++) {
+       do {
                dev = pci_get_device(PCI_VENDOR_ID_IBM,
                                     PCI_DEVICE_ID_IBM_CALGARY,
                                     dev);
@@ -861,12 +915,12 @@ static int __init calgary_init(void)
                ret = calgary_init_one(dev);
                if (ret)
                        goto error;
-       }
+       } while (1);
 
        return ret;
 
 error:
-       for (i--; i >= 0; i--) {
+       do {
                dev = pci_find_device_reverse(PCI_VENDOR_ID_IBM,
                                              PCI_DEVICE_ID_IBM_CALGARY,
                                              dev);
@@ -882,7 +936,7 @@ error:
                calgary_disable_translation(dev);
                calgary_free_bus(dev);
                pci_dev_put(dev); /* Undo calgary_init_one()'s pci_dev_get() */
-       }
+       } while (1);
 
        return ret;
 }
@@ -1052,7 +1106,7 @@ static int __init calgary_parse_options(char *p)
 
                        if (bridge < MAX_PHB_BUS_NUM) {
                                printk(KERN_INFO "Calgary: disabling "
-                                      "translation for PHB 0x%x\n", bridge);
+                                      "translation for PHB %#x\n", bridge);
                                bus_info[bridge].translation_disabled = 1;
                        }
                }
index de10cb8a2c97b8cde91e730bcb1486442fc4f82e..49f7fac6229e5f4e920d58fcdec1fd5e49e8667b 100644 (file)
@@ -238,20 +238,28 @@ void cpu_idle (void)
  * We execute MONITOR against need_resched and enter optimized wait state
  * through MWAIT. Whenever someone changes need_resched, we would be woken
  * up from MWAIT (without an IPI).
+ *
+ * New with Core Duo processors, MWAIT can take some hints based on CPU
+ * capability.
  */
-static void mwait_idle(void)
+void mwait_idle_with_hints(unsigned long eax, unsigned long ecx)
 {
-       local_irq_enable();
-
-       while (!need_resched()) {
+       if (!need_resched()) {
                __monitor((void *)&current_thread_info()->flags, 0, 0);
                smp_mb();
-               if (need_resched())
-                       break;
-               __mwait(0, 0);
+               if (!need_resched())
+                       __mwait(eax, ecx);
        }
 }
 
+/* Default MONITOR/MWAIT with no hints, used for default C1 state */
+static void mwait_idle(void)
+{
+       local_irq_enable();
+       while (!need_resched())
+               mwait_idle_with_hints(0,0);
+}
+
 void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c)
 {
        static int printed;
@@ -615,6 +623,9 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
                prev->gsindex = gsindex;
        }
 
+       /* Must be after DS reload */
+       unlazy_fpu(prev_p);
+
        /* 
         * Switch the PDA and FPU contexts.
         */
@@ -622,10 +633,6 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
        write_pda(oldrsp, next->userrsp); 
        write_pda(pcurrent, next_p); 
 
-       /* This must be here to ensure both math_state_restore() and
-          kernel_fpu_begin() work consistently. 
-          And the AMD workaround requires it to be after DS reload. */
-       unlazy_fpu(prev_p);
        write_pda(kernelstack,
        (unsigned long)task_stack_page(next_p) + THREAD_SIZE - PDA_STACKOFFSET);
 #ifdef CONFIG_CC_STACKPROTECTOR
index 557e92af7beabdf84b58d265ecda54bb5dbf4f58..88722f11ca132595cf11704e8e65cdb47e2790f9 100644 (file)
@@ -302,20 +302,20 @@ unsigned long long monotonic_clock(void)
 }
 EXPORT_SYMBOL(monotonic_clock);
 
-static noinline void handle_lost_ticks(int lost, struct pt_regs *regs)
+static noinline void handle_lost_ticks(int lost)
 {
        static long lost_count;
        static int warned;
        if (report_lost_ticks) {
                printk(KERN_WARNING "time.c: Lost %d timer tick(s)! ", lost);
-               print_symbol("rip %s)\n", regs->rip);
+               print_symbol("rip %s)\n", get_irq_regs()->rip);
        }
 
        if (lost_count == 1000 && !warned) {
                printk(KERN_WARNING "warning: many lost ticks.\n"
                       KERN_WARNING "Your time source seems to be instable or "
                                "some driver is hogging interupts\n");
-               print_symbol("rip %s\n", regs->rip);
+               print_symbol("rip %s\n", get_irq_regs()->rip);
                if (vxtime.mode == VXTIME_TSC && vxtime.hpet_address) {
                        printk(KERN_WARNING "Falling back to HPET\n");
                        if (hpet_use_timer)
@@ -339,7 +339,7 @@ static noinline void handle_lost_ticks(int lost, struct pt_regs *regs)
 #endif
 }
 
-void main_timer_handler(struct pt_regs *regs)
+void main_timer_handler(void)
 {
        static unsigned long rtc_update = 0;
        unsigned long tsc;
@@ -411,7 +411,7 @@ void main_timer_handler(struct pt_regs *regs)
        }
 
        if (lost > 0)
-               handle_lost_ticks(lost, regs);
+               handle_lost_ticks(lost);
        else
                lost = 0;
 
@@ -421,7 +421,7 @@ void main_timer_handler(struct pt_regs *regs)
 
        do_timer(lost + 1);
 #ifndef CONFIG_SMP
-       update_process_times(user_mode(regs));
+       update_process_times(user_mode(get_irq_regs()));
 #endif
 
 /*
@@ -431,7 +431,7 @@ void main_timer_handler(struct pt_regs *regs)
  */
 
        if (!using_apic_timer)
-               smp_local_timer_interrupt(regs);
+               smp_local_timer_interrupt();
 
 /*
  * If we have an externally synchronized Linux clock, then update CMOS clock
@@ -450,11 +450,11 @@ void main_timer_handler(struct pt_regs *regs)
        write_sequnlock(&xtime_lock);
 }
 
-static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t timer_interrupt(int irq, void *dev_id)
 {
        if (apic_runs_main_timer > 1)
                return IRQ_HANDLED;
-       main_timer_handler(regs);
+       main_timer_handler();
        if (using_apic_timer)
                smp_send_timer_broadcast_ipi();
        return IRQ_HANDLED;
@@ -948,7 +948,7 @@ __cpuinit int unsynchronized_tsc(void)
        if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) {
 #ifdef CONFIG_ACPI
                /* But TSC doesn't tick in C3 so don't use it there */
-               if (acpi_fadt.length > 0 && acpi_fadt.plvl3_lat < 100)
+               if (acpi_fadt.length > 0 && acpi_fadt.plvl3_lat < 1000)
                        return 1;
 #endif
                return 0;
@@ -1337,7 +1337,7 @@ irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        }
        if (call_rtc_interrupt) {
                rtc_int_flag |= (RTC_IRQF | (RTC_NUM_INTS << 8));
-               rtc_interrupt(rtc_int_flag, dev_id, regs);
+               rtc_interrupt(rtc_int_flag, dev_id);
        }
        return IRQ_HANDLED;
 }
index 01f2a8d254c2fd6683b423910b1af36a046add42..7819022a8db5986e29bf36247be94cab99cb7f06 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/delay.h>
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
+#include <linux/kallsyms.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/nmi.h>
@@ -115,7 +116,6 @@ static int call_trace = 1;
 #endif
 
 #ifdef CONFIG_KALLSYMS
-# include <linux/kallsyms.h>
 void printk_address(unsigned long address)
 {
        unsigned long offset = 0, symsize;
index b9df2ab6529fc8286b00f41d2081d393bbb2b444..1283614c9b247674ee75fd865744c9a95d902379 100644 (file)
@@ -17,6 +17,7 @@ PHDRS {
        text PT_LOAD FLAGS(5);  /* R_E */
        data PT_LOAD FLAGS(7);  /* RWE */
        user PT_LOAD FLAGS(7);  /* RWE */
+       data.init PT_LOAD FLAGS(7);     /* RWE */
        note PT_NOTE FLAGS(4);  /* R__ */
 }
 SECTIONS
@@ -131,7 +132,7 @@ SECTIONS
   . = ALIGN(8192);             /* init_task */
   .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
        *(.data.init_task)
-  } :data
+  }:data.init
 
   . = ALIGN(4096);
   .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
index 044e852bd25efb297c10545211d5fe80d5dfbf22..414caf0c5f9ae96b67bafea7589b532fa821b361 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/pci_ids.h>
 #include <linux/pci_regs.h>
 #include <asm/pci-direct.h>
+#include <asm/io.h>
 
 static int __init vsmp_init(void)
 {
index 19c72520a86876a616becaf31ab3d72f73e8bb3f..971dc1181e69ace1620338b845a5f4e5869dee30 100644 (file)
@@ -406,9 +406,12 @@ void __cpuinit zap_low_mappings(int cpu)
 #ifndef CONFIG_NUMA
 void __init paging_init(void)
 {
-       unsigned long max_zone_pfns[MAX_NR_ZONES] = {MAX_DMA_PFN,
-                                                       MAX_DMA32_PFN,
-                                                       end_pfn};
+       unsigned long max_zone_pfns[MAX_NR_ZONES];
+       memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
+       max_zone_pfns[ZONE_DMA] = MAX_DMA_PFN;
+       max_zone_pfns[ZONE_DMA32] = MAX_DMA32_PFN;
+       max_zone_pfns[ZONE_NORMAL] = end_pfn;
+
        memory_present(0, 0, end_pfn);
        sparse_init();
        free_area_init_nodes(max_zone_pfns);
index 829a008bd39b75a95eec6dfb66a46d4497459a48..2ee2e003606cad9cc727042af6ed435dadc45a53 100644 (file)
@@ -338,9 +338,11 @@ static void __init arch_sparse_init(void)
 void __init paging_init(void)
 { 
        int i;
-       unsigned long max_zone_pfns[MAX_NR_ZONES] = { MAX_DMA_PFN,
-               MAX_DMA32_PFN,
-               end_pfn};
+       unsigned long max_zone_pfns[MAX_NR_ZONES];
+       memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
+       max_zone_pfns[ZONE_DMA] = MAX_DMA_PFN;
+       max_zone_pfns[ZONE_DMA32] = MAX_DMA32_PFN;
+       max_zone_pfns[ZONE_NORMAL] = end_pfn;
 
        arch_sparse_init();
 
index 3cc0544e25f5a8569af1a727c3f819b252fe3635..1087e150a21896d1abfaadfccfe7fc4de98728ef 100644 (file)
@@ -207,7 +207,7 @@ static inline int save_add_info(void)
        return hotadd_percent > 0;
 }
 #else
-int update_end_of_memory(unsigned long end) {return 0;}
+int update_end_of_memory(unsigned long end) {return -1;}
 static int hotadd_enough_memory(struct bootnode *nd) {return 1;}
 #ifdef CONFIG_MEMORY_HOTPLUG_SPARSE
 static inline int save_add_info(void) {return 1;}
@@ -337,7 +337,7 @@ acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma)
        push_node_boundaries(node, nd->start >> PAGE_SHIFT,
                                                nd->end >> PAGE_SHIFT);
 
-       if (ma->flags.hot_pluggable && !reserve_hotadd(node, start, end) < 0) {
+       if (ma->flags.hot_pluggable && (reserve_hotadd(node, start, end) < 0)) {
                /* Ignore hotadd region. Undo damage */
                printk(KERN_NOTICE "SRAT: Hotplug region ignored\n");
                *nd = oldnode;
index 1eb18f421edff11924187e8242781bd68116a168..149aba05a5b8e70c6abb22dd17e21b1f1994adf4 100644 (file)
@@ -3,7 +3,7 @@
 #
 # Reuse the i386 PCI subsystem
 #
-CFLAGS += -Iarch/i386/pci
+EXTRA_CFLAGS += -Iarch/i386/pci
 
 obj-y          := i386.o
 obj-$(CONFIG_PCI_DIRECT)+= direct.o
index 487dd3da8853971d9bcb77cf6ecf51eb39faedf3..8ccd163254b8acf1469628e432308ab73cedd97b 100644 (file)
@@ -93,21 +93,18 @@ static inline int elv_try_merge(struct request *__rq, struct bio *bio)
 
 static struct elevator_type *elevator_find(const char *name)
 {
-       struct elevator_type *e = NULL;
+       struct elevator_type *e;
        struct list_head *entry;
 
        list_for_each(entry, &elv_list) {
-               struct elevator_type *__e;
 
-               __e = list_entry(entry, struct elevator_type, list);
+               e = list_entry(entry, struct elevator_type, list);
 
-               if (!strcmp(__e->elevator_name, name)) {
-                       e = __e;
-                       break;
-               }
+               if (!strcmp(e->elevator_name, name))
+                       return e;
        }
 
-       return e;
+       return NULL;
 }
 
 static void elevator_put(struct elevator_type *e)
@@ -1088,7 +1085,7 @@ ssize_t elv_iosched_show(request_queue_t *q, char *name)
        struct list_head *entry;
        int len = 0;
 
-       spin_lock_irq(q->queue_lock);
+       spin_lock_irq(&elv_list_lock);
        list_for_each(entry, &elv_list) {
                struct elevator_type *__e;
 
@@ -1098,7 +1095,7 @@ ssize_t elv_iosched_show(request_queue_t *q, char *name)
                else
                        len += sprintf(name+len, "%s ", __e->elevator_name);
        }
-       spin_unlock_irq(q->queue_lock);
+       spin_unlock_irq(&elv_list_lock);
 
        len += sprintf(len+name, "\n");
        return len;
index c847e17e5caa3dbf894631c321b3608c2417ca40..136066583c6810b6520c9a090f428427819d44c2 100644 (file)
@@ -56,11 +56,6 @@ static kmem_cache_t *requestq_cachep;
  */
 static kmem_cache_t *iocontext_cachep;
 
-static wait_queue_head_t congestion_wqh[2] = {
-               __WAIT_QUEUE_HEAD_INITIALIZER(congestion_wqh[0]),
-               __WAIT_QUEUE_HEAD_INITIALIZER(congestion_wqh[1])
-       };
-
 /*
  * Controlling structure to kblockd
  */
@@ -112,35 +107,6 @@ static void blk_queue_congestion_threshold(struct request_queue *q)
        q->nr_congestion_off = nr;
 }
 
-/*
- * A queue has just exitted congestion.  Note this in the global counter of
- * congested queues, and wake up anyone who was waiting for requests to be
- * put back.
- */
-static void clear_queue_congested(request_queue_t *q, int rw)
-{
-       enum bdi_state bit;
-       wait_queue_head_t *wqh = &congestion_wqh[rw];
-
-       bit = (rw == WRITE) ? BDI_write_congested : BDI_read_congested;
-       clear_bit(bit, &q->backing_dev_info.state);
-       smp_mb__after_clear_bit();
-       if (waitqueue_active(wqh))
-               wake_up(wqh);
-}
-
-/*
- * A queue has just entered congestion.  Flag that in the queue's VM-visible
- * state flags and increment the global gounter of congested queues.
- */
-static void set_queue_congested(request_queue_t *q, int rw)
-{
-       enum bdi_state bit;
-
-       bit = (rw == WRITE) ? BDI_write_congested : BDI_read_congested;
-       set_bit(bit, &q->backing_dev_info.state);
-}
-
 /**
  * blk_get_backing_dev_info - get the address of a queue's backing_dev_info
  * @bdev:      device
@@ -159,7 +125,6 @@ struct backing_dev_info *blk_get_backing_dev_info(struct block_device *bdev)
                ret = &q->backing_dev_info;
        return ret;
 }
-
 EXPORT_SYMBOL(blk_get_backing_dev_info);
 
 void blk_queue_activity_fn(request_queue_t *q, activity_fn *fn, void *data)
@@ -167,7 +132,6 @@ void blk_queue_activity_fn(request_queue_t *q, activity_fn *fn, void *data)
        q->activity_fn = fn;
        q->activity_data = data;
 }
-
 EXPORT_SYMBOL(blk_queue_activity_fn);
 
 /**
@@ -2067,7 +2031,7 @@ static void __freed_request(request_queue_t *q, int rw)
        struct request_list *rl = &q->rq;
 
        if (rl->count[rw] < queue_congestion_off_threshold(q))
-               clear_queue_congested(q, rw);
+               blk_clear_queue_congested(q, rw);
 
        if (rl->count[rw] + 1 <= q->nr_requests) {
                if (waitqueue_active(&rl->wait[rw]))
@@ -2137,7 +2101,7 @@ static struct request *get_request(request_queue_t *q, int rw, struct bio *bio,
                                }
                        }
                }
-               set_queue_congested(q, rw);
+               blk_set_queue_congested(q, rw);
        }
 
        /*
@@ -2755,41 +2719,6 @@ void blk_end_sync_rq(struct request *rq, int error)
 }
 EXPORT_SYMBOL(blk_end_sync_rq);
 
-/**
- * blk_congestion_wait - wait for a queue to become uncongested
- * @rw: READ or WRITE
- * @timeout: timeout in jiffies
- *
- * Waits for up to @timeout jiffies for a queue (any queue) to exit congestion.
- * If no queues are congested then just wait for the next request to be
- * returned.
- */
-long blk_congestion_wait(int rw, long timeout)
-{
-       long ret;
-       DEFINE_WAIT(wait);
-       wait_queue_head_t *wqh = &congestion_wqh[rw];
-
-       prepare_to_wait(wqh, &wait, TASK_UNINTERRUPTIBLE);
-       ret = io_schedule_timeout(timeout);
-       finish_wait(wqh, &wait);
-       return ret;
-}
-
-EXPORT_SYMBOL(blk_congestion_wait);
-
-/**
- * blk_congestion_end - wake up sleepers on a congestion queue
- * @rw: READ or WRITE
- */
-void blk_congestion_end(int rw)
-{
-       wait_queue_head_t *wqh = &congestion_wqh[rw];
-
-       if (waitqueue_active(wqh))
-               wake_up(wqh);
-}
-
 /*
  * Has to be called with the request spinlock acquired
  */
@@ -3765,14 +3694,14 @@ queue_requests_store(struct request_queue *q, const char *page, size_t count)
        blk_queue_congestion_threshold(q);
 
        if (rl->count[READ] >= queue_congestion_on_threshold(q))
-               set_queue_congested(q, READ);
+               blk_set_queue_congested(q, READ);
        else if (rl->count[READ] < queue_congestion_off_threshold(q))
-               clear_queue_congested(q, READ);
+               blk_clear_queue_congested(q, READ);
 
        if (rl->count[WRITE] >= queue_congestion_on_threshold(q))
-               set_queue_congested(q, WRITE);
+               blk_set_queue_congested(q, WRITE);
        else if (rl->count[WRITE] < queue_congestion_off_threshold(q))
-               clear_queue_congested(q, WRITE);
+               blk_clear_queue_congested(q, WRITE);
 
        if (rl->count[READ] >= q->nr_requests) {
                blk_set_queue_full(q, READ);
index 1e2f39c211801adb4a8d80eaa288647cc524ba3d..cbae8392ce11b848e5573194eb8591a175815822 100644 (file)
@@ -27,7 +27,6 @@ config CRYPTO_HASH
 config CRYPTO_MANAGER
        tristate "Cryptographic algorithm manager"
        select CRYPTO_ALGAPI
-       default m
        help
          Create default cryptographic template instantiations such as
          cbc(aes).
@@ -35,6 +34,7 @@ config CRYPTO_MANAGER
 config CRYPTO_HMAC
        tristate "HMAC support"
        select CRYPTO_HASH
+       select CRYPTO_MANAGER
        help
          HMAC: Keyed-Hashing for Message Authentication (RFC2104).
          This is required for IPSec.
@@ -131,6 +131,7 @@ config CRYPTO_TGR192
 config CRYPTO_ECB
        tristate "ECB support"
        select CRYPTO_BLKCIPHER
+       select CRYPTO_MANAGER
        default m
        help
          ECB: Electronic CodeBook mode
@@ -140,6 +141,7 @@ config CRYPTO_ECB
 config CRYPTO_CBC
        tristate "CBC support"
        select CRYPTO_BLKCIPHER
+       select CRYPTO_MANAGER
        default m
        help
          CBC: Cipher Block Chaining mode
index 2e84d4b547902d9e4827ad0f0a26a4d6e5939dbd..4fb7fa45cb0de649194262c5f6061669b3391a80 100644 (file)
@@ -331,7 +331,7 @@ struct crypto_tfm *__crypto_alloc_tfm(struct crypto_alg *alg, u32 flags)
        tfm_size = sizeof(*tfm) + crypto_ctxsize(alg, flags);
        tfm = kzalloc(tfm_size, GFP_KERNEL);
        if (tfm == NULL)
-               goto out;
+               goto out_err;
 
        tfm->__crt_alg = alg;
 
@@ -355,6 +355,7 @@ cra_init_failed:
        crypto_exit_ops(tfm);
 out_free_tfm:
        kfree(tfm);
+out_err:
        tfm = ERR_PTR(err);
 out:
        return tfm;
@@ -414,14 +415,14 @@ struct crypto_tfm *crypto_alloc_base(const char *alg_name, u32 type, u32 mask)
                struct crypto_alg *alg;
 
                alg = crypto_alg_mod_lookup(alg_name, type, mask);
-               err = PTR_ERR(alg);
-               tfm = ERR_PTR(err);
-               if (IS_ERR(alg))
+               if (IS_ERR(alg)) {
+                       err = PTR_ERR(alg);
                        goto err;
+               }
 
                tfm = __crypto_alloc_tfm(alg, 0);
                if (!IS_ERR(tfm))
-                       break;
+                       return tfm;
 
                crypto_mod_put(alg);
                err = PTR_ERR(tfm);
@@ -433,9 +434,9 @@ err:
                        err = -EINTR;
                        break;
                }
-       };
+       }
 
-       return tfm;
+       return ERR_PTR(err);
 }
 EXPORT_SYMBOL_GPL(crypto_alloc_base);
  
index 465d091cd3ec3439fe65f0e91d48adc23151667e..2b0a19a44ec596047d541dbefb1cc28f67ee6b86 100644 (file)
@@ -364,10 +364,10 @@ static void serpent_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
 {
        struct serpent_ctx *ctx = crypto_tfm_ctx(tfm);
        const u32
-               *k = ctx->expkey,
-               *s = (const u32 *)src;
-       u32     *d = (u32 *)dst,
-               r0, r1, r2, r3, r4;
+               *k = ctx->expkey;
+       const __le32 *s = (const __le32 *)src;
+       __le32  *d = (__le32 *)dst;
+       u32     r0, r1, r2, r3, r4;
 
 /*
  * Note: The conversions between u8* and u32* might cause trouble
@@ -423,10 +423,10 @@ static void serpent_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
 {
        struct serpent_ctx *ctx = crypto_tfm_ctx(tfm);
        const u32
-               *k = ((struct serpent_ctx *)ctx)->expkey,
-               *s = (const u32 *)src;
-       u32     *d = (u32 *)dst,
-               r0, r1, r2, r3, r4;
+               *k = ((struct serpent_ctx *)ctx)->expkey;
+       const __le32 *s = (const __le32 *)src;
+       __le32  *d = (__le32 *)dst;
+       u32     r0, r1, r2, r3, r4;
 
        r0 = le32_to_cpu(s[0]);
        r1 = le32_to_cpu(s[1]);
index 263e86ddc1a4d0740b3e524ced6703d3a991f3d2..f39463418904f0777e105911edfec32b0331dc7a 100644 (file)
@@ -14,6 +14,10 @@ source "drivers/pnp/Kconfig"
 
 source "drivers/block/Kconfig"
 
+# misc before ide - BLK_DEV_SGIIOC4 depends on SGI_IOC4
+
+source "drivers/misc/Kconfig"
+
 source "drivers/ide/Kconfig"
 
 source "drivers/scsi/Kconfig"
@@ -52,8 +56,6 @@ source "drivers/w1/Kconfig"
 
 source "drivers/hwmon/Kconfig"
 
-source "drivers/misc/Kconfig"
-
 source "drivers/mfd/Kconfig"
 
 source "drivers/media/Kconfig"
index 1bace29f4b6a0ae1b92dc40747ee1bdd6bde71da..7fde8f4daebfff867e688e275c09a735634c9292 100644 (file)
@@ -938,7 +938,7 @@ static void do_mfm_request(request_queue_t *q)
        mfm_request();
 }
 
-static void mfm_interrupt_handler(int unused, void *dev_id, struct pt_regs *regs)
+static void mfm_interrupt_handler(int unused, void *dev_id)
 {
        void (*handler) (void) = do_mfm;
 
index 98099de59b45bcfec5ee8636650c5eb29ee5fbd0..6bcd9e8e7bcb2b081df4262a20489f9fd7ec0779 100644 (file)
@@ -85,6 +85,8 @@ struct acpi_memory_device {
        struct list_head res_list;
 };
 
+static int acpi_hotmem_initialized;
+
 static acpi_status
 acpi_memory_get_resource(struct acpi_resource *resource, void *context)
 {
@@ -414,7 +416,7 @@ static int acpi_memory_device_add(struct acpi_device *device)
        /* Set the device state */
        mem_device->state = MEMORY_POWER_ON_STATE;
 
-       printk(KERN_INFO "%s \n", acpi_device_name(device));
+       printk(KERN_DEBUG "%s \n", acpi_device_name(device));
 
        return result;
 }
@@ -438,6 +440,15 @@ static int acpi_memory_device_start (struct acpi_device *device)
        struct acpi_memory_device *mem_device;
        int result = 0;
 
+       /*
+        * Early boot code has recognized memory area by EFI/E820.
+        * If DSDT shows these memory devices on boot, hotplug is not necessary
+        * for them. So, it just returns until completion of this driver's
+        * start up.
+        */
+       if (!acpi_hotmem_initialized)
+               return 0;
+
        mem_device = acpi_driver_data(device);
 
        if (!acpi_memory_check_device(mem_device)) {
@@ -537,6 +548,7 @@ static int __init acpi_memory_device_init(void)
                return -ENODEV;
        }
 
+       acpi_hotmem_initialized = 1;
        return 0;
 }
 
index e9ee4c52a5f6266a7edc5df20d80aad2647338ea..c7ac9297a20499893da15a4f2c766285310d6f1b 100644 (file)
@@ -138,6 +138,7 @@ struct asus_hotk {
                S2x,            //S200 (J1 reported), Victor MP-XP7210
                W1N,            //W1000N
                W5A,            //W5A
+               W3V,            //W3030V
                xxN,            //M2400N, M3700N, M5200N, M6800N, S1300N, S5200N
                //(Centrino)
                END_MODEL
@@ -376,6 +377,17 @@ static struct model_data model_conf[END_MODEL] = {
         .display_get = "\\ADVG"},
 
        {
+        .name = "W3V",
+        .mt_mled = "MLED",
+        .mt_wled = "WLED",
+        .mt_lcd_switch = xxN_PREFIX "_Q10",
+        .lcd_status = "\\BKLT",
+        .brightness_set = "SPLV",
+        .brightness_get = "GPLV",
+        .display_set = "SDSP",
+        .display_get = "\\INFB"},
+
+       {
         .name = "xxN",
         .mt_mled = "MLED",
 /* WLED present, but not controlled by ACPI */
@@ -555,11 +567,11 @@ static int
 write_led(const char __user * buffer, unsigned long count,
          char *ledname, int ledmask, int invert)
 {
-       int value;
+       int rv, value;
        int led_out = 0;
 
-       count = parse_arg(buffer, count, &value);
-       if (count > 0)
+       rv = parse_arg(buffer, count, &value);
+       if (rv > 0)
                led_out = value ? 1 : 0;
 
        hotk->status =
@@ -572,7 +584,7 @@ write_led(const char __user * buffer, unsigned long count,
                printk(KERN_WARNING "Asus ACPI: LED (%s) write failed\n",
                       ledname);
 
-       return count;
+       return rv;
 }
 
 /*
@@ -607,20 +619,18 @@ static int
 proc_write_ledd(struct file *file, const char __user * buffer,
                unsigned long count, void *data)
 {
-       int value;
+       int rv, value;
 
-       count = parse_arg(buffer, count, &value);
-       if (count > 0) {
+       rv = parse_arg(buffer, count, &value);
+       if (rv > 0) {
                if (!write_acpi_int
                    (hotk->handle, hotk->methods->mt_ledd, value, NULL))
                        printk(KERN_WARNING
                               "Asus ACPI: LED display write failed\n");
                else
                        hotk->ledd_status = (u32) value;
-       } else if (count < 0)
-               printk(KERN_WARNING "Asus ACPI: Error reading user input\n");
-
-       return count;
+       }
+       return rv;
 }
 
 /*
@@ -761,12 +771,12 @@ static int
 proc_write_lcd(struct file *file, const char __user * buffer,
               unsigned long count, void *data)
 {
-       int value;
+       int rv, value;
 
-       count = parse_arg(buffer, count, &value);
-       if (count > 0)
+       rv = parse_arg(buffer, count, &value);
+       if (rv > 0)
                set_lcd_state(value);
-       return count;
+       return rv;
 }
 
 static int read_brightness(void)
@@ -830,18 +840,15 @@ static int
 proc_write_brn(struct file *file, const char __user * buffer,
               unsigned long count, void *data)
 {
-       int value;
+       int rv, value;
 
-       count = parse_arg(buffer, count, &value);
-       if (count > 0) {
+       rv = parse_arg(buffer, count, &value);
+       if (rv > 0) {
                value = (0 < value) ? ((15 < value) ? 15 : value) : 0;
                /* 0 <= value <= 15 */
                set_brightness(value);
-       } else if (count < 0) {
-               printk(KERN_WARNING "Asus ACPI: Error reading user input\n");
        }
-
-       return count;
+       return rv;
 }
 
 static void set_display(int value)
@@ -880,15 +887,12 @@ static int
 proc_write_disp(struct file *file, const char __user * buffer,
                unsigned long count, void *data)
 {
-       int value;
+       int rv, value;
 
-       count = parse_arg(buffer, count, &value);
-       if (count > 0)
+       rv = parse_arg(buffer, count, &value);
+       if (rv > 0)
                set_display(value);
-       else if (count < 0)
-               printk(KERN_WARNING "Asus ACPI: Error reading user input\n");
-
-       return count;
+       return rv;
 }
 
 typedef int (proc_readfunc) (char *page, char **start, off_t off, int count,
@@ -1097,6 +1101,8 @@ static int asus_model_match(char *model)
                return A4G;
        else if (strncmp(model, "W1N", 3) == 0)
                return W1N;
+       else if (strncmp(model, "W3V", 3) == 0)
+               return W3V;
        else if (strncmp(model, "W5A", 3) == 0)
                return W5A;
        else
@@ -1200,9 +1206,10 @@ static int asus_hotk_get_info(void)
                hotk->methods->mt_wled = NULL;
        /* L5D's WLED is not controlled by ACPI */
        else if (strncmp(string, "M2N", 3) == 0 ||
+                strncmp(string, "W3V", 3) == 0 ||
                 strncmp(string, "S1N", 3) == 0)
                hotk->methods->mt_wled = "WLED";
-       /* M2N and S1N have a usable WLED */
+       /* M2N, S1N and W3V have a usable WLED */
        else if (asus_info) {
                if (strncmp(asus_info->oem_table_id, "L1", 2) == 0)
                        hotk->methods->mled_status = NULL;
index 9810e2a55d0adf3fb77758b20b9b670f3e2f5342..026e40755cdd7b0780c4832aade6a9601fb9db83 100644 (file)
@@ -64,6 +64,7 @@ extern void *acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir);
 
 static int acpi_battery_add(struct acpi_device *device);
 static int acpi_battery_remove(struct acpi_device *device, int type);
+static int acpi_battery_resume(struct acpi_device *device, int status);
 
 static struct acpi_driver acpi_battery_driver = {
        .name = ACPI_BATTERY_DRIVER_NAME,
@@ -71,6 +72,7 @@ static struct acpi_driver acpi_battery_driver = {
        .ids = ACPI_BATTERY_HID,
        .ops = {
                .add = acpi_battery_add,
+               .resume = acpi_battery_resume,
                .remove = acpi_battery_remove,
                },
 };
@@ -753,6 +755,18 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
        return 0;
 }
 
+/* this is needed to learn about changes made in suspended state */
+static int acpi_battery_resume(struct acpi_device *device, int state)
+{
+       struct acpi_battery *battery;
+
+       if (!device)
+               return -EINVAL;
+
+       battery = device->driver_data;
+       return acpi_battery_check(battery);
+}
+
 static int __init acpi_battery_init(void)
 {
        int result;
index a01ce6700bfeb6809e24b5b4936963d4e8b06c59..4a9b7bf6f44ed79a3fff799c3a5245ed49f273a6 100644 (file)
@@ -67,7 +67,7 @@ void acpi_unlock_ac_dir(struct proc_dir_entry *acpi_ac_dir_param)
                lock_ac_dir_cnt--;
        if (lock_ac_dir_cnt == 0 && acpi_ac_dir_param && acpi_ac_dir) {
                remove_proc_entry(ACPI_AC_CLASS, acpi_root_dir);
-               acpi_ac_dir = 0;
+               acpi_ac_dir = NULL;
        }
        mutex_unlock(&cm_sbs_mutex);
 }
@@ -99,7 +99,7 @@ void acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir_param)
        if (lock_battery_dir_cnt == 0 && acpi_battery_dir_param
            && acpi_battery_dir) {
                remove_proc_entry(ACPI_BATTERY_CLASS, acpi_root_dir);
-               acpi_battery_dir = 0;
+               acpi_battery_dir = NULL;
        }
        mutex_unlock(&cm_sbs_mutex);
        return;
index e5d7963628543edd9eb6d91042d795df11433e19..e6d4b084dca2eeb40213074998ccdfde52278260 100644 (file)
@@ -45,206 +45,143 @@ ACPI_MODULE_NAME("acpi_ec")
 #define ACPI_EC_DRIVER_NAME            "ACPI Embedded Controller Driver"
 #define ACPI_EC_DEVICE_NAME            "Embedded Controller"
 #define ACPI_EC_FILE_INFO              "info"
+
+/* EC status register */
 #define ACPI_EC_FLAG_OBF       0x01    /* Output buffer full */
 #define ACPI_EC_FLAG_IBF       0x02    /* Input buffer full */
 #define ACPI_EC_FLAG_BURST     0x10    /* burst mode */
 #define ACPI_EC_FLAG_SCI       0x20    /* EC-SCI occurred */
-#define ACPI_EC_EVENT_OBF      0x01    /* Output buffer full */
-#define ACPI_EC_EVENT_IBE      0x02    /* Input buffer empty */
-#define ACPI_EC_DELAY          50      /* Wait 50ms max. during EC ops */
-#define ACPI_EC_UDELAY_GLK     1000    /* Wait 1ms max. to get global lock */
-#define ACPI_EC_UDELAY         100     /* Poll @ 100us increments */
-#define ACPI_EC_UDELAY_COUNT   1000    /* Wait 10ms max. during EC ops */
+
+/* EC commands */
 #define ACPI_EC_COMMAND_READ   0x80
 #define ACPI_EC_COMMAND_WRITE  0x81
 #define ACPI_EC_BURST_ENABLE   0x82
 #define ACPI_EC_BURST_DISABLE  0x83
 #define ACPI_EC_COMMAND_QUERY  0x84
-#define EC_POLL                        0xFF
-#define EC_INTR                        0x00
+
+/* EC events */
+enum {
+       ACPI_EC_EVENT_OBF_1 = 1,        /* Output buffer full */
+       ACPI_EC_EVENT_IBF_0,            /* Input buffer empty */
+};
+
+#define ACPI_EC_DELAY          50      /* Wait 50ms max. during EC ops */
+#define ACPI_EC_UDELAY_GLK     1000    /* Wait 1ms max. to get global lock */
+#define ACPI_EC_UDELAY         100     /* Poll @ 100us increments */
+#define ACPI_EC_UDELAY_COUNT   1000    /* Wait 10ms max. during EC ops */
+
+enum {
+       EC_INTR = 1,    /* Output buffer full */
+       EC_POLL,        /* Input buffer empty */
+};
+
 static int acpi_ec_remove(struct acpi_device *device, int type);
 static int acpi_ec_start(struct acpi_device *device);
 static int acpi_ec_stop(struct acpi_device *device, int type);
-static int acpi_ec_intr_add(struct acpi_device *device);
-static int acpi_ec_poll_add(struct acpi_device *device);
+static int acpi_ec_add(struct acpi_device *device);
 
 static struct acpi_driver acpi_ec_driver = {
        .name = ACPI_EC_DRIVER_NAME,
        .class = ACPI_EC_CLASS,
        .ids = ACPI_EC_HID,
        .ops = {
-               .add = acpi_ec_intr_add,
+               .add = acpi_ec_add,
                .remove = acpi_ec_remove,
                .start = acpi_ec_start,
                .stop = acpi_ec_stop,
                },
 };
-union acpi_ec {
-       struct {
-               u32 mode;
-               acpi_handle handle;
-               unsigned long uid;
-               unsigned long gpe_bit;
-               struct acpi_generic_address status_addr;
-               struct acpi_generic_address command_addr;
-               struct acpi_generic_address data_addr;
-               unsigned long global_lock;
-       } common;
-
-       struct {
-               u32 mode;
-               acpi_handle handle;
-               unsigned long uid;
-               unsigned long gpe_bit;
-               struct acpi_generic_address status_addr;
-               struct acpi_generic_address command_addr;
-               struct acpi_generic_address data_addr;
-               unsigned long global_lock;
-               unsigned int expect_event;
-               atomic_t leaving_burst; /* 0 : No, 1 : Yes, 2: abort */
-               atomic_t pending_gpe;
-               struct semaphore sem;
-               wait_queue_head_t wait;
-       } intr;
-
-       struct {
-               u32 mode;
-               acpi_handle handle;
-               unsigned long uid;
-               unsigned long gpe_bit;
-               struct acpi_generic_address status_addr;
-               struct acpi_generic_address command_addr;
-               struct acpi_generic_address data_addr;
-               unsigned long global_lock;
-               struct semaphore sem;
-       } poll;
-};
 
-static int acpi_ec_poll_wait(union acpi_ec *ec, u8 event);
-static int acpi_ec_intr_wait(union acpi_ec *ec, unsigned int event);
-static int acpi_ec_poll_read(union acpi_ec *ec, u8 address, u32 * data);
-static int acpi_ec_intr_read(union acpi_ec *ec, u8 address, u32 * data);
-static int acpi_ec_poll_write(union acpi_ec *ec, u8 address, u8 data);
-static int acpi_ec_intr_write(union acpi_ec *ec, u8 address, u8 data);
-static int acpi_ec_poll_query(union acpi_ec *ec, u32 * data);
-static int acpi_ec_intr_query(union acpi_ec *ec, u32 * data);
-static void acpi_ec_gpe_poll_query(void *ec_cxt);
-static void acpi_ec_gpe_intr_query(void *ec_cxt);
-static u32 acpi_ec_gpe_poll_handler(void *data);
-static u32 acpi_ec_gpe_intr_handler(void *data);
-static acpi_status __init
-acpi_fake_ecdt_poll_callback(acpi_handle handle,
-                               u32 Level, void *context, void **retval);
-
-static acpi_status __init
-acpi_fake_ecdt_intr_callback(acpi_handle handle,
-                             u32 Level, void *context, void **retval);
-
-static int __init acpi_ec_poll_get_real_ecdt(void);
-static int __init acpi_ec_intr_get_real_ecdt(void);
 /* If we find an EC via the ECDT, we need to keep a ptr to its context */
-static union acpi_ec *ec_ecdt;
+struct acpi_ec {
+       acpi_handle handle;
+       unsigned long uid;
+       unsigned long gpe_bit;
+       unsigned long command_addr;
+       unsigned long data_addr;
+       unsigned long global_lock;
+       struct semaphore sem;
+       unsigned int expect_event;
+       atomic_t leaving_burst; /* 0 : No, 1 : Yes, 2: abort */
+       wait_queue_head_t wait;
+} *ec_ecdt;
 
 /* External interfaces use first EC only, so remember */
 static struct acpi_device *first_ec;
-static int acpi_ec_poll_mode = EC_INTR;
+static int acpi_ec_mode = EC_INTR;
 
 /* --------------------------------------------------------------------------
                              Transaction Management
    -------------------------------------------------------------------------- */
 
-static u32 acpi_ec_read_status(union acpi_ec *ec)
+static inline u8 acpi_ec_read_status(struct acpi_ec *ec)
 {
-       u32 status = 0;
-
-       acpi_hw_low_level_read(8, &status, &ec->common.status_addr);
-       return status;
+       return inb(ec->command_addr);
 }
 
-static int acpi_ec_wait(union acpi_ec *ec, u8 event)
+static inline u8 acpi_ec_read_data(struct acpi_ec *ec)
 {
-       if (acpi_ec_poll_mode)
-               return acpi_ec_poll_wait(ec, event);
-       else
-               return acpi_ec_intr_wait(ec, event);
+       return inb(ec->data_addr);
 }
 
-static int acpi_ec_poll_wait(union acpi_ec *ec, u8 event)
+static inline void acpi_ec_write_cmd(struct acpi_ec *ec, u8 command)
 {
-       u32 acpi_ec_status = 0;
-       u32 i = ACPI_EC_UDELAY_COUNT;
+       outb(command, ec->command_addr);
+}
 
-       if (!ec)
-               return -EINVAL;
+static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data)
+{
+       outb(data, ec->data_addr);
+}
 
-       /* Poll the EC status register waiting for the event to occur. */
+static int acpi_ec_check_status(u8 status, u8 event)
+{
        switch (event) {
-       case ACPI_EC_EVENT_OBF:
-               do {
-                       acpi_hw_low_level_read(8, &acpi_ec_status,
-                                              &ec->common.status_addr);
-                       if (acpi_ec_status & ACPI_EC_FLAG_OBF)
-                               return 0;
-                       udelay(ACPI_EC_UDELAY);
-               } while (--i > 0);
+       case ACPI_EC_EVENT_OBF_1:
+               if (status & ACPI_EC_FLAG_OBF)
+                       return 1;
                break;
-       case ACPI_EC_EVENT_IBE:
-               do {
-                       acpi_hw_low_level_read(8, &acpi_ec_status,
-                                              &ec->common.status_addr);
-                       if (!(acpi_ec_status & ACPI_EC_FLAG_IBF))
-                               return 0;
-                       udelay(ACPI_EC_UDELAY);
-               } while (--i > 0);
+       case ACPI_EC_EVENT_IBF_0:
+               if (!(status & ACPI_EC_FLAG_IBF))
+                       return 1;
                break;
        default:
-               return -EINVAL;
+               break;
        }
 
-       return -ETIME;
+       return 0;
 }
-static int acpi_ec_intr_wait(union acpi_ec *ec, unsigned int event)
-{
-       int result = 0;
-
 
-       ec->intr.expect_event = event;
-       smp_mb();
+static int acpi_ec_wait(struct acpi_ec *ec, u8 event)
+{
+       int i = (acpi_ec_mode == EC_POLL) ? ACPI_EC_UDELAY_COUNT : 0;
+       long time_left;
 
-       switch (event) {
-       case ACPI_EC_EVENT_IBE:
-               if (~acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF) {
-                       ec->intr.expect_event = 0;
-                       return 0;
-               }
-               break;
-       default:
-               break;
+       ec->expect_event = event;
+       if (acpi_ec_check_status(acpi_ec_read_status(ec), event)) {
+               ec->expect_event = 0;
+               return 0;
        }
 
-       result = wait_event_timeout(ec->intr.wait,
-                                   !ec->intr.expect_event,
+       do {
+               if (acpi_ec_mode == EC_POLL) {
+                       udelay(ACPI_EC_UDELAY);
+               } else {
+                       time_left = wait_event_timeout(ec->wait,
+                                   !ec->expect_event,
                                    msecs_to_jiffies(ACPI_EC_DELAY));
-
-       ec->intr.expect_event = 0;
-       smp_mb();
-
-       /*
-        * Verify that the event in question has actually happened by
-        * querying EC status. Do the check even if operation timed-out
-        * to make sure that we did not miss interrupt.
-        */
-       switch (event) {
-       case ACPI_EC_EVENT_OBF:
-               if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_OBF)
+                       if (time_left > 0) {
+                               ec->expect_event = 0;
+                               return 0;
+                       }
+               }
+               if (acpi_ec_check_status(acpi_ec_read_status(ec), event)) {
+                       ec->expect_event = 0;
                        return 0;
-               break;
+               }
+       } while (--i > 0);
 
-       case ACPI_EC_EVENT_IBE:
-               if (~acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF)
-                       return 0;
-               break;
-       }
+       ec->expect_event = 0;
 
        return -ETIME;
 }
@@ -254,272 +191,150 @@ static int acpi_ec_intr_wait(union acpi_ec *ec, unsigned int event)
  * Note: samsung nv5000 doesn't work with ec burst mode.
  * http://bugzilla.kernel.org/show_bug.cgi?id=4980
  */
-int acpi_ec_enter_burst_mode(union acpi_ec *ec)
+int acpi_ec_enter_burst_mode(struct acpi_ec *ec)
 {
-       u32 tmp = 0;
-       int status = 0;
+       u8 tmp = 0;
+       u8 status = 0;
 
 
        status = acpi_ec_read_status(ec);
        if (status != -EINVAL && !(status & ACPI_EC_FLAG_BURST)) {
-               status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
+               status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0);
                if (status)
                        goto end;
-               acpi_hw_low_level_write(8, ACPI_EC_BURST_ENABLE,
-                                       &ec->common.command_addr);
-               status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
-               acpi_hw_low_level_read(8, &tmp, &ec->common.data_addr);
+               acpi_ec_write_cmd(ec, ACPI_EC_BURST_ENABLE);
+               status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF_1);
+               tmp = acpi_ec_read_data(ec);
                if (tmp != 0x90) {      /* Burst ACK byte */
                        return -EINVAL;
                }
        }
 
-       atomic_set(&ec->intr.leaving_burst, 0);
+       atomic_set(&ec->leaving_burst, 0);
        return 0;
-      end:
-       ACPI_EXCEPTION ((AE_INFO, status, "EC wait, burst mode");
+  end:
+       ACPI_EXCEPTION((AE_INFO, status, "EC wait, burst mode"));
        return -1;
 }
 
-int acpi_ec_leave_burst_mode(union acpi_ec *ec)
+int acpi_ec_leave_burst_mode(struct acpi_ec *ec)
 {
-       int status = 0;
+       u8 status = 0;
 
 
        status = acpi_ec_read_status(ec);
        if (status != -EINVAL && (status & ACPI_EC_FLAG_BURST)){
-               status = acpi_ec_wait(ec, ACPI_EC_FLAG_IBF);
+               status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0);
                if(status)
                        goto end;
-               acpi_hw_low_level_write(8, ACPI_EC_BURST_DISABLE, &ec->common.command_addr);
-               acpi_ec_wait(ec, ACPI_EC_FLAG_IBF);
-       } 
-       atomic_set(&ec->intr.leaving_burst, 1);
+               acpi_ec_write_cmd(ec, ACPI_EC_BURST_DISABLE);
+               acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0);
+       }
+       atomic_set(&ec->leaving_burst, 1);
        return 0;
-end:
-       ACPI_EXCEPTION((AE_INFO, status, "EC leave burst mode");
+  end:
+       ACPI_EXCEPTION((AE_INFO, status, "EC leave burst mode"));
        return -1;
 }
 #endif /* ACPI_FUTURE_USAGE */
 
-static int acpi_ec_read(union acpi_ec *ec, u8 address, u32 * data)
-{
-       if (acpi_ec_poll_mode)
-               return acpi_ec_poll_read(ec, address, data);
-       else
-               return acpi_ec_intr_read(ec, address, data);
-}
-static int acpi_ec_write(union acpi_ec *ec, u8 address, u8 data)
-{
-       if (acpi_ec_poll_mode)
-               return acpi_ec_poll_write(ec, address, data);
-       else
-               return acpi_ec_intr_write(ec, address, data);
-}
-static int acpi_ec_poll_read(union acpi_ec *ec, u8 address, u32 * data)
+static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command,
+                                       const u8 *wdata, unsigned wdata_len,
+                                       u8 *rdata, unsigned rdata_len)
 {
-       acpi_status status = AE_OK;
-       int result = 0;
-       u32 glk = 0;
+       int result;
 
+       acpi_ec_write_cmd(ec, command);
 
-       if (!ec || !data)
-               return -EINVAL;
-
-       *data = 0;
-
-       if (ec->common.global_lock) {
-               status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
-               if (ACPI_FAILURE(status))
-                       return -ENODEV;
+       for (; wdata_len > 0; wdata_len --) {
+               result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0);
+               if (result)
+                       return result;
+               acpi_ec_write_data(ec, *(wdata++));
        }
 
-       if (down_interruptible(&ec->poll.sem)) {
-               result = -ERESTARTSYS;
-               goto end_nosem;
+       if (command == ACPI_EC_COMMAND_WRITE) {
+               result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0);
+               if (result)
+                       return result;
        }
-       
-       acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ,
-                               &ec->common.command_addr);
-       result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
-       if (result)
-               goto end;
-
-       acpi_hw_low_level_write(8, address, &ec->common.data_addr);
-       result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
-       if (result)
-               goto end;
-
-       acpi_hw_low_level_read(8, data, &ec->common.data_addr);
-
-       ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Read [%02x] from address [%02x]\n",
-                         *data, address));
-
-      end:
-       up(&ec->poll.sem);
-end_nosem:
-       if (ec->common.global_lock)
-               acpi_release_global_lock(glk);
-
-       return result;
-}
-
-static int acpi_ec_poll_write(union acpi_ec *ec, u8 address, u8 data)
-{
-       int result = 0;
-       acpi_status status = AE_OK;
-       u32 glk = 0;
 
+       for (; rdata_len > 0; rdata_len --) {
+               result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF_1);
+               if (result)
+                       return result;
 
-       if (!ec)
-               return -EINVAL;
-
-       if (ec->common.global_lock) {
-               status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
-               if (ACPI_FAILURE(status))
-                       return -ENODEV;
-       }
-
-       if (down_interruptible(&ec->poll.sem)) {
-               result = -ERESTARTSYS;
-               goto end_nosem;
+               *(rdata++) = acpi_ec_read_data(ec);
        }
-       
-       acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE,
-                               &ec->common.command_addr);
-       result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
-       if (result)
-               goto end;
-
-       acpi_hw_low_level_write(8, address, &ec->common.data_addr);
-       result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
-       if (result)
-               goto end;
-
-       acpi_hw_low_level_write(8, data, &ec->common.data_addr);
-       result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
-       if (result)
-               goto end;
 
-       ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Wrote [%02x] to address [%02x]\n",
-                         data, address));
-
-      end:
-       up(&ec->poll.sem);
-end_nosem:
-       if (ec->common.global_lock)
-               acpi_release_global_lock(glk);
-
-       return result;
+       return 0;
 }
 
-static int acpi_ec_intr_read(union acpi_ec *ec, u8 address, u32 * data)
+static int acpi_ec_transaction(struct acpi_ec *ec, u8 command,
+                               const u8 *wdata, unsigned wdata_len,
+                               u8 *rdata, unsigned rdata_len)
 {
-       int status = 0;
+       int status;
        u32 glk;
 
-
-       if (!ec || !data)
+       if (!ec || (wdata_len && !wdata) || (rdata_len && !rdata))
                return -EINVAL;
 
-       *data = 0;
+        if (rdata)
+                memset(rdata, 0, rdata_len);
 
-       if (ec->common.global_lock) {
+       if (ec->global_lock) {
                status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
                if (ACPI_FAILURE(status))
                        return -ENODEV;
        }
+       down(&ec->sem);
 
-       WARN_ON(in_interrupt());
-       down(&ec->intr.sem);
-
-       status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
+       status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0);
        if (status) {
                printk(KERN_DEBUG PREFIX "read EC, IB not empty\n");
                goto end;
        }
-       acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ,
-                               &ec->common.command_addr);
-       status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
-       if (status) {
-               printk(KERN_DEBUG PREFIX "read EC, IB not empty\n");
-       }
 
-       acpi_hw_low_level_write(8, address, &ec->common.data_addr);
-       status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
-       if (status) {
-               printk(KERN_DEBUG PREFIX "read EC, OB not full\n");
-               goto end;
-       }
-       acpi_hw_low_level_read(8, data, &ec->common.data_addr);
-       ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Read [%02x] from address [%02x]\n",
-                         *data, address));
+        status = acpi_ec_transaction_unlocked(ec, command,
+                                              wdata, wdata_len,
+                                              rdata, rdata_len);
 
-      end:
-       up(&ec->intr.sem);
+end:
+       up(&ec->sem);
 
-       if (ec->common.global_lock)
+       if (ec->global_lock)
                acpi_release_global_lock(glk);
 
        return status;
 }
 
-static int acpi_ec_intr_write(union acpi_ec *ec, u8 address, u8 data)
+static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 *data)
 {
-       int status = 0;
-       u32 glk;
-
-
-       if (!ec)
-               return -EINVAL;
-
-       if (ec->common.global_lock) {
-               status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
-               if (ACPI_FAILURE(status))
-                       return -ENODEV;
-       }
-
-       WARN_ON(in_interrupt());
-       down(&ec->intr.sem);
-
-       status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
-       if (status) {
-               printk(KERN_DEBUG PREFIX "write EC, IB not empty\n");
-       }
-       acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE,
-                               &ec->common.command_addr);
-       status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
-       if (status) {
-               printk(KERN_DEBUG PREFIX "write EC, IB not empty\n");
-       }
-
-       acpi_hw_low_level_write(8, address, &ec->common.data_addr);
-       status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
-       if (status) {
-               printk(KERN_DEBUG PREFIX "write EC, IB not empty\n");
-       }
-
-       acpi_hw_low_level_write(8, data, &ec->common.data_addr);
+       int result;
+       u8 d;
 
-       ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Wrote [%02x] to address [%02x]\n",
-                         data, address));
-
-       up(&ec->intr.sem);
-
-       if (ec->common.global_lock)
-               acpi_release_global_lock(glk);
+       result = acpi_ec_transaction(ec, ACPI_EC_COMMAND_READ,
+                                    &address, 1, &d, 1);
+       *data = d;
+       return result;
+}
 
-       return status;
+static int acpi_ec_write(struct acpi_ec *ec, u8 address, u8 data)
+{
+        u8 wdata[2] = { address, data };
+        return acpi_ec_transaction(ec, ACPI_EC_COMMAND_WRITE,
+                                  wdata, 2, NULL, 0);
 }
 
 /*
  * Externally callable EC access functions. For now, assume 1 EC only
  */
-int ec_read(u8 addr, u8 * val)
+int ec_read(u8 addr, u8 *val)
 {
-       union acpi_ec *ec;
+       struct acpi_ec *ec;
        int err;
-       u32 temp_data;
+       u8 temp_data;
 
        if (!first_ec)
                return -ENODEV;
@@ -539,7 +354,7 @@ EXPORT_SYMBOL(ec_read);
 
 int ec_write(u8 addr, u8 val)
 {
-       union acpi_ec *ec;
+       struct acpi_ec *ec;
        int err;
 
        if (!first_ec)
@@ -554,255 +369,106 @@ int ec_write(u8 addr, u8 val)
 
 EXPORT_SYMBOL(ec_write);
 
-static int acpi_ec_query(union acpi_ec *ec, u32 * data)
-{
-       if (acpi_ec_poll_mode)
-               return acpi_ec_poll_query(ec, data);
-       else
-               return acpi_ec_intr_query(ec, data);
-}
-static int acpi_ec_poll_query(union acpi_ec *ec, u32 * data)
+extern int ec_transaction(u8 command,
+                          const u8 *wdata, unsigned wdata_len,
+                          u8 *rdata, unsigned rdata_len)
 {
-       int result = 0;
-       acpi_status status = AE_OK;
-       u32 glk = 0;
-
-
-       if (!ec || !data)
-               return -EINVAL;
-
-       *data = 0;
-
-       if (ec->common.global_lock) {
-               status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
-               if (ACPI_FAILURE(status))
-                       return -ENODEV;
-       }
+       struct acpi_ec *ec;
 
-       /*
-        * Query the EC to find out which _Qxx method we need to evaluate.
-        * Note that successful completion of the query causes the ACPI_EC_SCI
-        * bit to be cleared (and thus clearing the interrupt source).
-        */
-       if (down_interruptible(&ec->poll.sem)) {
-               result = -ERESTARTSYS;
-               goto end_nosem;
-       }
-       
-       acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY,
-                               &ec->common.command_addr);
-       result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
-       if (result)
-               goto end;
-
-       acpi_hw_low_level_read(8, data, &ec->common.data_addr);
-       if (!*data)
-               result = -ENODATA;
+       if (!first_ec)
+               return -ENODEV;
 
-      end:
-       up(&ec->poll.sem);
-end_nosem:
-       if (ec->common.global_lock)
-               acpi_release_global_lock(glk);
+       ec = acpi_driver_data(first_ec);
 
-       return result;
+       return acpi_ec_transaction(ec, command, wdata,
+                                  wdata_len, rdata, rdata_len);
 }
-static int acpi_ec_intr_query(union acpi_ec *ec, u32 * data)
-{
-       int status = 0;
-       u32 glk;
-
 
-       if (!ec || !data)
-               return -EINVAL;
-       *data = 0;
-
-       if (ec->common.global_lock) {
-               status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
-               if (ACPI_FAILURE(status))
-                       return -ENODEV;
-       }
+EXPORT_SYMBOL(ec_transaction);
 
-       down(&ec->intr.sem);
+static int acpi_ec_query(struct acpi_ec *ec, u8 *data)
+{
+       int result;
+        u8 d;
 
-       status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
-       if (status) {
-               printk(KERN_DEBUG PREFIX "query EC, IB not empty\n");
-               goto end;
-       }
-       /*
-        * Query the EC to find out which _Qxx method we need to evaluate.
-        * Note that successful completion of the query causes the ACPI_EC_SCI
-        * bit to be cleared (and thus clearing the interrupt source).
-        */
-       acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY,
-                               &ec->common.command_addr);
-       status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
-       if (status) {
-               printk(KERN_DEBUG PREFIX "query EC, OB not full\n");
-               goto end;
-       }
+        if (!ec || !data)
+                return -EINVAL;
 
-       acpi_hw_low_level_read(8, data, &ec->common.data_addr);
-       if (!*data)
-               status = -ENODATA;
+        /*
+         * Query the EC to find out which _Qxx method we need to evaluate.
+         * Note that successful completion of the query causes the ACPI_EC_SCI
+         * bit to be cleared (and thus clearing the interrupt source).
+         */
 
-      end:
-       up(&ec->intr.sem);
+        result = acpi_ec_transaction(ec, ACPI_EC_COMMAND_QUERY, NULL, 0, &d, 1);
+        if (result)
+                return result;
 
-       if (ec->common.global_lock)
-               acpi_release_global_lock(glk);
+        if (!d)
+                return -ENODATA;
 
-       return status;
+        *data = d;
+        return 0;
 }
 
 /* --------------------------------------------------------------------------
                                 Event Management
    -------------------------------------------------------------------------- */
 
-union acpi_ec_query_data {
+struct acpi_ec_query_data {
        acpi_handle handle;
        u8 data;
 };
 
 static void acpi_ec_gpe_query(void *ec_cxt)
 {
-       if (acpi_ec_poll_mode)
-               acpi_ec_gpe_poll_query(ec_cxt);
-       else
-               acpi_ec_gpe_intr_query(ec_cxt);
-}
-
-static void acpi_ec_gpe_poll_query(void *ec_cxt)
-{
-       union acpi_ec *ec = (union acpi_ec *)ec_cxt;
-       u32 value = 0;
-       static char object_name[5] = { '_', 'Q', '0', '0', '\0' };
-       const char hex[] = { '0', '1', '2', '3', '4', '5', '6', '7',
-               '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
-       };
-
+       struct acpi_ec *ec = (struct acpi_ec *)ec_cxt;
+       u8 value = 0;
+       static char object_name[8];
 
-       if (!ec_cxt)
+       if (!ec)
                goto end;
 
-       if (down_interruptible (&ec->poll.sem)) {
-               return;
-       }
-       acpi_hw_low_level_read(8, &value, &ec->common.command_addr);
-       up(&ec->poll.sem);
-
-       /* TBD: Implement asynch events!
-        * NOTE: All we care about are EC-SCI's.  Other EC events are
-        * handled via polling (yuck!).  This is because some systems
-        * treat EC-SCIs as level (versus EDGE!) triggered, preventing
-        *  a purely interrupt-driven approach (grumble, grumble).
-        */
+       value = acpi_ec_read_status(ec);
+
        if (!(value & ACPI_EC_FLAG_SCI))
                goto end;
 
        if (acpi_ec_query(ec, &value))
                goto end;
 
-       object_name[2] = hex[((value >> 4) & 0x0F)];
-       object_name[3] = hex[(value & 0x0F)];
-
-       ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s\n", object_name));
+       snprintf(object_name, 8, "_Q%2.2X", value);
 
-       acpi_evaluate_object(ec->common.handle, object_name, NULL, NULL);
+       ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s", object_name));
 
-      end:
-       acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
-}
-static void acpi_ec_gpe_intr_query(void *ec_cxt)
-{
-       union acpi_ec *ec = (union acpi_ec *)ec_cxt;
-       u32 value;
-       int result = -ENODATA;
-       static char object_name[5] = { '_', 'Q', '0', '0', '\0' };
-       const char hex[] = { '0', '1', '2', '3', '4', '5', '6', '7',
-               '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
-       };
+       acpi_evaluate_object(ec->handle, object_name, NULL, NULL);
 
-
-       if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_SCI)
-               result = acpi_ec_query(ec, &value);
-
-       if (result)
-               goto end;
-
-       object_name[2] = hex[((value >> 4) & 0x0F)];
-       object_name[3] = hex[(value & 0x0F)];
-
-       ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s\n", object_name));
-
-       acpi_evaluate_object(ec->common.handle, object_name, NULL, NULL);
       end:
-       atomic_dec(&ec->intr.pending_gpe);
-       return;
+       acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
 }
 
 static u32 acpi_ec_gpe_handler(void *data)
-{
-       if (acpi_ec_poll_mode)
-               return acpi_ec_gpe_poll_handler(data);
-       else
-               return acpi_ec_gpe_intr_handler(data);
-}
-static u32 acpi_ec_gpe_poll_handler(void *data)
 {
        acpi_status status = AE_OK;
-       union acpi_ec *ec = (union acpi_ec *)data;
-
-       if (!ec)
-               return ACPI_INTERRUPT_NOT_HANDLED;
-
-       acpi_disable_gpe(NULL, ec->common.gpe_bit, ACPI_ISR);
-
-       status = acpi_os_execute(OSL_EC_POLL_HANDLER, acpi_ec_gpe_query, ec);
-
-       if (status == AE_OK)
-               return ACPI_INTERRUPT_HANDLED;
-       else
-               return ACPI_INTERRUPT_NOT_HANDLED;
-}
-static u32 acpi_ec_gpe_intr_handler(void *data)
-{
-       acpi_status status = AE_OK;
-       u32 value;
-       union acpi_ec *ec = (union acpi_ec *)data;
-
-       if (!ec)
-               return ACPI_INTERRUPT_NOT_HANDLED;
+       u8 value;
+       struct acpi_ec *ec = (struct acpi_ec *)data;
 
-       acpi_clear_gpe(NULL, ec->common.gpe_bit, ACPI_ISR);
+       acpi_clear_gpe(NULL, ec->gpe_bit, ACPI_ISR);
        value = acpi_ec_read_status(ec);
 
-       switch (ec->intr.expect_event) {
-       case ACPI_EC_EVENT_OBF:
-               if (!(value & ACPI_EC_FLAG_OBF))
-                       break;
-               ec->intr.expect_event = 0;
-               wake_up(&ec->intr.wait);
-               break;
-       case ACPI_EC_EVENT_IBE:
-               if ((value & ACPI_EC_FLAG_IBF))
-                       break;
-               ec->intr.expect_event = 0;
-               wake_up(&ec->intr.wait);
-               break;
-       default:
-               break;
+       if (acpi_ec_mode == EC_INTR) {
+               if (acpi_ec_check_status(value, ec->expect_event)) {
+                       ec->expect_event = 0;
+                       wake_up(&ec->wait);
+               }
        }
 
        if (value & ACPI_EC_FLAG_SCI) {
-               atomic_add(1, &ec->intr.pending_gpe);
-               status = acpi_os_execute(OSL_EC_BURST_HANDLER,
-                                                    acpi_ec_gpe_query, ec);
+               status = acpi_os_execute(OSL_EC_BURST_HANDLER, acpi_ec_gpe_query, ec);
                return status == AE_OK ?
                    ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED;
        }
-       acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_ISR);
+       acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_ISR);
        return status == AE_OK ?
            ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED;
 }
@@ -833,7 +499,7 @@ acpi_ec_space_handler(u32 function,
                      void *handler_context, void *region_context)
 {
        int result = 0;
-       union acpi_ec *ec = NULL;
+       struct acpi_ec *ec = NULL;
        u64 temp = *value;
        acpi_integer f_v = 0;
        int i = 0;
@@ -843,18 +509,16 @@ acpi_ec_space_handler(u32 function,
                return AE_BAD_PARAMETER;
 
        if (bit_width != 8 && acpi_strict) {
-               printk(KERN_WARNING PREFIX
-                      "acpi_ec_space_handler: bit_width should be 8\n");
                return AE_BAD_PARAMETER;
        }
 
-       ec = (union acpi_ec *)handler_context;
+       ec = (struct acpi_ec *)handler_context;
 
       next_byte:
        switch (function) {
        case ACPI_READ:
                temp = 0;
-               result = acpi_ec_read(ec, (u8) address, (u32 *) & temp);
+               result = acpi_ec_read(ec, (u8) address, (u8 *) &temp);
                break;
        case ACPI_WRITE:
                result = acpi_ec_write(ec, (u8) address, (u8) temp);
@@ -905,20 +569,20 @@ static struct proc_dir_entry *acpi_ec_dir;
 
 static int acpi_ec_read_info(struct seq_file *seq, void *offset)
 {
-       union acpi_ec *ec = (union acpi_ec *)seq->private;
+       struct acpi_ec *ec = (struct acpi_ec *)seq->private;
 
 
        if (!ec)
                goto end;
 
        seq_printf(seq, "gpe bit:                 0x%02x\n",
-                  (u32) ec->common.gpe_bit);
+                  (u32) ec->gpe_bit);
        seq_printf(seq, "ports:                   0x%02x, 0x%02x\n",
-                  (u32) ec->common.status_addr.address,
-                  (u32) ec->common.data_addr.address);
+                  (u32) ec->command_addr,
+                  (u32) ec->data_addr);
        seq_printf(seq, "use global lock:         %s\n",
-                  ec->common.global_lock ? "yes" : "no");
-       acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
+                  ec->global_lock ? "yes" : "no");
+       acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
 
       end:
        return 0;
@@ -929,7 +593,7 @@ static int acpi_ec_info_open_fs(struct inode *inode, struct file *file)
        return single_open(file, acpi_ec_read_info, PDE(inode)->data);
 }
 
-static const struct file_operations acpi_ec_info_ops = {
+static struct file_operations acpi_ec_info_ops = {
        .open = acpi_ec_info_open_fs,
        .read = seq_read,
        .llseek = seq_lseek,
@@ -978,101 +642,35 @@ static int acpi_ec_remove_fs(struct acpi_device *device)
                                Driver Interface
    -------------------------------------------------------------------------- */
 
-static int acpi_ec_poll_add(struct acpi_device *device)
+static int acpi_ec_add(struct acpi_device *device)
 {
        int result = 0;
        acpi_status status = AE_OK;
-       union acpi_ec *ec = NULL;
+       struct acpi_ec *ec = NULL;
 
 
        if (!device)
                return -EINVAL;
 
-       ec = kmalloc(sizeof(union acpi_ec), GFP_KERNEL);
+       ec = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL);
        if (!ec)
                return -ENOMEM;
-       memset(ec, 0, sizeof(union acpi_ec));
-
-       ec->common.handle = device->handle;
-       ec->common.uid = -1;
-       init_MUTEX(&ec->poll.sem);
-       strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME);
-       strcpy(acpi_device_class(device), ACPI_EC_CLASS);
-       acpi_driver_data(device) = ec;
-
-       /* Use the global lock for all EC transactions? */
-       acpi_evaluate_integer(ec->common.handle, "_GLK", NULL,
-                             &ec->common.global_lock);
-
-       /* XXX we don't test uids, because on some boxes ecdt uid = 0, see:
-          http://bugzilla.kernel.org/show_bug.cgi?id=6111 */
-       if (ec_ecdt) {
-               acpi_remove_address_space_handler(ACPI_ROOT_OBJECT,
-                                                 ACPI_ADR_SPACE_EC,
-                                                 &acpi_ec_space_handler);
-
-               acpi_remove_gpe_handler(NULL, ec_ecdt->common.gpe_bit,
-                                       &acpi_ec_gpe_handler);
-
-               kfree(ec_ecdt);
+       memset(ec, 0, sizeof(struct acpi_ec));
+
+       ec->handle = device->handle;
+       ec->uid = -1;
+       init_MUTEX(&ec->sem);
+       if (acpi_ec_mode == EC_INTR) {
+               atomic_set(&ec->leaving_burst, 1);
+               init_waitqueue_head(&ec->wait);
        }
-
-       /* Get GPE bit assignment (EC events). */
-       /* TODO: Add support for _GPE returning a package */
-       status =
-           acpi_evaluate_integer(ec->common.handle, "_GPE", NULL,
-                                 &ec->common.gpe_bit);
-       if (ACPI_FAILURE(status)) {
-               ACPI_EXCEPTION((AE_INFO, status, "Obtaining GPE bit"));
-               result = -ENODEV;
-               goto end;
-       }
-
-       result = acpi_ec_add_fs(device);
-       if (result)
-               goto end;
-
-       printk(KERN_INFO PREFIX "%s [%s] (gpe %d) polling mode.\n",
-              acpi_device_name(device), acpi_device_bid(device),
-              (u32) ec->common.gpe_bit);
-
-       if (!first_ec)
-               first_ec = device;
-
-      end:
-       if (result)
-               kfree(ec);
-
-       return result;
-}
-static int acpi_ec_intr_add(struct acpi_device *device)
-{
-       int result = 0;
-       acpi_status status = AE_OK;
-       union acpi_ec *ec = NULL;
-
-
-       if (!device)
-               return -EINVAL;
-
-       ec = kmalloc(sizeof(union acpi_ec), GFP_KERNEL);
-       if (!ec)
-               return -ENOMEM;
-       memset(ec, 0, sizeof(union acpi_ec));
-
-       ec->common.handle = device->handle;
-       ec->common.uid = -1;
-       atomic_set(&ec->intr.pending_gpe, 0);
-       atomic_set(&ec->intr.leaving_burst, 1);
-       init_MUTEX(&ec->intr.sem);
-       init_waitqueue_head(&ec->intr.wait);
        strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME);
        strcpy(acpi_device_class(device), ACPI_EC_CLASS);
        acpi_driver_data(device) = ec;
 
        /* Use the global lock for all EC transactions? */
-       acpi_evaluate_integer(ec->common.handle, "_GLK", NULL,
-                             &ec->common.global_lock);
+       acpi_evaluate_integer(ec->handle, "_GLK", NULL,
+                             &ec->global_lock);
 
        /* XXX we don't test uids, because on some boxes ecdt uid = 0, see:
           http://bugzilla.kernel.org/show_bug.cgi?id=6111 */
@@ -1081,7 +679,7 @@ static int acpi_ec_intr_add(struct acpi_device *device)
                                                  ACPI_ADR_SPACE_EC,
                                                  &acpi_ec_space_handler);
 
-               acpi_remove_gpe_handler(NULL, ec_ecdt->common.gpe_bit,
+               acpi_remove_gpe_handler(NULL, ec_ecdt->gpe_bit,
                                        &acpi_ec_gpe_handler);
 
                kfree(ec_ecdt);
@@ -1090,10 +688,10 @@ static int acpi_ec_intr_add(struct acpi_device *device)
        /* Get GPE bit assignment (EC events). */
        /* TODO: Add support for _GPE returning a package */
        status =
-           acpi_evaluate_integer(ec->common.handle, "_GPE", NULL,
-                                 &ec->common.gpe_bit);
+           acpi_evaluate_integer(ec->handle, "_GPE", NULL,
+                                 &ec->gpe_bit);
        if (ACPI_FAILURE(status)) {
-               printk(KERN_ERR PREFIX "Obtaining GPE bit assignment\n");
+               ACPI_EXCEPTION((AE_INFO, status, "Obtaining GPE bit assignment"));
                result = -ENODEV;
                goto end;
        }
@@ -1102,14 +700,14 @@ static int acpi_ec_intr_add(struct acpi_device *device)
        if (result)
                goto end;
 
-       printk(KERN_INFO PREFIX "%s [%s] (gpe %d) interrupt mode.\n",
+       ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s [%s] (gpe %d) interrupt mode.",
               acpi_device_name(device), acpi_device_bid(device),
-              (u32) ec->common.gpe_bit);
+              (u32) ec->gpe_bit));
 
        if (!first_ec)
                first_ec = device;
 
-      end:
+  end:
        if (result)
                kfree(ec);
 
@@ -1118,7 +716,7 @@ static int acpi_ec_intr_add(struct acpi_device *device)
 
 static int acpi_ec_remove(struct acpi_device *device, int type)
 {
-       union acpi_ec *ec = NULL;
+       struct acpi_ec *ec = NULL;
 
 
        if (!device)
@@ -1136,8 +734,7 @@ static int acpi_ec_remove(struct acpi_device *device, int type)
 static acpi_status
 acpi_ec_io_ports(struct acpi_resource *resource, void *context)
 {
-       union acpi_ec *ec = (union acpi_ec *)context;
-       struct acpi_generic_address *addr;
+       struct acpi_ec *ec = (struct acpi_ec *)context;
 
        if (resource->type != ACPI_RESOURCE_TYPE_IO) {
                return AE_OK;
@@ -1148,26 +745,21 @@ acpi_ec_io_ports(struct acpi_resource *resource, void *context)
         * the second address region returned is the status/command
         * port.
         */
-       if (ec->common.data_addr.register_bit_width == 0) {
-               addr = &ec->common.data_addr;
-       } else if (ec->common.command_addr.register_bit_width == 0) {
-               addr = &ec->common.command_addr;
+       if (ec->data_addr == 0) {
+               ec->data_addr = resource->data.io.minimum;
+       } else if (ec->command_addr == 0) {
+               ec->command_addr = resource->data.io.minimum;
        } else {
                return AE_CTRL_TERMINATE;
        }
 
-       addr->address_space_id = ACPI_ADR_SPACE_SYSTEM_IO;
-       addr->register_bit_width = 8;
-       addr->register_bit_offset = 0;
-       addr->address = resource->data.io.minimum;
-
        return AE_OK;
 }
 
 static int acpi_ec_start(struct acpi_device *device)
 {
        acpi_status status = AE_OK;
-       union acpi_ec *ec = NULL;
+       struct acpi_ec *ec = NULL;
 
 
        if (!device)
@@ -1181,39 +773,35 @@ static int acpi_ec_start(struct acpi_device *device)
        /*
         * Get I/O port addresses. Convert to GAS format.
         */
-       status = acpi_walk_resources(ec->common.handle, METHOD_NAME__CRS,
+       status = acpi_walk_resources(ec->handle, METHOD_NAME__CRS,
                                     acpi_ec_io_ports, ec);
-       if (ACPI_FAILURE(status)
-           || ec->common.command_addr.register_bit_width == 0) {
-               printk(KERN_ERR PREFIX "Error getting I/O port addresses\n");
+       if (ACPI_FAILURE(status) || ec->command_addr == 0) {
+               ACPI_EXCEPTION((AE_INFO, status,
+                               "Error getting I/O port addresses"));
                return -ENODEV;
        }
 
-       ec->common.status_addr = ec->common.command_addr;
-
-       ACPI_DEBUG_PRINT((ACPI_DB_INFO, "gpe=0x%02x, ports=0x%2x,0x%2x\n",
-                         (u32) ec->common.gpe_bit,
-                         (u32) ec->common.command_addr.address,
-                         (u32) ec->common.data_addr.address));
+       ACPI_DEBUG_PRINT((ACPI_DB_INFO, "gpe=0x%02lx, ports=0x%2lx,0x%2lx",
+                         ec->gpe_bit, ec->command_addr, ec->data_addr));
 
        /*
         * Install GPE handler
         */
-       status = acpi_install_gpe_handler(NULL, ec->common.gpe_bit,
+       status = acpi_install_gpe_handler(NULL, ec->gpe_bit,
                                          ACPI_GPE_EDGE_TRIGGERED,
                                          &acpi_ec_gpe_handler, ec);
        if (ACPI_FAILURE(status)) {
                return -ENODEV;
        }
-       acpi_set_gpe_type(NULL, ec->common.gpe_bit, ACPI_GPE_TYPE_RUNTIME);
-       acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
+       acpi_set_gpe_type(NULL, ec->gpe_bit, ACPI_GPE_TYPE_RUNTIME);
+       acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
 
-       status = acpi_install_address_space_handler(ec->common.handle,
+       status = acpi_install_address_space_handler(ec->handle,
                                                    ACPI_ADR_SPACE_EC,
                                                    &acpi_ec_space_handler,
                                                    &acpi_ec_space_setup, ec);
        if (ACPI_FAILURE(status)) {
-               acpi_remove_gpe_handler(NULL, ec->common.gpe_bit,
+               acpi_remove_gpe_handler(NULL, ec->gpe_bit,
                                        &acpi_ec_gpe_handler);
                return -ENODEV;
        }
@@ -1224,7 +812,7 @@ static int acpi_ec_start(struct acpi_device *device)
 static int acpi_ec_stop(struct acpi_device *device, int type)
 {
        acpi_status status = AE_OK;
-       union acpi_ec *ec = NULL;
+       struct acpi_ec *ec = NULL;
 
 
        if (!device)
@@ -1232,14 +820,14 @@ static int acpi_ec_stop(struct acpi_device *device, int type)
 
        ec = acpi_driver_data(device);
 
-       status = acpi_remove_address_space_handler(ec->common.handle,
+       status = acpi_remove_address_space_handler(ec->handle,
                                                   ACPI_ADR_SPACE_EC,
                                                   &acpi_ec_space_handler);
        if (ACPI_FAILURE(status))
                return -ENODEV;
 
        status =
-           acpi_remove_gpe_handler(NULL, ec->common.gpe_bit,
+           acpi_remove_gpe_handler(NULL, ec->gpe_bit,
                                    &acpi_ec_gpe_handler);
        if (ACPI_FAILURE(status))
                return -ENODEV;
@@ -1251,76 +839,30 @@ static acpi_status __init
 acpi_fake_ecdt_callback(acpi_handle handle,
                        u32 Level, void *context, void **retval)
 {
-
-       if (acpi_ec_poll_mode)
-               return acpi_fake_ecdt_poll_callback(handle,
-                                                      Level, context, retval);
-       else
-               return acpi_fake_ecdt_intr_callback(handle,
-                                                    Level, context, retval);
-}
-
-static acpi_status __init
-acpi_fake_ecdt_poll_callback(acpi_handle handle,
-                               u32 Level, void *context, void **retval)
-{
-       acpi_status status;
-
-       status = acpi_walk_resources(handle, METHOD_NAME__CRS,
-                                    acpi_ec_io_ports, ec_ecdt);
-       if (ACPI_FAILURE(status))
-               return status;
-       ec_ecdt->common.status_addr = ec_ecdt->common.command_addr;
-
-       ec_ecdt->common.uid = -1;
-       acpi_evaluate_integer(handle, "_UID", NULL, &ec_ecdt->common.uid);
-
-       status =
-           acpi_evaluate_integer(handle, "_GPE", NULL,
-                                 &ec_ecdt->common.gpe_bit);
-       if (ACPI_FAILURE(status))
-               return status;
-       init_MUTEX(&ec_ecdt->poll.sem);
-       ec_ecdt->common.global_lock = TRUE;
-       ec_ecdt->common.handle = handle;
-
-       printk(KERN_INFO PREFIX "GPE=0x%02x, ports=0x%2x, 0x%2x\n",
-              (u32) ec_ecdt->common.gpe_bit,
-              (u32) ec_ecdt->common.command_addr.address,
-              (u32) ec_ecdt->common.data_addr.address);
-
-       return AE_CTRL_TERMINATE;
-}
-
-static acpi_status __init
-acpi_fake_ecdt_intr_callback(acpi_handle handle,
-                             u32 Level, void *context, void **retval)
-{
        acpi_status status;
 
-       init_MUTEX(&ec_ecdt->intr.sem);
-       init_waitqueue_head(&ec_ecdt->intr.wait);
+       init_MUTEX(&ec_ecdt->sem);
+       if (acpi_ec_mode == EC_INTR) {
+               init_waitqueue_head(&ec_ecdt->wait);
+       }
        status = acpi_walk_resources(handle, METHOD_NAME__CRS,
                                     acpi_ec_io_ports, ec_ecdt);
        if (ACPI_FAILURE(status))
                return status;
-       ec_ecdt->common.status_addr = ec_ecdt->common.command_addr;
 
-       ec_ecdt->common.uid = -1;
-       acpi_evaluate_integer(handle, "_UID", NULL, &ec_ecdt->common.uid);
+       ec_ecdt->uid = -1;
+       acpi_evaluate_integer(handle, "_UID", NULL, &ec_ecdt->uid);
 
        status =
            acpi_evaluate_integer(handle, "_GPE", NULL,
-                                 &ec_ecdt->common.gpe_bit);
+                                 &ec_ecdt->gpe_bit);
        if (ACPI_FAILURE(status))
                return status;
-       ec_ecdt->common.global_lock = TRUE;
-       ec_ecdt->common.handle = handle;
+       ec_ecdt->global_lock = TRUE;
+       ec_ecdt->handle = handle;
 
-       printk(KERN_INFO PREFIX "GPE=0x%02x, ports=0x%2x, 0x%2x\n",
-              (u32) ec_ecdt->common.gpe_bit,
-              (u32) ec_ecdt->common.command_addr.address,
-              (u32) ec_ecdt->common.data_addr.address);
+       ACPI_DEBUG_PRINT((ACPI_DB_INFO, "GPE=0x%02lx, ports=0x%2lx, 0x%2lx",
+              ec_ecdt->gpe_bit, ec_ecdt->command_addr, ec_ecdt->data_addr));
 
        return AE_CTRL_TERMINATE;
 }
@@ -1340,14 +882,14 @@ static int __init acpi_ec_fake_ecdt(void)
        acpi_status status;
        int ret = 0;
 
-       printk(KERN_INFO PREFIX "Try to make an fake ECDT\n");
+       ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Try to make an fake ECDT"));
 
-       ec_ecdt = kmalloc(sizeof(union acpi_ec), GFP_KERNEL);
+       ec_ecdt = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL);
        if (!ec_ecdt) {
                ret = -ENOMEM;
                goto error;
        }
-       memset(ec_ecdt, 0, sizeof(union acpi_ec));
+       memset(ec_ecdt, 0, sizeof(struct acpi_ec));
 
        status = acpi_get_devices(ACPI_EC_HID,
                                  acpi_fake_ecdt_callback, NULL, NULL);
@@ -1355,23 +897,15 @@ static int __init acpi_ec_fake_ecdt(void)
                kfree(ec_ecdt);
                ec_ecdt = NULL;
                ret = -ENODEV;
+               ACPI_EXCEPTION((AE_INFO, status, "Can't make an fake ECDT"));
                goto error;
        }
        return 0;
-      error:
-       printk(KERN_ERR PREFIX "Can't make an fake ECDT\n");
+  error:
        return ret;
 }
 
 static int __init acpi_ec_get_real_ecdt(void)
-{
-       if (acpi_ec_poll_mode)
-               return acpi_ec_poll_get_real_ecdt();
-       else
-               return acpi_ec_intr_get_real_ecdt();
-}
-
-static int __init acpi_ec_poll_get_real_ecdt(void)
 {
        acpi_status status;
        struct acpi_table_ecdt *ecdt_ptr;
@@ -1382,80 +916,36 @@ static int __init acpi_ec_poll_get_real_ecdt(void)
        if (ACPI_FAILURE(status))
                return -ENODEV;
 
-       printk(KERN_INFO PREFIX "Found ECDT\n");
+       ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found ECDT"));
 
        /*
         * Generate a temporary ec context to use until the namespace is scanned
         */
-       ec_ecdt = kmalloc(sizeof(union acpi_ec), GFP_KERNEL);
+       ec_ecdt = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL);
        if (!ec_ecdt)
                return -ENOMEM;
-       memset(ec_ecdt, 0, sizeof(union acpi_ec));
-
-       ec_ecdt->common.command_addr = ecdt_ptr->ec_control;
-       ec_ecdt->common.status_addr = ecdt_ptr->ec_control;
-       ec_ecdt->common.data_addr = ecdt_ptr->ec_data;
-       ec_ecdt->common.gpe_bit = ecdt_ptr->gpe_bit;
-       init_MUTEX(&ec_ecdt->poll.sem);
-       /* use the GL just to be safe */
-       ec_ecdt->common.global_lock = TRUE;
-       ec_ecdt->common.uid = ecdt_ptr->uid;
+       memset(ec_ecdt, 0, sizeof(struct acpi_ec));
 
-       status =
-           acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->common.handle);
-       if (ACPI_FAILURE(status)) {
-               goto error;
+       init_MUTEX(&ec_ecdt->sem);
+       if (acpi_ec_mode == EC_INTR) {
+               init_waitqueue_head(&ec_ecdt->wait);
        }
-
-       return 0;
-      error:
-       printk(KERN_ERR PREFIX "Could not use ECDT\n");
-       kfree(ec_ecdt);
-       ec_ecdt = NULL;
-
-       return -ENODEV;
-}
-
-static int __init acpi_ec_intr_get_real_ecdt(void)
-{
-       acpi_status status;
-       struct acpi_table_ecdt *ecdt_ptr;
-
-       status = acpi_get_firmware_table("ECDT", 1, ACPI_LOGICAL_ADDRESSING,
-                                        (struct acpi_table_header **)
-                                        &ecdt_ptr);
-       if (ACPI_FAILURE(status))
-               return -ENODEV;
-
-       printk(KERN_INFO PREFIX "Found ECDT\n");
-
-       /*
-        * Generate a temporary ec context to use until the namespace is scanned
-        */
-       ec_ecdt = kmalloc(sizeof(union acpi_ec), GFP_KERNEL);
-       if (!ec_ecdt)
-               return -ENOMEM;
-       memset(ec_ecdt, 0, sizeof(union acpi_ec));
-
-       init_MUTEX(&ec_ecdt->intr.sem);
-       init_waitqueue_head(&ec_ecdt->intr.wait);
-       ec_ecdt->common.command_addr = ecdt_ptr->ec_control;
-       ec_ecdt->common.status_addr = ecdt_ptr->ec_control;
-       ec_ecdt->common.data_addr = ecdt_ptr->ec_data;
-       ec_ecdt->common.gpe_bit = ecdt_ptr->gpe_bit;
+       ec_ecdt->command_addr = ecdt_ptr->ec_control.address;
+       ec_ecdt->data_addr = ecdt_ptr->ec_data.address;
+       ec_ecdt->gpe_bit = ecdt_ptr->gpe_bit;
        /* use the GL just to be safe */
-       ec_ecdt->common.global_lock = TRUE;
-       ec_ecdt->common.uid = ecdt_ptr->uid;
+       ec_ecdt->global_lock = TRUE;
+       ec_ecdt->uid = ecdt_ptr->uid;
 
        status =
-           acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->common.handle);
+           acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->handle);
        if (ACPI_FAILURE(status)) {
                goto error;
        }
 
        return 0;
-      error:
-       printk(KERN_ERR PREFIX "Could not use ECDT\n");
+  error:
+       ACPI_EXCEPTION((AE_INFO, status, "Could not use ECDT"));
        kfree(ec_ecdt);
        ec_ecdt = NULL;
 
@@ -1480,14 +970,14 @@ int __init acpi_ec_ecdt_probe(void)
        /*
         * Install GPE handler
         */
-       status = acpi_install_gpe_handler(NULL, ec_ecdt->common.gpe_bit,
+       status = acpi_install_gpe_handler(NULL, ec_ecdt->gpe_bit,
                                          ACPI_GPE_EDGE_TRIGGERED,
                                          &acpi_ec_gpe_handler, ec_ecdt);
        if (ACPI_FAILURE(status)) {
                goto error;
        }
-       acpi_set_gpe_type(NULL, ec_ecdt->common.gpe_bit, ACPI_GPE_TYPE_RUNTIME);
-       acpi_enable_gpe(NULL, ec_ecdt->common.gpe_bit, ACPI_NOT_ISR);
+       acpi_set_gpe_type(NULL, ec_ecdt->gpe_bit, ACPI_GPE_TYPE_RUNTIME);
+       acpi_enable_gpe(NULL, ec_ecdt->gpe_bit, ACPI_NOT_ISR);
 
        status = acpi_install_address_space_handler(ACPI_ROOT_OBJECT,
                                                    ACPI_ADR_SPACE_EC,
@@ -1495,7 +985,7 @@ int __init acpi_ec_ecdt_probe(void)
                                                    &acpi_ec_space_setup,
                                                    ec_ecdt);
        if (ACPI_FAILURE(status)) {
-               acpi_remove_gpe_handler(NULL, ec_ecdt->common.gpe_bit,
+               acpi_remove_gpe_handler(NULL, ec_ecdt->gpe_bit,
                                        &acpi_ec_gpe_handler);
                goto error;
        }
@@ -1503,7 +993,7 @@ int __init acpi_ec_ecdt_probe(void)
        return 0;
 
       error:
-       printk(KERN_ERR PREFIX "Could not use ECDT\n");
+       ACPI_EXCEPTION((AE_INFO, status, "Could not use ECDT"));
        kfree(ec_ecdt);
        ec_ecdt = NULL;
 
@@ -1562,13 +1052,13 @@ static int __init acpi_ec_set_intr_mode(char *str)
                return 0;
 
        if (intr) {
-               acpi_ec_poll_mode = EC_INTR;
-               acpi_ec_driver.ops.add = acpi_ec_intr_add;
+               acpi_ec_mode = EC_INTR;
        } else {
-               acpi_ec_poll_mode = EC_POLL;
-               acpi_ec_driver.ops.add = acpi_ec_poll_add;
+               acpi_ec_mode = EC_POLL;
        }
-       printk(KERN_INFO PREFIX "EC %s mode.\n", intr ? "interrupt" : "polling");
+       acpi_ec_driver.ops.add = acpi_ec_add;
+       ACPI_DEBUG_PRINT((ACPI_DB_INFO, "EC %s mode.\n", intr ? "interrupt" : "polling"));
+
        return 1;
 }
 
index 6eef4efddcf62b0f83fba9f2014b61403e4564fe..ee2a10bf907745ceef823a5d9a2ecd637ae51b2c 100644 (file)
@@ -342,20 +342,8 @@ static u32 acpi_ev_global_lock_handler(void *context)
        if (acquired) {
 
                /* Got the lock, now wake all threads waiting for it */
-
                acpi_gbl_global_lock_acquired = TRUE;
-
-               /* Run the Global Lock thread which will signal all waiting threads */
-
-               status =
-                   acpi_os_execute(OSL_GLOBAL_LOCK_HANDLER,
-                                   acpi_ev_global_lock_thread, context);
-               if (ACPI_FAILURE(status)) {
-                       ACPI_EXCEPTION((AE_INFO, status,
-                                       "Could not queue Global Lock thread"));
-
-                       return (ACPI_INTERRUPT_NOT_HANDLED);
-               }
+               acpi_ev_global_lock_thread(context);
        }
 
        return (ACPI_INTERRUPT_HANDLED);
index 5b3c7a85eb9a609e7e1fcbc8910f15e95e5f1f26..203d1359190af2c8d52f694f506eda23d75de4bd 100644 (file)
@@ -225,13 +225,12 @@ acpi_ev_pci_config_region_setup(acpi_handle handle,
                                if (!
                                    (ACPI_STRNCMP
                                     (object_hID.value, PCI_ROOT_HID_STRING,
-                                     sizeof(PCI_ROOT_HID_STRING))
-                                    ||
-                                    !(ACPI_STRNCMP
-                                      (object_hID.value,
-                                       PCI_EXPRESS_ROOT_HID_STRING,
-                                       sizeof(PCI_EXPRESS_ROOT_HID_STRING)))))
-                               {
+                                     sizeof(PCI_ROOT_HID_STRING)))
+                                   ||
+                                   !(ACPI_STRNCMP
+                                     (object_hID.value,
+                                      PCI_EXPRESS_ROOT_HID_STRING,
+                                      sizeof(PCI_EXPRESS_ROOT_HID_STRING)))) {
 
                                        /* Install a handler for this PCI root bridge */
 
index 3143f36fcec9f50caa5b3320191a5c1086a5ab18..fa58c1edce1e52f00c6b1cecebbe3f63a7a4af6f 100644 (file)
@@ -665,8 +665,6 @@ acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value)
 
                /*
                 * Perform a read first to preserve certain bits (per ACPI spec)
-                *
-                * Note: This includes SCI_EN, we never want to change this bit
                 */
                status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK,
                                               ACPI_REGISTER_PM1_CONTROL,
index 15fc12482ba0ab723b8121f13b9562e128e9cc32..003a9876c9683bee7de662e5959f06ec42ed91f9 100644 (file)
@@ -1702,13 +1702,11 @@ static struct ibm_struct ibms[] = {
         .name = "brightness",
         .read = brightness_read,
         .write = brightness_write,
-        .experimental = 1,
         },
        {
         .name = "volume",
         .read = volume_read,
         .write = volume_write,
-        .experimental = 1,
         },
        {
         .name = "fan",
index ec6b7f9ede34d911818075d75eb11f7d95f02b87..2e17ec75af03e84756689ce8bca915f2b0e3c2d5 100644 (file)
@@ -48,6 +48,12 @@ ACPI_MODULE_NAME("acpi_motherboard")
  * the io ports if they really know they can use it, while
  * still preventing hotplug PCI devices from using it.
  */
+
+/*
+ * When CONFIG_PNP is enabled, pnp/system.c binds to PNP0C01
+ * and PNP0C02, redundant with acpi_reserve_io_ranges().
+ * But acpi_reserve_io_ranges() is necessary for !CONFIG_PNP.
+ */
 static acpi_status acpi_reserve_io_ranges(struct acpi_resource *res, void *data)
 {
        struct resource *requested_res = NULL;
index 20beea778ea2d929a7efceec03a3fe60f6f9ec12..c84286cbbe2571e3c5b4fb62bf60b93942ff941a 100644 (file)
@@ -73,6 +73,7 @@ static unsigned int acpi_irq_irq;
 static acpi_osd_handler acpi_irq_handler;
 static void *acpi_irq_context;
 static struct workqueue_struct *kacpid_wq;
+static struct workqueue_struct *kacpi_notify_wq;
 
 acpi_status acpi_os_initialize(void)
 {
@@ -91,8 +92,9 @@ acpi_status acpi_os_initialize1(void)
                return AE_NULL_ENTRY;
        }
        kacpid_wq = create_singlethread_workqueue("kacpid");
+       kacpi_notify_wq = create_singlethread_workqueue("kacpi_notify");
        BUG_ON(!kacpid_wq);
-
+       BUG_ON(!kacpi_notify_wq);
        return AE_OK;
 }
 
@@ -104,6 +106,7 @@ acpi_status acpi_os_terminate(void)
        }
 
        destroy_workqueue(kacpid_wq);
+       destroy_workqueue(kacpi_notify_wq);
 
        return AE_OK;
 }
@@ -237,7 +240,7 @@ acpi_os_table_override(struct acpi_table_header * existing_table,
        return AE_OK;
 }
 
-static irqreturn_t acpi_irq(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t acpi_irq(int irq, void *dev_id)
 {
        return (*acpi_irq_handler) (acpi_irq_context) ? IRQ_HANDLED : IRQ_NONE;
 }
@@ -566,10 +569,7 @@ void acpi_os_derive_pci_id(acpi_handle rhandle,    /* upper bound  */
 
 static void acpi_os_execute_deferred(void *context)
 {
-       struct acpi_os_dpc *dpc = NULL;
-
-
-       dpc = (struct acpi_os_dpc *)context;
+       struct acpi_os_dpc *dpc = (struct acpi_os_dpc *)context;
        if (!dpc) {
                printk(KERN_ERR PREFIX "Invalid (NULL) context\n");
                return;
@@ -604,14 +604,12 @@ acpi_status acpi_os_execute(acpi_execute_type type,
        struct acpi_os_dpc *dpc;
        struct work_struct *task;
 
-       ACPI_FUNCTION_TRACE("os_queue_for_execution");
-
        ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
                          "Scheduling function [%p(%p)] for deferred execution.\n",
                          function, context));
 
        if (!function)
-               return_ACPI_STATUS(AE_BAD_PARAMETER);
+               return AE_BAD_PARAMETER;
 
        /*
         * Allocate/initialize DPC structure.  Note that this memory will be
@@ -624,26 +622,20 @@ acpi_status acpi_os_execute(acpi_execute_type type,
         * from the same memory.
         */
 
-       dpc =
-           kmalloc(sizeof(struct acpi_os_dpc) + sizeof(struct work_struct),
-                   GFP_ATOMIC);
+       dpc = kmalloc(sizeof(struct acpi_os_dpc) +
+                       sizeof(struct work_struct), GFP_ATOMIC);
        if (!dpc)
-               return_ACPI_STATUS(AE_NO_MEMORY);
-
+               return AE_NO_MEMORY;
        dpc->function = function;
        dpc->context = context;
-
        task = (void *)(dpc + 1);
        INIT_WORK(task, acpi_os_execute_deferred, (void *)dpc);
-
-       if (!queue_work(kacpid_wq, task)) {
-               ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-                                 "Call to queue_work() failed.\n"));
-               kfree(dpc);
+       if (!queue_work((type == OSL_NOTIFY_HANDLER)?
+                       kacpi_notify_wq : kacpid_wq, task)) {
                status = AE_ERROR;
+               kfree(dpc);
        }
-
-       return_ACPI_STATUS(status);
+       return status;
 }
 
 EXPORT_SYMBOL(acpi_os_execute);
index 7f3e7e77e79436e9984c52a4d6c80345f3f3265d..d53bd9878ca2ccddcee6cde058d8781c74b698ba 100644 (file)
@@ -307,7 +307,7 @@ static int acpi_pci_link_set(struct acpi_pci_link *link, int irq)
        if (!link || !irq)
                return -EINVAL;
 
-       resource = kmalloc(sizeof(*resource) + 1, GFP_ATOMIC);
+       resource = kmalloc(sizeof(*resource) + 1, irqs_disabled() ? GFP_ATOMIC: GFP_KERNEL);
        if (!resource)
                return -ENOMEM;
 
index fec225d1b6b74520f6b132c2bcefd5dcb600b484..fe67a8af520ecdb715e020511b028c3b6d7f865c 100644 (file)
@@ -216,10 +216,8 @@ static int acpi_power_off_device(acpi_handle handle)
 {
        int result = 0;
        acpi_status status = AE_OK;
-       struct acpi_device *device = NULL;
        struct acpi_power_resource *resource = NULL;
 
-
        result = acpi_power_get_context(handle, &resource);
        if (result)
                return result;
@@ -230,13 +228,13 @@ static int acpi_power_off_device(acpi_handle handle)
        if (resource->references) {
                ACPI_DEBUG_PRINT((ACPI_DB_INFO,
                                  "Resource [%s] is still in use, dereferencing\n",
-                                 device->pnp.bus_id));
+                                 resource->device->pnp.bus_id));
                return 0;
        }
 
        if (resource->state == ACPI_POWER_RESOURCE_STATE_OFF) {
                ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] already off\n",
-                                 device->pnp.bus_id));
+                                 resource->device->pnp.bus_id));
                return 0;
        }
 
@@ -251,8 +249,7 @@ static int acpi_power_off_device(acpi_handle handle)
                return -ENOEXEC;
 
        /* Update the power resource's _device_ power state */
-       device = resource->device;
-       device->power.state = ACPI_STATE_D3;
+       resource->device->power.state = ACPI_STATE_D3;
 
        ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] turned off\n",
                          resource->name));
index b13d64415b7ab651fc42be5b13351427d9dad6a3..1908e0d202226a47b0f839439a84f599d91649b1 100644 (file)
@@ -519,7 +519,7 @@ static int acpi_processor_get_info(struct acpi_processor *pr)
 
 static void *processor_device_array[NR_CPUS];
 
-static int acpi_processor_start(struct acpi_device *device)
+static int __cpuinit acpi_processor_start(struct acpi_device *device)
 {
        int result = 0;
        acpi_status status = AE_OK;
index 0a395fca843b46686b748ffe1583515cc863e9af..65b3f056ad895a7d0f524f7412ff861ce9298649 100644 (file)
@@ -219,6 +219,23 @@ static void acpi_safe_halt(void)
 
 static atomic_t c3_cpu_count;
 
+/* Common C-state entry for C2, C3, .. */
+static void acpi_cstate_enter(struct acpi_processor_cx *cstate)
+{
+       if (cstate->space_id == ACPI_CSTATE_FFH) {
+               /* Call into architectural FFH based C-state */
+               acpi_processor_ffh_cstate_enter(cstate);
+       } else {
+               int unused;
+               /* IO port based C-state */
+               inb(cstate->address);
+               /* Dummy wait op - must do something useless after P_LVL2 read
+                  because chipsets cannot guarantee that STPCLK# signal
+                  gets asserted in time to freeze execution properly. */
+               unused = inl(acpi_fadt.xpm_tmr_blk.address);
+       }
+}
+
 static void acpi_processor_idle(void)
 {
        struct acpi_processor *pr = NULL;
@@ -361,11 +378,7 @@ static void acpi_processor_idle(void)
                /* Get start time (ticks) */
                t1 = inl(acpi_fadt.xpm_tmr_blk.address);
                /* Invoke C2 */
-               inb(cx->address);
-               /* Dummy wait op - must do something useless after P_LVL2 read
-                  because chipsets cannot guarantee that STPCLK# signal
-                  gets asserted in time to freeze execution properly. */
-               t2 = inl(acpi_fadt.xpm_tmr_blk.address);
+               acpi_cstate_enter(cx);
                /* Get end time (ticks) */
                t2 = inl(acpi_fadt.xpm_tmr_blk.address);
 
@@ -401,9 +414,7 @@ static void acpi_processor_idle(void)
                /* Get start time (ticks) */
                t1 = inl(acpi_fadt.xpm_tmr_blk.address);
                /* Invoke C3 */
-               inb(cx->address);
-               /* Dummy wait op (see above) */
-               t2 = inl(acpi_fadt.xpm_tmr_blk.address);
+               acpi_cstate_enter(cx);
                /* Get end time (ticks) */
                t2 = inl(acpi_fadt.xpm_tmr_blk.address);
                if (pr->flags.bm_check) {
@@ -628,20 +639,16 @@ static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr)
        return 0;
 }
 
-static int acpi_processor_get_power_info_default_c1(struct acpi_processor *pr)
+static int acpi_processor_get_power_info_default(struct acpi_processor *pr)
 {
-
-       /* Zero initialize all the C-states info. */
-       memset(pr->power.states, 0, sizeof(pr->power.states));
-
-       /* set the first C-State to C1 */
-       pr->power.states[ACPI_STATE_C1].type = ACPI_STATE_C1;
-
-       /* the C0 state only exists as a filler in our array,
-        * and all processors need to support C1 */
+       if (!pr->power.states[ACPI_STATE_C1].valid) {
+               /* set the first C-State to C1 */
+               /* all processors need to support C1 */
+               pr->power.states[ACPI_STATE_C1].type = ACPI_STATE_C1;
+               pr->power.states[ACPI_STATE_C1].valid = 1;
+       }
+       /* the C0 state only exists as a filler in our array */
        pr->power.states[ACPI_STATE_C0].valid = 1;
-       pr->power.states[ACPI_STATE_C1].valid = 1;
-
        return 0;
 }
 
@@ -658,12 +665,7 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr)
        if (nocst)
                return -ENODEV;
 
-       current_count = 1;
-
-       /* Zero initialize C2 onwards and prepare for fresh CST lookup */
-       for (i = 2; i < ACPI_PROCESSOR_MAX_POWER; i++)
-               memset(&(pr->power.states[i]), 0, 
-                               sizeof(struct acpi_processor_cx));
+       current_count = 0;
 
        status = acpi_evaluate_object(pr->handle, "_CST", NULL, &buffer);
        if (ACPI_FAILURE(status)) {
@@ -718,22 +720,39 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr)
                    (reg->space_id != ACPI_ADR_SPACE_FIXED_HARDWARE))
                        continue;
 
-               cx.address = (reg->space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) ?
-                   0 : reg->address;
-
                /* There should be an easy way to extract an integer... */
                obj = (union acpi_object *)&(element->package.elements[1]);
                if (obj->type != ACPI_TYPE_INTEGER)
                        continue;
 
                cx.type = obj->integer.value;
-
-               if ((cx.type != ACPI_STATE_C1) &&
-                   (reg->space_id != ACPI_ADR_SPACE_SYSTEM_IO))
-                       continue;
-
-               if ((cx.type < ACPI_STATE_C2) || (cx.type > ACPI_STATE_C3))
-                       continue;
+               /*
+                * Some buggy BIOSes won't list C1 in _CST -
+                * Let acpi_processor_get_power_info_default() handle them later
+                */
+               if (i == 1 && cx.type != ACPI_STATE_C1)
+                       current_count++;
+
+               cx.address = reg->address;
+               cx.index = current_count + 1;
+
+               cx.space_id = ACPI_CSTATE_SYSTEMIO;
+               if (reg->space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) {
+                       if (acpi_processor_ffh_cstate_probe
+                                       (pr->id, &cx, reg) == 0) {
+                               cx.space_id = ACPI_CSTATE_FFH;
+                       } else if (cx.type != ACPI_STATE_C1) {
+                               /*
+                                * C1 is a special case where FIXED_HARDWARE
+                                * can be handled in non-MWAIT way as well.
+                                * In that case, save this _CST entry info.
+                                * That is, we retain space_id of SYSTEM_IO for
+                                * halt based C1.
+                                * Otherwise, ignore this info and continue.
+                                */
+                               continue;
+                       }
+               }
 
                obj = (union acpi_object *)&(element->package.elements[2]);
                if (obj->type != ACPI_TYPE_INTEGER)
@@ -938,11 +957,17 @@ static int acpi_processor_get_power_info(struct acpi_processor *pr)
        /* NOTE: the idle thread may not be running while calling
         * this function */
 
-       /* Adding C1 state */
-       acpi_processor_get_power_info_default_c1(pr);
+       /* Zero initialize all the C-states info. */
+       memset(pr->power.states, 0, sizeof(pr->power.states));
+
        result = acpi_processor_get_power_info_cst(pr);
        if (result == -ENODEV)
-               acpi_processor_get_power_info_fadt(pr);
+               result = acpi_processor_get_power_info_fadt(pr);
+
+       if (result)
+               return result;
+
+       acpi_processor_get_power_info_default(pr);
 
        pr->power.count = acpi_processor_power_verify(pr);
 
@@ -1083,6 +1108,7 @@ static const struct file_operations acpi_processor_power_fops = {
        .release = single_release,
 };
 
+#ifdef CONFIG_SMP
 static void smp_callback(void *v)
 {
        /* we already woke the CPU up, nothing more to do */
@@ -1104,8 +1130,9 @@ static int acpi_processor_latency_notify(struct notifier_block *b,
 static struct notifier_block acpi_processor_latency_notifier = {
        .notifier_call = acpi_processor_latency_notify,
 };
+#endif
 
-int acpi_processor_power_init(struct acpi_processor *pr,
+int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
                              struct acpi_device *device)
 {
        acpi_status status = 0;
@@ -1121,7 +1148,9 @@ int acpi_processor_power_init(struct acpi_processor *pr,
                               "ACPI: processor limited to max C-state %d\n",
                               max_cstate);
                first_run++;
+#ifdef CONFIG_SMP
                register_latency_notifier(&acpi_processor_latency_notifier);
+#endif
        }
 
        if (!pr)
@@ -1193,7 +1222,9 @@ int acpi_processor_power_exit(struct acpi_processor *pr,
                 * copies of pm_idle before proceeding.
                 */
                cpu_idle_wait();
+#ifdef CONFIG_SMP
                unregister_latency_notifier(&acpi_processor_latency_notifier);
+#endif
        }
 
        return 0;
index 62bef0b3b614aef8d10742cd3494e9ecca149675..8908a975e5753ca028179298e008502b774eb3f2 100644 (file)
@@ -98,11 +98,11 @@ static int update_info_mode = UPDATE_INFO_MODE;
 static int update_time = UPDATE_TIME;
 static int update_time2 = UPDATE_TIME2;
 
-module_param(capacity_mode, int, CAPACITY_UNIT);
-module_param(update_mode, int, UPDATE_MODE);
-module_param(update_info_mode, int, UPDATE_INFO_MODE);
-module_param(update_time, int, UPDATE_TIME);
-module_param(update_time2, int, UPDATE_TIME2);
+module_param(capacity_mode, int, 0);
+module_param(update_mode, int, 0);
+module_param(update_info_mode, int, 0);
+module_param(update_time, int, 0);
+module_param(update_time2, int, 0);
 
 static int acpi_sbs_add(struct acpi_device *device);
 static int acpi_sbs_remove(struct acpi_device *device, int type);
@@ -1685,10 +1685,16 @@ static int acpi_sbs_add(struct acpi_device *device)
 
 int acpi_sbs_remove(struct acpi_device *device, int type)
 {
-       struct acpi_sbs *sbs = (struct acpi_sbs *)acpi_driver_data(device);
+       struct acpi_sbs *sbs = NULL;
        int id;
 
-       if (!device || !sbs) {
+       if (!device) {
+               return -EINVAL;
+       }
+
+       sbs = (struct acpi_sbs *)acpi_driver_data(device);
+
+       if (!sbs) {
                return -EINVAL;
        }
 
index 7856db759af0be7579abcd1733e74d1782455dbe..11e2d4454e053f6ece5f8d6aab31e5b6491e8f0a 100644 (file)
@@ -324,7 +324,7 @@ acpi_tb_get_this_table(struct acpi_pointer *address,
 
        if (header->length < sizeof(struct acpi_table_header)) {
                ACPI_ERROR((AE_INFO,
-                           "Table length (%X) is smaller than minimum (%X)",
+                           "Table length (%X) is smaller than minimum (%zX)",
                            header->length, sizeof(struct acpi_table_header)));
 
                return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH);
index 0ad3dbb9ebca377563a6a177ab092704f63545f8..86a5fca9b739de2b9d42344dc6c5406c55f17f73 100644 (file)
@@ -187,7 +187,7 @@ acpi_status acpi_tb_validate_rsdt(struct acpi_table_header *table_ptr)
 
        if (table_ptr->length < sizeof(struct acpi_table_header)) {
                ACPI_ERROR((AE_INFO,
-                           "RSDT/XSDT length (%X) is smaller than minimum (%X)",
+                           "RSDT/XSDT length (%X) is smaller than minimum (%zX)",
                            table_ptr->length,
                            sizeof(struct acpi_table_header)));
 
index 3f4aa0c99ee4dccaf096330732887bc5be153f79..03f6338acc8fb7223e040078b1f196d28835c444 100644 (file)
@@ -6,6 +6,7 @@ menu "Serial ATA (prod) and Parallel ATA (experimental) drivers"
 
 config ATA
        tristate "ATA device support"
+       depends on BLOCK
        depends on !(M32R || M68K) || BROKEN
        depends on !SUN4 || BROKEN
        select SCSI
index 54e1f38ce30187be1800ea581ed54589b38bcacd..cef2e70d64f8d57d2e62bbec19a5fda752e05d40 100644 (file)
@@ -204,7 +204,7 @@ static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg);
 static void ahci_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
 static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
 static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc);
-static irqreturn_t ahci_interrupt (int irq, void *dev_instance, struct pt_regs *regs);
+static irqreturn_t ahci_interrupt (int irq, void *dev_instance);
 static void ahci_irq_clear(struct ata_port *ap);
 static int ahci_port_start(struct ata_port *ap);
 static void ahci_port_stop(struct ata_port *ap);
@@ -1041,7 +1041,7 @@ static void ahci_host_intr(struct ata_port *ap)
        /* hmmm... a spurious interupt */
 
        /* some devices send D2H reg with I bit set during NCQ command phase */
-       if (ap->sactive && status & PORT_IRQ_D2H_REG_FIS)
+       if (ap->sactive && (status & PORT_IRQ_D2H_REG_FIS))
                return;
 
        /* ignore interim PIO setup fis interrupts */
@@ -1059,7 +1059,7 @@ static void ahci_irq_clear(struct ata_port *ap)
        /* TODO */
 }
 
-static irqreturn_t ahci_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
+static irqreturn_t ahci_interrupt(int irq, void *dev_instance)
 {
        struct ata_host *host = dev_instance;
        struct ahci_host_priv *hpriv;
index 5719704eb0ee5a6d5699399cf2edb3b12f174f18..5250187ffce2a610f456e3814d019bc3a4b656b6 100644 (file)
@@ -432,9 +432,9 @@ static const struct piix_map_db ich8_map_db = {
        .present_shift = 8,
        .map = {
                /* PM   PS   SM   SS       MAP */
-               {  P0,  NA,  P1,  NA }, /* 00b (hardwired) */
+               {  P0,  P2,  P1,  P3 }, /* 00b (hardwired when in AHCI) */
                {  RV,  RV,  RV,  RV },
-               {  RV,  RV,  RV,  RV }, /* 10b (never) */
+               {  IDE,  IDE,  NA,  NA }, /* 10b (IDE mode) */
                {  RV,  RV,  RV,  RV },
        },
 };
index dce65651d8586ffb67c4bf4dcc3efc38940cc8b0..83728a9457ad896590e79fa44d55d9e6efedaf8f 100644 (file)
@@ -870,7 +870,11 @@ static unsigned int ata_id_xfermask(const u16 *id)
                 * the PIO timing number for the maximum. Turn it into
                 * a mask.
                 */
-               pio_mask = (2 << (id[ATA_ID_OLD_PIO_MODES] & 0xFF)) - 1 ;
+               u8 mode = id[ATA_ID_OLD_PIO_MODES] & 0xFF;
+               if (mode < 5)   /* Valid PIO range */
+                       pio_mask = (2 << mode) - 1;
+               else
+                       pio_mask = 1;
 
                /* But wait.. there's more. Design your standards by
                 * committee and you too can get a free iordy field to
@@ -4857,7 +4861,6 @@ idle_irq:
  *     ata_interrupt - Default ATA host interrupt handler
  *     @irq: irq line (unused)
  *     @dev_instance: pointer to our ata_host information structure
- *     @regs: unused
  *
  *     Default interrupt handler for PCI IDE devices.  Calls
  *     ata_host_intr() for each port that is not disabled.
@@ -4869,7 +4872,7 @@ idle_irq:
  *     IRQ_NONE or IRQ_HANDLED.
  */
 
-irqreturn_t ata_interrupt (int irq, void *dev_instance, struct pt_regs *regs)
+irqreturn_t ata_interrupt (int irq, void *dev_instance)
 {
        struct ata_host *host = dev_instance;
        unsigned int i;
index b0d0cc41f3e8332041195a71e97c98405a04650c..7af2a4ba49905e068d7eb38c4ad0f778ccc3702e 100644 (file)
@@ -164,10 +164,10 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg)
 {
        int rc = 0;
        u8 scsi_cmd[MAX_COMMAND_SIZE];
-       u8 args[4], *argbuf = NULL;
+       u8 args[4], *argbuf = NULL, *sensebuf = NULL;
        int argsize = 0;
-       struct scsi_sense_hdr sshdr;
        enum dma_data_direction data_dir;
+       int cmd_result;
 
        if (arg == NULL)
                return -EINVAL;
@@ -175,6 +175,10 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg)
        if (copy_from_user(args, arg, sizeof(args)))
                return -EFAULT;
 
+       sensebuf = kzalloc(SCSI_SENSE_BUFFERSIZE, GFP_NOIO);
+       if (!sensebuf)
+               return -ENOMEM;
+
        memset(scsi_cmd, 0, sizeof(scsi_cmd));
 
        if (args[3]) {
@@ -191,7 +195,7 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg)
                data_dir = DMA_FROM_DEVICE;
        } else {
                scsi_cmd[1]  = (3 << 1); /* Non-data */
-               /* scsi_cmd[2] is already 0 -- no off.line, cc, or data xfer */
+               scsi_cmd[2]  = 0x20;     /* cc but no off.line or data xfer */
                data_dir = DMA_NONE;
        }
 
@@ -210,18 +214,46 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg)
 
        /* Good values for timeout and retries?  Values below
           from scsi_ioctl_send_command() for default case... */
-       if (scsi_execute_req(scsidev, scsi_cmd, data_dir, argbuf, argsize,
-                            &sshdr, (10*HZ), 5)) {
+       cmd_result = scsi_execute(scsidev, scsi_cmd, data_dir, argbuf, argsize,
+                                 sensebuf, (10*HZ), 5, 0);
+
+       if (driver_byte(cmd_result) == DRIVER_SENSE) {/* sense data available */
+               u8 *desc = sensebuf + 8;
+               cmd_result &= ~(0xFF<<24); /* DRIVER_SENSE is not an error */
+
+               /* If we set cc then ATA pass-through will cause a
+                * check condition even if no error. Filter that. */
+               if (cmd_result & SAM_STAT_CHECK_CONDITION) {
+                       struct scsi_sense_hdr sshdr;
+                       scsi_normalize_sense(sensebuf, SCSI_SENSE_BUFFERSIZE,
+                                             &sshdr);
+                       if (sshdr.sense_key==0 &&
+                           sshdr.asc==0 && sshdr.ascq==0)
+                               cmd_result &= ~SAM_STAT_CHECK_CONDITION;
+               }
+
+               /* Send userspace a few ATA registers (same as drivers/ide) */
+               if (sensebuf[0] == 0x72 &&     /* format is "descriptor" */
+                   desc[0] == 0x09 ) {        /* code is "ATA Descriptor" */
+                       args[0] = desc[13];    /* status */
+                       args[1] = desc[3];     /* error */
+                       args[2] = desc[5];     /* sector count (0:7) */
+                       if (copy_to_user(arg, args, sizeof(args)))
+                               rc = -EFAULT;
+               }
+       }
+
+
+       if (cmd_result) {
                rc = -EIO;
                goto error;
        }
 
-       /* Need code to retrieve data from check condition? */
-
        if ((argbuf)
         && copy_to_user(arg + sizeof(args), argbuf, argsize))
                rc = -EFAULT;
 error:
+       kfree(sensebuf);
        kfree(argbuf);
        return rc;
 }
index 06daaa3736a2cbcd35efde2e377d0ad90cfc5d98..7645f2b30ccf2f35547025ed3f07e85700dcf9eb 100644 (file)
@@ -981,6 +981,15 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
                mask = (1 << 2) | (1 << 0);
                if ((tmp8 & mask) != mask)
                        legacy_mode = (1 << 3);
+#if defined(CONFIG_NO_ATA_LEGACY)
+               /* Some platforms with PCI limits cannot address compat
+                  port space. In that case we punt if their firmware has
+                  left a device in compatibility mode */
+               if (legacy_mode) {
+                       printk(KERN_ERR "ata: Compatibility mode ATA is not supported on this platform, skipping.\n");
+                       return -EOPNOTSUPP;
+               }
+#endif
        }
 
        rc = pci_request_regions(pdev, DRV_NAME);
index 7977f471d5e9a0619674f209600121c86b52ce24..2c3cc0ccc6060fd19bdce5631bccb2e4b475005f 100644 (file)
@@ -141,7 +141,7 @@ static void qdi_data_xfer(struct ata_device *adev, unsigned char *buf, unsigned
                                memcpy(&pad, buf + buflen - slop, slop);
                                outl(le32_to_cpu(pad), ap->ioaddr.data_addr);
                        } else {
-                               pad = cpu_to_le16(inl(ap->ioaddr.data_addr));
+                               pad = cpu_to_le32(inl(ap->ioaddr.data_addr));
                                memcpy(buf + buflen - slop, &pad, slop);
                        }
                }
index 81f3d219e70ed6351ebf2b818fa06fe9fe7d052e..9021e34d20966f7b70a631408b9599556e3042c3 100644 (file)
@@ -124,8 +124,7 @@ struct adma_port_priv {
 
 static int adma_ata_init_one (struct pci_dev *pdev,
                                const struct pci_device_id *ent);
-static irqreturn_t adma_intr (int irq, void *dev_instance,
-                               struct pt_regs *regs);
+static irqreturn_t adma_intr (int irq, void *dev_instance);
 static int adma_port_start(struct ata_port *ap);
 static void adma_host_stop(struct ata_host *host);
 static void adma_port_stop(struct ata_port *ap);
@@ -508,7 +507,7 @@ static inline unsigned int adma_intr_mmio(struct ata_host *host)
        return handled;
 }
 
-static irqreturn_t adma_intr(int irq, void *dev_instance, struct pt_regs *regs)
+static irqreturn_t adma_intr(int irq, void *dev_instance)
 {
        struct ata_host *host = dev_instance;
        unsigned int handled = 0;
index e6aa1a86d5cfeb84b9539af329f3bbb5f01d04f1..1b8e0eb9e0321a2254b1c8a162f71afca0f4cdea 100644 (file)
@@ -348,8 +348,7 @@ static void mv_port_stop(struct ata_port *ap);
 static void mv_qc_prep(struct ata_queued_cmd *qc);
 static void mv_qc_prep_iie(struct ata_queued_cmd *qc);
 static unsigned int mv_qc_issue(struct ata_queued_cmd *qc);
-static irqreturn_t mv_interrupt(int irq, void *dev_instance,
-                               struct pt_regs *regs);
+static irqreturn_t mv_interrupt(int irq, void *dev_instance);
 static void mv_eng_timeout(struct ata_port *ap);
 static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
 
@@ -1448,8 +1447,7 @@ static void mv_host_intr(struct ata_host *host, u32 relevant, unsigned int hc)
  *      This routine holds the host lock while processing pending
  *      interrupts.
  */
-static irqreturn_t mv_interrupt(int irq, void *dev_instance,
-                               struct pt_regs *regs)
+static irqreturn_t mv_interrupt(int irq, void *dev_instance)
 {
        struct ata_host *host = dev_instance;
        unsigned int hc, handled = 0, n_hcs;
index d09d20a177908642aa944255bbae25e047341eeb..323b607108063b41d84913c7b14ac3ae2b26ec90 100644 (file)
@@ -82,12 +82,9 @@ enum {
 
 static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
 static void nv_ck804_host_stop(struct ata_host *host);
-static irqreturn_t nv_generic_interrupt(int irq, void *dev_instance,
-                                       struct pt_regs *regs);
-static irqreturn_t nv_nf2_interrupt(int irq, void *dev_instance,
-                                   struct pt_regs *regs);
-static irqreturn_t nv_ck804_interrupt(int irq, void *dev_instance,
-                                     struct pt_regs *regs);
+static irqreturn_t nv_generic_interrupt(int irq, void *dev_instance);
+static irqreturn_t nv_nf2_interrupt(int irq, void *dev_instance);
+static irqreturn_t nv_ck804_interrupt(int irq, void *dev_instance);
 static u32 nv_scr_read (struct ata_port *ap, unsigned int sc_reg);
 static void nv_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
 
@@ -276,8 +273,7 @@ MODULE_LICENSE("GPL");
 MODULE_DEVICE_TABLE(pci, nv_pci_tbl);
 MODULE_VERSION(DRV_VERSION);
 
-static irqreturn_t nv_generic_interrupt(int irq, void *dev_instance,
-                                       struct pt_regs *regs)
+static irqreturn_t nv_generic_interrupt(int irq, void *dev_instance)
 {
        struct ata_host *host = dev_instance;
        unsigned int i;
@@ -357,8 +353,7 @@ static irqreturn_t nv_do_interrupt(struct ata_host *host, u8 irq_stat)
        return IRQ_RETVAL(handled);
 }
 
-static irqreturn_t nv_nf2_interrupt(int irq, void *dev_instance,
-                                   struct pt_regs *regs)
+static irqreturn_t nv_nf2_interrupt(int irq, void *dev_instance)
 {
        struct ata_host *host = dev_instance;
        u8 irq_stat;
@@ -372,8 +367,7 @@ static irqreturn_t nv_nf2_interrupt(int irq, void *dev_instance,
        return ret;
 }
 
-static irqreturn_t nv_ck804_interrupt(int irq, void *dev_instance,
-                                     struct pt_regs *regs)
+static irqreturn_t nv_ck804_interrupt(int irq, void *dev_instance)
 {
        struct ata_host *host = dev_instance;
        u8 irq_stat;
index 15c9437710fc1735e8f378856649b090f1889fba..72eda5160fadea392178458f7d71a1c13f41d2a2 100644 (file)
@@ -93,7 +93,7 @@ struct pdc_host_priv {
 static u32 pdc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg);
 static void pdc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
 static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
-static irqreturn_t pdc_interrupt (int irq, void *dev_instance, struct pt_regs *regs);
+static irqreturn_t pdc_interrupt (int irq, void *dev_instance);
 static void pdc_eng_timeout(struct ata_port *ap);
 static int pdc_port_start(struct ata_port *ap);
 static void pdc_port_stop(struct ata_port *ap);
@@ -260,6 +260,7 @@ static const struct pci_device_id pdc_ata_pci_tbl[] = {
 #if 0
        { PCI_VDEVICE(PROMISE, 0x3570), board_20771 },
 #endif
+       { PCI_VDEVICE(PROMISE, 0x3577), board_20771 },
 
        { }     /* terminate list */
 };
@@ -360,7 +361,7 @@ static void pdc_sata_phy_reset(struct ata_port *ap)
 static void pdc_pata_cbl_detect(struct ata_port *ap)
 {
        u8 tmp;
-       void __iomem *mmio = (void *) ap->ioaddr.cmd_addr + PDC_CTLSTAT + 0x03;
+       void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr + PDC_CTLSTAT + 0x03;
 
        tmp = readb(mmio);
 
@@ -498,7 +499,7 @@ static void pdc_irq_clear(struct ata_port *ap)
        readl(mmio + PDC_INT_SEQMASK);
 }
 
-static irqreturn_t pdc_interrupt (int irq, void *dev_instance, struct pt_regs *regs)
+static irqreturn_t pdc_interrupt (int irq, void *dev_instance)
 {
        struct ata_host *host = dev_instance;
        struct ata_port *ap;
index 7f6cc3c07de5db6820d165035c1d444419b66c59..710909df4eaf18a7e846d29f1f20d945318b7542 100644 (file)
@@ -114,7 +114,7 @@ struct qs_port_priv {
 static u32 qs_scr_read (struct ata_port *ap, unsigned int sc_reg);
 static void qs_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
 static int qs_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
-static irqreturn_t qs_intr (int irq, void *dev_instance, struct pt_regs *regs);
+static irqreturn_t qs_intr (int irq, void *dev_instance);
 static int qs_port_start(struct ata_port *ap);
 static void qs_host_stop(struct ata_host *host);
 static void qs_port_stop(struct ata_port *ap);
@@ -454,7 +454,7 @@ static inline unsigned int qs_intr_mmio(struct ata_host *host)
        return handled;
 }
 
-static irqreturn_t qs_intr(int irq, void *dev_instance, struct pt_regs *regs)
+static irqreturn_t qs_intr(int irq, void *dev_instance)
 {
        struct ata_host *host = dev_instance;
        unsigned int handled = 0;
index 3d9fa1cc834d4ddb32d13eccb5ec60e897060b79..ca8d9931247239c6f83bef81df18f8ec48ddf88e 100644 (file)
@@ -116,8 +116,7 @@ static void sil_dev_config(struct ata_port *ap, struct ata_device *dev);
 static u32 sil_scr_read (struct ata_port *ap, unsigned int sc_reg);
 static void sil_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
 static void sil_post_set_mode (struct ata_port *ap);
-static irqreturn_t sil_interrupt(int irq, void *dev_instance,
-                                struct pt_regs *regs);
+static irqreturn_t sil_interrupt(int irq, void *dev_instance);
 static void sil_freeze(struct ata_port *ap);
 static void sil_thaw(struct ata_port *ap);
 
@@ -350,7 +349,7 @@ static u32 sil_scr_read (struct ata_port *ap, unsigned int sc_reg)
 
 static void sil_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
 {
-       void *mmio = (void __iomem *) sil_scr_addr(ap, sc_reg);
+       void __iomem *mmio = (void __iomem *) sil_scr_addr(ap, sc_reg);
        if (mmio)
                writel(val, mmio);
 }
@@ -437,8 +436,7 @@ static void sil_host_intr(struct ata_port *ap, u32 bmdma2)
        ata_port_freeze(ap);
 }
 
-static irqreturn_t sil_interrupt(int irq, void *dev_instance,
-                                struct pt_regs *regs)
+static irqreturn_t sil_interrupt(int irq, void *dev_instance)
 {
        struct ata_host *host = dev_instance;
        void __iomem *mmio_base = host->mmio_base;
index a951f40c2f21ba365ed2866a6cee6311b260445c..169e200a6a719a2c716fad986164054bfbd0aa16 100644 (file)
@@ -330,7 +330,7 @@ static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf);
 static void sil24_qc_prep(struct ata_queued_cmd *qc);
 static unsigned int sil24_qc_issue(struct ata_queued_cmd *qc);
 static void sil24_irq_clear(struct ata_port *ap);
-static irqreturn_t sil24_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
+static irqreturn_t sil24_interrupt(int irq, void *dev_instance);
 static void sil24_freeze(struct ata_port *ap);
 static void sil24_thaw(struct ata_port *ap);
 static void sil24_error_handler(struct ata_port *ap);
@@ -870,7 +870,7 @@ static inline void sil24_host_intr(struct ata_port *ap)
                        slot_stat, ap->active_tag, ap->sactive);
 }
 
-static irqreturn_t sil24_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
+static irqreturn_t sil24_interrupt(int irq, void *dev_instance)
 {
        struct ata_host *host = dev_instance;
        struct sil24_host_priv *hpriv = host->private_data;
index 84025a2fd5be2167d58f8a35d5349f896b3f220f..db32d15b7fa1c5d390b47c3a7f5b64d25bbce3b4 100644 (file)
@@ -177,7 +177,7 @@ static void k2_bmdma_setup_mmio (struct ata_queued_cmd *qc)
        struct ata_port *ap = qc->ap;
        unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE);
        u8 dmactl;
-       void *mmio = (void *) ap->ioaddr.bmdma_addr;
+       void __iomem *mmio = (void __iomem *) ap->ioaddr.bmdma_addr;
        /* load PRD table addr. */
        mb();   /* make sure PRD table writes are visible to controller */
        writel(ap->prd_dma, mmio + ATA_DMA_TABLE_OFS);
@@ -205,7 +205,7 @@ static void k2_bmdma_setup_mmio (struct ata_queued_cmd *qc)
 static void k2_bmdma_start_mmio (struct ata_queued_cmd *qc)
 {
        struct ata_port *ap = qc->ap;
-       void *mmio = (void *) ap->ioaddr.bmdma_addr;
+       void __iomem *mmio = (void __iomem *) ap->ioaddr.bmdma_addr;
        u8 dmactl;
 
        /* start host DMA transaction */
index 8c74f2ff4344eacee424ef455f9111926c6a9e40..ae7992de4b08ff44c0b668899ca3f5fce3f2aee2 100644 (file)
@@ -152,7 +152,7 @@ struct pdc_host_priv {
 
 
 static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
-static irqreturn_t pdc20621_interrupt (int irq, void *dev_instance, struct pt_regs *regs);
+static irqreturn_t pdc20621_interrupt (int irq, void *dev_instance);
 static void pdc_eng_timeout(struct ata_port *ap);
 static void pdc_20621_phy_reset (struct ata_port *ap);
 static int pdc_port_start(struct ata_port *ap);
@@ -788,7 +788,7 @@ static void pdc20621_irq_clear(struct ata_port *ap)
        readl(mmio + PDC_20621_SEQMASK);
 }
 
-static irqreturn_t pdc20621_interrupt (int irq, void *dev_instance, struct pt_regs *regs)
+static irqreturn_t pdc20621_interrupt (int irq, void *dev_instance)
 {
        struct ata_host *host = dev_instance;
        struct ata_port *ap;
index 273d88fcf980fd185418fa6f3b05b6de3ed5cf48..e654b990b90541405f53ec2c53a2dcc53ffcf4dd 100644 (file)
@@ -203,8 +203,7 @@ static void vsc_sata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
  *
  * Read the interrupt register and process for the devices that have them pending.
  */
-static irqreturn_t vsc_sata_interrupt (int irq, void *dev_instance,
-                                      struct pt_regs *regs)
+static irqreturn_t vsc_sata_interrupt (int irq, void *dev_instance)
 {
        struct ata_host *host = dev_instance;
        unsigned int i;
index da599e6e9d34c2fd47aa02bac6c615704f2a9244..9fffa7af6db1f5c2feaf448fd7dec744e41ab308 100644 (file)
@@ -861,18 +861,11 @@ static inline void interrupts_off (amb_dev * dev) {
 
 /********** interrupt handling **********/
 
-static irqreturn_t interrupt_handler(int irq, void *dev_id,
-                                       struct pt_regs *pt_regs) {
-  amb_dev * dev = (amb_dev *) dev_id;
-  (void) pt_regs;
+static irqreturn_t interrupt_handler(int irq, void *dev_id) {
+  amb_dev * dev = dev_id;
   
   PRINTD (DBG_IRQ|DBG_FLOW, "interrupt_handler: %p", dev_id);
   
-  if (!dev_id) {
-    PRINTD (DBG_IRQ|DBG_ERR, "irq with NULL dev_id: %d", irq);
-    return IRQ_NONE;
-  }
-  
   {
     u32 interrupt = rd_plain (dev, offsetof(amb_mem, interrupt));
   
@@ -2459,8 +2452,8 @@ static int __init amb_module_init (void)
 static void __exit amb_module_exit (void)
 {
   PRINTD (DBG_FLOW|DBG_INIT, "cleanup_module");
-  
-  return pci_unregister_driver(&amb_driver);
+
+  pci_unregister_driver(&amb_driver);
 }
 
 module_init(amb_module_init);
index df359a6c14f6ab57a140c62bed4d6b274595f674..bc1b13c8f5d717893661d12ee0fad2512175c91b 100644 (file)
@@ -1488,7 +1488,7 @@ static void bug_int(struct atm_dev *dev,unsigned long reason)
 }
 
 
-static irqreturn_t eni_int(int irq,void *dev_id,struct pt_regs *regs)
+static irqreturn_t eni_int(int irq,void *dev_id)
 {
        struct atm_dev *dev;
        struct eni_dev *eni_dev;
index 5f25e5efefcd72838f46ab9a1b1dcd62aff2d21b..697ad82f6634e2f74e4c3298d17f6ac13d0162cc 100644 (file)
@@ -1002,6 +1002,10 @@ static int fs_open(struct atm_vcc *atm_vcc)
                                        r = ROUND_UP;
                                }
                                error = make_rate (pcr, r, &tmc0, NULL);
+                               if (error) {
+                                       kfree(tc);
+                                       return error;
+                               }
                        }
                        fs_dprintk (FS_DEBUG_OPEN, "pcr = %d.\n", pcr);
                }
@@ -1546,7 +1550,7 @@ static void __devexit free_freepool (struct fs_dev *dev, struct freepool *fp)
 
 
 
-static irqreturn_t fs_irq (int irq, void *dev_id,  struct pt_regs * pt_regs
+static irqreturn_t fs_irq (int irq, void *dev_id) 
 {
        int i;
        u32 status;
index 98622130de5b65d9573d7d18856115d9579c7c52..3a7b21ff30a558b7bf1bd121eb0b428eef8c630c 100644 (file)
@@ -1328,7 +1328,7 @@ fore200e_irq(struct fore200e* fore200e)
 
 
 static irqreturn_t
-fore200e_interrupt(int irq, void* dev, struct pt_regs* regs)
+fore200e_interrupt(int irq, void* dev)
 {
     struct fore200e* fore200e = FORE200E_DEV((struct atm_dev*)dev);
 
index b22a9142b240677530dc06a6781e5590b17ecafc..c7314a79da0fffcedeb9e40ecef63ec14c994b9e 100644 (file)
@@ -109,7 +109,7 @@ static int he_open(struct atm_vcc *vcc);
 static void he_close(struct atm_vcc *vcc);
 static int he_send(struct atm_vcc *vcc, struct sk_buff *skb);
 static int he_ioctl(struct atm_dev *dev, unsigned int cmd, void __user *arg);
-static irqreturn_t he_irq_handler(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t he_irq_handler(int irq, void *dev_id);
 static void he_tasklet(unsigned long data);
 static int he_proc_read(struct atm_dev *dev,loff_t *pos,char *page);
 static int he_start(struct atm_dev *dev);
@@ -2216,7 +2216,7 @@ he_tasklet(unsigned long data)
 }
 
 static irqreturn_t
-he_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
+he_irq_handler(int irq, void *dev_id)
 {
        unsigned long flags;
        struct he_dev *he_dev = (struct he_dev * )dev_id;
index 209dba1c70da530474afc0271fb01e36df2e8cea..44268cba5a5a215c3f8de6a78af1ada1653cd393 100644 (file)
@@ -1382,24 +1382,13 @@ static inline void rx_data_av_handler (hrz_dev * dev) {
 
 /********** interrupt handler **********/
 
-static irqreturn_t interrupt_handler(int irq, void *dev_id,
-                                       struct pt_regs *pt_regs) {
+static irqreturn_t interrupt_handler(int irq, void *dev_id) {
   hrz_dev * dev = (hrz_dev *) dev_id;
   u32 int_source;
   unsigned int irq_ok;
-  (void) pt_regs;
   
   PRINTD (DBG_FLOW, "interrupt_handler: %p", dev_id);
   
-  if (!dev_id) {
-    PRINTD (DBG_IRQ|DBG_ERR, "irq with NULL dev_id: %d", irq);
-    return IRQ_NONE;
-  }
-  if (irq != dev->irq) {
-    PRINTD (DBG_IRQ|DBG_ERR, "irq mismatch: %d", irq);
-    return IRQ_NONE;
-  }
-  
   // definitely for us
   irq_ok = 0;
   while ((int_source = rd_regl (dev, INT_SOURCE_REG_OFF)
@@ -2943,8 +2932,8 @@ static int __init hrz_module_init (void) {
 
 static void __exit hrz_module_exit (void) {
   PRINTD (DBG_FLOW, "cleanup_module");
-  
-  return pci_unregister_driver(&hrz_driver);
+
+  pci_unregister_driver(&hrz_driver);
 }
 
 module_init(hrz_module_init);
index 7487f0ad68e9cdd869e21e004227188b6d2ab2a9..87b17c33b3f958595d6fec200b55432714475927 100644 (file)
@@ -2774,7 +2774,7 @@ idt77252_collect_stat(struct idt77252_dev *card)
 }
 
 static irqreturn_t
-idt77252_interrupt(int irq, void *dev_id, struct pt_regs *ptregs)
+idt77252_interrupt(int irq, void *dev_id)
 {
        struct idt77252_dev *card = dev_id;
        u32 stat;
index f20b0b2c06c6b19bc2643061e0ac740d692ac467..9ed1c60048f03002cd4d5df7d835a7fe28ad274a 100644 (file)
@@ -2195,7 +2195,7 @@ err_out:
        return -ENOMEM;
 }   
    
-static irqreturn_t ia_int(int irq, void *dev_id, struct pt_regs *regs)  
+static irqreturn_t ia_int(int irq, void *dev_id)  
 {  
    struct atm_dev *dev;  
    IADEV *iadev;  
index b9568e10965a068b7372860e38696cf4069e85ef..267825501dfe61570ed12300b45be52590bf5f89 100644 (file)
@@ -1890,13 +1890,11 @@ static inline void lanai_int_1(struct lanai_dev *lanai, u32 reason)
                reg_write(lanai, ack, IntAck_Reg);
 }
 
-static irqreturn_t lanai_int(int irq, void *devid, struct pt_regs *regs)
+static irqreturn_t lanai_int(int irq, void *devid)
 {
-       struct lanai_dev *lanai = (struct lanai_dev *) devid;
+       struct lanai_dev *lanai = devid;
        u32 reason;
 
-       (void) irq; (void) regs;        /* unused variables */
-
 #ifdef USE_POWERDOWN
        /*
         * If we're powered down we shouldn't be generating any interrupts -
index b8036899e56f467d18284dfa3ac852995d450069..bd09045948054ab836fe3b14f9f0384a85b08f86 100644 (file)
@@ -214,7 +214,7 @@ static void __devinit ns_init_card_error(ns_dev *card, int error);
 static scq_info *get_scq(int size, u32 scd);
 static void free_scq(scq_info *scq, struct atm_vcc *vcc);
 static void push_rxbufs(ns_dev *, struct sk_buff *);
-static irqreturn_t ns_irq_handler(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t ns_irq_handler(int irq, void *dev_id);
 static int ns_open(struct atm_vcc *vcc);
 static void ns_close(struct atm_vcc *vcc);
 static void fill_tst(ns_dev *card, int n, vc_map *vc);
@@ -1194,7 +1194,7 @@ static void push_rxbufs(ns_dev *card, struct sk_buff *skb)
 
 
 
-static irqreturn_t ns_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t ns_irq_handler(int irq, void *dev_id)
 {
    u32 stat_r;
    ns_dev *card;
@@ -2759,7 +2759,7 @@ static int ns_ioctl(struct atm_dev *dev, unsigned int cmd, void __user *arg)
 {
    ns_dev *card;
    pool_levels pl;
-   int btype;
+   long btype;
    unsigned long flags;
 
    card = dev->dev_data;
@@ -2859,7 +2859,7 @@ static int ns_ioctl(struct atm_dev *dev, unsigned int cmd, void __user *arg)
       case NS_ADJBUFLEV:
          if (!capable(CAP_NET_ADMIN))
            return -EPERM;
-         btype = (int) arg;    /* an int is the same size as a pointer */
+         btype = (long) arg;   /* a long is the same size as a pointer or bigger */
          switch (btype)
         {
            case NS_BUFTYPE_SMALL:
index 083c5d3f2e1855d25a568174fa176a65269327a9..7df0f373188eaad68253ff3d56a466752436e6b6 100644 (file)
@@ -1012,7 +1012,7 @@ static int start_tx(struct atm_dev *dev)
 /*------------------------------- interrupts --------------------------------*/
 
 
-static irqreturn_t zatm_int(int irq,void *dev_id,struct pt_regs *regs)
+static irqreturn_t zatm_int(int irq,void *dev_id)
 {
        struct atm_dev *dev;
        struct zatm_dev *zatm_dev;
index 12173d16bea7332b9b76e8f19d6568dc01c5a2fd..7d8a7ce73fb314a22d8d2ec51c8717b2ab10cc0b 100644 (file)
@@ -372,19 +372,30 @@ int bus_add_device(struct device * dev)
                pr_debug("bus %s: add device %s\n", bus->name, dev->bus_id);
                error = device_add_attrs(bus, dev);
                if (error)
-                       goto out;
+                       goto out_put;
                error = sysfs_create_link(&bus->devices.kobj,
                                                &dev->kobj, dev->bus_id);
                if (error)
-                       goto out;
+                       goto out_id;
                error = sysfs_create_link(&dev->kobj,
                                &dev->bus->subsys.kset.kobj, "subsystem");
                if (error)
-                       goto out;
+                       goto out_subsys;
                error = sysfs_create_link(&dev->kobj,
                                &dev->bus->subsys.kset.kobj, "bus");
+               if (error)
+                       goto out_deprecated;
        }
-out:
+       return 0;
+
+out_deprecated:
+       sysfs_remove_link(&dev->kobj, "subsystem");
+out_subsys:
+       sysfs_remove_link(&bus->devices.kobj, dev->bus_id);
+out_id:
+       device_remove_attrs(bus, dev);
+out_put:
+       put_bus(dev->bus);
        return error;
 }
 
@@ -428,8 +439,10 @@ void bus_remove_device(struct device * dev)
                sysfs_remove_link(&dev->kobj, "bus");
                sysfs_remove_link(&dev->bus->devices.kobj, dev->bus_id);
                device_remove_attrs(dev->bus, dev);
-               dev->is_registered = 0;
-               klist_del(&dev->knode_bus);
+               if (dev->is_registered) {
+                       dev->is_registered = 0;
+                       klist_del(&dev->knode_bus);
+               }
                pr_debug("bus %s: remove device %s\n", dev->bus->name, dev->bus_id);
                device_release_driver(dev);
                put_bus(dev->bus);
@@ -505,34 +518,36 @@ int bus_add_driver(struct device_driver *drv)
        struct bus_type * bus = get_bus(drv->bus);
        int error = 0;
 
-       if (bus) {
-               pr_debug("bus %s: add driver %s\n", bus->name, drv->name);
-               error = kobject_set_name(&drv->kobj, "%s", drv->name);
-               if (error)
-                       goto out_put_bus;
-               drv->kobj.kset = &bus->drivers;
-               if ((error = kobject_register(&drv->kobj)))
-                       goto out_put_bus;
-
-               error = driver_attach(drv);
-               if (error)
-                       goto out_unregister;
-               klist_add_tail(&drv->knode_bus, &bus->klist_drivers);
-               module_add_driver(drv->owner, drv);
-
-               error = driver_add_attrs(bus, drv);
-               if (error) {
-                       /* How the hell do we get out of this pickle? Give up */
-                       printk(KERN_ERR "%s: driver_add_attrs(%s) failed\n",
-                               __FUNCTION__, drv->name);
-               }
-               error = add_bind_files(drv);
-               if (error) {
-                       /* Ditto */
-                       printk(KERN_ERR "%s: add_bind_files(%s) failed\n",
-                               __FUNCTION__, drv->name);
-               }
+       if (!bus)
+               return 0;
+
+       pr_debug("bus %s: add driver %s\n", bus->name, drv->name);
+       error = kobject_set_name(&drv->kobj, "%s", drv->name);
+       if (error)
+               goto out_put_bus;
+       drv->kobj.kset = &bus->drivers;
+       if ((error = kobject_register(&drv->kobj)))
+               goto out_put_bus;
+
+       error = driver_attach(drv);
+       if (error)
+               goto out_unregister;
+       klist_add_tail(&drv->knode_bus, &bus->klist_drivers);
+       module_add_driver(drv->owner, drv);
+
+       error = driver_add_attrs(bus, drv);
+       if (error) {
+               /* How the hell do we get out of this pickle? Give up */
+               printk(KERN_ERR "%s: driver_add_attrs(%s) failed\n",
+                       __FUNCTION__, drv->name);
        }
+       error = add_bind_files(drv);
+       if (error) {
+               /* Ditto */
+               printk(KERN_ERR "%s: add_bind_files(%s) failed\n",
+                       __FUNCTION__, drv->name);
+       }
+
        return error;
 out_unregister:
        kobject_unregister(&drv->kobj);
@@ -552,16 +567,17 @@ out_put_bus:
 
 void bus_remove_driver(struct device_driver * drv)
 {
-       if (drv->bus) {
-               remove_bind_files(drv);
-               driver_remove_attrs(drv->bus, drv);
-               klist_remove(&drv->knode_bus);
-               pr_debug("bus %s: remove driver %s\n", drv->bus->name, drv->name);
-               driver_detach(drv);
-               module_remove_driver(drv);
-               kobject_unregister(&drv->kobj);
-               put_bus(drv->bus);
-       }
+       if (!drv->bus)
+               return;
+
+       remove_bind_files(drv);
+       driver_remove_attrs(drv->bus, drv);
+       klist_remove(&drv->knode_bus);
+       pr_debug("bus %s: remove driver %s\n", drv->bus->name, drv->name);
+       driver_detach(drv);
+       module_remove_driver(drv);
+       kobject_unregister(&drv->kobj);
+       put_bus(drv->bus);
 }
 
 
@@ -732,11 +748,15 @@ int bus_register(struct bus_type * bus)
 
        klist_init(&bus->klist_devices, klist_devices_get, klist_devices_put);
        klist_init(&bus->klist_drivers, NULL, NULL);
-       bus_add_attrs(bus);
+       retval = bus_add_attrs(bus);
+       if (retval)
+               goto bus_attrs_fail;
 
        pr_debug("bus type '%s' registered\n", bus->name);
        return 0;
 
+bus_attrs_fail:
+       kset_unregister(&bus->drivers);
 bus_drivers_fail:
        kset_unregister(&bus->devices);
 bus_devices_fail:
index b32b77ff2dcd7c1814c66318a477b74840b88e2f..0ff267a248dba8ff5e215a380a54ea0f4221c7ce 100644 (file)
@@ -562,7 +562,10 @@ int class_device_add(struct class_device *class_dev)
                goto out2;
 
        /* add the needed attributes to this device */
-       sysfs_create_link(&class_dev->kobj, &parent_class->subsys.kset.kobj, "subsystem");
+       error = sysfs_create_link(&class_dev->kobj,
+                                 &parent_class->subsys.kset.kobj, "subsystem");
+       if (error)
+               goto out3;
        class_dev->uevent_attr.attr.name = "uevent";
        class_dev->uevent_attr.attr.mode = S_IWUSR;
        class_dev->uevent_attr.attr.owner = parent_class->owner;
index b224bb43ff638f812694efe1e4c8eaa5bbd47967..68ad11af22b41e307277f3826be989c37dbe2bbf 100644 (file)
@@ -44,7 +44,7 @@ const char *dev_driver_string(struct device *dev)
        return dev->driver ? dev->driver->name :
                        (dev->bus ? dev->bus->name : "");
 }
-EXPORT_SYMBOL_GPL(dev_driver_string);
+EXPORT_SYMBOL(dev_driver_string);
 
 #define to_dev(obj) container_of(obj, struct device, kobj)
 #define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr)
@@ -433,14 +433,16 @@ int device_add(struct device *dev)
        if (dev->driver)
                dev->uevent_attr.attr.owner = dev->driver->owner;
        dev->uevent_attr.store = store_uevent;
-       device_create_file(dev, &dev->uevent_attr);
+       error = device_create_file(dev, &dev->uevent_attr);
+       if (error)
+               goto attrError;
 
        if (MAJOR(dev->devt)) {
                struct device_attribute *attr;
                attr = kzalloc(sizeof(*attr), GFP_KERNEL);
                if (!attr) {
                        error = -ENOMEM;
-                       goto PMError;
+                       goto ueventattrError;
                }
                attr->attr.name = "dev";
                attr->attr.mode = S_IRUGO;
@@ -450,7 +452,7 @@ int device_add(struct device *dev)
                error = device_create_file(dev, attr);
                if (error) {
                        kfree(attr);
-                       goto attrError;
+                       goto ueventattrError;
                }
 
                dev->devt_attr = attr;
@@ -477,7 +479,8 @@ int device_add(struct device *dev)
        if ((error = bus_add_device(dev)))
                goto BusError;
        kobject_uevent(&dev->kobj, KOBJ_ADD);
-       bus_attach_device(dev);
+       if ((error = bus_attach_device(dev)))
+               goto AttachError;
        if (parent)
                klist_add_tail(&dev->knode_parent, &parent->klist_children);
 
@@ -496,6 +499,8 @@ int device_add(struct device *dev)
        kfree(class_name);
        put_device(dev);
        return error;
+ AttachError:
+       bus_remove_device(dev);
  BusError:
        device_pm_remove(dev);
  PMError:
@@ -507,6 +512,8 @@ int device_add(struct device *dev)
                device_remove_file(dev, dev->devt_attr);
                kfree(dev->devt_attr);
        }
+ ueventattrError:
+       device_remove_file(dev, &dev->uevent_attr);
  attrError:
        kobject_uevent(&dev->kobj, KOBJ_REMOVE);
        kobject_del(&dev->kobj);
@@ -805,8 +812,10 @@ int device_rename(struct device *dev, char *new_name)
 
        if (dev->class) {
                old_symlink_name = kmalloc(BUS_ID_SIZE, GFP_KERNEL);
-               if (!old_symlink_name)
-                       return -ENOMEM;
+               if (!old_symlink_name) {
+                       error = -ENOMEM;
+                       goto out_free_old_class;
+               }
                strlcpy(old_symlink_name, dev->bus_id, BUS_ID_SIZE);
        }
 
@@ -830,9 +839,10 @@ int device_rename(struct device *dev, char *new_name)
        }
        put_device(dev);
 
-       kfree(old_class_name);
        kfree(new_class_name);
        kfree(old_symlink_name);
+ out_free_old_class:
+       kfree(old_class_name);
 
        return error;
 }
index b5f43c3e44fa2a5c9d5bf23898ea57472e7b38ae..db01b95a47a501d5976c04d66052a8809f026f29 100644 (file)
@@ -171,6 +171,8 @@ int driver_probe_device(struct device_driver * drv, struct device * dev)
                 drv->bus->name, dev->bus_id, drv->name);
 
        data = kmalloc(sizeof(*data), GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
        data->drv = drv;
        data->dev = dev;
 
@@ -178,7 +180,7 @@ int driver_probe_device(struct device_driver * drv, struct device * dev)
                probe_task = kthread_run(really_probe, data,
                                         "probe-%s", dev->bus_id);
                if (IS_ERR(probe_task))
-                       ret = PTR_ERR(probe_task);
+                       ret = really_probe(data);
        } else
                ret = really_probe(data);
 
index 33c5cce1560b261b767fa56faa410e19ed47d5e4..b2efbd4cf710d9d0ce79474c2280d04c6bbd7c42 100644 (file)
@@ -141,11 +141,20 @@ dma_pool_create (const char *name, struct device *dev,
        init_waitqueue_head (&retval->waitq);
 
        if (dev) {
+               int ret;
+
                down (&pools_lock);
                if (list_empty (&dev->dma_pools))
-                       device_create_file (dev, &dev_attr_pools);
+                       ret = device_create_file (dev, &dev_attr_pools);
+               else
+                       ret = 0;
                /* note:  not currently insisting "name" be unique */
-               list_add (&retval->pools, &dev->dma_pools);
+               if (!ret)
+                       list_add (&retval->pools, &dev->dma_pools);
+               else {
+                       kfree(retval);
+                       retval = NULL;
+               }
                up (&pools_lock);
        } else
                INIT_LIST_HEAD (&retval->pools);
index 3ef9d514b916985af339d2af7067903daf9a881e..28dccb730af99032a9bf653990b604df35ff29b9 100644 (file)
@@ -97,8 +97,7 @@ static struct attribute_group topology_attr_group = {
 /* Add/Remove cpu_topology interface for CPU device */
 static int __cpuinit topology_add_dev(struct sys_device * sys_dev)
 {
-       sysfs_create_group(&sys_dev->kobj, &topology_attr_group);
-       return 0;
+       return sysfs_create_group(&sys_dev->kobj, &topology_attr_group);
 }
 
 static int __cpuinit topology_remove_dev(struct sys_device * sys_dev)
index b3f639fbf220038a8b04fad8de15178741ab9e16..742d0740310140a59e7a03ca4ab6883ee82be8e2 100644 (file)
@@ -2698,8 +2698,7 @@ DAC960_DetectController(struct pci_dev *PCI_Device,
 {
   struct DAC960_privdata *privdata =
                (struct DAC960_privdata *)entry->driver_data;
-  irqreturn_t (*InterruptHandler)(int, void *, struct pt_regs *) =
-               privdata->InterruptHandler;
+  irq_handler_t InterruptHandler = privdata->InterruptHandler;
   unsigned int MemoryWindowSize = privdata->MemoryWindowSize;
   DAC960_Controller_T *Controller = NULL;
   unsigned char DeviceFunction = PCI_Device->devfn;
@@ -5253,10 +5252,9 @@ static void DAC960_V2_ProcessCompletedCommand(DAC960_Command_T *Command)
 */
 
 static irqreturn_t DAC960_GEM_InterruptHandler(int IRQ_Channel,
-                                      void *DeviceIdentifier,
-                                      struct pt_regs *InterruptRegisters)
+                                      void *DeviceIdentifier)
 {
-  DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier;
+  DAC960_Controller_T *Controller = DeviceIdentifier;
   void __iomem *ControllerBaseAddress = Controller->BaseAddress;
   DAC960_V2_StatusMailbox_T *NextStatusMailbox;
   unsigned long flags;
@@ -5295,10 +5293,9 @@ static irqreturn_t DAC960_GEM_InterruptHandler(int IRQ_Channel,
 */
 
 static irqreturn_t DAC960_BA_InterruptHandler(int IRQ_Channel,
-                                      void *DeviceIdentifier,
-                                      struct pt_regs *InterruptRegisters)
+                                      void *DeviceIdentifier)
 {
-  DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier;
+  DAC960_Controller_T *Controller = DeviceIdentifier;
   void __iomem *ControllerBaseAddress = Controller->BaseAddress;
   DAC960_V2_StatusMailbox_T *NextStatusMailbox;
   unsigned long flags;
@@ -5338,10 +5335,9 @@ static irqreturn_t DAC960_BA_InterruptHandler(int IRQ_Channel,
 */
 
 static irqreturn_t DAC960_LP_InterruptHandler(int IRQ_Channel,
-                                      void *DeviceIdentifier,
-                                      struct pt_regs *InterruptRegisters)
+                                      void *DeviceIdentifier)
 {
-  DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier;
+  DAC960_Controller_T *Controller = DeviceIdentifier;
   void __iomem *ControllerBaseAddress = Controller->BaseAddress;
   DAC960_V2_StatusMailbox_T *NextStatusMailbox;
   unsigned long flags;
@@ -5381,10 +5377,9 @@ static irqreturn_t DAC960_LP_InterruptHandler(int IRQ_Channel,
 */
 
 static irqreturn_t DAC960_LA_InterruptHandler(int IRQ_Channel,
-                                      void *DeviceIdentifier,
-                                      struct pt_regs *InterruptRegisters)
+                                      void *DeviceIdentifier)
 {
-  DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier;
+  DAC960_Controller_T *Controller = DeviceIdentifier;
   void __iomem *ControllerBaseAddress = Controller->BaseAddress;
   DAC960_V1_StatusMailbox_T *NextStatusMailbox;
   unsigned long flags;
@@ -5420,10 +5415,9 @@ static irqreturn_t DAC960_LA_InterruptHandler(int IRQ_Channel,
 */
 
 static irqreturn_t DAC960_PG_InterruptHandler(int IRQ_Channel,
-                                      void *DeviceIdentifier,
-                                      struct pt_regs *InterruptRegisters)
+                                      void *DeviceIdentifier)
 {
-  DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier;
+  DAC960_Controller_T *Controller = DeviceIdentifier;
   void __iomem *ControllerBaseAddress = Controller->BaseAddress;
   DAC960_V1_StatusMailbox_T *NextStatusMailbox;
   unsigned long flags;
@@ -5459,10 +5453,9 @@ static irqreturn_t DAC960_PG_InterruptHandler(int IRQ_Channel,
 */
 
 static irqreturn_t DAC960_PD_InterruptHandler(int IRQ_Channel,
-                                      void *DeviceIdentifier,
-                                      struct pt_regs *InterruptRegisters)
+                                      void *DeviceIdentifier)
 {
-  DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier;
+  DAC960_Controller_T *Controller = DeviceIdentifier;
   void __iomem *ControllerBaseAddress = Controller->BaseAddress;
   unsigned long flags;
 
@@ -5498,10 +5491,9 @@ static irqreturn_t DAC960_PD_InterruptHandler(int IRQ_Channel,
 */
 
 static irqreturn_t DAC960_P_InterruptHandler(int IRQ_Channel,
-                                     void *DeviceIdentifier,
-                                     struct pt_regs *InterruptRegisters)
+                                     void *DeviceIdentifier)
 {
-  DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier;
+  DAC960_Controller_T *Controller = DeviceIdentifier;
   void __iomem *ControllerBaseAddress = Controller->BaseAddress;
   unsigned long flags;
 
index f9217c34bc2bb2cbf200f2d4a3f3eb486de11cf0..6148073532b2951ec9172f6ea0fc069fec58baa0 100644 (file)
@@ -2175,7 +2175,7 @@ static char
 struct DAC960_privdata {
        DAC960_HardwareType_T   HardwareType;
        DAC960_FirmwareType_T   FirmwareType;
-       irqreturn_t (*InterruptHandler)(int, void *, struct pt_regs *);
+       irq_handler_t           InterruptHandler;
        unsigned int            MemoryWindowSize;
 };
 
@@ -4379,8 +4379,8 @@ static inline void DAC960_P_To_PD_TranslateEnquiry(void *Enquiry)
 static inline void DAC960_P_To_PD_TranslateDeviceState(void *DeviceState)
 {
   memcpy(DeviceState + 2, DeviceState + 3, 1);
-  memcpy(DeviceState + 4, DeviceState + 5, 2);
-  memcpy(DeviceState + 6, DeviceState + 8, 4);
+  memmove(DeviceState + 4, DeviceState + 5, 2);
+  memmove(DeviceState + 6, DeviceState + 8, 4);
 }
 
 static inline
@@ -4412,12 +4412,12 @@ static void DAC960_FinalizeController(DAC960_Controller_T *);
 static void DAC960_V1_QueueReadWriteCommand(DAC960_Command_T *);
 static void DAC960_V2_QueueReadWriteCommand(DAC960_Command_T *); 
 static void DAC960_RequestFunction(struct request_queue *);
-static irqreturn_t DAC960_BA_InterruptHandler(int, void *, struct pt_regs *);
-static irqreturn_t DAC960_LP_InterruptHandler(int, void *, struct pt_regs *);
-static irqreturn_t DAC960_LA_InterruptHandler(int, void *, struct pt_regs *);
-static irqreturn_t DAC960_PG_InterruptHandler(int, void *, struct pt_regs *);
-static irqreturn_t DAC960_PD_InterruptHandler(int, void *, struct pt_regs *);
-static irqreturn_t DAC960_P_InterruptHandler(int, void *, struct pt_regs *);
+static irqreturn_t DAC960_BA_InterruptHandler(int, void *);
+static irqreturn_t DAC960_LP_InterruptHandler(int, void *);
+static irqreturn_t DAC960_LA_InterruptHandler(int, void *);
+static irqreturn_t DAC960_PG_InterruptHandler(int, void *);
+static irqreturn_t DAC960_PD_InterruptHandler(int, void *);
+static irqreturn_t DAC960_P_InterruptHandler(int, void *);
 static void DAC960_V1_QueueMonitoringCommand(DAC960_Command_T *);
 static void DAC960_V2_QueueMonitoringCommand(DAC960_Command_T *);
 static void DAC960_MonitoringTimerFunction(unsigned long);
index 0b80fbb8dbfde08fa393d306432b647ef0ebf687..706cdc6a69eca719c856bc3c65575e77804036a7 100644 (file)
@@ -346,7 +346,7 @@ static int acsicmd_dma( const char *cmd, char *buffer, int blocks, int
                         rwflag, int enable);
 static int acsi_reqsense( char *buffer, int targ, int lun);
 static void acsi_print_error(const unsigned char *errblk, struct acsi_info_struct *aip);
-static irqreturn_t acsi_interrupt (int irq, void *data, struct pt_regs *fp);
+static irqreturn_t acsi_interrupt (int irq, void *data);
 static void unexpected_acsi_interrupt( void );
 static void bad_rw_intr( void );
 static void read_intr( void );
@@ -726,7 +726,7 @@ static void acsi_print_error(const unsigned char *errblk, struct acsi_info_struc
  *
  *******************************************************************/
 
-static irqreturn_t acsi_interrupt(int irq, void *data, struct pt_regs *fp )
+static irqreturn_t acsi_interrupt(int irq, void *data )
 
 {      void (*acsi_irq_handler)(void) = do_acsi;
 
index 4030a8fd11872992e2c5040746c873f6e8a6f01a..8e41c87b026e79282ac48c9c37d42a565ff916d1 100644 (file)
@@ -246,7 +246,7 @@ static int slm_getstats( char *buffer, int device );
 static ssize_t slm_read( struct file* file, char *buf, size_t count, loff_t
                          *ppos );
 static void start_print( int device );
-static irqreturn_t slm_interrupt(int irc, void *data, struct pt_regs *fp);
+static irqreturn_t slm_interrupt(int irc, void *data);
 static void slm_test_ready( unsigned long dummy );
 static void set_dma_addr( unsigned long paddr );
 static unsigned long get_dma_addr( void );
@@ -452,7 +452,7 @@ static void start_print( int device )
 
 /* Only called when an error happened or at the end of a page */
 
-static irqreturn_t slm_interrupt(int irc, void *data, struct pt_regs *fp)
+static irqreturn_t slm_interrupt(int irc, void *data)
 
 {      unsigned long   addr;
        int                             stat;
index 2641597c654916827f4e90661332da330b71e9ea..5d6562171533ff31f226756ae025f4fe7a678be7 100644 (file)
@@ -209,7 +209,7 @@ static int fd_device[4] = { 0, 0, 0, 0 };
 
 /* Milliseconds timer */
 
-static irqreturn_t ms_isr(int irq, void *dummy, struct pt_regs *fp)
+static irqreturn_t ms_isr(int irq, void *dummy)
 {
        ms_busy = -1;
        wake_up(&ms_wait);
@@ -560,7 +560,7 @@ static unsigned long fd_get_drive_id(int drive)
        return (id);
 }
 
-static irqreturn_t fd_block_done(int irq, void *dummy, struct pt_regs *fp)
+static irqreturn_t fd_block_done(int irq, void *dummy)
 {
        if (block_flag)
                custom.dsklen = 0x4000;
@@ -1709,10 +1709,13 @@ static struct kobject *floppy_find(dev_t dev, int *part, void *data)
        return get_disk(unit[drive].gendisk);
 }
 
-int __init amiga_floppy_init(void)
+static int __init amiga_floppy_init(void)
 {
        int i, ret;
 
+       if (!MACH_IS_AMIGA)
+               return -ENXIO;
+
        if (!AMIGAHW_PRESENT(AMI_FLOPPY))
                return -ENXIO;
 
@@ -1809,15 +1812,9 @@ out_blkdev:
        return ret;
 }
 
+module_init(amiga_floppy_init);
 #ifdef MODULE
 
-int init_module(void)
-{
-       if (!MACH_IS_AMIGA)
-               return -ENXIO;
-       return amiga_floppy_init();
-}
-
 #if 0 /* not safe to unload */
 void cleanup_module(void)
 {
index 6eebcb7be97e82fc0f83cb9411c039f5a826cc02..6d111228cfac1848fad99d9687b01e03e1230f7c 100644 (file)
@@ -1,5 +1,5 @@
-/* Copyright (c) 2004 Coraid, Inc.  See COPYING for GPL terms. */
-#define VERSION "22"
+/* Copyright (c) 2006 Coraid, Inc.  See COPYING for GPL terms. */
+#define VERSION "32"
 #define AOE_MAJOR 152
 #define DEVICE_NAME "aoe"
 
@@ -65,7 +65,7 @@ struct aoe_atahdr {
 struct aoe_cfghdr {
        __be16 bufcnt;
        __be16 fwver;
-       unsigned char res;
+       unsigned char scnt;
        unsigned char aoeccmd;
        unsigned char cslen[2];
 };
@@ -78,12 +78,14 @@ enum {
        DEVFL_GDALLOC = (1<<4), /* need to alloc gendisk */
        DEVFL_PAUSE = (1<<5),
        DEVFL_NEWSIZE = (1<<6), /* need to update dev size in block layer */
+       DEVFL_MAXBCNT = (1<<7), /* d->maxbcnt is not changeable */
+       DEVFL_KICKME = (1<<8),
 
        BUFFL_FAIL = 1,
 };
 
 enum {
-       MAXATADATA = 1024,
+       DEFAULTBCNT = 2 * 512,  /* 2 sectors */
        NPERSHELF = 16,         /* number of slots per shelf address */
        FREETAG = -1,
        MIN_BUFS = 8,
@@ -107,11 +109,9 @@ struct frame {
        ulong waited;
        struct buf *buf;
        char *bufaddr;
-       int writedatalen;
-       int ndata;
-
-       /* largest possible */
-       unsigned char data[sizeof(struct aoe_hdr) + sizeof(struct aoe_atahdr)];
+       ulong bcnt;
+       sector_t lba;
+       struct sk_buff *skb;
 };
 
 struct aoedev {
@@ -121,9 +121,12 @@ struct aoedev {
        ulong sysminor;
        ulong aoemajor;
        ulong aoeminor;
-       ulong nopen;            /* (bd_openers isn't available without sleeping) */
-       ulong rttavg;           /* round trip average of requests/responses */
+       u16 nopen;              /* (bd_openers isn't available without sleeping) */
+       u16 lasttag;            /* last tag sent */
+       u16 rttavg;             /* round trip average of requests/responses */
+       u16 mintimer;
        u16 fw_ver;             /* version of blade's firmware */
+       u16 maxbcnt;
        struct work_struct work;/* disk create work struct */
        struct gendisk *gd;
        request_queue_t blkq;
@@ -137,8 +140,8 @@ struct aoedev {
        mempool_t *bufpool;     /* for deadlock-free Buf allocation */
        struct list_head bufq;  /* queue of bios to work on */
        struct buf *inprocess;  /* the one we're currently working on */
-       ulong lasttag;          /* last tag sent */
-       ulong nframes;          /* number of frames below */
+       ushort lostjumbo;
+       ushort nframes;         /* number of frames below */
        struct frame *frames;
 };
 
@@ -157,6 +160,7 @@ void aoecmd_cfg(ushort aoemajor, unsigned char aoeminor);
 void aoecmd_ata_rsp(struct sk_buff *);
 void aoecmd_cfg_rsp(struct sk_buff *);
 void aoecmd_sleepwork(void *vp);
+struct sk_buff *new_skb(ulong);
 
 int aoedev_init(void);
 void aoedev_exit(void);
index 393b86a3dbf8e189ca26913aef7692d38c3072a3..d433f27e0ce2529c1617a6584e42abe55be62d36 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2004 Coraid, Inc.  See COPYING for GPL terms. */
+/* Copyright (c) 2006 Coraid, Inc.  See COPYING for GPL terms. */
 /*
  * aoeblk.c
  * block device routines
@@ -14,7 +14,6 @@
 
 static kmem_cache_t *buf_pool_cache;
 
-/* add attributes for our block devices in sysfs */
 static ssize_t aoedisk_show_state(struct gendisk * disk, char *page)
 {
        struct aoedev *d = disk->private_data;
@@ -64,21 +63,26 @@ static struct disk_attribute disk_attr_fwver = {
        .show = aoedisk_show_fwver
 };
 
-static void
+static struct attribute *aoe_attrs[] = {
+       &disk_attr_state.attr,
+       &disk_attr_mac.attr,
+       &disk_attr_netif.attr,
+       &disk_attr_fwver.attr,
+};
+
+static const struct attribute_group attr_group = {
+       .attrs = aoe_attrs,
+};
+
+static int
 aoedisk_add_sysfs(struct aoedev *d)
 {
-       sysfs_create_file(&d->gd->kobj, &disk_attr_state.attr);
-       sysfs_create_file(&d->gd->kobj, &disk_attr_mac.attr);
-       sysfs_create_file(&d->gd->kobj, &disk_attr_netif.attr);
-       sysfs_create_file(&d->gd->kobj, &disk_attr_fwver.attr);
+       return sysfs_create_group(&d->gd->kobj, &attr_group);
 }
 void
 aoedisk_rm_sysfs(struct aoedev *d)
 {
-       sysfs_remove_link(&d->gd->kobj, "state");
-       sysfs_remove_link(&d->gd->kobj, "mac");
-       sysfs_remove_link(&d->gd->kobj, "netif");
-       sysfs_remove_link(&d->gd->kobj, "firmware-version");
+       sysfs_remove_group(&d->gd->kobj, &attr_group);
 }
 
 static int
@@ -132,8 +136,7 @@ aoeblk_make_request(request_queue_t *q, struct bio *bio)
        d = bio->bi_bdev->bd_disk->private_data;
        buf = mempool_alloc(d->bufpool, GFP_NOIO);
        if (buf == NULL) {
-               printk(KERN_INFO "aoe: aoeblk_make_request: buf allocation "
-                       "failure\n");
+               printk(KERN_INFO "aoe: buf allocation failure\n");
                bio_endio(bio, bio->bi_size, -ENOMEM);
                return 0;
        }
@@ -143,14 +146,15 @@ aoeblk_make_request(request_queue_t *q, struct bio *bio)
        buf->bio = bio;
        buf->resid = bio->bi_size;
        buf->sector = bio->bi_sector;
-       buf->bv = buf->bio->bi_io_vec;
+       buf->bv = &bio->bi_io_vec[bio->bi_idx];
+       WARN_ON(buf->bv->bv_len == 0);
        buf->bv_resid = buf->bv->bv_len;
        buf->bufaddr = page_address(buf->bv->bv_page) + buf->bv->bv_offset;
 
        spin_lock_irqsave(&d->lock, flags);
 
        if ((d->flags & DEVFL_UP) == 0) {
-               printk(KERN_INFO "aoe: aoeblk_make_request: device %ld.%ld is not up\n",
+               printk(KERN_INFO "aoe: device %ld.%ld is not up\n",
                        d->aoemajor, d->aoeminor);
                spin_unlock_irqrestore(&d->lock, flags);
                mempool_free(buf, d->bufpool);
@@ -176,7 +180,7 @@ aoeblk_getgeo(struct block_device *bdev, struct hd_geometry *geo)
        struct aoedev *d = bdev->bd_disk->private_data;
 
        if ((d->flags & DEVFL_UP) == 0) {
-               printk(KERN_ERR "aoe: aoeblk_ioctl: disk not up\n");
+               printk(KERN_ERR "aoe: disk not up\n");
                return -ENODEV;
        }
 
@@ -203,8 +207,8 @@ aoeblk_gdalloc(void *vp)
 
        gd = alloc_disk(AOE_PARTITIONS);
        if (gd == NULL) {
-               printk(KERN_ERR "aoe: aoeblk_gdalloc: cannot allocate disk "
-                       "structure for %ld.%ld\n", d->aoemajor, d->aoeminor);
+               printk(KERN_ERR "aoe: cannot allocate disk structure for %ld.%ld\n",
+                       d->aoemajor, d->aoeminor);
                spin_lock_irqsave(&d->lock, flags);
                d->flags &= ~DEVFL_GDALLOC;
                spin_unlock_irqrestore(&d->lock, flags);
@@ -213,8 +217,8 @@ aoeblk_gdalloc(void *vp)
 
        d->bufpool = mempool_create_slab_pool(MIN_BUFS, buf_pool_cache);
        if (d->bufpool == NULL) {
-               printk(KERN_ERR "aoe: aoeblk_gdalloc: cannot allocate bufpool "
-                       "for %ld.%ld\n", d->aoemajor, d->aoeminor);
+               printk(KERN_ERR "aoe: cannot allocate bufpool for %ld.%ld\n",
+                       d->aoemajor, d->aoeminor);
                put_disk(gd);
                spin_lock_irqsave(&d->lock, flags);
                d->flags &= ~DEVFL_GDALLOC;
index 1bc1cf9603f19c4e4975bb63c1ff5ccbeb09a7cb..e22b4c9520a9fdecee3317636bb532ea6404cda6 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2004 Coraid, Inc.  See COPYING for GPL terms. */
+/* Copyright (c) 2006 Coraid, Inc.  See COPYING for GPL terms. */
 /*
  * aoechr.c
  * AoE character device driver
@@ -15,7 +15,6 @@ enum {
        MINOR_INTERFACES,
        MINOR_REVALIDATE,
        MSGSZ = 2048,
-       NARGS = 10,
        NMSG = 100,             /* message backlog to retain */
 };
 
@@ -56,9 +55,8 @@ static int
 interfaces(const char __user *str, size_t size)
 {
        if (set_aoe_iflist(str, size)) {
-               printk(KERN_CRIT
-                      "%s: could not set interface list: %s\n",
-                      __FUNCTION__, "too many interfaces");
+               printk(KERN_ERR
+                       "aoe: could not set interface list: too many interfaces\n");
                return -EINVAL;
        }
        return 0;
@@ -81,8 +79,7 @@ revalidate(const char __user *str, size_t size)
        /* should be e%d.%d format */
        n = sscanf(buf, "e%d.%d", &major, &minor);
        if (n != 2) {
-               printk(KERN_ERR "aoe: %s: invalid device specification\n",
-                       __FUNCTION__);
+               printk(KERN_ERR "aoe: invalid device specification\n");
                return -EINVAL;
        }
        d = aoedev_by_aoeaddr(major, minor);
@@ -90,6 +87,7 @@ revalidate(const char __user *str, size_t size)
                return -EINVAL;
 
        spin_lock_irqsave(&d->lock, flags);
+       d->flags &= ~DEVFL_MAXBCNT;
        d->flags |= DEVFL_PAUSE;
        spin_unlock_irqrestore(&d->lock, flags);
        aoecmd_cfg(major, minor);
@@ -116,7 +114,7 @@ bail:               spin_unlock_irqrestore(&emsgs_lock, flags);
 
        mp = kmalloc(n, GFP_ATOMIC);
        if (mp == NULL) {
-               printk(KERN_CRIT "aoe: aoechr_error: allocation failure, len=%ld\n", n);
+               printk(KERN_ERR "aoe: allocation failure, len=%ld\n", n);
                goto bail;
        }
 
@@ -141,7 +139,7 @@ aoechr_write(struct file *filp, const char __user *buf, size_t cnt, loff_t *offp
 
        switch ((unsigned long) filp->private_data) {
        default:
-               printk(KERN_INFO "aoe: aoechr_write: can't write to that file.\n");
+               printk(KERN_INFO "aoe: can't write to that file.\n");
                break;
        case MINOR_DISCOVER:
                ret = discover();
@@ -250,7 +248,7 @@ aoechr_init(void)
 
        n = register_chrdev(AOE_MAJOR, "aoechr", &aoe_fops);
        if (n < 0) { 
-               printk(KERN_ERR "aoe: aoechr_init: can't register char device\n");
+               printk(KERN_ERR "aoe: can't register char device\n");
                return n;
        }
        sema_init(&emsgs_sema, 0);
index 39da28d344fe9465186f6bed89be04ff449a7f77..8a13b1af8babdde7468af212794fa874b0a2745e 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2004 Coraid, Inc.  See COPYING for GPL terms. */
+/* Copyright (c) 2006 Coraid, Inc.  See COPYING for GPL terms. */
 /*
  * aoecmd.c
  * Filesystem request handling methods
 #define TIMERTICK (HZ / 10)
 #define MINTIMER (2 * TIMERTICK)
 #define MAXTIMER (HZ << 1)
-#define MAXWAIT (60 * 3)       /* After MAXWAIT seconds, give up and fail dev */
 
-static struct sk_buff *
-new_skb(struct net_device *if_dev, ulong len)
+static int aoe_deadsecs = 60 * 3;
+module_param(aoe_deadsecs, int, 0644);
+MODULE_PARM_DESC(aoe_deadsecs, "After aoe_deadsecs seconds, give up and fail dev.");
+
+struct sk_buff *
+new_skb(ulong len)
 {
        struct sk_buff *skb;
 
        skb = alloc_skb(len, GFP_ATOMIC);
        if (skb) {
                skb->nh.raw = skb->mac.raw = skb->data;
-               skb->dev = if_dev;
                skb->protocol = __constant_htons(ETH_P_AOE);
                skb->priority = 0;
                skb_put(skb, len);
@@ -40,29 +42,6 @@ new_skb(struct net_device *if_dev, ulong len)
        return skb;
 }
 
-static struct sk_buff *
-skb_prepare(struct aoedev *d, struct frame *f)
-{
-       struct sk_buff *skb;
-       char *p;
-
-       skb = new_skb(d->ifp, f->ndata + f->writedatalen);
-       if (!skb) {
-               printk(KERN_INFO "aoe: skb_prepare: failure to allocate skb\n");
-               return NULL;
-       }
-
-       p = skb->mac.raw;
-       memcpy(p, f->data, f->ndata);
-
-       if (f->writedatalen) {
-               p += sizeof(struct aoe_hdr) + sizeof(struct aoe_atahdr);
-               memcpy(p, f->bufaddr, f->writedatalen);
-       }
-
-       return skb;
-}
-
 static struct frame *
 getframe(struct aoedev *d, int tag)
 {
@@ -107,6 +86,17 @@ aoehdr_atainit(struct aoedev *d, struct aoe_hdr *h)
        return host_tag;
 }
 
+static inline void
+put_lba(struct aoe_atahdr *ah, sector_t lba)
+{
+       ah->lba0 = lba;
+       ah->lba1 = lba >>= 8;
+       ah->lba2 = lba >>= 8;
+       ah->lba3 = lba >>= 8;
+       ah->lba4 = lba >>= 8;
+       ah->lba5 = lba >>= 8;
+}
+
 static void
 aoecmd_ata_rw(struct aoedev *d, struct frame *f)
 {
@@ -125,29 +115,27 @@ aoecmd_ata_rw(struct aoedev *d, struct frame *f)
 
        sector = buf->sector;
        bcnt = buf->bv_resid;
-       if (bcnt > MAXATADATA)
-               bcnt = MAXATADATA;
+       if (bcnt > d->maxbcnt)
+               bcnt = d->maxbcnt;
 
        /* initialize the headers & frame */
-       h = (struct aoe_hdr *) f->data;
+       skb = f->skb;
+       h = (struct aoe_hdr *) skb->mac.raw;
        ah = (struct aoe_atahdr *) (h+1);
-       f->ndata = sizeof *h + sizeof *ah;
-       memset(h, 0, f->ndata);
+       skb->len = sizeof *h + sizeof *ah;
+       memset(h, 0, ETH_ZLEN);
        f->tag = aoehdr_atainit(d, h);
        f->waited = 0;
        f->buf = buf;
        f->bufaddr = buf->bufaddr;
+       f->bcnt = bcnt;
+       f->lba = sector;
 
        /* set up ata header */
        ah->scnt = bcnt >> 9;
-       ah->lba0 = sector;
-       ah->lba1 = sector >>= 8;
-       ah->lba2 = sector >>= 8;
-       ah->lba3 = sector >>= 8;
+       put_lba(ah, sector);
        if (d->flags & DEVFL_EXT) {
                ah->aflags |= AOEAFL_EXT;
-               ah->lba4 = sector >>= 8;
-               ah->lba5 = sector >>= 8;
        } else {
                extbit = 0;
                ah->lba3 &= 0x0f;
@@ -155,11 +143,14 @@ aoecmd_ata_rw(struct aoedev *d, struct frame *f)
        }
 
        if (bio_data_dir(buf->bio) == WRITE) {
+               skb_fill_page_desc(skb, 0, virt_to_page(f->bufaddr),
+                       offset_in_page(f->bufaddr), bcnt);
                ah->aflags |= AOEAFL_WRITE;
-               f->writedatalen = bcnt;
+               skb->len += bcnt;
+               skb->data_len = bcnt;
        } else {
+               skb->len = ETH_ZLEN;
                writebit = 0;
-               f->writedatalen = 0;
        }
 
        ah->cmdstat = WIN_READ | writebit | extbit;
@@ -168,26 +159,27 @@ aoecmd_ata_rw(struct aoedev *d, struct frame *f)
        buf->nframesout += 1;
        buf->bufaddr += bcnt;
        buf->bv_resid -= bcnt;
-/* printk(KERN_INFO "aoe: bv_resid=%ld\n", buf->bv_resid); */
+/* printk(KERN_DEBUG "aoe: bv_resid=%ld\n", buf->bv_resid); */
        buf->resid -= bcnt;
        buf->sector += bcnt >> 9;
        if (buf->resid == 0) {
                d->inprocess = NULL;
        } else if (buf->bv_resid == 0) {
                buf->bv++;
+               WARN_ON(buf->bv->bv_len == 0);
                buf->bv_resid = buf->bv->bv_len;
                buf->bufaddr = page_address(buf->bv->bv_page) + buf->bv->bv_offset;
        }
 
-       skb = skb_prepare(d, f);
-       if (skb) {
-               skb->next = NULL;
-               if (d->sendq_hd)
-                       d->sendq_tl->next = skb;
-               else
-                       d->sendq_hd = skb;
-               d->sendq_tl = skb;
-       }
+       skb->dev = d->ifp;
+       skb = skb_clone(skb, GFP_ATOMIC);
+       if (skb == NULL)
+               return;
+       if (d->sendq_hd)
+               d->sendq_tl->next = skb;
+       else
+               d->sendq_hd = skb;
+       d->sendq_tl = skb;
 }
 
 /* some callers cannot sleep, and they can call this function,
@@ -209,11 +201,12 @@ aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff **tail)
                if (!is_aoe_netif(ifp))
                        continue;
 
-               skb = new_skb(ifp, sizeof *h + sizeof *ch);
+               skb = new_skb(sizeof *h + sizeof *ch);
                if (skb == NULL) {
-                       printk(KERN_INFO "aoe: aoecmd_cfg: skb alloc failure\n");
+                       printk(KERN_INFO "aoe: skb alloc failure\n");
                        continue;
                }
+               skb->dev = ifp;
                if (sl_tail == NULL)
                        sl_tail = skb;
                h = (struct aoe_hdr *) skb->mac.raw;
@@ -237,6 +230,29 @@ aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff **tail)
        return sl;
 }
 
+static struct frame *
+freeframe(struct aoedev *d)
+{
+       struct frame *f, *e;
+       int n = 0;
+
+       f = d->frames;
+       e = f + d->nframes;
+       for (; f<e; f++) {
+               if (f->tag != FREETAG)
+                       continue;
+               if (atomic_read(&skb_shinfo(f->skb)->dataref) == 1) {
+                       skb_shinfo(f->skb)->nr_frags = f->skb->data_len = 0;
+                       return f;
+               }
+               n++;
+       }
+       if (n == d->nframes)    /* wait for network layer */
+               d->flags |= DEVFL_KICKME;
+
+       return NULL;
+}
+
 /* enters with d->lock held */
 void
 aoecmd_work(struct aoedev *d)
@@ -252,7 +268,7 @@ aoecmd_work(struct aoedev *d)
        }
 
 loop:
-       f = getframe(d, FREETAG);
+       f = freeframe(d);
        if (f == NULL)
                return;
        if (d->inprocess == NULL) {
@@ -260,7 +276,7 @@ loop:
                        return;
                buf = container_of(d->bufq.next, struct buf, bufs);
                list_del(d->bufq.next);
-/*printk(KERN_INFO "aoecmd_work: bi_size=%ld\n", buf->bio->bi_size); */
+/*printk(KERN_DEBUG "aoe: bi_size=%ld\n", buf->bio->bi_size); */
                d->inprocess = buf;
        }
        aoecmd_ata_rw(d, f);
@@ -272,6 +288,7 @@ rexmit(struct aoedev *d, struct frame *f)
 {
        struct sk_buff *skb;
        struct aoe_hdr *h;
+       struct aoe_atahdr *ah;
        char buf[128];
        u32 n;
 
@@ -283,21 +300,41 @@ rexmit(struct aoedev *d, struct frame *f)
                d->aoemajor, d->aoeminor, f->tag, jiffies, n);
        aoechr_error(buf);
 
-       h = (struct aoe_hdr *) f->data;
+       skb = f->skb;
+       h = (struct aoe_hdr *) skb->mac.raw;
+       ah = (struct aoe_atahdr *) (h+1);
        f->tag = n;
        h->tag = cpu_to_be32(n);
        memcpy(h->dst, d->addr, sizeof h->dst);
        memcpy(h->src, d->ifp->dev_addr, sizeof h->src);
 
-       skb = skb_prepare(d, f);
-       if (skb) {
-               skb->next = NULL;
-               if (d->sendq_hd)
-                       d->sendq_tl->next = skb;
-               else
-                       d->sendq_hd = skb;
-               d->sendq_tl = skb;
+       n = DEFAULTBCNT / 512;
+       if (ah->scnt > n) {
+               ah->scnt = n;
+               if (ah->aflags & AOEAFL_WRITE) {
+                       skb_fill_page_desc(skb, 0, virt_to_page(f->bufaddr),
+                               offset_in_page(f->bufaddr), DEFAULTBCNT);
+                       skb->len = sizeof *h + sizeof *ah + DEFAULTBCNT;
+                       skb->data_len = DEFAULTBCNT;
+               }
+               if (++d->lostjumbo > (d->nframes << 1))
+               if (d->maxbcnt != DEFAULTBCNT) {
+                       printk(KERN_INFO "aoe: e%ld.%ld: too many lost jumbo on %s - using 1KB frames.\n",
+                               d->aoemajor, d->aoeminor, d->ifp->name);
+                       d->maxbcnt = DEFAULTBCNT;
+                       d->flags |= DEVFL_MAXBCNT;
+               }
        }
+
+       skb->dev = d->ifp;
+       skb = skb_clone(skb, GFP_ATOMIC);
+       if (skb == NULL)
+               return;
+       if (d->sendq_hd)
+               d->sendq_tl->next = skb;
+       else
+               d->sendq_hd = skb;
+       d->sendq_tl = skb;
 }
 
 static int
@@ -340,13 +377,17 @@ rexmit_timer(ulong vp)
                if (f->tag != FREETAG && tsince(f->tag) >= timeout) {
                        n = f->waited += timeout;
                        n /= HZ;
-                       if (n > MAXWAIT) { /* waited too long.  device failure. */
+                       if (n > aoe_deadsecs) { /* waited too long for response */
                                aoedev_downdev(d);
                                break;
                        }
                        rexmit(d, f);
                }
        }
+       if (d->flags & DEVFL_KICKME) {
+               d->flags &= ~DEVFL_KICKME;
+               aoecmd_work(d);
+       }
 
        sl = d->sendq_hd;
        d->sendq_hd = d->sendq_tl = NULL;
@@ -431,8 +472,8 @@ ataid_complete(struct aoedev *d, unsigned char *id)
        }
 
        if (d->ssize != ssize)
-               printk(KERN_INFO "aoe: %012llx e%lu.%lu v%04x has %llu "
-                       "sectors\n", (unsigned long long)mac_addr(d->addr),
+               printk(KERN_INFO "aoe: %012llx e%lu.%lu v%04x has %llu sectors\n",
+                       (unsigned long long)mac_addr(d->addr),
                        d->aoemajor, d->aoeminor,
                        d->fw_ver, (long long)ssize);
        d->ssize = ssize;
@@ -442,11 +483,9 @@ ataid_complete(struct aoedev *d, unsigned char *id)
                d->flags |= DEVFL_NEWSIZE;
        } else {
                if (d->flags & DEVFL_GDALLOC) {
-                       printk(KERN_INFO "aoe: %s: %s e%lu.%lu, %s\n",
-                              __FUNCTION__,
-                              "can't schedule work for",
+                       printk(KERN_ERR "aoe: can't schedule work for e%lu.%lu, %s\n",
                               d->aoemajor, d->aoeminor,
-                              "it's already on! (This really shouldn't happen).\n");
+                              "it's already on!  This shouldn't happen.\n");
                        return;
                }
                d->flags |= DEVFL_GDALLOC;
@@ -460,8 +499,15 @@ calc_rttavg(struct aoedev *d, int rtt)
        register long n;
 
        n = rtt;
-       if (n < MINTIMER)
-               n = MINTIMER;
+       if (n < 0) {
+               n = -rtt;
+               if (n < MINTIMER)
+                       n = MINTIMER;
+               else if (n > MAXTIMER)
+                       n = MAXTIMER;
+               d->mintimer += (n - d->mintimer) >> 1;
+       } else if (n < d->mintimer)
+               n = d->mintimer;
        else if (n > MAXTIMER)
                n = MAXTIMER;
 
@@ -474,7 +520,7 @@ void
 aoecmd_ata_rsp(struct sk_buff *skb)
 {
        struct aoedev *d;
-       struct aoe_hdr *hin;
+       struct aoe_hdr *hin, *hout;
        struct aoe_atahdr *ahin, *ahout;
        struct frame *f;
        struct buf *buf;
@@ -497,8 +543,10 @@ aoecmd_ata_rsp(struct sk_buff *skb)
 
        spin_lock_irqsave(&d->lock, flags);
 
-       f = getframe(d, be32_to_cpu(hin->tag));
+       n = be32_to_cpu(hin->tag);
+       f = getframe(d, n);
        if (f == NULL) {
+               calc_rttavg(d, -tsince(n));
                spin_unlock_irqrestore(&d->lock, flags);
                snprintf(ebuf, sizeof ebuf,
                        "%15s e%d.%d    tag=%08x@%08lx\n",
@@ -514,26 +562,27 @@ aoecmd_ata_rsp(struct sk_buff *skb)
        calc_rttavg(d, tsince(f->tag));
 
        ahin = (struct aoe_atahdr *) (hin+1);
-       ahout = (struct aoe_atahdr *) (f->data + sizeof(struct aoe_hdr));
+       hout = (struct aoe_hdr *) f->skb->mac.raw;
+       ahout = (struct aoe_atahdr *) (hout+1);
        buf = f->buf;
 
        if (ahout->cmdstat == WIN_IDENTIFY)
                d->flags &= ~DEVFL_PAUSE;
        if (ahin->cmdstat & 0xa9) {     /* these bits cleared on success */
-               printk(KERN_CRIT "aoe: aoecmd_ata_rsp: ata error cmd=%2.2Xh "
-                       "stat=%2.2Xh from e%ld.%ld\n", 
+               printk(KERN_ERR
+                       "aoe: ata error cmd=%2.2Xh stat=%2.2Xh from e%ld.%ld\n",
                        ahout->cmdstat, ahin->cmdstat,
                        d->aoemajor, d->aoeminor);
                if (buf)
                        buf->flags |= BUFFL_FAIL;
        } else {
+               n = ahout->scnt << 9;
                switch (ahout->cmdstat) {
                case WIN_READ:
                case WIN_READ_EXT:
-                       n = ahout->scnt << 9;
                        if (skb->len - sizeof *hin - sizeof *ahin < n) {
-                               printk(KERN_CRIT "aoe: aoecmd_ata_rsp: runt "
-                                       "ata data size in read.  skb->len=%d\n",
+                               printk(KERN_ERR
+                                       "aoe: runt data size in read.  skb->len=%d\n",
                                        skb->len);
                                /* fail frame f?  just returning will rexmit. */
                                spin_unlock_irqrestore(&d->lock, flags);
@@ -542,22 +591,49 @@ aoecmd_ata_rsp(struct sk_buff *skb)
                        memcpy(f->bufaddr, ahin+1, n);
                case WIN_WRITE:
                case WIN_WRITE_EXT:
+                       if (f->bcnt -= n) {
+                               skb = f->skb;
+                               f->bufaddr += n;
+                               put_lba(ahout, f->lba += ahout->scnt);
+                               n = f->bcnt;
+                               if (n > DEFAULTBCNT)
+                                       n = DEFAULTBCNT;
+                               ahout->scnt = n >> 9;
+                               if (ahout->aflags & AOEAFL_WRITE) {
+                                       skb_fill_page_desc(skb, 0,
+                                               virt_to_page(f->bufaddr),
+                                               offset_in_page(f->bufaddr), n);
+                                       skb->len = sizeof *hout + sizeof *ahout + n;
+                                       skb->data_len = n;
+                               }
+                               f->tag = newtag(d);
+                               hout->tag = cpu_to_be32(f->tag);
+                               skb->dev = d->ifp;
+                               skb = skb_clone(skb, GFP_ATOMIC);
+                               spin_unlock_irqrestore(&d->lock, flags);
+                               if (skb)
+                                       aoenet_xmit(skb);
+                               return;
+                       }
+                       if (n > DEFAULTBCNT)
+                               d->lostjumbo = 0;
                        break;
                case WIN_IDENTIFY:
                        if (skb->len - sizeof *hin - sizeof *ahin < 512) {
-                               printk(KERN_INFO "aoe: aoecmd_ata_rsp: runt data size "
-                                       "in ataid.  skb->len=%d\n", skb->len);
+                               printk(KERN_INFO
+                                       "aoe: runt data size in ataid.  skb->len=%d\n",
+                                       skb->len);
                                spin_unlock_irqrestore(&d->lock, flags);
                                return;
                        }
                        ataid_complete(d, (char *) (ahin+1));
                        break;
                default:
-                       printk(KERN_INFO "aoe: aoecmd_ata_rsp: unrecognized "
-                              "outbound ata command %2.2Xh for %d.%d\n", 
-                              ahout->cmdstat,
-                              be16_to_cpu(hin->major),
-                              hin->minor);
+                       printk(KERN_INFO
+                               "aoe: unrecognized ata command %2.2Xh for %d.%d\n",
+                               ahout->cmdstat,
+                               be16_to_cpu(hin->major),
+                               hin->minor);
                }
        }
 
@@ -612,33 +688,32 @@ aoecmd_ata_id(struct aoedev *d)
        struct frame *f;
        struct sk_buff *skb;
 
-       f = getframe(d, FREETAG);
+       f = freeframe(d);
        if (f == NULL) {
-               printk(KERN_CRIT "aoe: aoecmd_ata_id: can't get a frame.  "
-                       "This shouldn't happen.\n");
+               printk(KERN_ERR "aoe: can't get a frame. This shouldn't happen.\n");
                return NULL;
        }
 
        /* initialize the headers & frame */
-       h = (struct aoe_hdr *) f->data;
+       skb = f->skb;
+       h = (struct aoe_hdr *) skb->mac.raw;
        ah = (struct aoe_atahdr *) (h+1);
-       f->ndata = sizeof *h + sizeof *ah;
-       memset(h, 0, f->ndata);
+       skb->len = ETH_ZLEN;
+       memset(h, 0, ETH_ZLEN);
        f->tag = aoehdr_atainit(d, h);
        f->waited = 0;
-       f->writedatalen = 0;
 
        /* set up ata header */
        ah->scnt = 1;
        ah->cmdstat = WIN_IDENTIFY;
        ah->lba3 = 0xa0;
 
-       skb = skb_prepare(d, f);
+       skb->dev = d->ifp;
 
        d->rttavg = MAXTIMER;
        d->timer.function = rexmit_timer;
 
-       return skb;
+       return skb_clone(skb, GFP_ATOMIC);
 }
  
 void
@@ -648,9 +723,9 @@ aoecmd_cfg_rsp(struct sk_buff *skb)
        struct aoe_hdr *h;
        struct aoe_cfghdr *ch;
        ulong flags, sysminor, aoemajor;
-       u16 bufcnt;
        struct sk_buff *sl;
        enum { MAXFRAMES = 16 };
+       u16 n;
 
        h = (struct aoe_hdr *) skb->mac.raw;
        ch = (struct aoe_cfghdr *) (h+1);
@@ -661,26 +736,25 @@ aoecmd_cfg_rsp(struct sk_buff *skb)
         */
        aoemajor = be16_to_cpu(h->major);
        if (aoemajor == 0xfff) {
-               printk(KERN_CRIT "aoe: aoecmd_cfg_rsp: Warning: shelf "
-                       "address is all ones.  Check shelf dip switches\n");
+               printk(KERN_ERR "aoe: Warning: shelf address is all ones.  "
+                       "Check shelf dip switches.\n");
                return;
        }
 
        sysminor = SYSMINOR(aoemajor, h->minor);
        if (sysminor * AOE_PARTITIONS + AOE_PARTITIONS > MINORMASK) {
-               printk(KERN_INFO
-                       "aoe: e%ld.%d: minor number too large\n", 
+               printk(KERN_INFO "aoe: e%ld.%d: minor number too large\n",
                        aoemajor, (int) h->minor);
                return;
        }
 
-       bufcnt = be16_to_cpu(ch->bufcnt);
-       if (bufcnt > MAXFRAMES) /* keep it reasonable */
-               bufcnt = MAXFRAMES;
+       n = be16_to_cpu(ch->bufcnt);
+       if (n > MAXFRAMES)      /* keep it reasonable */
+               n = MAXFRAMES;
 
-       d = aoedev_by_sysminor_m(sysminor, bufcnt);
+       d = aoedev_by_sysminor_m(sysminor, n);
        if (d == NULL) {
-               printk(KERN_INFO "aoe: aoecmd_cfg_rsp: device sysminor_m failure\n");
+               printk(KERN_INFO "aoe: device sysminor_m failure\n");
                return;
        }
 
@@ -689,6 +763,20 @@ aoecmd_cfg_rsp(struct sk_buff *skb)
        /* permit device to migrate mac and network interface */
        d->ifp = skb->dev;
        memcpy(d->addr, h->src, sizeof d->addr);
+       if (!(d->flags & DEVFL_MAXBCNT)) {
+               n = d->ifp->mtu;
+               n -= sizeof (struct aoe_hdr) + sizeof (struct aoe_atahdr);
+               n /= 512;
+               if (n > ch->scnt)
+                       n = ch->scnt;
+               n = n ? n * 512 : DEFAULTBCNT;
+               if (n != d->maxbcnt) {
+                       printk(KERN_INFO
+                               "aoe: e%ld.%ld: setting %d byte data frames on %s\n",
+                               d->aoemajor, d->aoeminor, n, d->ifp->name);
+                       d->maxbcnt = n;
+               }
+       }
 
        /* don't change users' perspective */
        if (d->nopen && !(d->flags & DEVFL_PAUSE)) {
@@ -696,6 +784,7 @@ aoecmd_cfg_rsp(struct sk_buff *skb)
                return;
        }
        d->flags |= DEVFL_PAUSE;        /* force pause */
+       d->mintimer = MINTIMER;
        d->fw_ver = be16_to_cpu(ch->fwver);
 
        /* check for already outstanding ataid */
index ed4258a62df5a889028cf6f131d4276cf436a768..6125921bbec4d971534947fa53dc4cf5cc750838 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2004 Coraid, Inc.  See COPYING for GPL terms. */
+/* Copyright (c) 2006 Coraid, Inc.  See COPYING for GPL terms. */
 /*
  * aoedev.c
  * AoE device utility functions; maintains device list.
@@ -20,11 +20,8 @@ aoedev_isbusy(struct aoedev *d)
        f = d->frames;
        e = f + d->nframes;
        do {
-               if (f->tag != FREETAG) {
-                       printk(KERN_DEBUG "aoe: %ld.%ld isbusy\n",
-                               d->aoemajor, d->aoeminor);
+               if (f->tag != FREETAG)
                        return 1;
-               }
        } while (++f < e);
 
        return 0;
@@ -66,22 +63,32 @@ aoedev_newdev(ulong nframes)
        struct frame *f, *e;
 
        d = kzalloc(sizeof *d, GFP_ATOMIC);
-       if (d == NULL)
-               return NULL;
        f = kcalloc(nframes, sizeof *f, GFP_ATOMIC);
-       if (f == NULL) {
-               kfree(d);
+       switch (!d || !f) {
+       case 0:
+               d->nframes = nframes;
+               d->frames = f;
+               e = f + nframes;
+               for (; f<e; f++) {
+                       f->tag = FREETAG;
+                       f->skb = new_skb(ETH_ZLEN);
+                       if (!f->skb)
+                               break;
+               }
+               if (f == e)
+                       break;
+               while (f > d->frames) {
+                       f--;
+                       dev_kfree_skb(f->skb);
+               }
+       default:
+               if (f)
+                       kfree(f);
+               if (d)
+                       kfree(d);
                return NULL;
        }
-
        INIT_WORK(&d->work, aoecmd_sleepwork, d);
-
-       d->nframes = nframes;
-       d->frames = f;
-       e = f + nframes;
-       for (; f<e; f++)
-               f->tag = FREETAG;
-
        spin_lock_init(&d->lock);
        init_timer(&d->timer);
        d->timer.data = (ulong) d;
@@ -114,6 +121,7 @@ aoedev_downdev(struct aoedev *d)
                        mempool_free(buf, d->bufpool);
                        bio_endio(bio, bio->bi_size, -EIO);
                }
+               skb_shinfo(f->skb)->nr_frags = f->skb->data_len = 0;
        }
        d->inprocess = NULL;
 
@@ -148,7 +156,7 @@ aoedev_by_sysminor_m(ulong sysminor, ulong bufcnt)
                d = aoedev_newdev(bufcnt);
                if (d == NULL) {
                        spin_unlock_irqrestore(&devlist_lock, flags);
-                       printk(KERN_INFO "aoe: aoedev_set: aoedev_newdev failure.\n");
+                       printk(KERN_INFO "aoe: aoedev_newdev failure.\n");
                        return NULL;
                }
                d->sysminor = sysminor;
@@ -163,11 +171,19 @@ aoedev_by_sysminor_m(ulong sysminor, ulong bufcnt)
 static void
 aoedev_freedev(struct aoedev *d)
 {
+       struct frame *f, *e;
+
        if (d->gd) {
                aoedisk_rm_sysfs(d);
                del_gendisk(d->gd);
                put_disk(d->gd);
        }
+       f = d->frames;
+       e = f + d->nframes;
+       for (; f<e; f++) {
+               skb_shinfo(f->skb)->nr_frags = 0;
+               dev_kfree_skb(f->skb);
+       }
        kfree(d->frames);
        if (d->bufpool)
                mempool_destroy(d->bufpool);
index de08491ebe666a12b25e432a6657d4ee288c1295..a04b7d613299dfc3ae73ba6ec456acdf187d2626 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2004 Coraid, Inc.  See COPYING for GPL terms. */
+/* Copyright (c) 2006 Coraid, Inc.  See COPYING for GPL terms. */
 /*
  * aoemain.c
  * Module initialization routines, discover timer
@@ -84,13 +84,11 @@ aoe_init(void)
                goto net_fail;
        ret = register_blkdev(AOE_MAJOR, DEVICE_NAME);
        if (ret < 0) {
-               printk(KERN_ERR "aoe: aoeblk_init: can't register major\n");
+               printk(KERN_ERR "aoe: can't register major\n");
                goto blkreg_fail;
        }
 
-       printk(KERN_INFO
-              "aoe: aoe_init: AoE v%s initialised.\n",
-              VERSION);
+       printk(KERN_INFO "aoe: AoE v%s initialised.\n", VERSION);
        discover_timer(TINIT);
        return 0;
 
@@ -103,7 +101,7 @@ aoe_init(void)
  chr_fail:
        aoedev_exit();
        
-       printk(KERN_INFO "aoe: aoe_init: initialisation failure.\n");
+       printk(KERN_INFO "aoe: initialisation failure.\n");
        return ret;
 }
 
index c1434ed118808999a3b05f148ef3b76b0590360f..9626e0f5da9dd4edc73d7ab559b3aa6d233e0836 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2004 Coraid, Inc.  See COPYING for GPL terms. */
+/* Copyright (c) 2006 Coraid, Inc.  See COPYING for GPL terms. */
 /*
  * aoenet.c
  * Ethernet portion of AoE driver
@@ -74,7 +74,7 @@ set_aoe_iflist(const char __user *user_str, size_t size)
                return -EINVAL;
 
        if (copy_from_user(aoe_iflist, user_str, size)) {
-               printk(KERN_INFO "aoe: %s: copy from user failed\n", __FUNCTION__);
+               printk(KERN_INFO "aoe: copy from user failed\n");
                return -EFAULT;
        }
        aoe_iflist[size] = 0x00;
@@ -132,8 +132,7 @@ aoenet_rcv(struct sk_buff *skb, struct net_device *ifp, struct packet_type *pt,
                if (n > NECODES)
                        n = 0;
                if (net_ratelimit())
-                       printk(KERN_ERR "aoe: aoenet_rcv: error packet from %d.%d; "
-                              "ecode=%d '%s'\n",
+                       printk(KERN_ERR "aoe: error packet from %d.%d; ecode=%d '%s'\n",
                               be16_to_cpu(h->major), h->minor, 
                               h->err, aoe_errlist[n]);
                goto exit;
@@ -147,7 +146,7 @@ aoenet_rcv(struct sk_buff *skb, struct net_device *ifp, struct packet_type *pt,
                aoecmd_cfg_rsp(skb);
                break;
        default:
-               printk(KERN_INFO "aoe: aoenet_rcv: unknown cmd %d\n", h->cmd);
+               printk(KERN_INFO "aoe: unknown cmd %d\n", h->cmd);
        }
 exit:
        dev_kfree_skb(skb);
index c39650920bdf7ff85be4be0455ea11965dbea9b0..14d6b949275025ef26fbeb6296f739b98f25752a 100644 (file)
@@ -342,7 +342,7 @@ static void fd_select_drive( int drive );
 static void fd_deselect( void );
 static void fd_motor_off_timer( unsigned long dummy );
 static void check_change( unsigned long dummy );
-static irqreturn_t floppy_irq (int irq, void *dummy, struct pt_regs *fp);
+static irqreturn_t floppy_irq (int irq, void *dummy);
 static void fd_error( void );
 static int do_format(int drive, int type, struct atari_format_descr *desc);
 static void do_fd_action( int drive );
@@ -573,7 +573,7 @@ static inline void copy_buffer(void *from, void *to)
 
 static void (*FloppyIRQHandler)( int status ) = NULL;
 
-static irqreturn_t floppy_irq (int irq, void *dummy, struct pt_regs *fp)
+static irqreturn_t floppy_irq (int irq, void *dummy)
 {
        unsigned char status;
        void (*handler)( int );
index 36b88f6c5f82c7a28c725ab3dd94d28c3f4ec8f9..bc6602606fb541726f1537f610cc4d80d340ca2d 100644 (file)
@@ -130,7 +130,7 @@ static struct board_type products[] = {
 static ctlr_info_t *hba[MAX_CTLR];
 
 static void do_cciss_request(request_queue_t *q);
-static irqreturn_t do_cciss_intr(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t do_cciss_intr(int irq, void *dev_id);
 static int cciss_open(struct inode *inode, struct file *filep);
 static int cciss_release(struct inode *inode, struct file *filep);
 static int cciss_ioctl(struct inode *inode, struct file *filep,
@@ -1923,7 +1923,6 @@ static void cciss_geometry_inquiry(int ctlr, int logvol,
 {
        int return_code;
        unsigned long t;
-       unsigned long rem;
 
        memset(inq_buff, 0, sizeof(InquiryData_struct));
        if (withirq)
@@ -1939,26 +1938,23 @@ static void cciss_geometry_inquiry(int ctlr, int logvol,
                        printk(KERN_WARNING
                               "cciss: reading geometry failed, volume "
                               "does not support reading geometry\n");
-                       drv->block_size = block_size;
-                       drv->nr_blocks = total_size;
                        drv->heads = 255;
                        drv->sectors = 32;      // Sectors per track
-                       t = drv->heads * drv->sectors;
-                       drv->cylinders = total_size;
-                       rem = do_div(drv->cylinders, t);
                } else {
-                       drv->block_size = block_size;
-                       drv->nr_blocks = total_size;
                        drv->heads = inq_buff->data_byte[6];
                        drv->sectors = inq_buff->data_byte[7];
                        drv->cylinders = (inq_buff->data_byte[4] & 0xff) << 8;
                        drv->cylinders += inq_buff->data_byte[5];
                        drv->raid_level = inq_buff->data_byte[8];
-                       t = drv->heads * drv->sectors;
-                       if (t > 1) {
-                               drv->cylinders = total_size;
-                               rem = do_div(drv->cylinders, t);
-                       }
+               }
+               drv->block_size = block_size;
+               drv->nr_blocks = total_size;
+               t = drv->heads * drv->sectors;
+               if (t > 1) {
+                       unsigned rem = sector_div(total_size, t);
+                       if (rem)
+                               total_size++;
+                       drv->cylinders = total_size;
                }
        } else {                /* Get geometry failed */
                printk(KERN_WARNING "cciss: reading geometry failed\n");
@@ -2300,7 +2296,7 @@ static int sendcmd(__u8 cmd, int ctlr, void *buff, size_t size, unsigned int use
 #ifdef CONFIG_CISS_SCSI_TAPE
        /* if we saved some commands for later, process them now. */
        if (info_p->scsi_rejects.ncompletions > 0)
-               do_cciss_intr(0, info_p, NULL);
+               do_cciss_intr(0, info_p);
 #endif
        cmd_free(info_p, c, 1);
        return status;
@@ -2652,7 +2648,7 @@ static inline long interrupt_not_for_us(ctlr_info_t *h)
 #endif
 }
 
-static irqreturn_t do_cciss_intr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t do_cciss_intr(int irq, void *dev_id)
 {
        ctlr_info_t *h = dev_id;
        CommandList_struct *c;
index ada68e65b5ff554deafd347a703653180668a028..570d2f0493233a5c6c9c2a1a47783765334eeef8 100644 (file)
@@ -169,7 +169,7 @@ static inline cmdlist_t *removeQ(cmdlist_t **Qptr, cmdlist_t *c);
 static inline void complete_buffers(struct bio *bio, int ok);
 static inline void complete_command(cmdlist_t *cmd, int timeout);
 
-static irqreturn_t do_ida_intr(int irq, void *dev_id, struct pt_regs * regs);
+static irqreturn_t do_ida_intr(int irq, void *dev_id);
 static void ida_timer(unsigned long tdata);
 static int ida_revalidate(struct gendisk *disk);
 static int revalidate_allvol(ctlr_info_t *host);
@@ -1042,7 +1042,7 @@ static inline void complete_command(cmdlist_t *cmd, int timeout)
  *  Find the command on the completion queue, remove it, tell the OS and
  *  try to queue up more IO
  */
-static irqreturn_t do_ida_intr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t do_ida_intr(int irq, void *dev_id)
 {
        ctlr_info_t *h = dev_id;
        cmdlist_t *c;
index 629c5769d994e3a45aa9063cfd5cf08532f2c494..9e6d3a87cbe3fab9fced8a0e7efc5a32c733ee11 100644 (file)
@@ -221,7 +221,7 @@ static DEFINE_SPINLOCK(floppy_lock);
 static struct completion device_release;
 
 static unsigned short virtual_dma_port = 0x3f0;
-irqreturn_t floppy_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+irqreturn_t floppy_interrupt(int irq, void *dev_id);
 static int set_dor(int fdc, char mask, char data);
 
 #define K_64   0x10000         /* 64KB */
@@ -1726,7 +1726,7 @@ static void print_result(char *message, int inr)
 }
 
 /* interrupt handler. Note that this can be called externally on the Sparc */
-irqreturn_t floppy_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t floppy_interrupt(int irq, void *dev_id)
 {
        void (*handler) (void) = do_floppy;
        int do_print;
index d6bb8da955a213c0c192dd3272ea435393a0a180..beab6d2643cb0fb27419bed3aa16b87034d2de0f 100644 (file)
@@ -295,7 +295,7 @@ fail:
  * and do_lo_send_write().
  */
 static int __do_lo_send_write(struct file *file,
-               u8 __user *buf, const int len, loff_t pos)
+               u8 *buf, const int len, loff_t pos)
 {
        ssize_t bw;
        mm_segment_t old_fs = get_fs();
@@ -324,7 +324,7 @@ static int do_lo_send_direct_write(struct loop_device *lo,
                struct bio_vec *bvec, int bsize, loff_t pos, struct page *page)
 {
        ssize_t bw = __do_lo_send_write(lo->lo_backing_file,
-                       (u8 __user *)kmap(bvec->bv_page) + bvec->bv_offset,
+                       kmap(bvec->bv_page) + bvec->bv_offset,
                        bvec->bv_len, pos);
        kunmap(bvec->bv_page);
        cond_resched();
@@ -351,7 +351,7 @@ static int do_lo_send_write(struct loop_device *lo, struct bio_vec *bvec,
                        bvec->bv_offset, bvec->bv_len, pos >> 9);
        if (likely(!ret))
                return __do_lo_send_write(lo->lo_backing_file,
-                               (u8 __user *)page_address(page), bvec->bv_len,
+                               page_address(page), bvec->bv_len,
                                pos);
        printk(KERN_ERR "loop: Transfer error at byte offset %llu, "
                        "length %i.\n", (unsigned long long)pos, bvec->bv_len);
@@ -1187,7 +1187,7 @@ struct compat_loop_info {
  * - noinlined to reduce stack space usage in main part of driver
  */
 static noinline int
-loop_info64_from_compat(const struct compat_loop_info *arg,
+loop_info64_from_compat(const struct compat_loop_info __user *arg,
                        struct loop_info64 *info64)
 {
        struct compat_loop_info info;
index 5537974fb2424603c89983ba9643b2aabab13015..688a4fb0dc997236c3f7436566900fcafa40cd71 100644 (file)
@@ -75,8 +75,7 @@ static int ps2esdi_out_cmd_blk(u_short * cmd_blk);
 
 static void ps2esdi_prep_dma(char *buffer, u_short length, u_char dma_xmode);
 
-static irqreturn_t ps2esdi_interrupt_handler(int irq, void *dev_id,
-                                     struct pt_regs *regs);
+static irqreturn_t ps2esdi_interrupt_handler(int irq, void *dev_id);
 static void (*current_int_handler) (u_int) = NULL;
 static void ps2esdi_normal_interrupt_handler(u_int);
 static void ps2esdi_initial_reset_int_handler(u_int);
@@ -687,8 +686,7 @@ static void ps2esdi_prep_dma(char *buffer, u_short length, u_char dma_xmode)
 
 
 
-static irqreturn_t ps2esdi_interrupt_handler(int irq, void *dev_id,
-                                     struct pt_regs *regs)
+static irqreturn_t ps2esdi_interrupt_handler(int irq, void *dev_id)
 {
        u_int int_ret_code;
 
index a3f64bfe6b5870eb52229cdd9e9dd36fd6289aaf..485aa87e9bcd6069b7c17a72d2fe946a95100db5 100644 (file)
@@ -432,6 +432,12 @@ static int __init rd_init(void)
                rd_disks[i] = alloc_disk(1);
                if (!rd_disks[i])
                        goto out;
+
+               rd_queue[i] = blk_alloc_queue(GFP_KERNEL);
+               if (!rd_queue[i]) {
+                       put_disk(rd_disks[i]);
+                       goto out;
+               }
        }
 
        if (register_blkdev(RAMDISK_MAJOR, "ramdisk")) {
@@ -442,10 +448,6 @@ static int __init rd_init(void)
        for (i = 0; i < CONFIG_BLK_DEV_RAM_COUNT; i++) {
                struct gendisk *disk = rd_disks[i];
 
-               rd_queue[i] = blk_alloc_queue(GFP_KERNEL);
-               if (!rd_queue[i])
-                       goto out_queue;
-
                blk_queue_make_request(rd_queue[i], &rd_make_request);
                blk_queue_hardsect_size(rd_queue[i], rd_blocksize);
 
@@ -466,8 +468,6 @@ static int __init rd_init(void)
                CONFIG_BLK_DEV_RAM_COUNT, rd_size, rd_blocksize);
 
        return 0;
-out_queue:
-       unregister_blkdev(RAMDISK_MAJOR, "ramdisk");
 out:
        while (i--) {
                put_disk(rd_disks[i]);
index fdc8f892eb866ddba508805816ba57a022d015b9..1a65979f1f0fda6be1f2c4e6a4d9b841eb889473 100644 (file)
@@ -238,8 +238,8 @@ static void scan_timeout(unsigned long data);
 static void seek_timeout(unsigned long data);
 static void settle_timeout(unsigned long data);
 static void xfer_timeout(unsigned long data);
-static irqreturn_t swim3_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-/*static void fd_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs);*/
+static irqreturn_t swim3_interrupt(int irq, void *dev_id);
+/*static void fd_dma_interrupt(int irq, void *dev_id);*/
 static int grab_drive(struct floppy_state *fs, enum swim_state state,
                      int interruptible);
 static void release_drive(struct floppy_state *fs);
@@ -624,7 +624,7 @@ static void xfer_timeout(unsigned long data)
        start_request(fs);
 }
 
-static irqreturn_t swim3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t swim3_interrupt(int irq, void *dev_id)
 {
        struct floppy_state *fs = (struct floppy_state *) dev_id;
        struct swim3 __iomem *sw = fs->swim3;
@@ -777,7 +777,7 @@ static irqreturn_t swim3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 }
 
 /*
-static void fd_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static void fd_dma_interrupt(int irq, void *dev_id)
 {
 }
 */
index dfda796eba563df8fbfa53b476f7abc0f48d9372..ed7b06cf3e687300e392981eb0ee3b7bda50536a 100644 (file)
@@ -94,7 +94,7 @@ static char *drive_names[7] = {
 int swimiop_init(void);
 static void swimiop_init_request(struct swim_iop_req *);
 static int swimiop_send_request(struct swim_iop_req *);
-static void swimiop_receive(struct iop_msg *, struct pt_regs *);
+static void swimiop_receive(struct iop_msg *);
 static void swimiop_status_update(int, struct swim_drvstatus *);
 static int swimiop_eject(struct floppy_state *fs);
 
@@ -257,7 +257,7 @@ static int swimiop_send_request(struct swim_iop_req *req)
  * 2. An unsolicited message was received from the IOP.
  */
 
-void swimiop_receive(struct iop_msg *msg, struct pt_regs *regs)
+void swimiop_receive(struct iop_msg *msg)
 {
        struct swim_iop_req *req;
        struct swimmsg_status *sm;
index c6beee18a07c90f8f965e2f1a566517463fd7f16..47d6975268ff3348f7991ed8ff215e3baacfbe95 100644 (file)
@@ -1200,7 +1200,7 @@ static inline void carm_handle_responses(struct carm_host *host)
        host->resp_idx += work;
 }
 
-static irqreturn_t carm_interrupt(int irq, void *__host, struct pt_regs *regs)
+static irqreturn_t carm_interrupt(int irq, void *__host)
 {
        struct carm_host *host = __host;
        void __iomem *mmio;
index 45a8f402b07bd6c214ce69a1a3b348c32127cda8..0d5c73f0726558414efc03863c544c1843f79459 100644 (file)
@@ -362,7 +362,7 @@ static void ub_end_rq(struct request *rq, unsigned int status);
 static int ub_rw_cmd_retry(struct ub_dev *sc, struct ub_lun *lun,
     struct ub_request *urq, struct ub_scsi_cmd *cmd);
 static int ub_submit_scsi(struct ub_dev *sc, struct ub_scsi_cmd *cmd);
-static void ub_urb_complete(struct urb *urb, struct pt_regs *pt);
+static void ub_urb_complete(struct urb *urb);
 static void ub_scsi_action(unsigned long _dev);
 static void ub_scsi_dispatch(struct ub_dev *sc);
 static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd);
@@ -959,7 +959,7 @@ static void ub_urb_timeout(unsigned long arg)
  * the sc->lock taken) and from an interrupt (while we do NOT have
  * the sc->lock taken). Therefore, bounce this off to a tasklet.
  */
-static void ub_urb_complete(struct urb *urb, struct pt_regs *pt)
+static void ub_urb_complete(struct urb *urb)
 {
        struct ub_dev *sc = urb->context;
 
@@ -1923,7 +1923,7 @@ err_alloc:
 
 /*
  */
-static void ub_probe_urb_complete(struct urb *urb, struct pt_regs *pt)
+static void ub_probe_urb_complete(struct urb *urb)
 {
        struct completion *cop = urb->context;
        complete(cop);
index cbb9d0f21acc7d8f52dbdbacb499465172b36982..30f16bd836505f2900050f4f484b59d0346fe8b3 100644 (file)
@@ -571,7 +571,7 @@ static int mm_make_request(request_queue_t *q, struct bio *bio)
 --                              mm_interrupt
 -----------------------------------------------------------------------------------
 */
-static irqreturn_t mm_interrupt(int irq, void *__card, struct pt_regs *regs)
+static irqreturn_t mm_interrupt(int irq, void *__card)
 {
        struct cardinfo *card = (struct cardinfo *) __card;
        unsigned int dma_status;
index ebf3025721d148866aeb0f5be68fbd4e6fdfb7ea..0d97b7eb818aa69dc39c06229bb484a39eef2978 100644 (file)
@@ -48,9 +48,9 @@
 #include <linux/blkdev.h>
 #include <linux/blkpg.h>
 #include <linux/delay.h>
+#include <linux/io.h>
 
 #include <asm/system.h>
-#include <asm/io.h>
 #include <asm/uaccess.h>
 #include <asm/dma.h>
 
@@ -462,8 +462,7 @@ static void xd_recalibrate (u_char drive)
 }
 
 /* xd_interrupt_handler: interrupt service routine */
-static irqreturn_t xd_interrupt_handler(int irq, void *dev_id,
-                                       struct pt_regs *regs)
+static irqreturn_t xd_interrupt_handler(int irq, void *dev_id)
 {
        if (inb(XD_STATUS) & STAT_INTERRUPT) {                                                  /* check if it was our device */
 #ifdef DEBUG_OTHER
index 71ac2e3dffc876edf09c2904e1180a6a7f5868ac..82e090fea957110a6a854761d9dc9f6951fef746 100644 (file)
@@ -109,8 +109,7 @@ static int xd_ioctl (struct inode *inode,struct file *file,unsigned int cmd,unsi
 static int xd_readwrite (u_char operation,XD_INFO *disk,char *buffer,u_int block,u_int count);
 static void xd_recalibrate (u_char drive);
 
-static irqreturn_t xd_interrupt_handler(int irq, void *dev_id,
-                                       struct pt_regs *regs);
+static irqreturn_t xd_interrupt_handler(int irq, void *dev_id);
 static u_char xd_setup_dma (u_char opcode,u_char *buffer,u_int count);
 static u_char *xd_build (u_char *cmdblk,u_char command,u_char drive,u_char head,u_short cylinder,u_char sector,u_char count,u_char control);
 static void xd_watchdog (unsigned long unused);
index 82ddbdd7bd4ba18f0718e388f6db83b8131992a9..7cc2685ca84abb08c29a8ec426cb871e84566ad6 100644 (file)
@@ -329,7 +329,7 @@ static struct kobject *z2_find(dev_t dev, int *part, void *data)
 
 static struct request_queue *z2_queue;
 
-int __init 
+static int __init 
 z2_init(void)
 {
     int ret;
@@ -370,26 +370,7 @@ err:
     return ret;
 }
 
-#if defined(MODULE)
-
-MODULE_LICENSE("GPL");
-
-int
-init_module( void )
-{
-    int error;
-    
-    error = z2_init();
-    if ( error == 0 )
-    {
-       printk( KERN_INFO DEVICE_NAME ": loaded as module\n" );
-    }
-    
-    return error;
-}
-
-void
-cleanup_module( void )
+static void __exit z2_exit(void)
 {
     int i, j;
     blk_unregister_region(MKDEV(Z2RAM_MAJOR, 0), 256);
@@ -425,4 +406,7 @@ cleanup_module( void )
 
     return;
 } 
-#endif
+
+module_init(z2_init);
+module_exit(z2_exit);
+MODULE_LICENSE("GPL");
index 13ba729cdd57445821dbe4bb5bf92f1dd1d4ac07..516751754aa9e6d33b4b139f84bcb10edaecb239 100644 (file)
@@ -29,7 +29,6 @@
 #include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/errno.h>
-#include <linux/timer.h>
 
 #include <linux/device.h>
 #include <linux/firmware.h>
@@ -43,7 +42,7 @@
 #define BT_DBG(D...)
 #endif
 
-#define VERSION "1.0"
+#define VERSION "1.1"
 
 static int ignore = 0;
 
@@ -72,7 +71,7 @@ struct bcm203x_data {
 
        unsigned long           state;
 
-       struct timer_list       timer;
+       struct work_struct      work;
 
        struct urb              *urb;
        unsigned char           *buffer;
@@ -82,7 +81,7 @@ struct bcm203x_data {
        unsigned int            fw_sent;
 };
 
-static void bcm203x_complete(struct urb *urb, struct pt_regs *regs)
+static void bcm203x_complete(struct urb *urb)
 {
        struct bcm203x_data *data = urb->context;
        struct usb_device *udev = urb->dev;
@@ -105,7 +104,7 @@ static void bcm203x_complete(struct urb *urb, struct pt_regs *regs)
 
                data->state = BCM203X_SELECT_MEMORY;
 
-               mod_timer(&data->timer, jiffies + (HZ / 10));
+               schedule_work(&data->work);
                break;
 
        case BCM203X_SELECT_MEMORY:
@@ -158,9 +157,9 @@ static void bcm203x_complete(struct urb *urb, struct pt_regs *regs)
        }
 }
 
-static void bcm203x_timer(unsigned long user_data)
+static void bcm203x_work(void *user_data)
 {
-       struct bcm203x_data *data = (struct bcm203x_data *) user_data;
+       struct bcm203x_data *data = user_data;
 
        if (usb_submit_urb(data->urb, GFP_ATOMIC) < 0)
                BT_ERR("Can't submit URB");
@@ -247,13 +246,11 @@ static int bcm203x_probe(struct usb_interface *intf, const struct usb_device_id
 
        release_firmware(firmware);
 
-       init_timer(&data->timer);
-       data->timer.function = bcm203x_timer;
-       data->timer.data = (unsigned long) data;
+       INIT_WORK(&data->work, bcm203x_work, (void *) data);
 
        usb_set_intfdata(intf, data);
 
-       mod_timer(&data->timer, jiffies + HZ);
+       schedule_work(&data->work);
 
        return 0;
 }
index efcc28ec9d9a2a1b719fc8e5a5e87d527a71ab20..31ade991aa913893e088fb69923be3c86e0d3e12 100644 (file)
@@ -95,8 +95,8 @@ struct bfusb_data_scb {
        struct urb *urb;
 };
 
-static void bfusb_tx_complete(struct urb *urb, struct pt_regs *regs);
-static void bfusb_rx_complete(struct urb *urb, struct pt_regs *regs);
+static void bfusb_tx_complete(struct urb *urb);
+static void bfusb_rx_complete(struct urb *urb);
 
 static struct urb *bfusb_get_completed(struct bfusb_data *data)
 {
@@ -190,7 +190,7 @@ static void bfusb_tx_wakeup(struct bfusb_data *data)
        clear_bit(BFUSB_TX_PROCESS, &data->state);
 }
 
-static void bfusb_tx_complete(struct urb *urb, struct pt_regs *regs)
+static void bfusb_tx_complete(struct urb *urb)
 {
        struct sk_buff *skb = (struct sk_buff *) urb->context;
        struct bfusb_data *data = (struct bfusb_data *) skb->dev;
@@ -349,7 +349,7 @@ static inline int bfusb_recv_block(struct bfusb_data *data, int hdr, unsigned ch
        return 0;
 }
 
-static void bfusb_rx_complete(struct urb *urb, struct pt_regs *regs)
+static void bfusb_rx_complete(struct urb *urb)
 {
        struct sk_buff *skb = (struct sk_buff *) urb->context;
        struct bfusb_data *data = (struct bfusb_data *) skb->dev;
index 8eebf9ca378664d3068fd963e1ae7f0fccf97b29..845b8680032a0a904de4460f25873b2a1ccd857d 100644 (file)
@@ -497,7 +497,7 @@ static void bluecard_receive(bluecard_info_t *info, unsigned int offset)
 }
 
 
-static irqreturn_t bluecard_interrupt(int irq, void *dev_inst, struct pt_regs *regs)
+static irqreturn_t bluecard_interrupt(int irq, void *dev_inst)
 {
        bluecard_info_t *info = dev_inst;
        unsigned int iobase;
index e0231dc2cb1a87a4d14425b22e2dbc0d0f8631b0..9fca6513562d10c1f1b1e577463cb635ae639ea4 100644 (file)
@@ -263,7 +263,7 @@ static void bpa10x_wakeup(struct bpa10x_data *data)
        }
 }
 
-static void bpa10x_complete(struct urb *urb, struct pt_regs *regs)
+static void bpa10x_complete(struct urb *urb)
 {
        struct bpa10x_data *data = urb->context;
        unsigned char *buf = urb->transfer_buffer;
index df7bb016df491bdda5296eeee2b74e60e7713704..3a96a0babc6af679a36fb3b2b5a954a17f09a2f9 100644 (file)
@@ -338,7 +338,7 @@ static void bt3c_receive(bt3c_info_t *info)
 }
 
 
-static irqreturn_t bt3c_interrupt(int irq, void *dev_inst, struct pt_regs *regs)
+static irqreturn_t bt3c_interrupt(int irq, void *dev_inst)
 {
        bt3c_info_t *info = dev_inst;
        unsigned int iobase;
index 746ccca97f6f93aae72b8ffff71d6be269cb3417..3b29086b7c3ff72d88defc8cc454f8c304b54435 100644 (file)
@@ -288,7 +288,7 @@ static void btuart_receive(btuart_info_t *info)
 }
 
 
-static irqreturn_t btuart_interrupt(int irq, void *dev_inst, struct pt_regs *regs)
+static irqreturn_t btuart_interrupt(int irq, void *dev_inst)
 {
        btuart_info_t *info = dev_inst;
        unsigned int iobase;
index 0e99def8a1e3886f9abab5591343600515943efb..07eafbc5dc3a7571ee42b8dfc48c6a75973fd137 100644 (file)
@@ -291,7 +291,7 @@ static void dtl1_receive(dtl1_info_t *info)
 }
 
 
-static irqreturn_t dtl1_interrupt(int irq, void *dev_inst, struct pt_regs *regs)
+static irqreturn_t dtl1_interrupt(int irq, void *dev_inst)
 {
        dtl1_info_t *info = dev_inst;
        unsigned int iobase;
@@ -711,6 +711,7 @@ static void dtl1_release(struct pcmcia_device *link)
 
 static struct pcmcia_device_id dtl1_ids[] = {
        PCMCIA_DEVICE_PROD_ID12("Nokia Mobile Phones", "DTL-1", 0xe1bfdd64, 0xe168480d),
+       PCMCIA_DEVICE_PROD_ID12("Nokia Mobile Phones", "DTL-4", 0xe1bfdd64, 0x9102bc82),
        PCMCIA_DEVICE_PROD_ID12("Socket", "CF", 0xb38bcc2e, 0x44ebf863),
        PCMCIA_DEVICE_PROD_ID12("Socket", "CF+ Personal Network Card", 0xb38bcc2e, 0xe732bae3),
        PCMCIA_DEVICE_NULL
index 0801af4ad2b9cab68ca22db8206e98031a090fb6..fdea58ae16b23c31dcb7cb24ecf57e5dab9ecc77 100644 (file)
@@ -118,6 +118,9 @@ static struct usb_device_id blacklist_ids[] = {
        /* IBM/Lenovo ThinkPad with Broadcom chip */
        { USB_DEVICE(0x0a5c, 0x201e), .driver_info = HCI_WRONG_SCO_MTU },
 
+       /* ANYCOM Bluetooth USB-200 and USB-250 */
+       { USB_DEVICE(0x0a5c, 0x2111), .driver_info = HCI_RESET },
+
        /* Microsoft Wireless Transceiver for Bluetooth 2.0 */
        { USB_DEVICE(0x045e, 0x009c), .driver_info = HCI_RESET },
 
@@ -176,8 +179,8 @@ static struct _urb *_urb_dequeue(struct _urb_queue *q)
        return _urb;
 }
 
-static void hci_usb_rx_complete(struct urb *urb, struct pt_regs *regs);
-static void hci_usb_tx_complete(struct urb *urb, struct pt_regs *regs);
+static void hci_usb_rx_complete(struct urb *urb);
+static void hci_usb_tx_complete(struct urb *urb);
 
 #define __pending_tx(husb, type)  (&husb->pending_tx[type-1])
 #define __pending_q(husb, type)   (&husb->pending_q[type-1])
@@ -732,7 +735,7 @@ static inline int __recv_frame(struct hci_usb *husb, int type, void *data, int c
        return 0;
 }
 
-static void hci_usb_rx_complete(struct urb *urb, struct pt_regs *regs)
+static void hci_usb_rx_complete(struct urb *urb)
 {
        struct _urb *_urb = container_of(urb, struct _urb, urb);
        struct hci_usb *husb = (void *) urb->context;
@@ -786,7 +789,7 @@ unlock:
        read_unlock(&husb->completion_lock);
 }
 
-static void hci_usb_tx_complete(struct urb *urb, struct pt_regs *regs)
+static void hci_usb_tx_complete(struct urb *urb)
 {
        struct _urb *_urb = container_of(urb, struct _urb, urb);
        struct hci_usb *husb = (void *) urb->context;
index 2a0c50d84fc513842aedb86caf313e64cb9d11b9..7ea0f48f8fa6e63c1bd081d29910d781cd6834b4 100644 (file)
@@ -703,7 +703,7 @@ static int cdrom_has_defect_mgt(struct cdrom_device_info *cdi)
 {
        struct packet_command cgc;
        char buffer[16];
-       __u16 *feature_code;
+       __be16 *feature_code;
        int ret;
 
        init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ);
@@ -716,7 +716,7 @@ static int cdrom_has_defect_mgt(struct cdrom_device_info *cdi)
        if ((ret = cdi->ops->generic_packet(cdi, &cgc)))
                return ret;
 
-       feature_code = (__u16 *) &buffer[sizeof(struct feature_header)];
+       feature_code = (__be16 *) &buffer[sizeof(struct feature_header)];
        if (be16_to_cpu(*feature_code) == CDF_HWDM)
                return 0;
 
@@ -2963,7 +2963,7 @@ static int mmc_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
                   how much data is available for transfer. buffer[1] is
                   unfortunately ambigious and the only reliable way seem
                   to be to simply skip over the block descriptor... */
-               offset = 8 + be16_to_cpu(*(unsigned short *)(buffer+6));
+               offset = 8 + be16_to_cpu(*(__be16 *)(buffer+6));
 
                if (offset + 16 > sizeof(buffer))
                        return -E2BIG;
index ccd91c1a84bd10d2e0c2ca42a7cbd161f93146af..2157c58755e0a3f0c34c2c66bd8c930e56643ae2 100644 (file)
@@ -513,7 +513,7 @@ static inline void write_cmd(unsigned char cmd)
        outb(cmd, sony_cd_cmd_reg);
 }
 
-static irqreturn_t cdu31a_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t cdu31a_interrupt(int irq, void *dev_id)
 {
        unsigned char val;
 
index 9b05ddd23141dbd4acb8b53b7bef3589de587cf4..e6d8e9ededeaeb57e562e84ad5987f89c8262f0c 100644 (file)
@@ -359,7 +359,7 @@ static struct tasklet_struct cm206_tasklet;
    as there seems so reason for this to happen.
 */
 
-static irqreturn_t cm206_interrupt(int sig, void *dev_id, struct pt_regs *regs)
+static irqreturn_t cm206_interrupt(int sig, void *dev_id)
 {
        volatile ush fool;
        cd->intr_ds = inw(r_data_status);       /* resets data_ready, data_error,
index dcd1ab684f3e0dfa120fb373bdc16912f8f132c4..f574962f4288d36233491eb0d98f8968e2d0da2b 100644 (file)
@@ -845,15 +845,11 @@ static void mcdx_delay(struct s_drive_stuff *stuff, long jifs)
        }
 }
 
-static irqreturn_t mcdx_intr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t mcdx_intr(int irq, void *dev_id)
 {
        struct s_drive_stuff *stuffp = dev_id;
        unsigned char b;
 
-       if (stuffp == NULL) {
-               xwarn("mcdx: no device for intr %d\n", irq);
-               return IRQ_NONE;
-       }
 #ifdef AK2
        if (!stuffp->busy && stuffp->pending)
                stuffp->int_err = 1;
index 30ab56258a92ff4fc82d333c03ffa08d8c255c5c..f77ada933ea0a89643d0efb4cf6953059aee9e49 100644 (file)
@@ -322,7 +322,7 @@ disable_interrupts(void)
 }
 
 static irqreturn_t
-cdu535_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+cdu535_interrupt(int irq, void *dev_id)
 {
        disable_interrupts();
        if (waitqueue_active(&cdu535_irq_wait)) {
index 0e6f35fcc2ebf9ed0fd36ddaa74c5faf3b8cedac..39a9f8cc6412a0faa1ed80df4ff12fbf56693f91 100644 (file)
@@ -1046,7 +1046,7 @@ source "drivers/char/tpm/Kconfig"
 
 config TELCLOCK
        tristate "Telecom clock driver for MPBL0010 ATCA SBC"
-       depends on EXPERIMENTAL
+       depends on EXPERIMENTAL && X86
        default n
        help
          The telecom clock device is specific to the MPBL0010 ATCA computer and
index 91b71e750ee15f16a0372a3f7d8559c4fa2d6d72..dffc19382f7eb828f73426e91b7524f5ffce3305 100644 (file)
 static int uninorth_rev;
 static int is_u3;
 
+static char __devinitdata *aperture = NULL;
 
 static int uninorth_fetch_size(void)
 {
-       int i;
-       u32 temp;
-       struct aper_size_info_32 *values;
-
-       pci_read_config_dword(agp_bridge->dev, UNI_N_CFG_GART_BASE, &temp);
-       temp &= ~(0xfffff000);
-       values = A_SIZE_32(agp_bridge->driver->aperture_sizes);
-
-       for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
-               if (temp == values[i].size_value) {
-                       agp_bridge->previous_size =
-                           agp_bridge->current_size = (void *) (values + i);
-                       agp_bridge->aperture_size_idx = i;
-                       return values[i].size;
+       int i, size = 0;
+       struct aper_size_info_32 *values =
+           A_SIZE_32(agp_bridge->driver->aperture_sizes);
+
+       if (aperture) {
+               char *save = aperture;
+
+               size = memparse(aperture, &aperture) >> 20;
+               aperture = save;
+
+               for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++)
+                       if (size == values[i].size)
+                               break;
+
+               if (i == agp_bridge->driver->num_aperture_sizes) {
+                       printk(KERN_ERR PFX "Invalid aperture size, using"
+                              " default\n");
+                       size = 0;
+                       aperture = NULL;
                }
        }
 
-       agp_bridge->previous_size =
-           agp_bridge->current_size = (void *) (values + 1);
-       agp_bridge->aperture_size_idx = 1;
-       return values[1].size;
+       if (!size) {
+               for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++)
+                       if (values[i].size == 32)
+                               break;
+       }
 
-       return 0;
+       agp_bridge->previous_size =
+           agp_bridge->current_size = (void *)(values + i);
+       agp_bridge->aperture_size_idx = i;
+       return values[i].size;
 }
 
 static void uninorth_tlbflush(struct agp_memory *mem)
@@ -683,5 +693,11 @@ static void __exit agp_uninorth_cleanup(void)
 module_init(agp_uninorth_init);
 module_exit(agp_uninorth_cleanup);
 
+module_param(aperture, charp, 0);
+MODULE_PARM_DESC(aperture,
+                "Aperture size, must be power of two between 4MB and an\n"
+                "\t\tupper limit specific to the UniNorth revision.\n"
+                "\t\tDefault: 32M");
+
 MODULE_AUTHOR("Ben Herrenschmidt & Paul Mackerras");
 MODULE_LICENSE("GPL");
index 486f97c3f4e5a7d186d3370a9a6a379eb44eed64..66086fa2d59a2c38188f854ecc8a55bb5081eac3 100644 (file)
@@ -447,7 +447,7 @@ static void check_modem_status(struct async_struct *info)
        }
 }
 
-static irqreturn_t ser_vbl_int( int irq, void *data, struct pt_regs *regs)
+static irqreturn_t ser_vbl_int( int irq, void *data)
 {
         /* vbl is just a periodic interrupt we tie into to update modem status */
        struct async_struct * info = IRQ_ports;
@@ -460,7 +460,7 @@ static irqreturn_t ser_vbl_int( int irq, void *data, struct pt_regs *regs)
        return IRQ_HANDLED;
 }
 
-static irqreturn_t ser_rx_int(int irq, void *dev_id, struct pt_regs * regs)
+static irqreturn_t ser_rx_int(int irq, void *dev_id)
 {
        struct async_struct * info;
 
@@ -480,7 +480,7 @@ static irqreturn_t ser_rx_int(int irq, void *dev_id, struct pt_regs * regs)
        return IRQ_HANDLED;
 }
 
-static irqreturn_t ser_tx_int(int irq, void *dev_id, struct pt_regs * regs)
+static irqreturn_t ser_tx_int(int irq, void *dev_id)
 {
        struct async_struct * info;
 
index 10a389dafd60ffe99fc8f052fb7330cf28f5832f..1f0b752e5de1810f05ec96c943072f5c367f212c 100644 (file)
@@ -110,7 +110,7 @@ static ssize_t ac_read (struct file *, char __user *, size_t, loff_t *);
 static ssize_t ac_write (struct file *, const char __user *, size_t, loff_t *);
 static int ac_ioctl(struct inode *, struct file *, unsigned int,
                    unsigned long);
-static irqreturn_t ac_interrupt(int, void *, struct pt_regs *);
+static irqreturn_t ac_interrupt(int, void *);
 
 static const struct file_operations ac_fops = {
        .owner = THIS_MODULE,
@@ -617,7 +617,7 @@ static ssize_t ac_read (struct file *filp, char __user *buf, size_t count, loff_
        } 
 }
 
-static irqreturn_t ac_interrupt(int vec, void *dev_instance, struct pt_regs *regs)
+static irqreturn_t ac_interrupt(int vec, void *dev_instance)
 {
        unsigned int i;
        unsigned int FlagInt;
index 87b2fb5108713d63715b50340691b6176bcf4ea7..e608dadece2fa0fa75878213c4012b99b1e1c28d 100644 (file)
@@ -1057,7 +1057,7 @@ detect_isa_irq(void __iomem *address)
    received, out buffer empty, modem change, etc.
  */
 static irqreturn_t
-cyy_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+cyy_interrupt(int irq, void *dev_id)
 {
   struct tty_struct *tty;
   int status;
@@ -1802,7 +1802,7 @@ cyz_handle_cmd(struct cyclades_card *cinfo)
 
 #ifdef CONFIG_CYZ_INTR
 static irqreturn_t
-cyz_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+cyz_interrupt(int irq, void *dev_id)
 {
   struct cyclades_card *cinfo;
 
index 695115d703822e704a447fcfeb64ea66f6ac713f..2908b72daa6e9a333c3ebfb46bf296f3596abd81 100644 (file)
@@ -38,7 +38,7 @@
                        drm_device_t    *dev    = priv->head->dev
 
 /** IRQ handler arguments and return type and values */
-#define DRM_IRQ_ARGS           int irq, void *arg, struct pt_regs *regs
+#define DRM_IRQ_ARGS           int irq, void *arg
 
 /** AGP types */
 #if __OS_HAS_AGP
index abac18b1871c5a7102ea15d9b69f39e9dc461875..77f58ed6d59af01b9688c6ce9851ffc5a7ce80cb 100644 (file)
@@ -370,7 +370,7 @@ static void e5_receive(struct e5_struct *k)
        }
 }
 
-static void ec3104_keyb_interrupt(int irq, void *data, struct pt_regs *regs)
+static void ec3104_keyb_interrupt(int irq, void *data)
 {
        struct e5_struct *k = &ec3104_keyb;
        u8 msr, lsr;
index c3f95583a120ca1ca89ebd7d3d4259f024255df7..706733c0b36a7e7af833f97580fb978454dc0ed1 100644 (file)
@@ -1157,6 +1157,7 @@ static int __init pc_init(void)
        int crd;
        struct board_info *bd;
        unsigned char board_id = 0;
+       int err = -ENOMEM;
 
        int pci_boards_found, pci_count;
 
@@ -1164,13 +1165,11 @@ static int __init pc_init(void)
 
        pc_driver = alloc_tty_driver(MAX_ALLOC);
        if (!pc_driver)
-               return -ENOMEM;
+               goto out1;
 
        pc_info = alloc_tty_driver(MAX_ALLOC);
-       if (!pc_info) {
-               put_tty_driver(pc_driver);
-               return -ENOMEM;
-       }
+       if (!pc_info)
+               goto out2;
 
        /* -----------------------------------------------------------------------
                If epca_setup has not been ran by LILO set num_cards to defaults; copy
@@ -1370,11 +1369,17 @@ static int __init pc_init(void)
 
        } /* End for each card */
 
-       if (tty_register_driver(pc_driver))
-               panic("Couldn't register Digi PC/ driver");
+       err = tty_register_driver(pc_driver);
+       if (err) {
+               printk(KERN_ERR "Couldn't register Digi PC/ driver");
+               goto out3;
+       }
 
-       if (tty_register_driver(pc_info))
-               panic("Couldn't register Digi PC/ info ");
+       err = tty_register_driver(pc_info);
+       if (err) {
+               printk(KERN_ERR "Couldn't register Digi PC/ info ");
+               goto out4;
+       }
 
        /* -------------------------------------------------------------------
           Start up the poller to check for events on all enabled boards
@@ -1385,6 +1390,15 @@ static int __init pc_init(void)
        mod_timer(&epca_timer, jiffies + HZ/25);
        return 0;
 
+out4:
+       tty_unregister_driver(pc_driver);
+out3:
+       put_tty_driver(pc_info);
+out2:
+       put_tty_driver(pc_driver);
+out1:
+       return err;
+
 } /* End pc_init */
 
 /* ------------------ Begin post_fep_init  ---------------------- */
index 05788c75d7fc83dffc807c5e654cae160a469959..15a4ea896328cc23ad6be070357b76baf41c59bd 100644 (file)
@@ -615,8 +615,7 @@ static inline void check_modem_status(struct esp_struct *info)
 /*
  * This is the serial driver's interrupt routine
  */
-static irqreturn_t rs_interrupt_single(int irq, void *dev_id,
-                                       struct pt_regs *regs)
+static irqreturn_t rs_interrupt_single(int irq, void *dev_id)
 {
        struct esp_struct * info;
        unsigned err_status;
index 2165324456520a5f786716154b63491519aaebb7..bbcf918f056fc94eaeb3ee9246b011b4b5a93a3f 100644 (file)
@@ -1243,7 +1243,7 @@ static int fdc_config(void)
        TRACE_EXIT 0;
 }
 
-static irqreturn_t ftape_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t ftape_interrupt(int irq, void *dev_id)
 {
        void (*handler) (void) = *fdc.hook;
        int handled = 0;
index d69f2ad9a67de08f55e5e6d817919e8bbf2d3079..1aa93a752a9c0c636bf6945224c7ea6aa787bf48 100644 (file)
@@ -159,7 +159,7 @@ static void hangcheck_fire(unsigned long data)
                if (hangcheck_dump_tasks) {
                        printk(KERN_CRIT "Hangcheck: Task state:\n");
 #ifdef CONFIG_MAGIC_SYSRQ
-                       handle_sysrq('t', NULL, NULL);
+                       handle_sysrq('t', NULL);
 #endif  /* CONFIG_MAGIC_SYSRQ */
                }
                if (hangcheck_reboot) {
index 58b0eb58111457713088be8daaffb2a9cac44d89..091a11cd878c21731898313185e43058228d4dcd 100644 (file)
@@ -116,7 +116,7 @@ static inline void writeq(unsigned long long v, void __iomem *addr)
 }
 #endif
 
-static irqreturn_t hpet_interrupt(int irq, void *data, struct pt_regs *regs)
+static irqreturn_t hpet_interrupt(int irq, void *data)
 {
        struct hpet_dev *devp;
        unsigned long isr;
index 4053d1cd393f520101857047d52fc63b70efe7d7..9902ffad3b12ddb26e8d064f3ea0b5f3d1a9bb66 100644 (file)
@@ -294,7 +294,7 @@ static int hvc_poll(struct hvc_struct *hp);
  * NOTE: This API isn't used if the console adapter doesn't support interrupts.
  * In this case the console is poll driven.
  */
-static irqreturn_t hvc_handle_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
+static irqreturn_t hvc_handle_interrupt(int irq, void *dev_instance)
 {
        /* if hvc_poll request a repoll, then kick the hvcd thread */
        if (hvc_poll(dev_instance))
@@ -621,7 +621,7 @@ static int hvc_poll(struct hvc_struct *hp)
                                        sysrq_pressed = 1;
                                        continue;
                                } else if (sysrq_pressed) {
-                                       handle_sysrq(buf[i], NULL, tty);
+                                       handle_sysrq(buf[i], tty);
                                        sysrq_pressed = 0;
                                        continue;
                                }
index 0b89bcde8c52e80c6550e96d42ed9503c91f1a99..8728255c9463743046da3b69fde2b198d3fd1329 100644 (file)
@@ -313,8 +313,7 @@ static DEFINE_SPINLOCK(hvcs_structs_lock);
 
 static void hvcs_unthrottle(struct tty_struct *tty);
 static void hvcs_throttle(struct tty_struct *tty);
-static irqreturn_t hvcs_handle_interrupt(int irq, void *dev_instance,
-               struct pt_regs *regs);
+static irqreturn_t hvcs_handle_interrupt(int irq, void *dev_instance);
 
 static int hvcs_write(struct tty_struct *tty,
                const unsigned char *buf, int count);
@@ -387,8 +386,7 @@ static void hvcs_throttle(struct tty_struct *tty)
  * handler taking any further interrupts because they are disabled which means
  * the hvcs_struct will always be valid in this handler.
  */
-static irqreturn_t hvcs_handle_interrupt(int irq, void *dev_instance,
-               struct pt_regs *regs)
+static irqreturn_t hvcs_handle_interrupt(int irq, void *dev_instance)
 {
        struct hvcs_struct *hvcsd = dev_instance;
 
index c07dc58d5c1d7261eb6a4b75f9f935d3bf61ce72..2cf63e7305a3b067896df8a4c7bd35d77d1980c0 100644 (file)
@@ -406,7 +406,7 @@ static void hvsi_insert_chars(struct hvsi_struct *hp, const char *buf, int len)
                        hp->sysrq = 1;
                        continue;
                } else if (hp->sysrq) {
-                       handle_sysrq(c, NULL, hp->tty);
+                       handle_sysrq(c, hp->tty);
                        hp->sysrq = 0;
                        continue;
                }
@@ -555,7 +555,7 @@ static void hvsi_send_overflow(struct hvsi_struct *hp)
  * must get all pending data because we only get an irq on empty->non-empty
  * transition
  */
-static irqreturn_t hvsi_interrupt(int irq, void *arg, struct pt_regs *regs)
+static irqreturn_t hvsi_interrupt(int irq, void *arg)
 {
        struct hvsi_struct *hp = (struct hvsi_struct *)arg;
        struct tty_struct *flip;
@@ -616,7 +616,7 @@ static int __init poll_for_state(struct hvsi_struct *hp, int state)
        unsigned long end_jiffies = jiffies + HVSI_TIMEOUT;
 
        for (;;) {
-               hvsi_interrupt(hp->virq, (void *)hp, NULL); /* get pending data */
+               hvsi_interrupt(hp->virq, (void *)hp); /* get pending data */
 
                if (hp->state == state)
                        return 0;
index fc944d375be75101429b98e2f160dd41f4e6100e..54d93f0345e8565ae2459ce236bd9a8be49cc8f3 100644 (file)
@@ -1007,7 +1007,7 @@ i2InputAvailable(i2ChanStrPtr pCh)
 // applications that one cannot break out of.
 //******************************************************************************
 static int
-i2Output(i2ChanStrPtr pCh, const char *pSource, int count, int user )
+i2Output(i2ChanStrPtr pCh, const char *pSource, int count)
 {
        i2eBordStrPtr pB;
        unsigned char *pInsert;
@@ -1020,7 +1020,7 @@ i2Output(i2ChanStrPtr pCh, const char *pSource, int count, int user )
 
        int bailout = 10;
 
-       ip2trace (CHANN, ITRC_OUTPUT, ITRC_ENTER, 2, count, user );
+       ip2trace (CHANN, ITRC_OUTPUT, ITRC_ENTER, 2, count, 0 );
 
        // Ensure channel structure seems real
        if ( !i2Validate ( pCh ) ) 
@@ -1087,12 +1087,7 @@ i2Output(i2ChanStrPtr pCh, const char *pSource, int count, int user )
                        DATA_COUNT_OF(pInsert)  = amountToMove;
 
                        // Move the data
-                       if ( user ) {
-                               rc = copy_from_user((char*)(DATA_OF(pInsert)), pSource,
-                                               amountToMove );
-                       } else {
-                               memcpy( (char*)(DATA_OF(pInsert)), pSource, amountToMove );
-                       }
+                       memcpy( (char*)(DATA_OF(pInsert)), pSource, amountToMove );
                        // Adjust pointers and indices
                        pSource                                 += amountToMove;
                        pCh->Obuf_char_count    += amountToMove;
index 952e113ccd8a48b84c15f6af1b6b535e79f7ab28..e559e9bac06d11645c3832b0bd7464684b727508 100644 (file)
@@ -332,7 +332,7 @@ static int  i2QueueCommands(int, i2ChanStrPtr, int, int, cmdSyntaxPtr,...);
 static int  i2GetStatus(i2ChanStrPtr, int);
 static int  i2Input(i2ChanStrPtr);
 static int  i2InputFlush(i2ChanStrPtr);
-static int  i2Output(i2ChanStrPtr, const char *, int, int);
+static int  i2Output(i2ChanStrPtr, const char *, int);
 static int  i2OutputFree(i2ChanStrPtr);
 static int  i2ServiceBoard(i2eBordStrPtr);
 static void i2DrainOutput(i2ChanStrPtr, int);
index 62ef511d143bf92888beffddf3441d2fc9460677..a3f32d46d2f80300bb1dfc1a3e28a39655bd3b0e 100644 (file)
@@ -190,7 +190,7 @@ static int  ip2_tiocmset(struct tty_struct *tty, struct file *file,
 
 static void set_irq(int, int);
 static void ip2_interrupt_bh(i2eBordStrPtr pB);
-static irqreturn_t ip2_interrupt(int irq, void *dev_id, struct pt_regs * regs);
+static irqreturn_t ip2_interrupt(int irq, void *dev_id);
 static void ip2_poll(unsigned long arg);
 static inline void service_all_boards(void);
 static void do_input(void *p);
@@ -1154,10 +1154,9 @@ ip2_interrupt_bh(i2eBordStrPtr pB)
 
 
 /******************************************************************************/
-/* Function:   ip2_interrupt(int irq, void *dev_id, struct pt_regs * regs)    */
+/* Function:   ip2_interrupt(int irq, void *dev_id)    */
 /* Parameters: irq - interrupt number                                         */
 /*             pointer to optional device ID structure                        */
-/*             pointer to register structure                                  */
 /* Returns:    Nothing                                                        */
 /*                                                                            */
 /* Description:                                                               */
@@ -1173,7 +1172,7 @@ ip2_interrupt_bh(i2eBordStrPtr pB)
 /*                                                                            */
 /******************************************************************************/
 static irqreturn_t
-ip2_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+ip2_interrupt(int irq, void *dev_id)
 {
        int i;
        i2eBordStrPtr  pB;
@@ -1237,7 +1236,7 @@ ip2_poll(unsigned long arg)
        // Just polled boards, IRQ = 0 will hit all non-interrupt boards.
        // It will NOT poll boards handled by hard interrupts.
        // The issue of queued BH interrups is handled in ip2_interrupt().
-       ip2_interrupt(0, NULL, NULL);
+       ip2_interrupt(0, NULL);
 
        PollTimer.expires = POLL_TIMEOUT;
        add_timer( &PollTimer );
@@ -1705,7 +1704,7 @@ ip2_write( PTTY tty, const unsigned char *pData, int count)
 
        /* This is the actual move bit. Make sure it does what we need!!!!! */
        WRITE_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags);
-       bytesSent = i2Output( pCh, pData, count, 0 );
+       bytesSent = i2Output( pCh, pData, count);
        WRITE_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);
 
        ip2trace (CHANN, ITRC_WRITE, ITRC_RETURN, 1, bytesSent );
@@ -1765,7 +1764,7 @@ ip2_flush_chars( PTTY tty )
                //
                // We may need to restart i2Output if it does not fullfill this request
                //
-               strip = i2Output( pCh, pCh->Pbuf, pCh->Pbuf_stuff, 0 );
+               strip = i2Output( pCh, pCh->Pbuf, pCh->Pbuf_stuff);
                if ( strip != pCh->Pbuf_stuff ) {
                        memmove( pCh->Pbuf, &pCh->Pbuf[strip], pCh->Pbuf_stuff - strip );
                }
index 2455e8d478ace521bd7ef8f85c3ffac7e6a5388e..34a4fd13fa817ec0241a05157593872716b49600 100644 (file)
@@ -1928,13 +1928,8 @@ static ssize_t guid_show(struct device *dev, struct device_attribute *attr,
                        (long long) bmc->guid[8]);
 }
 
-static void
-cleanup_bmc_device(struct kref *ref)
+static void remove_files(struct bmc_device *bmc)
 {
-       struct bmc_device *bmc;
-
-       bmc = container_of(ref, struct bmc_device, refcount);
-
        device_remove_file(&bmc->dev->dev,
                           &bmc->device_id_attr);
        device_remove_file(&bmc->dev->dev,
@@ -1951,12 +1946,23 @@ cleanup_bmc_device(struct kref *ref)
                           &bmc->manufacturer_id_attr);
        device_remove_file(&bmc->dev->dev,
                           &bmc->product_id_attr);
+
        if (bmc->id.aux_firmware_revision_set)
                device_remove_file(&bmc->dev->dev,
                                   &bmc->aux_firmware_rev_attr);
        if (bmc->guid_set)
                device_remove_file(&bmc->dev->dev,
                                   &bmc->guid_attr);
+}
+
+static void
+cleanup_bmc_device(struct kref *ref)
+{
+       struct bmc_device *bmc;
+
+       bmc = container_of(ref, struct bmc_device, refcount);
+
+       remove_files(bmc);
        platform_device_unregister(bmc->dev);
        kfree(bmc);
 }
@@ -1977,6 +1983,79 @@ static void ipmi_bmc_unregister(ipmi_smi_t intf)
        mutex_unlock(&ipmidriver_mutex);
 }
 
+static int create_files(struct bmc_device *bmc)
+{
+       int err;
+
+       err = device_create_file(&bmc->dev->dev,
+                          &bmc->device_id_attr);
+       if (err) goto out;
+       err = device_create_file(&bmc->dev->dev,
+                          &bmc->provides_dev_sdrs_attr);
+       if (err) goto out_devid;
+       err = device_create_file(&bmc->dev->dev,
+                          &bmc->revision_attr);
+       if (err) goto out_sdrs;
+       err = device_create_file(&bmc->dev->dev,
+                          &bmc->firmware_rev_attr);
+       if (err) goto out_rev;
+       err = device_create_file(&bmc->dev->dev,
+                          &bmc->version_attr);
+       if (err) goto out_firm;
+       err = device_create_file(&bmc->dev->dev,
+                          &bmc->add_dev_support_attr);
+       if (err) goto out_version;
+       err = device_create_file(&bmc->dev->dev,
+                          &bmc->manufacturer_id_attr);
+       if (err) goto out_add_dev;
+       err = device_create_file(&bmc->dev->dev,
+                          &bmc->product_id_attr);
+       if (err) goto out_manu;
+       if (bmc->id.aux_firmware_revision_set) {
+               err = device_create_file(&bmc->dev->dev,
+                                  &bmc->aux_firmware_rev_attr);
+               if (err) goto out_prod_id;
+       }
+       if (bmc->guid_set) {
+               err = device_create_file(&bmc->dev->dev,
+                                  &bmc->guid_attr);
+               if (err) goto out_aux_firm;
+       }
+
+       return 0;
+
+out_aux_firm:
+       if (bmc->id.aux_firmware_revision_set)
+               device_remove_file(&bmc->dev->dev,
+                                  &bmc->aux_firmware_rev_attr);
+out_prod_id:
+       device_remove_file(&bmc->dev->dev,
+                          &bmc->product_id_attr);
+out_manu:
+       device_remove_file(&bmc->dev->dev,
+                          &bmc->manufacturer_id_attr);
+out_add_dev:
+       device_remove_file(&bmc->dev->dev,
+                          &bmc->add_dev_support_attr);
+out_version:
+       device_remove_file(&bmc->dev->dev,
+                          &bmc->version_attr);
+out_firm:
+       device_remove_file(&bmc->dev->dev,
+                          &bmc->firmware_rev_attr);
+out_rev:
+       device_remove_file(&bmc->dev->dev,
+                          &bmc->revision_attr);
+out_sdrs:
+       device_remove_file(&bmc->dev->dev,
+                          &bmc->provides_dev_sdrs_attr);
+out_devid:
+       device_remove_file(&bmc->dev->dev,
+                          &bmc->device_id_attr);
+out:
+       return err;
+}
+
 static int ipmi_bmc_register(ipmi_smi_t intf)
 {
        int               rv;
@@ -2051,7 +2130,6 @@ static int ipmi_bmc_register(ipmi_smi_t intf)
                bmc->provides_dev_sdrs_attr.attr.mode = S_IRUGO;
                bmc->provides_dev_sdrs_attr.show = provides_dev_sdrs_show;
 
-
                bmc->revision_attr.attr.name = "revision";
                bmc->revision_attr.attr.owner = THIS_MODULE;
                bmc->revision_attr.attr.mode = S_IRUGO;
@@ -2093,28 +2171,14 @@ static int ipmi_bmc_register(ipmi_smi_t intf)
                bmc->aux_firmware_rev_attr.attr.mode = S_IRUGO;
                bmc->aux_firmware_rev_attr.show = aux_firmware_rev_show;
 
-               device_create_file(&bmc->dev->dev,
-                                  &bmc->device_id_attr);
-               device_create_file(&bmc->dev->dev,
-                                  &bmc->provides_dev_sdrs_attr);
-               device_create_file(&bmc->dev->dev,
-                                  &bmc->revision_attr);
-               device_create_file(&bmc->dev->dev,
-                                  &bmc->firmware_rev_attr);
-               device_create_file(&bmc->dev->dev,
-                                  &bmc->version_attr);
-               device_create_file(&bmc->dev->dev,
-                                  &bmc->add_dev_support_attr);
-               device_create_file(&bmc->dev->dev,
-                                  &bmc->manufacturer_id_attr);
-               device_create_file(&bmc->dev->dev,
-                                  &bmc->product_id_attr);
-               if (bmc->id.aux_firmware_revision_set)
-                       device_create_file(&bmc->dev->dev,
-                                          &bmc->aux_firmware_rev_attr);
-               if (bmc->guid_set)
-                       device_create_file(&bmc->dev->dev,
-                                          &bmc->guid_attr);
+               rv = create_files(bmc);
+               if (rv) {
+                       mutex_lock(&ipmidriver_mutex);
+                       platform_device_unregister(bmc->dev);
+                       mutex_unlock(&ipmidriver_mutex);
+
+                       return rv;
+               }
 
                printk(KERN_INFO
                       "ipmi: Found new BMC (man_id: 0x%6.6x, "
index b106c45abfc927f359ae463ad8659cd2f2cdf7e7..e5cfb1fa47d173a93c6817b30851935b5ad71353 100644 (file)
@@ -872,7 +872,7 @@ static void smi_timeout(unsigned long data)
        add_timer(&(smi_info->si_timer));
 }
 
-static irqreturn_t si_irq_handler(int irq, void *data, struct pt_regs *regs)
+static irqreturn_t si_irq_handler(int irq, void *data)
 {
        struct smi_info *smi_info = data;
        unsigned long   flags;
@@ -899,14 +899,14 @@ static irqreturn_t si_irq_handler(int irq, void *data, struct pt_regs *regs)
        return IRQ_HANDLED;
 }
 
-static irqreturn_t si_bt_irq_handler(int irq, void *data, struct pt_regs *regs)
+static irqreturn_t si_bt_irq_handler(int irq, void *data)
 {
        struct smi_info *smi_info = data;
        /* We need to clear the IRQ flag for the BT interface. */
        smi_info->io.outputb(&smi_info->io, IPMI_BT_INTMASK_REG,
                             IPMI_BT_INTMASK_CLEAR_IRQ_BIT
                             | IPMI_BT_INTMASK_ENABLE_IRQ_BIT);
-       return si_irq_handler(irq, data, regs);
+       return si_irq_handler(irq, data);
 }
 
 static int smi_start_processing(void       *send_info,
@@ -1789,7 +1789,7 @@ static int __devinit ipmi_pci_probe(struct pci_dev *pdev,
 
        info = kzalloc(sizeof(*info), GFP_KERNEL);
        if (!info)
-               return ENOMEM;
+               return -ENOMEM;
 
        info->addr_source = "PCI";
 
@@ -1810,7 +1810,7 @@ static int __devinit ipmi_pci_probe(struct pci_dev *pdev,
                kfree(info);
                printk(KERN_INFO "ipmi_si: %s: Unknown IPMI type: %d\n",
                       pci_name(pdev), class_type);
-               return ENOMEM;
+               return -ENOMEM;
        }
 
        rv = pci_enable_device(pdev);
index accaaf1a6b697fb6c5604f290464a43d8b56a53f..73f759eaa5a6a2a777e733cf9da9bf8b4c7fa9e9 100644 (file)
@@ -903,7 +903,7 @@ static void ipmi_register_watchdog(int ipmi_intf)
 
 #ifdef HAVE_NMI_HANDLER
 static int
-ipmi_nmi(void *dev_id, struct pt_regs *regs, int cpu, int handled)
+ipmi_nmi(void *dev_id, int cpu, int handled)
 {
         /* If we are not expecting a timeout, ignore it. */
        if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE)
index ea2bbf80ad33839b381bb526ab957dd540e55b8a..e9e9bf31c369ef9b8b96cd3f65ac463647b7af69 100644 (file)
@@ -546,7 +546,7 @@ static void isicom_bottomhalf(void *data)
  *     Main interrupt handler routine
  */
 
-static irqreturn_t isicom_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t isicom_interrupt(int irq, void *dev_id)
 {
        struct isi_board *card = dev_id;
        struct isi_port *port;
index d6e031542c6bdbd68932b3a46c7fa3ccaf1d2925..ffdf9df1a67a3cb92a48bd5ce53596a69bc4fde4 100644 (file)
@@ -686,37 +686,37 @@ static stlibrd_t *stli_allocbrd(void);
 static void    stli_ecpinit(stlibrd_t *brdp);
 static void    stli_ecpenable(stlibrd_t *brdp);
 static void    stli_ecpdisable(stlibrd_t *brdp);
-static char    *stli_ecpgetmemptr(stlibrd_t *brdp, unsigned long offset, int line);
+static void __iomem *stli_ecpgetmemptr(stlibrd_t *brdp, unsigned long offset, int line);
 static void    stli_ecpreset(stlibrd_t *brdp);
 static void    stli_ecpintr(stlibrd_t *brdp);
 static void    stli_ecpeiinit(stlibrd_t *brdp);
 static void    stli_ecpeienable(stlibrd_t *brdp);
 static void    stli_ecpeidisable(stlibrd_t *brdp);
-static char    *stli_ecpeigetmemptr(stlibrd_t *brdp, unsigned long offset, int line);
+static void __iomem *stli_ecpeigetmemptr(stlibrd_t *brdp, unsigned long offset, int line);
 static void    stli_ecpeireset(stlibrd_t *brdp);
 static void    stli_ecpmcenable(stlibrd_t *brdp);
 static void    stli_ecpmcdisable(stlibrd_t *brdp);
-static char    *stli_ecpmcgetmemptr(stlibrd_t *brdp, unsigned long offset, int line);
+static void __iomem *stli_ecpmcgetmemptr(stlibrd_t *brdp, unsigned long offset, int line);
 static void    stli_ecpmcreset(stlibrd_t *brdp);
 static void    stli_ecppciinit(stlibrd_t *brdp);
-static char    *stli_ecppcigetmemptr(stlibrd_t *brdp, unsigned long offset, int line);
+static void __iomem *stli_ecppcigetmemptr(stlibrd_t *brdp, unsigned long offset, int line);
 static void    stli_ecppcireset(stlibrd_t *brdp);
 
 static void    stli_onbinit(stlibrd_t *brdp);
 static void    stli_onbenable(stlibrd_t *brdp);
 static void    stli_onbdisable(stlibrd_t *brdp);
-static char    *stli_onbgetmemptr(stlibrd_t *brdp, unsigned long offset, int line);
+static void __iomem *stli_onbgetmemptr(stlibrd_t *brdp, unsigned long offset, int line);
 static void    stli_onbreset(stlibrd_t *brdp);
 static void    stli_onbeinit(stlibrd_t *brdp);
 static void    stli_onbeenable(stlibrd_t *brdp);
 static void    stli_onbedisable(stlibrd_t *brdp);
-static char    *stli_onbegetmemptr(stlibrd_t *brdp, unsigned long offset, int line);
+static void __iomem *stli_onbegetmemptr(stlibrd_t *brdp, unsigned long offset, int line);
 static void    stli_onbereset(stlibrd_t *brdp);
 static void    stli_bbyinit(stlibrd_t *brdp);
-static char    *stli_bbygetmemptr(stlibrd_t *brdp, unsigned long offset, int line);
+static void __iomem *stli_bbygetmemptr(stlibrd_t *brdp, unsigned long offset, int line);
 static void    stli_bbyreset(stlibrd_t *brdp);
 static void    stli_stalinit(stlibrd_t *brdp);
-static char    *stli_stalgetmemptr(stlibrd_t *brdp, unsigned long offset, int line);
+static void __iomem *stli_stalgetmemptr(stlibrd_t *brdp, unsigned long offset, int line);
 static void    stli_stalreset(stlibrd_t *brdp);
 
 static stliport_t *stli_getport(int brdnr, int panelnr, int portnr);
@@ -1566,7 +1566,7 @@ static void stli_flushchars(struct tty_struct *tty)
 
        len = MIN(len, cooksize);
        count = 0;
-       shbuf = (char *) EBRDGETMEMPTR(brdp, portp->txoffset);
+       shbuf = EBRDGETMEMPTR(brdp, portp->txoffset);
        buf = stli_txcookbuf;
 
        while (len > 0) {
@@ -2948,9 +2948,9 @@ static void stli_ecpdisable(stlibrd_t *brdp)
 
 /*****************************************************************************/
 
-static char *stli_ecpgetmemptr(stlibrd_t *brdp, unsigned long offset, int line)
+static void __iomem *stli_ecpgetmemptr(stlibrd_t *brdp, unsigned long offset, int line)
 {      
-       void *ptr;
+       void __iomem *ptr;
        unsigned char val;
 
        if (offset > brdp->memsize) {
@@ -3022,9 +3022,9 @@ static void stli_ecpeidisable(stlibrd_t *brdp)
 
 /*****************************************************************************/
 
-static char *stli_ecpeigetmemptr(stlibrd_t *brdp, unsigned long offset, int line)
+static void __iomem *stli_ecpeigetmemptr(stlibrd_t *brdp, unsigned long offset, int line)
 {      
-       void            *ptr;
+       void __iomem *ptr;
        unsigned char   val;
 
        if (offset > brdp->memsize) {
@@ -3074,9 +3074,9 @@ static void stli_ecpmcdisable(stlibrd_t *brdp)
 
 /*****************************************************************************/
 
-static char *stli_ecpmcgetmemptr(stlibrd_t *brdp, unsigned long offset, int line)
+static void __iomem *stli_ecpmcgetmemptr(stlibrd_t *brdp, unsigned long offset, int line)
 {      
-       void *ptr;
+       void __iomem *ptr;
        unsigned char val;
 
        if (offset > brdp->memsize) {
@@ -3119,9 +3119,9 @@ static void stli_ecppciinit(stlibrd_t *brdp)
 
 /*****************************************************************************/
 
-static char *stli_ecppcigetmemptr(stlibrd_t *brdp, unsigned long offset, int line)
+static void __iomem *stli_ecppcigetmemptr(stlibrd_t *brdp, unsigned long offset, int line)
 {      
-       void            *ptr;
+       void __iomem *ptr;
        unsigned char   val;
 
        if (offset > brdp->memsize) {
@@ -3185,9 +3185,9 @@ static void stli_onbdisable(stlibrd_t *brdp)
 
 /*****************************************************************************/
 
-static char *stli_onbgetmemptr(stlibrd_t *brdp, unsigned long offset, int line)
+static void __iomem *stli_onbgetmemptr(stlibrd_t *brdp, unsigned long offset, int line)
 {      
-       void    *ptr;
+       void __iomem *ptr;
 
        if (offset > brdp->memsize) {
                printk(KERN_ERR "STALLION: shared memory pointer=%x out of "
@@ -3250,9 +3250,9 @@ static void stli_onbedisable(stlibrd_t *brdp)
 
 /*****************************************************************************/
 
-static char *stli_onbegetmemptr(stlibrd_t *brdp, unsigned long offset, int line)
+static void __iomem *stli_onbegetmemptr(stlibrd_t *brdp, unsigned long offset, int line)
 {      
-       void *ptr;
+       void __iomem *ptr;
        unsigned char val;
 
        if (offset > brdp->memsize) {
@@ -3300,9 +3300,9 @@ static void stli_bbyinit(stlibrd_t *brdp)
 
 /*****************************************************************************/
 
-static char *stli_bbygetmemptr(stlibrd_t *brdp, unsigned long offset, int line)
+static void __iomem *stli_bbygetmemptr(stlibrd_t *brdp, unsigned long offset, int line)
 {      
-       void *ptr;
+       void __iomem *ptr;
        unsigned char val;
 
        BUG_ON(offset > brdp->memsize);
@@ -3337,7 +3337,7 @@ static void stli_stalinit(stlibrd_t *brdp)
 
 /*****************************************************************************/
 
-static char *stli_stalgetmemptr(stlibrd_t *brdp, unsigned long offset, int line)
+static void __iomem *stli_stalgetmemptr(stlibrd_t *brdp, unsigned long offset, int line)
 {      
        BUG_ON(offset > brdp->memsize);
        return brdp->membase + (offset % STAL_PAGESIZE);
@@ -3876,7 +3876,7 @@ static int stli_eisamemprobe(stlibrd_t *brdp)
                        continue;
 
                if (brdp->brdtype == BRD_ECPE) {
-                       ecpsigp = (cdkecpsig_t __iomem *) stli_ecpeigetmemptr(brdp,
+                       ecpsigp = stli_ecpeigetmemptr(brdp,
                                CDK_SIGADDR, __LINE__);
                        memcpy_fromio(&ecpsig, ecpsigp, sizeof(cdkecpsig_t));
                        if (ecpsig.magic == cpu_to_le32(ECP_MAGIC))
@@ -4184,7 +4184,7 @@ static int stli_initbrds(void)
 static ssize_t stli_memread(struct file *fp, char __user *buf, size_t count, loff_t *offp)
 {
        unsigned long flags;
-       void *memptr;
+       void __iomem *memptr;
        stlibrd_t *brdp;
        int brdnr, size, n;
        void *p;
@@ -4214,7 +4214,7 @@ static ssize_t stli_memread(struct file *fp, char __user *buf, size_t count, lof
        while (size > 0) {
                spin_lock_irqsave(&brd_lock, flags);
                EBRDENABLE(brdp);
-               memptr = (void *) EBRDGETMEMPTR(brdp, off);
+               memptr = EBRDGETMEMPTR(brdp, off);
                n = MIN(size, (brdp->pagesize - (((unsigned long) off) % brdp->pagesize)));
                n = MIN(n, PAGE_SIZE);
                memcpy_fromio(p, memptr, n);
@@ -4247,7 +4247,7 @@ out:
 static ssize_t stli_memwrite(struct file *fp, const char __user *buf, size_t count, loff_t *offp)
 {
        unsigned long flags;
-       void *memptr;
+       void __iomem *memptr;
        stlibrd_t *brdp;
        char __user *chbuf;
        int brdnr, size, n;
@@ -4287,7 +4287,7 @@ static ssize_t stli_memwrite(struct file *fp, const char __user *buf, size_t cou
                }
                spin_lock_irqsave(&brd_lock, flags);
                EBRDENABLE(brdp);
-               memptr = (void *) EBRDGETMEMPTR(brdp, off);
+               memptr = EBRDGETMEMPTR(brdp, off);
                memcpy_toio(memptr, p, n);
                EBRDDISABLE(brdp);
                spin_unlock_irqrestore(&brd_lock, flags);
index e2011669c7bb4bc187a3e216e21a37b1711b9f4e..20b6c8b30248f354f4bfcf5b3d6fffbb4a07a112 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/string.h>
 #include <linux/init.h>
 #include <linux/slab.h>
+#include <linux/irq.h>
 
 #include <linux/kbd_kern.h>
 #include <linux/kbd_diacr.h>
@@ -77,7 +78,7 @@ void compute_shiftstate(void);
        k_slock,        k_dead2,        k_brl,          k_ignore
 
 typedef void (k_handler_fn)(struct vc_data *vc, unsigned char value,
-                           char up_flag, struct pt_regs *regs);
+                           char up_flag);
 static k_handler_fn K_HANDLERS;
 static k_handler_fn *k_handler[16] = { K_HANDLERS };
 
@@ -88,7 +89,7 @@ static k_handler_fn *k_handler[16] = { K_HANDLERS };
        fn_boot_it,     fn_caps_on,     fn_compose,     fn_SAK,\
        fn_dec_console, fn_inc_console, fn_spawn_con,   fn_bare_num
 
-typedef void (fn_handler_fn)(struct vc_data *vc, struct pt_regs *regs);
+typedef void (fn_handler_fn)(struct vc_data *vc);
 static fn_handler_fn FN_HANDLERS;
 static fn_handler_fn *fn_handler[] = { FN_HANDLERS };
 
@@ -428,7 +429,7 @@ static unsigned int handle_diacr(struct vc_data *vc, unsigned int ch)
 /*
  * Special function handlers
  */
-static void fn_enter(struct vc_data *vc, struct pt_regs *regs)
+static void fn_enter(struct vc_data *vc)
 {
        if (diacr) {
                if (kbd->kbdmode == VC_UNICODE)
@@ -442,27 +443,28 @@ static void fn_enter(struct vc_data *vc, struct pt_regs *regs)
                put_queue(vc, 10);
 }
 
-static void fn_caps_toggle(struct vc_data *vc, struct pt_regs *regs)
+static void fn_caps_toggle(struct vc_data *vc)
 {
        if (rep)
                return;
        chg_vc_kbd_led(kbd, VC_CAPSLOCK);
 }
 
-static void fn_caps_on(struct vc_data *vc, struct pt_regs *regs)
+static void fn_caps_on(struct vc_data *vc)
 {
        if (rep)
                return;
        set_vc_kbd_led(kbd, VC_CAPSLOCK);
 }
 
-static void fn_show_ptregs(struct vc_data *vc, struct pt_regs *regs)
+static void fn_show_ptregs(struct vc_data *vc)
 {
+       struct pt_regs *regs = get_irq_regs();
        if (regs)
                show_regs(regs);
 }
 
-static void fn_hold(struct vc_data *vc, struct pt_regs *regs)
+static void fn_hold(struct vc_data *vc)
 {
        struct tty_struct *tty = vc->vc_tty;
 
@@ -480,12 +482,12 @@ static void fn_hold(struct vc_data *vc, struct pt_regs *regs)
                stop_tty(tty);
 }
 
-static void fn_num(struct vc_data *vc, struct pt_regs *regs)
+static void fn_num(struct vc_data *vc)
 {
        if (vc_kbd_mode(kbd,VC_APPLIC))
                applkey(vc, 'P', 1);
        else
-               fn_bare_num(vc, regs);
+               fn_bare_num(vc);
 }
 
 /*
@@ -494,19 +496,19 @@ static void fn_num(struct vc_data *vc, struct pt_regs *regs)
  * Bind this to NumLock if you prefer that the NumLock key always
  * changes the NumLock flag.
  */
-static void fn_bare_num(struct vc_data *vc, struct pt_regs *regs)
+static void fn_bare_num(struct vc_data *vc)
 {
        if (!rep)
                chg_vc_kbd_led(kbd, VC_NUMLOCK);
 }
 
-static void fn_lastcons(struct vc_data *vc, struct pt_regs *regs)
+static void fn_lastcons(struct vc_data *vc)
 {
        /* switch to the last used console, ChN */
        set_console(last_console);
 }
 
-static void fn_dec_console(struct vc_data *vc, struct pt_regs *regs)
+static void fn_dec_console(struct vc_data *vc)
 {
        int i, cur = fg_console;
 
@@ -523,7 +525,7 @@ static void fn_dec_console(struct vc_data *vc, struct pt_regs *regs)
        set_console(i);
 }
 
-static void fn_inc_console(struct vc_data *vc, struct pt_regs *regs)
+static void fn_inc_console(struct vc_data *vc)
 {
        int i, cur = fg_console;
 
@@ -540,7 +542,7 @@ static void fn_inc_console(struct vc_data *vc, struct pt_regs *regs)
        set_console(i);
 }
 
-static void fn_send_intr(struct vc_data *vc, struct pt_regs *regs)
+static void fn_send_intr(struct vc_data *vc)
 {
        struct tty_struct *tty = vc->vc_tty;
 
@@ -550,37 +552,37 @@ static void fn_send_intr(struct vc_data *vc, struct pt_regs *regs)
        con_schedule_flip(tty);
 }
 
-static void fn_scroll_forw(struct vc_data *vc, struct pt_regs *regs)
+static void fn_scroll_forw(struct vc_data *vc)
 {
        scrollfront(vc, 0);
 }
 
-static void fn_scroll_back(struct vc_data *vc, struct pt_regs *regs)
+static void fn_scroll_back(struct vc_data *vc)
 {
        scrollback(vc, 0);
 }
 
-static void fn_show_mem(struct vc_data *vc, struct pt_regs *regs)
+static void fn_show_mem(struct vc_data *vc)
 {
        show_mem();
 }
 
-static void fn_show_state(struct vc_data *vc, struct pt_regs *regs)
+static void fn_show_state(struct vc_data *vc)
 {
        show_state();
 }
 
-static void fn_boot_it(struct vc_data *vc, struct pt_regs *regs)
+static void fn_boot_it(struct vc_data *vc)
 {
        ctrl_alt_del();
 }
 
-static void fn_compose(struct vc_data *vc, struct pt_regs *regs)
+static void fn_compose(struct vc_data *vc)
 {
        dead_key_next = 1;
 }
 
-static void fn_spawn_con(struct vc_data *vc, struct pt_regs *regs)
+static void fn_spawn_con(struct vc_data *vc)
 {
        spin_lock(&vt_spawn_con.lock);
        if (vt_spawn_con.pid)
@@ -591,7 +593,7 @@ static void fn_spawn_con(struct vc_data *vc, struct pt_regs *regs)
        spin_unlock(&vt_spawn_con.lock);
 }
 
-static void fn_SAK(struct vc_data *vc, struct pt_regs *regs)
+static void fn_SAK(struct vc_data *vc)
 {
        struct tty_struct *tty = vc->vc_tty;
 
@@ -604,7 +606,7 @@ static void fn_SAK(struct vc_data *vc, struct pt_regs *regs)
        reset_vc(vc);
 }
 
-static void fn_null(struct vc_data *vc, struct pt_regs *regs)
+static void fn_null(struct vc_data *vc)
 {
        compute_shiftstate();
 }
@@ -612,11 +614,11 @@ static void fn_null(struct vc_data *vc, struct pt_regs *regs)
 /*
  * Special key handlers
  */
-static void k_ignore(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs)
+static void k_ignore(struct vc_data *vc, unsigned char value, char up_flag)
 {
 }
 
-static void k_spec(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs)
+static void k_spec(struct vc_data *vc, unsigned char value, char up_flag)
 {
        if (up_flag)
                return;
@@ -626,15 +628,15 @@ static void k_spec(struct vc_data *vc, unsigned char value, char up_flag, struct
             kbd->kbdmode == VC_MEDIUMRAW) &&
             value != KVAL(K_SAK))
                return;         /* SAK is allowed even in raw mode */
-       fn_handler[value](vc, regs);
+       fn_handler[value](vc);
 }
 
-static void k_lowercase(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs)
+static void k_lowercase(struct vc_data *vc, unsigned char value, char up_flag)
 {
        printk(KERN_ERR "keyboard.c: k_lowercase was called - impossible\n");
 }
 
-static void k_unicode(struct vc_data *vc, unsigned int value, char up_flag, struct pt_regs *regs)
+static void k_unicode(struct vc_data *vc, unsigned int value, char up_flag)
 {
        if (up_flag)
                return;         /* no action, if this is a key release */
@@ -658,41 +660,41 @@ static void k_unicode(struct vc_data *vc, unsigned int value, char up_flag, stru
  * dead keys modifying the same character. Very useful
  * for Vietnamese.
  */
-static void k_deadunicode(struct vc_data *vc, unsigned int value, char up_flag, struct pt_regs *regs)
+static void k_deadunicode(struct vc_data *vc, unsigned int value, char up_flag)
 {
        if (up_flag)
                return;
        diacr = (diacr ? handle_diacr(vc, value) : value);
 }
 
-static void k_self(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs)
+static void k_self(struct vc_data *vc, unsigned char value, char up_flag)
 {
-       k_unicode(vc, value, up_flag, regs);
+       k_unicode(vc, value, up_flag);
 }
 
-static void k_dead2(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs)
+static void k_dead2(struct vc_data *vc, unsigned char value, char up_flag)
 {
-       k_deadunicode(vc, value, up_flag, regs);
+       k_deadunicode(vc, value, up_flag);
 }
 
 /*
  * Obsolete - for backwards compatibility only
  */
-static void k_dead(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs)
+static void k_dead(struct vc_data *vc, unsigned char value, char up_flag)
 {
        static const unsigned char ret_diacr[NR_DEAD] = {'`', '\'', '^', '~', '"', ',' };
        value = ret_diacr[value];
-       k_deadunicode(vc, value, up_flag, regs);
+       k_deadunicode(vc, value, up_flag);
 }
 
-static void k_cons(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs)
+static void k_cons(struct vc_data *vc, unsigned char value, char up_flag)
 {
        if (up_flag)
                return;
        set_console(value);
 }
 
-static void k_fn(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs)
+static void k_fn(struct vc_data *vc, unsigned char value, char up_flag)
 {
        unsigned v;
 
@@ -706,7 +708,7 @@ static void k_fn(struct vc_data *vc, unsigned char value, char up_flag, struct p
                printk(KERN_ERR "k_fn called with value=%d\n", value);
 }
 
-static void k_cur(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs)
+static void k_cur(struct vc_data *vc, unsigned char value, char up_flag)
 {
        static const char *cur_chars = "BDCA";
 
@@ -715,7 +717,7 @@ static void k_cur(struct vc_data *vc, unsigned char value, char up_flag, struct
        applkey(vc, cur_chars[value], vc_kbd_mode(kbd, VC_CKMODE));
 }
 
-static void k_pad(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs)
+static void k_pad(struct vc_data *vc, unsigned char value, char up_flag)
 {
        static const char pad_chars[] = "0123456789+-*/\015,.?()#";
        static const char app_map[] = "pqrstuvwxylSRQMnnmPQS";
@@ -733,34 +735,34 @@ static void k_pad(struct vc_data *vc, unsigned char value, char up_flag, struct
                switch (value) {
                        case KVAL(K_PCOMMA):
                        case KVAL(K_PDOT):
-                               k_fn(vc, KVAL(K_REMOVE), 0, regs);
+                               k_fn(vc, KVAL(K_REMOVE), 0);
                                return;
                        case KVAL(K_P0):
-                               k_fn(vc, KVAL(K_INSERT), 0, regs);
+                               k_fn(vc, KVAL(K_INSERT), 0);
                                return;
                        case KVAL(K_P1):
-                               k_fn(vc, KVAL(K_SELECT), 0, regs);
+                               k_fn(vc, KVAL(K_SELECT), 0);
                                return;
                        case KVAL(K_P2):
-                               k_cur(vc, KVAL(K_DOWN), 0, regs);
+                               k_cur(vc, KVAL(K_DOWN), 0);
                                return;
                        case KVAL(K_P3):
-                               k_fn(vc, KVAL(K_PGDN), 0, regs);
+                               k_fn(vc, KVAL(K_PGDN), 0);
                                return;
                        case KVAL(K_P4):
-                               k_cur(vc, KVAL(K_LEFT), 0, regs);
+                               k_cur(vc, KVAL(K_LEFT), 0);
                                return;
                        case KVAL(K_P6):
-                               k_cur(vc, KVAL(K_RIGHT), 0, regs);
+                               k_cur(vc, KVAL(K_RIGHT), 0);
                                return;
                        case KVAL(K_P7):
-                               k_fn(vc, KVAL(K_FIND), 0, regs);
+                               k_fn(vc, KVAL(K_FIND), 0);
                                return;
                        case KVAL(K_P8):
-                               k_cur(vc, KVAL(K_UP), 0, regs);
+                               k_cur(vc, KVAL(K_UP), 0);
                                return;
                        case KVAL(K_P9):
-                               k_fn(vc, KVAL(K_PGUP), 0, regs);
+                               k_fn(vc, KVAL(K_PGUP), 0);
                                return;
                        case KVAL(K_P5):
                                applkey(vc, 'G', vc_kbd_mode(kbd, VC_APPLIC));
@@ -772,7 +774,7 @@ static void k_pad(struct vc_data *vc, unsigned char value, char up_flag, struct
                put_queue(vc, 10);
 }
 
-static void k_shift(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs)
+static void k_shift(struct vc_data *vc, unsigned char value, char up_flag)
 {
        int old_state = shift_state;
 
@@ -813,7 +815,7 @@ static void k_shift(struct vc_data *vc, unsigned char value, char up_flag, struc
        }
 }
 
-static void k_meta(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs)
+static void k_meta(struct vc_data *vc, unsigned char value, char up_flag)
 {
        if (up_flag)
                return;
@@ -825,7 +827,7 @@ static void k_meta(struct vc_data *vc, unsigned char value, char up_flag, struct
                put_queue(vc, value | 0x80);
 }
 
-static void k_ascii(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs)
+static void k_ascii(struct vc_data *vc, unsigned char value, char up_flag)
 {
        int base;
 
@@ -847,16 +849,16 @@ static void k_ascii(struct vc_data *vc, unsigned char value, char up_flag, struc
                npadch = npadch * base + value;
 }
 
-static void k_lock(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs)
+static void k_lock(struct vc_data *vc, unsigned char value, char up_flag)
 {
        if (up_flag || rep)
                return;
        chg_vc_kbd_lock(kbd, value);
 }
 
-static void k_slock(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs)
+static void k_slock(struct vc_data *vc, unsigned char value, char up_flag)
 {
-       k_shift(vc, value, up_flag, regs);
+       k_shift(vc, value, up_flag);
        if (up_flag || rep)
                return;
        chg_vc_kbd_slock(kbd, value);
@@ -876,25 +878,25 @@ static unsigned brl_nbchords = 1;
 MODULE_PARM_DESC(brl_nbchords, "Number of chords that produce a braille pattern (0 for dead chords)");
 module_param(brl_nbchords, uint, 0644);
 
-static void k_brlcommit(struct vc_data *vc, unsigned int pattern, char up_flag, struct pt_regs *regs)
+static void k_brlcommit(struct vc_data *vc, unsigned int pattern, char up_flag)
 {
        static unsigned long chords;
        static unsigned committed;
 
        if (!brl_nbchords)
-               k_deadunicode(vc, BRL_UC_ROW | pattern, up_flag, regs);
+               k_deadunicode(vc, BRL_UC_ROW | pattern, up_flag);
        else {
                committed |= pattern;
                chords++;
                if (chords == brl_nbchords) {
-                       k_unicode(vc, BRL_UC_ROW | committed, up_flag, regs);
+                       k_unicode(vc, BRL_UC_ROW | committed, up_flag);
                        chords = 0;
                        committed = 0;
                }
        }
 }
 
-static void k_brl(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs)
+static void k_brl(struct vc_data *vc, unsigned char value, char up_flag)
 {
        static unsigned pressed,committing;
        static unsigned long releasestart;
@@ -906,7 +908,7 @@ static void k_brl(struct vc_data *vc, unsigned char value, char up_flag, struct
        }
 
        if (!value) {
-               k_unicode(vc, BRL_UC_ROW, up_flag, regs);
+               k_unicode(vc, BRL_UC_ROW, up_flag);
                return;
        }
 
@@ -923,13 +925,13 @@ static void k_brl(struct vc_data *vc, unsigned char value, char up_flag, struct
                        pressed &= ~(1 << (value - 1));
                        if (!pressed) {
                                if (committing) {
-                                       k_brlcommit(vc, committing, 0, regs);
+                                       k_brlcommit(vc, committing, 0);
                                        committing = 0;
                                }
                        }
                } else {
                        if (committing) {
-                               k_brlcommit(vc, committing, 0, regs);
+                               k_brlcommit(vc, committing, 0);
                                committing = 0;
                        }
                        pressed &= ~(1 << (value - 1));
@@ -1133,8 +1135,7 @@ static void kbd_rawcode(unsigned char data)
                put_queue(vc, data);
 }
 
-static void kbd_keycode(unsigned int keycode, int down,
-                       int hw_raw, struct pt_regs *regs)
+static void kbd_keycode(unsigned int keycode, int down, int hw_raw)
 {
        struct vc_data *vc = vc_cons[fg_console].d;
        unsigned short keysym, *key_map;
@@ -1181,7 +1182,7 @@ static void kbd_keycode(unsigned int keycode, int down,
        if (sysrq_down && !down && keycode == sysrq_alt_use)
                sysrq_down = 0;
        if (sysrq_down && down && !rep) {
-               handle_sysrq(kbd_sysrq_xlate[keycode], regs, tty);
+               handle_sysrq(kbd_sysrq_xlate[keycode], tty);
                return;
        }
 #endif
@@ -1267,7 +1268,7 @@ static void kbd_keycode(unsigned int keycode, int down,
                }
        }
 
-       (*k_handler[type])(vc, keysym & 0xff, !down, regs);
+       (*k_handler[type])(vc, keysym & 0xff, !down);
 
        if (type != KT_SLOCK)
                kbd->slockstate = 0;
@@ -1279,7 +1280,7 @@ static void kbd_event(struct input_handle *handle, unsigned int event_type,
        if (event_type == EV_MSC && event_code == MSC_RAW && HW_RAW(handle->dev))
                kbd_rawcode(value);
        if (event_type == EV_KEY)
-               kbd_keycode(event_code, value, HW_RAW(handle->dev), handle->dev->regs);
+               kbd_keycode(event_code, value, HW_RAW(handle->dev));
        tasklet_schedule(&keyboard_tasklet);
        do_poke_blanked_console = 1;
        schedule_console_callback();
index 636354722658eb4b6cc035f7f0a22196fc91e141..0afb7ba999cf6b55cc03065c1fa58c12bf0cef67 100644 (file)
@@ -516,11 +516,10 @@ int mbcs_gscr_mmap(struct file *fp, struct vm_area_struct *vma)
  * mbcs_completion_intr_handler - Primary completion handler.
  * @irq: irq
  * @arg: soft struct for device
- * @ep: regs
  *
  */
 static irqreturn_t
-mbcs_completion_intr_handler(int irq, void *arg, struct pt_regs *ep)
+mbcs_completion_intr_handler(int irq, void *arg)
 {
        struct mbcs_soft *soft = (struct mbcs_soft *)arg;
        void *mmr_base;
index 6511012cbdcd86d971a6cdebcf6e1baad66ccded..55473371b7c6934abe8486af6fc3055701187140 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/backing-dev.h>
 #include <linux/bootmem.h>
 #include <linux/pipe_fs_i.h>
+#include <linux/pfn.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
@@ -292,8 +293,8 @@ static int mmap_kmem(struct file * file, struct vm_area_struct * vma)
 {
        unsigned long pfn;
 
-       /* Turn a kernel-virtual address into a physical page frame */
-       pfn = __pa((u64)vma->vm_pgoff << PAGE_SHIFT) >> PAGE_SHIFT;
+       /* Turn a pfn offset into an absolute pfn */
+       pfn = PFN_DOWN(virt_to_phys((void *)PAGE_OFFSET)) + vma->vm_pgoff;
 
        /*
         * RED-PEN: on some architectures there is more mapped memory
index 1f0f2b6dae2658e8736842db0d91c5ea3d90d929..22b9905c1e526f7521c0b70a143c766c1e0f534c 100644 (file)
@@ -422,7 +422,6 @@ static int inline reschedule_periodic_timer(mmtimer_t *x)
  * mmtimer_interrupt - timer interrupt handler
  * @irq: irq received
  * @dev_id: device the irq came from
- * @regs: register state upon receipt of the interrupt
  *
  * Called when one of the comarators matches the counter, This
  * routine will send signals to processes that have requested
@@ -433,7 +432,7 @@ static int inline reschedule_periodic_timer(mmtimer_t *x)
  * registers.
  */
 static irqreturn_t
-mmtimer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+mmtimer_interrupt(int irq, void *dev_id)
 {
        int i;
        unsigned long expires = 0;
index b401383808c26ac4c16ce38f15fc129b4dafd56a..96cb1f07332b68e5fb5b77dfb68a74d6356c6b64 100644 (file)
@@ -130,6 +130,7 @@ static moxa_isa_board_conf moxa_isa_boards[] =
 typedef struct _moxa_pci_devinfo {
        ushort busNum;
        ushort devNum;
+       struct pci_dev *pdev;
 } moxa_pci_devinfo;
 
 typedef struct _moxa_board_conf {
@@ -324,6 +325,9 @@ static int moxa_get_PCI_conf(struct pci_dev *p, int board_type, moxa_board_conf
        board->busType = MOXA_BUS_TYPE_PCI;
        board->pciInfo.busNum = p->bus->number;
        board->pciInfo.devNum = p->devfn >> 3;
+       board->pciInfo.pdev = p;
+       /* don't lose the reference in the next pci_get_device iteration */
+       pci_dev_get(p);
 
        return (0);
 }
@@ -493,6 +497,11 @@ static void __exit moxa_exit(void)
        if (tty_unregister_driver(moxaDriver))
                printk("Couldn't unregister MOXA Intellio family serial driver\n");
        put_tty_driver(moxaDriver);
+
+       for (i = 0; i < MAX_BOARDS; i++)
+               if (moxa_boards[i].busType == MOXA_BUS_TYPE_PCI)
+                       pci_dev_put(moxa_boards[i].pciInfo.pdev);
+
        if (verbose)
                printk("Done\n");
 }
index cc3e54dd72346735b0d0ec96bb873547a0545e99..f282976daaacfe8e6da245071757c9d552f0fbad 100644 (file)
@@ -95,14 +95,14 @@ static void EnableSRAM(THINKPAD_BD_DATA * pBDData)
 }
 
 
-static irqreturn_t UartInterrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t UartInterrupt(int irq, void *dev_id)
 {
        PRINTK_3(TRACE_TP3780I,
                "tp3780i::UartInterrupt entry irq %x dev_id %p\n", irq, dev_id);
        return IRQ_HANDLED;
 }
 
-static irqreturn_t DspInterrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t DspInterrupt(int irq, void *dev_id)
 {
        pMWAVE_DEVICE_DATA pDrvData = &mwave_s_mdd;
        DSP_3780I_CONFIG_SETTINGS *pSettings = &pDrvData->rBDData.rDspSettings;
index 8253fca8efd527c3a1d763a2805bffc4c20cb77a..048d91142c172176fa03b033527e393f263bb8b9 100644 (file)
@@ -407,7 +407,7 @@ static void mxser_stop(struct tty_struct *);
 static void mxser_start(struct tty_struct *);
 static void mxser_hangup(struct tty_struct *);
 static void mxser_rs_break(struct tty_struct *, int);
-static irqreturn_t mxser_interrupt(int, void *, struct pt_regs *);
+static irqreturn_t mxser_interrupt(int, void *);
 static void mxser_receive_chars(struct mxser_struct *, int *);
 static void mxser_transmit_chars(struct mxser_struct *);
 static void mxser_check_modem_status(struct mxser_struct *, int);
@@ -1916,7 +1916,7 @@ static void mxser_rs_break(struct tty_struct *tty, int break_state)
 /*
  * This is the serial driver's generic interrupt routine
  */
-static irqreturn_t mxser_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t mxser_interrupt(int irq, void *dev_id)
 {
        int status, iir, i;
        struct mxser_struct *info;
index ea1aa7764f8e1a0b756b8be75172488bdc7bf714..2d264971d839809d70ba8fe780ed3ba6ef89ff33 100644 (file)
@@ -144,7 +144,7 @@ static void button_sequence_finished (unsigned long parameters)
  *  increments the counter.
  */ 
 
-static irqreturn_t button_handler (int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t button_handler (int irq, void *dev_id)
 {
        if (button_press_count) {
                del_timer (&button_timer);
index ddb7b928dcbb5d958cd7b07dfb948fd31b19d224..c3ebc16ce8a7722b18f7589b437f43e3c905ed75 100644 (file)
@@ -25,7 +25,7 @@ struct button_callback {
 /* Function prototypes: */
 
 static void button_sequence_finished (unsigned long parameters);
-static irqreturn_t button_handler (int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t button_handler (int irq, void *dev_id);
 int button_init (void);
 int button_add_callback (void (*callback) (void), int count);
 int button_del_callback (void (*callback) (void));
index 73e3242099139e0c41892fe6198210355b2e413d..1a0bc30b79d10f8e858b998378c4b6ad68a4f99e 100644 (file)
@@ -416,7 +416,7 @@ static void rx_reset_buffers(MGSLPC_INFO *info);
 static int  rx_alloc_buffers(MGSLPC_INFO *info);
 static void rx_free_buffers(MGSLPC_INFO *info);
 
-static irqreturn_t mgslpc_isr(int irq, void *dev_id, struct pt_regs * regs);
+static irqreturn_t mgslpc_isr(int irq, void *dev_id);
 
 /*
  * Bottom half interrupt handlers
@@ -1234,9 +1234,8 @@ static void ri_change(MGSLPC_INFO *info)
  * 
  * irq     interrupt number that caused interrupt
  * dev_id  device ID supplied during interrupt registration
- * regs    interrupted processor context
  */
-static irqreturn_t mgslpc_isr(int irq, void *dev_id, struct pt_regs * regs)
+static irqreturn_t mgslpc_isr(int irq, void *dev_id)
 {
        MGSLPC_INFO * info = (MGSLPC_INFO *)dev_id;
        unsigned short isr;
index 520d2cf82bc0ca74edbe00b834288cfdd022ec8d..efc485edad1c26ebbb1d3a43a95c9b54f881d617 100644 (file)
@@ -269,7 +269,7 @@ static ssize_t pp_write (struct file * file, const char __user * buf,
        return bytes_written;
 }
 
-static void pp_irq (int irq, void * private, struct pt_regs * unused)
+static void pp_irq (int irq, void * private)
 {
        struct pp_struct * pp = (struct pp_struct *) private;
 
diff --git a/drivers/char/qtronix.c b/drivers/char/qtronix.c
deleted file mode 100644 (file)
index 9d134e9..0000000
+++ /dev/null
@@ -1,605 +0,0 @@
-/*
- *
- * BRIEF MODULE DESCRIPTION
- *     Qtronix 990P infrared keyboard driver.
- *
- *
- * Copyright 2001 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *             ppopov@mvista.com or source@mvista.com
- *
- *
- *  The bottom portion of this driver was take from 
- *  pc_keyb.c  Please see that file for copyrights.
- *
- *  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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  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.
- */
-
-
-/* 
- * NOTE:  
- *
- *     This driver has only been tested with the Consumer IR
- *     port of the ITE 8172 system controller.
- *
- *     You do not need this driver if you are using the ps/2 or
- *     USB adapter that the keyboard ships with.  You only need 
- *     this driver if your board has a IR port and the keyboard
- *     data is being sent directly to the IR.  In that case,
- *     you also need some low-level IR support. See it8172_cir.c.
- *     
- */
-
-#ifdef CONFIG_QTRONIX_KEYBOARD
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/kernel.h>
-
-#include <asm/it8172/it8172.h>
-#include <asm/it8172/it8172_int.h>
-#include <asm/it8172/it8172_cir.h>
-
-#include <linux/spinlock.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/tty.h>
-#include <linux/mm.h>
-#include <linux/signal.h>
-#include <linux/init.h>
-#include <linux/kbd_ll.h>
-#include <linux/delay.h>
-#include <linux/poll.h>
-#include <linux/miscdevice.h>
-#include <linux/slab.h>
-#include <linux/kbd_kern.h>
-#include <linux/smp_lock.h>
-#include <asm/io.h>
-#include <linux/pc_keyb.h>
-
-#include <asm/keyboard.h>
-#include <linux/bitops.h>
-#include <asm/uaccess.h>
-#include <asm/irq.h>
-#include <asm/system.h>
-
-#define leading1 0
-#define leading2 0xF
-
-#define KBD_CIR_PORT 0
-#define AUX_RECONNECT 170 /* scancode when ps2 device is plugged (back) in */
-
-static int data_index;
-struct cir_port *cir;
-static unsigned char kbdbytes[5];
-static unsigned char cir_data[32]; /* we only need 16 chars */
-
-static void kbd_int_handler(int irq, void *dev_id, struct pt_regs *regs);
-static int handle_data(unsigned char *p_data);
-static inline void handle_mouse_event(unsigned char scancode);
-static inline void handle_keyboard_event(unsigned char scancode, int down);
-static int __init psaux_init(void);
-
-static struct aux_queue *queue;        /* Mouse data buffer. */
-static int aux_count = 0;
-
-/*
- * Keys accessed through the 'Fn' key
- * The Fn key does not produce a key-up sequence. So, the first
- * time the user presses it, it will be key-down event. The key
- * stays down until the user presses it again.
- */
-#define NUM_FN_KEYS 56
-static unsigned char fn_keys[NUM_FN_KEYS] = {
-       0,0,0,0,0,0,0,0,        /* 0 7   */
-       8,9,10,93,0,0,0,0,      /* 8 15  */
-       0,0,0,0,0,0,0,5,        /* 16 23 */
-       6,7,91,0,0,0,0,0,       /* 24 31 */
-       0,0,0,0,0,2,3,4,        /* 32 39 */
-       92,0,0,0,0,0,0,0,       /* 40 47 */
-       0,0,0,0,11,0,94,95        /* 48 55 */
-
-};
-
-void __init init_qtronix_990P_kbd(void)
-{
-       int retval;
-
-       cir = (struct cir_port *)kmalloc(sizeof(struct cir_port), GFP_KERNEL);
-       if (!cir) {
-               printk("Unable to initialize Qtronix keyboard\n");
-               return;
-       }
-
-       /* 
-        * revisit
-        * this should be programmable, somehow by the, by the user.
-        */
-       cir->port = KBD_CIR_PORT;
-       cir->baud_rate = 0x1d;
-       cir->rdwos = 0;
-       cir->rxdcr = 0x3;
-       cir->hcfs = 0;
-       cir->fifo_tl = 0;
-       cir->cfq = 0x1d;
-       cir_port_init(cir);
-
-       retval = request_irq(IT8172_CIR0_IRQ, kbd_int_handler, 
-                       (unsigned long )(IRQF_DISABLED|IRQF_SHARED),
-                       (const char *)"Qtronix IR Keyboard", (void *)cir);
-
-       if (retval) {
-               printk("unable to allocate cir %d irq %d\n", 
-                               cir->port, IT8172_CIR0_IRQ);
-       }
-#ifdef CONFIG_PSMOUSE
-       psaux_init();
-#endif
-}
-
-static inline unsigned char BitReverse(unsigned short key)
-{
-       unsigned char rkey = 0;
-       rkey |= (key & 0x1) << 7;
-       rkey |= (key & 0x2) << 5;
-       rkey |= (key & 0x4) << 3;
-       rkey |= (key & 0x8) << 1;
-       rkey |= (key & 0x10) >> 1;
-       rkey |= (key & 0x20) >> 3;
-       rkey |= (key & 0x40) >> 5;
-       rkey |= (key & 0x80) >> 7;
-       return rkey;
-
-}
-
-
-static inline u_int8_t UpperByte(u_int8_t data)
-{
-       return (data >> 4);
-}
-
-
-static inline u_int8_t LowerByte(u_int8_t data)
-{
-       return (data & 0xF);
-}
-
-
-int CheckSumOk(u_int8_t byte1, u_int8_t byte2, 
-               u_int8_t byte3, u_int8_t byte4, u_int8_t byte5)
-{
-       u_int8_t CheckSum;
-
-       CheckSum = (byte1 & 0x0F) + byte2 + byte3 + byte4 + byte5;
-       if ( LowerByte(UpperByte(CheckSum) + LowerByte(CheckSum)) != UpperByte(byte1) )
-               return 0;
-       else
-               return 1;
-}
-
-
-static void kbd_int_handler(int irq, void *dev_id, struct pt_regs *regs)
-{
-       struct cir_port *cir;
-       int j;
-       unsigned char int_status;
-
-       cir = (struct cir_port *)dev_id;
-       int_status = get_int_status(cir);
-       if (int_status & 0x4) {
-               clear_fifo(cir);
-               return;
-       }
-
-       while (cir_get_rx_count(cir)) {
-
-               cir_data[data_index] = cir_read_data(cir);
-
-               if (data_index == 0) {/* expecting first byte */
-                       if (cir_data[data_index] != leading1) {
-                               //printk("!leading byte %x\n", cir_data[data_index]);
-                               set_rx_active(cir);
-                               clear_fifo(cir);
-                               continue;
-                       }
-               }
-               if (data_index == 1) {
-                       if ((cir_data[data_index] & 0xf) != leading2) {
-                               set_rx_active(cir);
-                               data_index = 0; /* start over */
-                               clear_fifo(cir);
-                               continue;
-                       }
-               }
-
-               if ( (cir_data[data_index] == 0xff)) { /* last byte */
-                       //printk("data_index %d\n", data_index);
-                       set_rx_active(cir);
-#if 0
-                       for (j=0; j<=data_index; j++) {
-                               printk("rx_data %d:  %x\n", j, cir_data[j]);
-                       }
-#endif
-                       data_index = 0;
-                       handle_data(cir_data);
-                       return;
-               }
-               else if (data_index>16) {
-                       set_rx_active(cir);
-#if 0
-                       printk("warning: data_index %d\n", data_index);
-                       for (j=0; j<=data_index; j++) {
-                               printk("rx_data %d:  %x\n", j, cir_data[j]);
-                       }
-#endif
-                       data_index = 0;
-                       clear_fifo(cir);
-                       return;
-               }
-               data_index++;
-       }
-}
-
-
-#define NUM_KBD_BYTES 5
-static int handle_data(unsigned char *p_data)
-{
-       u_int32_t bit_bucket;
-       u_int32_t i, j;
-       u_int32_t got_bits, next_byte;
-       int down = 0;
-
-       /* Reorganize the bit stream */
-       for (i=0; i<16; i++)
-               p_data[i] = BitReverse(~p_data[i]);
-
-       /* 
-        * We've already previously checked that p_data[0]
-        * is equal to leading1 and that (p_data[1] & 0xf)
-        * is equal to leading2. These twelve bits are the
-        * leader code.  We can now throw them away (the 12
-        * bits) and continue parsing the stream.
-        */
-       bit_bucket = p_data[1] << 12;
-       got_bits = 4;
-       next_byte = 2;
-
-       /* 
-        * Process four bits at a time
-        */
-       for (i=0; i<NUM_KBD_BYTES; i++) {
-
-               kbdbytes[i]=0;
-
-               for (j=0; j<8; j++) /* 8 bits per byte */
-               {
-                       if (got_bits < 4) {
-                               bit_bucket |= (p_data[next_byte++] << (8 - got_bits));
-                               got_bits += 8;
-                       }
-
-                       if ((bit_bucket & 0xF000) == 0x8000) { 
-                               /* Convert 1000b to 1 */
-                               kbdbytes[i] = 0x80 | (kbdbytes[i] >> 1);
-                               got_bits -= 4;
-                               bit_bucket = bit_bucket << 4;
-                       }
-                       else if ((bit_bucket & 0xC000) == 0x8000) {
-                               /* Convert 10b to 0 */
-                               kbdbytes[i] =  kbdbytes[i] >> 1;
-                               got_bits -= 2;
-                               bit_bucket = bit_bucket << 2;
-                       }
-                       else {
-                               /* bad serial stream */
-                               return 1;
-                       }
-
-                       if (next_byte > 16) {
-                               //printk("error: too many bytes\n");
-                               return 1;
-                       }
-               }
-       }
-
-
-       if (!CheckSumOk(kbdbytes[0], kbdbytes[1], 
-                               kbdbytes[2], kbdbytes[3], kbdbytes[4])) {
-               //printk("checksum failed\n");
-               return 1;
-       }
-
-       if (kbdbytes[1] & 0x08) {
-               //printk("m: %x %x %x\n", kbdbytes[1], kbdbytes[2], kbdbytes[3]);
-               handle_mouse_event(kbdbytes[1]);
-               handle_mouse_event(kbdbytes[2]);
-               handle_mouse_event(kbdbytes[3]);
-       }
-       else {
-               if (kbdbytes[2] == 0) down = 1;
-#if 0
-               if (down)
-                       printk("down %d\n", kbdbytes[3]);
-               else
-                       printk("up %d\n", kbdbytes[3]);
-#endif
-               handle_keyboard_event(kbdbytes[3], down);
-       }
-       return 0;
-}
-
-
-DEFINE_SPINLOCK(kbd_controller_lock);
-static unsigned char handle_kbd_event(void);
-
-
-int kbd_setkeycode(unsigned int scancode, unsigned int keycode)
-{
-       printk("kbd_setkeycode scancode %x keycode %x\n", scancode, keycode);
-       return 0;
-}
-
-int kbd_getkeycode(unsigned int scancode)
-{
-       return scancode;
-}
-
-
-int kbd_translate(unsigned char scancode, unsigned char *keycode,
-                   char raw_mode)
-{
-       static int prev_scancode = 0;
-
-       if (scancode == 0x00 || scancode == 0xff) {
-               prev_scancode = 0;
-               return 0;
-       }
-
-       /* todo */
-       if (!prev_scancode && scancode == 160) { /* Fn key down */
-               //printk("Fn key down\n");
-               prev_scancode = 160;
-               return 0;
-       }
-       else if (prev_scancode && scancode == 160) { /* Fn key up */
-               //printk("Fn key up\n");
-               prev_scancode = 0;
-               return 0;
-       }
-
-       /* todo */
-       if (prev_scancode == 160) {
-               if (scancode <= NUM_FN_KEYS) {
-                       *keycode = fn_keys[scancode];
-                       //printk("fn keycode %d\n", *keycode);
-               }
-               else
-                       return 0;
-       } 
-       else if (scancode <= 127) {
-               *keycode = scancode;
-       }
-       else
-               return 0;
-
-
-       return 1;
-}
-
-char kbd_unexpected_up(unsigned char keycode)
-{
-       //printk("kbd_unexpected_up\n");
-       return 0;
-}
-
-static unsigned char kbd_exists = 1;
-
-static inline void handle_keyboard_event(unsigned char scancode, int down)
-{
-       kbd_exists = 1;
-       handle_scancode(scancode, down);
-       tasklet_schedule(&keyboard_tasklet);
-}      
-
-
-void kbd_leds(unsigned char leds)
-{
-}
-
-/* dummy */
-void kbd_init_hw(void)
-{
-}
-
-
-
-static inline void handle_mouse_event(unsigned char scancode)
-{
-       if(scancode == AUX_RECONNECT){
-               queue->head = queue->tail = 0;  /* Flush input queue */
-       //      __aux_write_ack(AUX_ENABLE_DEV);  /* ping the mouse :) */
-               return;
-       }
-
-       if (aux_count) {
-               int head = queue->head;
-
-               queue->buf[head] = scancode;
-               head = (head + 1) & (AUX_BUF_SIZE-1);
-               if (head != queue->tail) {
-                       queue->head = head;
-                       kill_fasync(&queue->fasync, SIGIO, POLL_IN);
-                       wake_up_interruptible(&queue->proc_list);
-               }
-       }
-}
-
-static unsigned char get_from_queue(void)
-{
-       unsigned char result;
-       unsigned long flags;
-
-       spin_lock_irqsave(&kbd_controller_lock, flags);
-       result = queue->buf[queue->tail];
-       queue->tail = (queue->tail + 1) & (AUX_BUF_SIZE-1);
-       spin_unlock_irqrestore(&kbd_controller_lock, flags);
-       return result;
-}
-
-
-static inline int queue_empty(void)
-{
-       return queue->head == queue->tail;
-}
-
-static int fasync_aux(int fd, struct file *filp, int on)
-{
-       int retval;
-
-       //printk("fasync_aux\n");
-       retval = fasync_helper(fd, filp, on, &queue->fasync);
-       if (retval < 0)
-               return retval;
-       return 0;
-}
-
-
-/*
- * Random magic cookie for the aux device
- */
-#define AUX_DEV ((void *)queue)
-
-static int release_aux(struct inode * inode, struct file * file)
-{
-       fasync_aux(-1, file, 0);
-       aux_count--;
-       return 0;
-}
-
-static int open_aux(struct inode * inode, struct file * file)
-{
-       if (aux_count++) {
-               return 0;
-       }
-       queue->head = queue->tail = 0;          /* Flush input queue */
-       return 0;
-}
-
-/*
- * Put bytes from input queue to buffer.
- */
-
-static ssize_t read_aux(struct file * file, char * buffer,
-                       size_t count, loff_t *ppos)
-{
-       DECLARE_WAITQUEUE(wait, current);
-       ssize_t i = count;
-       unsigned char c;
-
-       if (queue_empty()) {
-               if (file->f_flags & O_NONBLOCK)
-                       return -EAGAIN;
-               add_wait_queue(&queue->proc_list, &wait);
-repeat:
-               set_current_state(TASK_INTERRUPTIBLE);
-               if (queue_empty() && !signal_pending(current)) {
-                       schedule();
-                       goto repeat;
-               }
-               current->state = TASK_RUNNING;
-               remove_wait_queue(&queue->proc_list, &wait);
-       }
-       while (i > 0 && !queue_empty()) {
-               c = get_from_queue();
-               put_user(c, buffer++);
-               i--;
-       }
-       if (count-i) {
-               struct inode *inode = file->f_dentry->d_inode;
-               inode->i_atime = current_fs_time(inode->i_sb);
-               return count-i;
-       }
-       if (signal_pending(current))
-               return -ERESTARTSYS;
-       return 0;
-}
-
-/*
- * Write to the aux device.
- */
-
-static ssize_t write_aux(struct file * file, const char * buffer,
-                        size_t count, loff_t *ppos)
-{
-       /*
-        * The ITE boards this was tested on did not have the
-        * transmit wires connected.
-        */
-       return count;
-}
-
-static unsigned int aux_poll(struct file *file, poll_table * wait)
-{
-       poll_wait(file, &queue->proc_list, wait);
-       if (!queue_empty())
-               return POLLIN | POLLRDNORM;
-       return 0;
-}
-
-struct file_operations psaux_fops = {
-       .read           = read_aux,
-       .write          = write_aux,
-       .poll           = aux_poll,
-       .open           = open_aux,
-       .release        = release_aux,
-       .fasync         = fasync_aux,
-};
-
-/*
- * Initialize driver.
- */
-static struct miscdevice psaux_mouse = {
-       PSMOUSE_MINOR, "psaux", &psaux_fops
-};
-
-static int __init psaux_init(void)
-{
-       int retval;
-
-       retval = misc_register(&psaux_mouse);
-       if(retval < 0)
-               return retval;
-
-       queue = (struct aux_queue *) kmalloc(sizeof(*queue), GFP_KERNEL);
-       if (!queue) {
-               misc_deregister(&psaux_mouse);
-               return -ENOMEM;
-       }
-               
-       memset(queue, 0, sizeof(*queue));
-       queue->head = queue->tail = 0;
-       init_waitqueue_head(&queue->proc_list);
-
-       return 0;
-}
-module_init(init_qtronix_990P_kbd);
-#endif
index 07f47a0208a7200b4e0ba1f32bd747d82ae1db6b..eb6b13f4211aed23994734537ecc81a3919dfcb2 100644 (file)
@@ -645,6 +645,7 @@ void add_input_randomness(unsigned int type, unsigned int code,
        add_timer_randomness(&input_timer_state,
                             (type << 4) ^ code ^ (code >> 4) ^ value);
 }
+EXPORT_SYMBOL_GPL(add_input_randomness);
 
 void add_interrupt_randomness(int irq)
 {
index 6b039186856d6a85b1ac28980c0e67dbb475473a..9e7283bd81a01b32a027c20afb23be87e1cfd81f 100644 (file)
@@ -88,7 +88,7 @@ void RIOHostReset(unsigned int, struct DpRam __iomem *, unsigned int);
 
 /* riointr.c */
 void RIOTxEnable(char *);
-void RIOServiceHost(struct rio_info *, struct Host *, int);
+void RIOServiceHost(struct rio_info *, struct Host *);
 int riotproc(struct rio_info *, struct ttystatics *, int, int);
 
 /* rioparam.c */
index ee2ddea7a63a838e084f1103f7df5147f2b417f0..23d0681fe491abffeb08795f4028cc017c297b16 100644 (file)
@@ -44,6 +44,7 @@
 **    the host.
 */
 struct Host {
+       struct pci_dev *pdev;
        unsigned char Type;             /* RIO_EISA, RIO_MCA, ... */
        unsigned char Ivec;             /* POLLED or ivec number */
        unsigned char Mode;             /* Control stuff */
index 202a3b0945b78749dbf0c4cc97356e217753f07b..7ac68cb3beddfa61df80e8ca0cfb22a3b53cf70b 100644 (file)
@@ -363,12 +363,12 @@ static void rio_reset_interrupt(struct Host *HostP)
 }
 
 
-static irqreturn_t rio_interrupt(int irq, void *ptr, struct pt_regs *regs)
+static irqreturn_t rio_interrupt(int irq, void *ptr)
 {
        struct Host *HostP;
        func_enter();
 
-       HostP = (struct Host *) ptr;    /* &p->RIOHosts[(long)ptr]; */
+       HostP = ptr;                    /* &p->RIOHosts[(long)ptr]; */
        rio_dprintk(RIO_DEBUG_IFLOW, "rio: enter rio_interrupt (%d/%d)\n", irq, HostP->Ivec);
 
        /* AAargh! The order in which to do these things is essential and
@@ -402,7 +402,7 @@ static irqreturn_t rio_interrupt(int irq, void *ptr, struct pt_regs *regs)
                return IRQ_HANDLED;
        }
 
-       RIOServiceHost(p, HostP, irq);
+       RIOServiceHost(p, HostP);
 
        rio_dprintk(RIO_DEBUG_IFLOW, "riointr() doing host %p type %d\n", ptr, HostP->Type);
 
@@ -417,7 +417,7 @@ static void rio_pollfunc(unsigned long data)
 {
        func_enter();
 
-       rio_interrupt(0, &p->RIOHosts[data], NULL);
+       rio_interrupt(0, &p->RIOHosts[data]);
        p->RIOHosts[data].timer.expires = jiffies + rio_poll;
        add_timer(&p->RIOHosts[data].timer);
 
@@ -1017,6 +1017,10 @@ static int __init rio_init(void)
                        rio_dprintk(RIO_DEBUG_PROBE, "Hmm Tested ok, uniqid = %x.\n", p->RIOHosts[p->RIONumHosts].UniqueNum);
 
                        fix_rio_pci(pdev);
+
+                       p->RIOHosts[p->RIONumHosts].pdev = pdev;
+                       pci_dev_get(pdev);
+
                        p->RIOLastPCISearch = 0;
                        p->RIONumHosts++;
                        found++;
@@ -1066,6 +1070,9 @@ static int __init rio_init(void)
                            ((readb(&p->RIOHosts[p->RIONumHosts].Unique[1]) & 0xFF) << 8) | ((readb(&p->RIOHosts[p->RIONumHosts].Unique[2]) & 0xFF) << 16) | ((readb(&p->RIOHosts[p->RIONumHosts].Unique[3]) & 0xFF) << 24);
                        rio_dprintk(RIO_DEBUG_PROBE, "Hmm Tested ok, uniqid = %x.\n", p->RIOHosts[p->RIONumHosts].UniqueNum);
 
+                       p->RIOHosts[p->RIONumHosts].pdev = pdev;
+                       pci_dev_get(pdev);
+
                        p->RIOLastPCISearch = 0;
                        p->RIONumHosts++;
                        found++;
@@ -1181,6 +1188,8 @@ static void __exit rio_exit(void)
                }
                /* It is safe/allowed to del_timer a non-active timer */
                del_timer(&hp->timer);
+               if (hp->Type == RIO_PCI)
+                       pci_dev_put(hp->pdev);
        }
 
        if (misc_deregister(&rio_fw_device) < 0) {
index 052e8120a4713ccc2008e8f2f88988bc1adb0985..7ce77619707cf2f4fa1db2480d1acaebaf968ca9 100644 (file)
@@ -662,7 +662,7 @@ int riocontrol(struct rio_info *p, dev_t dev, int cmd, unsigned long arg, int su
                        p->RIOError.Error = COPYIN_FAILED;
                        return -EFAULT;
                }
-               if (portStats.port >= RIO_PORTS) {
+               if (portStats.port < 0 || portStats.port >= RIO_PORTS) {
                        p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
                        return -ENXIO;
                }
@@ -702,7 +702,7 @@ int riocontrol(struct rio_info *p, dev_t dev, int cmd, unsigned long arg, int su
                        p->RIOError.Error = COPYIN_FAILED;
                        return -EFAULT;
                }
-               if (portStats.port >= RIO_PORTS) {
+               if (portStats.port < 0 || portStats.port >= RIO_PORTS) {
                        p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
                        return -ENXIO;
                }
index 0bd09040a5c091e0640c0214e893d17777c29764..eeda40c5e189067a547e1db2a5670a6756fc5a74 100644 (file)
@@ -181,7 +181,7 @@ static int RupIntr;
 static int RxIntr;
 static int TxIntr;
 
-void RIOServiceHost(struct rio_info *p, struct Host *HostP, int From)
+void RIOServiceHost(struct rio_info *p, struct Host *HostP)
 {
        rio_spin_lock(&HostP->HostLock);
        if ((HostP->Flags & RUN_STATE) != RC_RUNNING) {
index b0ab3f28cc6a84768b77a169bdd0b7d968f86a11..5ab32b38f45a28f55737c1b88ead868d299671ea 100644 (file)
@@ -550,7 +550,7 @@ static inline void rc_check_modem(struct riscom_board const * bp)
 }
 
 /* The main interrupt processing routine */
-static irqreturn_t rc_interrupt(int irq, void * dev_id, struct pt_regs * regs)
+static irqreturn_t rc_interrupt(int irq, void * dev_id)
 {
        unsigned char status;
        unsigned char ack;
@@ -559,11 +559,10 @@ static irqreturn_t rc_interrupt(int irq, void * dev_id, struct pt_regs * regs)
        int handled = 0;
 
        bp = IRQ_to_board[irq];
-       
-       if (!bp || !(bp->flags & RC_BOARD_ACTIVE))  {
+
+       if (!(bp->flags & RC_BOARD_ACTIVE))
                return IRQ_NONE;
-       }
-       
+
        while ((++loop < 16) && ((status = ~(rc_in(bp, RC_BSR))) &
                                 (RC_BSR_TOUT | RC_BSR_TINT |
                                  RC_BSR_MINT | RC_BSR_RINT))) {
index 656f8c0ca52effdc31f343360a91309278ae5760..66a7385bc34aebb96cbda088b2a0b74f23f31363 100644 (file)
  *     1.09a   Pete Zaitcev: Sun SPARC
  *     1.09b   Jeff Garzik: Modularize, init cleanup
  *     1.09c   Jeff Garzik: SMP cleanup
- *     1.10    Paul Barton-Davis: add support for async I/O
+ *     1.10    Paul Barton-Davis: add support for async I/O
  *     1.10a   Andrea Arcangeli: Alpha updates
  *     1.10b   Andrew Morton: SMP lock fix
  *     1.10c   Cesar Barros: SMP locking fixes and cleanup
  *     1.10d   Paul Gortmaker: delete paranoia check in rtc_exit
  *     1.10e   Maciej W. Rozycki: Handle DECstation's year weirdness.
- *      1.11    Takashi Iwai: Kernel access functions
+ *     1.11    Takashi Iwai: Kernel access functions
  *                           rtc_register/rtc_unregister/rtc_control
  *      1.11a   Daniele Bellucci: Audit create_proc_read_entry in rtc_init
  *     1.12    Venkatesh Pallipadi: Hooks for emulating rtc on HPET base-timer
@@ -113,9 +113,9 @@ static int rtc_has_irq = 1;
 #define hpet_set_rtc_irq_bit(arg)              0
 #define hpet_rtc_timer_init()                  do { } while (0)
 #define hpet_rtc_dropped_irq()                         0
-static inline irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs) {return 0;}
+static inline irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id) {return 0;}
 #else
-extern irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+extern irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id);
 #endif
 
 /*
@@ -229,7 +229,7 @@ static inline unsigned char rtc_is_updating(void)
  *     (See ./arch/XXXX/kernel/time.c for the set_rtc_mmss() function.)
  */
 
-irqreturn_t rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t rtc_interrupt(int irq, void *dev_id)
 {
        /*
         *      Can be an alarm interrupt, update complete interrupt,
@@ -915,7 +915,7 @@ static const struct file_operations rtc_proc_fops = {
 };
 
 #if defined(RTC_IRQ) && !defined(__sparc__)
-static irqreturn_t (*rtc_int_handler_ptr)(int irq, void *dev_id, struct pt_regs *regs);
+static irq_handler_t rtc_int_handler_ptr;
 #endif
 
 static int __init rtc_init(void)
index 65c751d0d64350b2b6c25df7d777504da53c6c21..4217d38caef90f83e7272b68c21a8d2202a1eb3f 100644 (file)
 
 /***************************** Prototypes ***************************/
 /* The interrupt service routine */
-static irqreturn_t a2232_vbl_inter(int irq, void *data, struct pt_regs *fp);
+static irqreturn_t a2232_vbl_inter(int irq, void *data);
 /* Initialize the port structures */
 static void a2232_init_portstructs(void);
 /* Initialize and register TTY drivers. */
@@ -504,7 +504,7 @@ static int  a2232_open(struct tty_struct * tty, struct file * filp)
 }
 /*** END OF FUNCTIONS EXPECTED BY TTY DRIVER STRUCTS ***/
 
-static irqreturn_t a2232_vbl_inter(int irq, void *data, struct pt_regs *fp)
+static irqreturn_t a2232_vbl_inter(int irq, void *data)
 {
 #if A2232_IOBUFLEN != 256
 #error "Re-Implement a2232_vbl_inter()!"
index f4809c8183ccd9acaf1dfe4dbbec145ff6700929..3af7f0958c5d85a6a49a96ca8562eb2e31e122d3 100644 (file)
@@ -62,6 +62,7 @@
 #include <linux/console.h>
 #include <linux/module.h>
 #include <linux/bitops.h>
+#include <linux/tty_flip.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
@@ -370,7 +371,7 @@ cy_sched_event(struct cyclades_port *info, int event)
    received, out buffer empty, modem change, etc.
  */
 static irqreturn_t
-cd2401_rxerr_interrupt(int irq, void *dev_id, struct pt_regs *fp)
+cd2401_rxerr_interrupt(int irq, void *dev_id)
 {
     struct tty_struct *tty;
     struct cyclades_port *info;
@@ -427,8 +428,9 @@ cd2401_rxerr_interrupt(int irq, void *dev_id, struct pt_regs *fp)
                       overflowing, we still loose
                       the next incoming character.
                     */
-                   tty_insert_flip_char(tty, data, TTY_NORMAL);
-               }
+                   if (tty_buffer_request_room(tty, 1) != 0){
+                       tty_insert_flip_char(tty, data, TTY_FRAME);
+                   }
                /* These two conditions may imply */
                /* a normal read should be done. */
                /* else if(data & CyTIMEOUT) */
@@ -437,21 +439,21 @@ cd2401_rxerr_interrupt(int irq, void *dev_id, struct pt_regs *fp)
                    tty_insert_flip_char(tty, 0, TTY_NORMAL);
                }
            }else{
-                   tty_insert_flip_char(tty, data, TTY_NORMAL);
+               tty_insert_flip_char(tty, data, TTY_NORMAL);
            }
        }else{
            /* there was a software buffer overrun
               and nothing could be done about it!!! */
        }
     }
-    schedule_delayed_work(&tty->flip.work, 1);
+    tty_schedule_flip(tty);
     /* end of service */
     base_addr[CyREOIR] = rfoc ? 0 : CyNOTRANS;
     return IRQ_HANDLED;
 } /* cy_rxerr_interrupt */
 
 static irqreturn_t
-cd2401_modem_interrupt(int irq, void *dev_id, struct pt_regs *fp)
+cd2401_modem_interrupt(int irq, void *dev_id)
 {
     struct cyclades_port *info;
     volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR;
@@ -506,7 +508,7 @@ cd2401_modem_interrupt(int irq, void *dev_id, struct pt_regs *fp)
 } /* cy_modem_interrupt */
 
 static irqreturn_t
-cd2401_tx_interrupt(int irq, void *dev_id, struct pt_regs *fp)
+cd2401_tx_interrupt(int irq, void *dev_id)
 {
     struct cyclades_port *info;
     volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR;
@@ -626,7 +628,7 @@ cd2401_tx_interrupt(int irq, void *dev_id, struct pt_regs *fp)
 } /* cy_tx_interrupt */
 
 static irqreturn_t
-cd2401_rx_interrupt(int irq, void *dev_id, struct pt_regs *fp)
+cd2401_rx_interrupt(int irq, void *dev_id)
 {
     struct tty_struct *tty;
     struct cyclades_port *info;
@@ -635,6 +637,7 @@ cd2401_rx_interrupt(int irq, void *dev_id, struct pt_regs *fp)
     char data;
     int char_count;
     int save_cnt;
+    int len;
 
     /* determine the channel and change to that context */
     channel = (u_short ) (base_addr[CyLICR] >> 2);
@@ -667,14 +670,15 @@ cd2401_rx_interrupt(int irq, void *dev_id, struct pt_regs *fp)
            info->mon.char_max = char_count;
        info->mon.char_last = char_count;
 #endif
-       while(char_count--){
+       len = tty_buffer_request_room(tty, char_count);
+       while(len--){
            data = base_addr[CyRDR];
            tty_insert_flip_char(tty, data, TTY_NORMAL);
 #ifdef CYCLOM_16Y_HACK
            udelay(10L);
 #endif
         }
-       schedule_delayed_work(&tty->flip.work, 1);
+       tty_schedule_flip(tty);
     }
     /* end of service */
     base_addr[CyREOIR] = save_cnt ? 0 : CyNOTRANS;
@@ -835,7 +839,7 @@ shutdown(struct cyclades_port * info)
     local_irq_save(flags);
        if (info->xmit_buf){
            free_page((unsigned long) info->xmit_buf);
-           info->xmit_buf = 0;
+           info->xmit_buf = NULL;
        }
 
        base_addr[CyCAR] = (u_char)channel;
@@ -1350,7 +1354,7 @@ cy_unthrottle(struct tty_struct * tty)
 
 static int
 get_serial_info(struct cyclades_port * info,
-                           struct serial_struct * retinfo)
+                           struct serial_struct __user * retinfo)
 {
   struct serial_struct tmp;
 
@@ -1372,7 +1376,7 @@ get_serial_info(struct cyclades_port * info,
 
 static int
 set_serial_info(struct cyclades_port * info,
-                           struct serial_struct * new_info)
+                           struct serial_struct __user * new_info)
 {
   struct serial_struct new_serial;
   struct cyclades_port old_info;
@@ -1422,7 +1426,6 @@ cy_tiocmget(struct tty_struct *tty, struct file *file)
   volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
   unsigned long flags;
   unsigned char status;
-  unsigned int result;
 
     channel = info->line;
 
@@ -1446,7 +1449,6 @@ cy_tiocmset(struct tty_struct *tty, struct file *file,
   int channel;
   volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
   unsigned long flags;
-  unsigned int arg;
          
     channel = info->line;
 
@@ -1501,7 +1503,7 @@ send_break( struct cyclades_port * info, int duration)
 } /* send_break */
 
 static int
-get_mon_info(struct cyclades_port * info, struct cyclades_monitor * mon)
+get_mon_info(struct cyclades_port * info, struct cyclades_monitor __user * mon)
 {
 
    if (copy_to_user(mon, &info->mon, sizeof(struct cyclades_monitor)))
@@ -1514,7 +1516,7 @@ get_mon_info(struct cyclades_port * info, struct cyclades_monitor * mon)
 }
 
 static int
-set_threshold(struct cyclades_port * info, unsigned long *arg)
+set_threshold(struct cyclades_port * info, unsigned long __user *arg)
 {
    volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
    unsigned long value;
@@ -1531,7 +1533,7 @@ set_threshold(struct cyclades_port * info, unsigned long *arg)
 }
 
 static int
-get_threshold(struct cyclades_port * info, unsigned long *value)
+get_threshold(struct cyclades_port * info, unsigned long __user *value)
 {
    volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
    int channel;
@@ -1544,7 +1546,7 @@ get_threshold(struct cyclades_port * info, unsigned long *value)
 }
 
 static int
-set_default_threshold(struct cyclades_port * info, unsigned long *arg)
+set_default_threshold(struct cyclades_port * info, unsigned long __user *arg)
 {
    unsigned long value;
 
@@ -1556,13 +1558,13 @@ set_default_threshold(struct cyclades_port * info, unsigned long *arg)
 }
 
 static int
-get_default_threshold(struct cyclades_port * info, unsigned long *value)
+get_default_threshold(struct cyclades_port * info, unsigned long __user *value)
 {
    return put_user(info->default_threshold,value);
 }
 
 static int
-set_timeout(struct cyclades_port * info, unsigned long *arg)
+set_timeout(struct cyclades_port * info, unsigned long __user *arg)
 {
    volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
    int channel;
@@ -1579,7 +1581,7 @@ set_timeout(struct cyclades_port * info, unsigned long *arg)
 }
 
 static int
-get_timeout(struct cyclades_port * info, unsigned long *value)
+get_timeout(struct cyclades_port * info, unsigned long __user *value)
 {
    volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
    int channel;
@@ -1599,7 +1601,7 @@ set_default_timeout(struct cyclades_port * info, unsigned long value)
 }
 
 static int
-get_default_timeout(struct cyclades_port * info, unsigned long *value)
+get_default_timeout(struct cyclades_port * info, unsigned long __user *value)
 {
    return put_user(info->default_timeout,value);
 }
@@ -1611,6 +1613,7 @@ cy_ioctl(struct tty_struct *tty, struct file * file,
   unsigned long val;
   struct cyclades_port * info = (struct cyclades_port *)tty->driver_data;
   int ret_val = 0;
+  void __user *argp = (void __user *)arg;
 
 #ifdef SERIAL_DEBUG_OTHER
     printk("cy_ioctl %s, cmd = %x arg = %lx\n", tty->name, cmd, arg); /* */
@@ -1618,28 +1621,28 @@ cy_ioctl(struct tty_struct *tty, struct file * file,
 
     switch (cmd) {
         case CYGETMON:
-            ret_val = get_mon_info(info, (struct cyclades_monitor *)arg);
+            ret_val = get_mon_info(info, argp);
            break;
         case CYGETTHRESH:
-           ret_val = get_threshold(info, (unsigned long *)arg);
+           ret_val = get_threshold(info, argp);
            break;
         case CYSETTHRESH:
-            ret_val = set_threshold(info, (unsigned long *)arg);
+            ret_val = set_threshold(info, argp);
            break;
         case CYGETDEFTHRESH:
-           ret_val = get_default_threshold(info, (unsigned long *)arg);
+           ret_val = get_default_threshold(info, argp);
            break;
         case CYSETDEFTHRESH:
-            ret_val = set_default_threshold(info, (unsigned long *)arg);
+            ret_val = set_default_threshold(info, argp);
            break;
         case CYGETTIMEOUT:
-           ret_val = get_timeout(info, (unsigned long *)arg);
+           ret_val = get_timeout(info, argp);
            break;
         case CYSETTIMEOUT:
-            ret_val = set_timeout(info, (unsigned long *)arg);
+            ret_val = set_timeout(info, argp);
            break;
         case CYGETDEFTIMEOUT:
-           ret_val = get_default_timeout(info, (unsigned long *)arg);
+           ret_val = get_default_timeout(info, argp);
            break;
         case CYSETDEFTIMEOUT:
             ret_val = set_default_timeout(info, (unsigned long)arg);
@@ -1662,21 +1665,20 @@ cy_ioctl(struct tty_struct *tty, struct file * file,
 
 /* The following commands are incompletely implemented!!! */
         case TIOCGSOFTCAR:
-            ret_val = put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long *) arg);
+            ret_val = put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long __user *) argp);
             break;
         case TIOCSSOFTCAR:
-            ret_val = get_user(val, (unsigned long *) arg);
+            ret_val = get_user(val, (unsigned long __user *) argp);
            if (ret_val)
                    break;
             tty->termios->c_cflag =
                     ((tty->termios->c_cflag & ~CLOCAL) | (val ? CLOCAL : 0));
             break;
         case TIOCGSERIAL:
-            ret_val = get_serial_info(info, (struct serial_struct *) arg);
+            ret_val = get_serial_info(info, argp);
             break;
         case TIOCSSERIAL:
-            ret_val = set_serial_info(info,
-                                   (struct serial_struct *) arg);
+            ret_val = set_serial_info(info, argp);
             break;
         default:
            ret_val = -ENOIOCTLCMD;
@@ -1771,7 +1773,7 @@ cy_close(struct tty_struct * tty, struct file * filp)
        tty->driver->flush_buffer(tty);
     tty_ldisc_flush(tty);
     info->event = 0;
-    info->tty = 0;
+    info->tty = NULL;
     if (info->blocked_open) {
        if (info->close_delay) {
            msleep_interruptible(jiffies_to_msecs(info->close_delay));
@@ -2248,7 +2250,7 @@ scrn[1] = '\0';
                info->card = index;
                info->line = port_num;
                info->flags = STD_COM_FLAGS;
-               info->tty = 0;
+               info->tty = NULL;
                info->xmit_fifo_size = 12;
                info->cor1 = CyPARITY_NONE|Cy_8_BITS;
                info->cor2 = CyETC;
index 07e0b75f2338b59a6ca2b9c76917115afd935526..52753e723eaae5cf361a5b06cc097b2a7ce0da25 100644 (file)
@@ -34,7 +34,7 @@
 #define SCDRV_TIMEOUT  1000
 
 static irqreturn_t
-scdrv_interrupt(int irq, void *subch_data, struct pt_regs *regs)
+scdrv_interrupt(int irq, void *subch_data)
 {
        struct subch_data_s *sd = subch_data;
        unsigned long flags;
index 864854c58866ad12076e970acbea1181872e4a79..2f56e8c54897d5c55ca1caec974c95e43c787fd6 100644 (file)
@@ -36,7 +36,7 @@ DECLARE_TASKLET(sn_sysctl_event, scdrv_event, 0);
  * destination.
  */
 static irqreturn_t
-scdrv_event_interrupt(int irq, void *subch_data, struct pt_regs *regs)
+scdrv_event_interrupt(int irq, void *subch_data)
 {
        struct subch_data_s *sd = subch_data;
        unsigned long flags;
index d4e434d694b747f63d45b4fbad1735190d696c8d..c084149153de1050bb996fdb59cf017bd2137936 100644 (file)
@@ -826,7 +826,7 @@ static void sonypi_report_input_event(u8 event)
 }
 
 /* Interrupt handler: some event is available */
-static irqreturn_t sonypi_irq(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t sonypi_irq(int irq, void *dev_id)
 {
        u8 v1, v2, event = 0;
        int i, j;
index 902c48dca3bc98e86938fb23a0affbd052d921ea..7e1bd9562c2ac3c2e63b40fb50dc92019b5231f8 100644 (file)
@@ -183,11 +183,6 @@ static int sx_poll = HZ;
 
 static struct tty_driver *specialix_driver;
 
-static unsigned long baud_table[] =  {
-       0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
-       9600, 19200, 38400, 57600, 115200, 0,
-};
-
 static struct specialix_board sx_board[SX_NBOARD] =  {
        { 0, SX_IOBASE1,  9, },
        { 0, SX_IOBASE2, 11, },
@@ -200,7 +195,7 @@ static struct specialix_port sx_port[SX_NBOARD * SX_NPORT];
 
 #ifdef SPECIALIX_TIMER
 static struct timer_list missed_irq_timer;
-static irqreturn_t sx_interrupt(int irq, void * dev_id, struct pt_regs * regs);
+static irqreturn_t sx_interrupt(int irq, void * dev_id);
 #endif
 
 
@@ -897,7 +892,7 @@ static inline void sx_check_modem(struct specialix_board * bp)
 
 
 /* The main interrupt processing routine */
-static irqreturn_t sx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t sx_interrupt(int irq, void *dev_id)
 {
        unsigned char status;
        unsigned char ack;
@@ -912,7 +907,7 @@ static irqreturn_t sx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        spin_lock_irqsave(&bp->lock, flags);
 
        dprintk (SX_DEBUG_FLOW, "enter %s port %d room: %ld\n", __FUNCTION__, port_No(sx_get_port(bp, "INT")), SERIAL_XMIT_SIZE - sx_get_port(bp, "ITN")->xmit_cnt - 1);
-       if (!bp || !(bp->flags & SX_BOARD_ACTIVE)) {
+       if (!(bp->flags & SX_BOARD_ACTIVE)) {
                dprintk (SX_DEBUG_IRQ, "sx: False interrupt. irq %d.\n", irq);
                spin_unlock_irqrestore(&bp->lock, flags);
                func_exit();
@@ -1090,9 +1085,9 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
 
        if (baud == 38400) {
                if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
-                       baud ++;
+                       baud = 57600;
                if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
-                       baud += 2;
+                       baud = 115200;
        }
 
        if (!baud) {
@@ -1150,11 +1145,9 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
        sx_out(bp, CD186x_RBPRL, tmp & 0xff);
        sx_out(bp, CD186x_TBPRL, tmp & 0xff);
        spin_unlock_irqrestore(&bp->lock, flags);
-       if (port->custom_divisor) {
+       if (port->custom_divisor)
                baud = (SX_OSCFREQ + port->custom_divisor/2) / port->custom_divisor;
-               baud = ( baud + 5 ) / 10;
-       } else
-               baud = (baud_table[baud] + 5) / 10;   /* Estimated CPS */
+       baud = (baud + 5) / 10;         /* Estimated CPS */
 
        /* Two timer ticks seems enough to wakeup something like SLIP driver */
        tmp = ((baud + HZ/2) / HZ) * 2 - CD186x_NFIFO;
index bd711537ec4e851791699c377e2540218aaa7ff6..522e88e395ccac7358ed2cb2ac1b999244af55c2 100644 (file)
@@ -1927,13 +1927,12 @@ stl_readdone:
  *     calls off to the approrpriate board interrupt handlers.
  */
 
-static irqreturn_t stl_intr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t stl_intr(int irq, void *dev_id)
 {
        stlbrd_t        *brdp = (stlbrd_t *) dev_id;
 
 #ifdef DEBUG
-       printk("stl_intr(brdp=%x,irq=%d,regs=%x)\n", (int) brdp, irq,
-           (int) regs);
+       printk("stl_intr(brdp=%x,irq=%d)\n", (int) brdp, irq);
 #endif
 
        return IRQ_RETVAL((* brdp->isr)(brdp));
index 8fd71a5fc6192b1befd31c2b611e894d0e2299a1..cc10af08cb059b7f587586518011613541bf028b 100644 (file)
@@ -1192,7 +1192,7 @@ static inline void sx_check_modem_signals (struct sx_port *port)
  * Small, elegant, clear.
  */
 
-static irqreturn_t sx_interrupt (int irq, void *ptr, struct pt_regs *regs)
+static irqreturn_t sx_interrupt (int irq, void *ptr)
 {
        struct sx_board *board = ptr;
        struct sx_port *port;
@@ -1300,7 +1300,7 @@ static void sx_pollfunc (unsigned long data)
 
        func_enter ();
 
-       sx_interrupt (0, board, NULL);
+       sx_interrupt (0, board);
 
        init_timer(&board->timer);
 
@@ -2602,7 +2602,7 @@ static void __exit sx_exit (void)
                }
        }
        if (misc_deregister(&sx_fw_device) < 0) {
-               printk (KERN_INFO "sx: couldn't deregister firmware loader devic\n");
+               printk (KERN_INFO "sx: couldn't deregister firmware loader device\n");
        }
        sx_dprintk (SX_DEBUG_CLEANUP, "Cleaning up drivers (%d)\n", sx_initialized);
        if (sx_initialized)
index a4150c4519c4e4173a9a1f60951d3cf5e0b6fc32..06784adcc35c78f7f17650aa69722359b11129a2 100644 (file)
@@ -133,8 +133,8 @@ static MGSL_PARAMS default_params = {
 };
 
 #define SHARED_MEM_ADDRESS_SIZE 0x40000
-#define BUFFERLISTSIZE (PAGE_SIZE)
-#define DMABUFFERSIZE (PAGE_SIZE)
+#define BUFFERLISTSIZE 4096
+#define DMABUFFERSIZE 4096
 #define MAXRXFRAMES 7
 
 typedef struct _DMABUFFERENTRY
@@ -1698,11 +1698,10 @@ static void mgsl_isr_transmit_dma( struct mgsl_struct *info )
  * 
  *     irq             interrupt number that caused interrupt
  *     dev_id          device ID supplied during interrupt registration
- *     regs            interrupted processor context
  *     
  * Return Value: None
  */
-static irqreturn_t mgsl_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+static irqreturn_t mgsl_interrupt(int irq, void *dev_id)
 {
        struct mgsl_struct * info;
        u16 UscVector;
index bdc7cb248b8f1818db19b0bbb09ae46904f8cd06..d4334c79f8d44cece757c8f56630a39a23308fb7 100644 (file)
@@ -491,7 +491,7 @@ static void isr_serial(struct slgt_info *info);
 static void isr_rdma(struct slgt_info *info);
 static void isr_txeom(struct slgt_info *info, unsigned short status);
 static void isr_tdma(struct slgt_info *info);
-static irqreturn_t slgt_interrupt(int irq, void *dev_id, struct pt_regs * regs);
+static irqreturn_t slgt_interrupt(int irq, void *dev_id);
 
 static int  alloc_dma_bufs(struct slgt_info *info);
 static void free_dma_bufs(struct slgt_info *info);
@@ -2217,9 +2217,8 @@ static void isr_gpio(struct slgt_info *info, unsigned int changed, unsigned int
  *
  *     irq     interrupt number
  *     dev_id  device ID supplied during interrupt registration
- *     regs    interrupted processor context
  */
-static irqreturn_t slgt_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+static irqreturn_t slgt_interrupt(int irq, void *dev_id)
 {
        struct slgt_info *info;
        unsigned int gsr;
index 6eb75dcd79613b2f8c454be4331f496004156000..3e932b68137118286959ecbd39f3df7de41eeaa2 100644 (file)
@@ -2596,8 +2596,7 @@ void isr_io_pin( SLMP_INFO *info, u16 status )
  *     dev_id          device ID supplied during interrupt registration
  *     regs            interrupted processor context
  */
-static irqreturn_t synclinkmp_interrupt(int irq, void *dev_id,
-                                       struct pt_regs *regs)
+static irqreturn_t synclinkmp_interrupt(int irq, void *dev_id)
 {
        SLMP_INFO * info;
        unsigned char status, status0, status1=0;
index 6b4d4d1e343da3332f413b8d47c65b00e9ff4a0b..5f49280779fb0a98c567ec12e2350a634d95eece 100644 (file)
 #include <linux/vt_kern.h>
 #include <linux/workqueue.h>
 #include <linux/kexec.h>
+#include <linux/irq.h>
 
 #include <asm/ptrace.h>
+#include <asm/irq_regs.h>
 
 /* Whether we react on sysrq keys or just ignore them */
 int sysrq_enabled = 1;
 
-static void sysrq_handle_loglevel(int key, struct pt_regs *pt_regs,
-                                 struct tty_struct *tty)
+static void sysrq_handle_loglevel(int key, struct tty_struct *tty)
 {
        int i;
        i = key - '0';
@@ -58,8 +59,7 @@ static struct sysrq_key_op sysrq_loglevel_op = {
 };
 
 #ifdef CONFIG_VT
-static void sysrq_handle_SAK(int key, struct pt_regs *pt_regs,
-                            struct tty_struct *tty)
+static void sysrq_handle_SAK(int key, struct tty_struct *tty)
 {
        if (tty)
                do_SAK(tty);
@@ -76,8 +76,7 @@ static struct sysrq_key_op sysrq_SAK_op = {
 #endif
 
 #ifdef CONFIG_VT
-static void sysrq_handle_unraw(int key, struct pt_regs *pt_regs,
-                              struct tty_struct *tty)
+static void sysrq_handle_unraw(int key, struct tty_struct *tty)
 {
        struct kbd_struct *kbd = &kbd_table[fg_console];
 
@@ -95,10 +94,9 @@ static struct sysrq_key_op sysrq_unraw_op = {
 #endif /* CONFIG_VT */
 
 #ifdef CONFIG_KEXEC
-static void sysrq_handle_crashdump(int key, struct pt_regs *pt_regs,
-                               struct tty_struct *tty)
+static void sysrq_handle_crashdump(int key, struct tty_struct *tty)
 {
-       crash_kexec(pt_regs);
+       crash_kexec(get_irq_regs());
 }
 static struct sysrq_key_op sysrq_crashdump_op = {
        .handler        = sysrq_handle_crashdump,
@@ -110,8 +108,7 @@ static struct sysrq_key_op sysrq_crashdump_op = {
 #define sysrq_crashdump_op (*(struct sysrq_key_op *)0)
 #endif
 
-static void sysrq_handle_reboot(int key, struct pt_regs *pt_regs,
-                               struct tty_struct *tty)
+static void sysrq_handle_reboot(int key, struct tty_struct *tty)
 {
        lockdep_off();
        local_irq_enable();
@@ -124,8 +121,7 @@ static struct sysrq_key_op sysrq_reboot_op = {
        .enable_mask    = SYSRQ_ENABLE_BOOT,
 };
 
-static void sysrq_handle_sync(int key, struct pt_regs *pt_regs,
-                             struct tty_struct *tty)
+static void sysrq_handle_sync(int key, struct tty_struct *tty)
 {
        emergency_sync();
 }
@@ -136,8 +132,7 @@ static struct sysrq_key_op sysrq_sync_op = {
        .enable_mask    = SYSRQ_ENABLE_SYNC,
 };
 
-static void sysrq_handle_mountro(int key, struct pt_regs *pt_regs,
-                                struct tty_struct *tty)
+static void sysrq_handle_mountro(int key, struct tty_struct *tty)
 {
        emergency_remount();
 }
@@ -149,8 +144,7 @@ static struct sysrq_key_op sysrq_mountro_op = {
 };
 
 #ifdef CONFIG_LOCKDEP
-static void sysrq_handle_showlocks(int key, struct pt_regs *pt_regs,
-                               struct tty_struct *tty)
+static void sysrq_handle_showlocks(int key, struct tty_struct *tty)
 {
        debug_show_all_locks();
 }
@@ -164,11 +158,11 @@ static struct sysrq_key_op sysrq_showlocks_op = {
 #define sysrq_showlocks_op (*(struct sysrq_key_op *)0)
 #endif
 
-static void sysrq_handle_showregs(int key, struct pt_regs *pt_regs,
-                                 struct tty_struct *tty)
+static void sysrq_handle_showregs(int key, struct tty_struct *tty)
 {
-       if (pt_regs)
-               show_regs(pt_regs);
+       struct pt_regs *regs = get_irq_regs();
+       if (regs)
+               show_regs(regs);
 }
 static struct sysrq_key_op sysrq_showregs_op = {
        .handler        = sysrq_handle_showregs,
@@ -177,8 +171,7 @@ static struct sysrq_key_op sysrq_showregs_op = {
        .enable_mask    = SYSRQ_ENABLE_DUMP,
 };
 
-static void sysrq_handle_showstate(int key, struct pt_regs *pt_regs,
-                                  struct tty_struct *tty)
+static void sysrq_handle_showstate(int key, struct tty_struct *tty)
 {
        show_state();
 }
@@ -189,8 +182,7 @@ static struct sysrq_key_op sysrq_showstate_op = {
        .enable_mask    = SYSRQ_ENABLE_DUMP,
 };
 
-static void sysrq_handle_showmem(int key, struct pt_regs *pt_regs,
-                                struct tty_struct *tty)
+static void sysrq_handle_showmem(int key, struct tty_struct *tty)
 {
        show_mem();
 }
@@ -215,8 +207,7 @@ static void send_sig_all(int sig)
        }
 }
 
-static void sysrq_handle_term(int key, struct pt_regs *pt_regs,
-                             struct tty_struct *tty)
+static void sysrq_handle_term(int key, struct tty_struct *tty)
 {
        send_sig_all(SIGTERM);
        console_loglevel = 8;
@@ -236,8 +227,7 @@ static void moom_callback(void *ignored)
 
 static DECLARE_WORK(moom_work, moom_callback, NULL);
 
-static void sysrq_handle_moom(int key, struct pt_regs *pt_regs,
-                             struct tty_struct *tty)
+static void sysrq_handle_moom(int key, struct tty_struct *tty)
 {
        schedule_work(&moom_work);
 }
@@ -247,8 +237,7 @@ static struct sysrq_key_op sysrq_moom_op = {
        .action_msg     = "Manual OOM execution",
 };
 
-static void sysrq_handle_kill(int key, struct pt_regs *pt_regs,
-                             struct tty_struct *tty)
+static void sysrq_handle_kill(int key, struct tty_struct *tty)
 {
        send_sig_all(SIGKILL);
        console_loglevel = 8;
@@ -260,8 +249,7 @@ static struct sysrq_key_op sysrq_kill_op = {
        .enable_mask    = SYSRQ_ENABLE_SIGNAL,
 };
 
-static void sysrq_handle_unrt(int key, struct pt_regs *pt_regs,
-                               struct tty_struct *tty)
+static void sysrq_handle_unrt(int key, struct tty_struct *tty)
 {
        normalize_rt_tasks();
 }
@@ -361,8 +349,7 @@ static void __sysrq_put_key_op(int key, struct sysrq_key_op *op_p)
  * This is the non-locking version of handle_sysrq.  It must/can only be called
  * by sysrq key handlers, as they are inside of the lock
  */
-void __handle_sysrq(int key, struct pt_regs *pt_regs, struct tty_struct *tty,
-                       int check_mask)
+void __handle_sysrq(int key, struct tty_struct *tty, int check_mask)
 {
        struct sysrq_key_op *op_p;
        int orig_log_level;
@@ -384,7 +371,7 @@ void __handle_sysrq(int key, struct pt_regs *pt_regs, struct tty_struct *tty,
                    (sysrq_enabled & op_p->enable_mask)) {
                        printk("%s\n", op_p->action_msg);
                        console_loglevel = orig_log_level;
-                       op_p->handler(key, pt_regs, tty);
+                       op_p->handler(key, tty);
                } else {
                        printk("This sysrq operation is disabled.\n");
                }
@@ -413,11 +400,11 @@ void __handle_sysrq(int key, struct pt_regs *pt_regs, struct tty_struct *tty,
  * This function is called by the keyboard handler when SysRq is pressed
  * and any other keycode arrives.
  */
-void handle_sysrq(int key, struct pt_regs *pt_regs, struct tty_struct *tty)
+void handle_sysrq(int key, struct tty_struct *tty)
 {
        if (!sysrq_enabled)
                return;
-       __handle_sysrq(key, pt_regs, tty, 1);
+       __handle_sysrq(key, tty, 1);
 }
 EXPORT_SYMBOL(handle_sysrq);
 
index d2c5ba4e83b8bcdada44f028b0dfe9dd93952222..2444a0e24b3106bedabb9f00d6dcdda5b4be81b7 100644 (file)
@@ -193,7 +193,7 @@ static DEFINE_SPINLOCK(event_lock);
 
 static int tlclk_major = TLCLK_MAJOR;
 
-static irqreturn_t tlclk_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t tlclk_interrupt(int irq, void *dev_id);
 
 static DECLARE_WAIT_QUEUE_HEAD(wq);
 
@@ -856,7 +856,7 @@ static void switchover_timeout(unsigned long data)
        wake_up(&wq);
 }
 
-static irqreturn_t tlclk_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t tlclk_interrupt(int irq, void *dev_id)
 {
        unsigned long flags;
 
index a082a2e342522a78edfd642f272784bd1fbee276..6ad2d3bb945c06fc2dc86d92eaa8d2fa410c0308 100644 (file)
@@ -1153,7 +1153,14 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, const struct tpm_vend
 
        spin_unlock(&driver_lock);
 
-       sysfs_create_group(&dev->kobj, chip->vendor.attr_group);
+       if (sysfs_create_group(&dev->kobj, chip->vendor.attr_group)) {
+               list_del(&chip->list);
+               put_device(dev);
+               clear_bit(chip->dev_num, dev_mask);
+               kfree(chip);
+               kfree(devname);
+               return NULL;
+       }
 
        chip->bios_dir = tpm_bios_log_setup(devname);
 
index ad8ffe49256f75990e45a535b534851133eb8526..1ab0896070be2fa7cbc97006de065f5b27ef85dc 100644 (file)
@@ -184,7 +184,9 @@ static int __init init_atmel(void)
        unsigned long base;
        struct  tpm_chip *chip;
 
-       driver_register(&atml_drv);
+       rc = driver_register(&atml_drv);
+       if (rc)
+               return rc;
 
        if ((iobase = atmel_get_base_addr(&base, &region_size)) == NULL) {
                rc = -ENODEV;
@@ -195,10 +197,8 @@ static int __init init_atmel(void)
            (atmel_request_region
             (tpm_atmel.base, region_size, "tpm_atmel0") == NULL) ? 0 : 1;
 
-
-       if (IS_ERR
-           (pdev =
-            platform_device_register_simple("tpm_atmel", -1, NULL, 0))) {
+       pdev = platform_device_register_simple("tpm_atmel", -1, NULL, 0);
+       if (IS_ERR(pdev)) {
                rc = PTR_ERR(pdev);
                goto err_rel_reg;
        }
index 26287aace87db5376bd7a48b18d37ba03564937f..608f73071bef91acbdbcb93d6bf17a7527d9a26a 100644 (file)
@@ -284,7 +284,7 @@ static struct device_driver nsc_drv = {
 static int __init init_nsc(void)
 {
        int rc = 0;
-       int lo, hi;
+       int lo, hi, err;
        int nscAddrBase = TPM_ADDR;
        struct tpm_chip *chip;
        unsigned long base;
@@ -297,7 +297,9 @@ static int __init init_nsc(void)
                        return -ENODEV;
        }
 
-       driver_register(&nsc_drv);
+       err = driver_register(&nsc_drv);
+       if (err)
+               return err;
 
        hi = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_HI);
        lo = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_LO);
index ee7ac6f43c653bd49d7f4f3ac8649b54c092c24a..483f3f60013c70c48df984a840a7bd416fd5658c 100644 (file)
@@ -377,7 +377,7 @@ static struct tpm_vendor_specific tpm_tis = {
                    .fops = &tis_ops,},
 };
 
-static irqreturn_t tis_int_probe(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t tis_int_probe(int irq, void *dev_id)
 {
        struct tpm_chip *chip = (struct tpm_chip *) dev_id;
        u32 interrupt;
@@ -397,7 +397,7 @@ static irqreturn_t tis_int_probe(int irq, void *dev_id, struct pt_regs *regs)
        return IRQ_HANDLED;
 }
 
-static irqreturn_t tis_int_handler(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t tis_int_handler(int irq, void *dev_id)
 {
        struct tpm_chip *chip = (struct tpm_chip *) dev_id;
        u32 interrupt;
index a362ee9c92ddb68305cf0d2b6ba2ef2c89932301..6d2e314860df52f32314f66eb830c981af7dd1b8 100644 (file)
@@ -947,7 +947,7 @@ static void vioHandleData(struct HvLpEvent *event)
                                 */
                                continue;
                        } else if (vio_sysrq_pressed) {
-                               handle_sysrq(cevent->data[index], NULL, tty);
+                               handle_sysrq(cevent->data[index], tty);
                                vio_sysrq_pressed = 0;
                                /*
                                 * continue because we don't want to add
index c2ca31eb850ba034b9c7e9f27f06c9e15086d422..d0b94dd1af6da1253aeadf7c92d570d28c709982 100644 (file)
@@ -81,10 +81,10 @@ static int scc_ioctl(struct tty_struct * tty, struct file * filp,
                      unsigned int cmd, unsigned long arg);
 static void scc_throttle(struct tty_struct *tty);
 static void scc_unthrottle(struct tty_struct *tty);
-static irqreturn_t scc_tx_int(int irq, void *data, struct pt_regs *fp);
-static irqreturn_t scc_rx_int(int irq, void *data, struct pt_regs *fp);
-static irqreturn_t scc_stat_int(int irq, void *data, struct pt_regs *fp);
-static irqreturn_t scc_spcond_int(int irq, void *data, struct pt_regs *fp);
+static irqreturn_t scc_tx_int(int irq, void *data);
+static irqreturn_t scc_rx_int(int irq, void *data);
+static irqreturn_t scc_stat_int(int irq, void *data);
+static irqreturn_t scc_spcond_int(int irq, void *data);
 static void scc_setsignals(struct scc_port *port, int dtr, int rts);
 static void scc_break_ctl(struct tty_struct *tty, int break_state);
 
@@ -419,7 +419,7 @@ module_init(vme_scc_init);
  * Interrupt handlers
  *--------------------------------------------------------------------------*/
 
-static irqreturn_t scc_rx_int(int irq, void *data, struct pt_regs *fp)
+static irqreturn_t scc_rx_int(int irq, void *data)
 {
        unsigned char   ch;
        struct scc_port *port = data;
@@ -440,7 +440,7 @@ static irqreturn_t scc_rx_int(int irq, void *data, struct pt_regs *fp)
         */
        if (SCCread(INT_PENDING_REG) &
            (port->channel == CHANNEL_A ? IPR_A_RX : IPR_B_RX)) {
-               scc_spcond_int (irq, data, fp);
+               scc_spcond_int (irq, data);
                return IRQ_HANDLED;
        }
 
@@ -451,7 +451,7 @@ static irqreturn_t scc_rx_int(int irq, void *data, struct pt_regs *fp)
 }
 
 
-static irqreturn_t scc_spcond_int(int irq, void *data, struct pt_regs *fp)
+static irqreturn_t scc_spcond_int(int irq, void *data)
 {
        struct scc_port *port = data;
        struct tty_struct *tty = port->gs.tty;
@@ -496,7 +496,7 @@ static irqreturn_t scc_spcond_int(int irq, void *data, struct pt_regs *fp)
 }
 
 
-static irqreturn_t scc_tx_int(int irq, void *data, struct pt_regs *fp)
+static irqreturn_t scc_tx_int(int irq, void *data)
 {
        struct scc_port *port = data;
        SCC_ACCESS_INIT(port);
@@ -538,7 +538,7 @@ static irqreturn_t scc_tx_int(int irq, void *data, struct pt_regs *fp)
 }
 
 
-static irqreturn_t scc_stat_int(int irq, void *data, struct pt_regs *fp)
+static irqreturn_t scc_stat_int(int irq, void *data)
 {
        struct scc_port *port = data;
        unsigned channel = port->channel;
@@ -593,7 +593,7 @@ static void scc_enable_tx_interrupts(void *ptr)
        local_irq_save(flags);
        SCCmod(INT_AND_DMA_REG, 0xff, IDR_TX_INT_ENAB);
        /* restart the transmitter */
-       scc_tx_int (0, port, 0);
+       scc_tx_int (0, port);
        local_irq_restore(flags);
 }
 
index 8116a47b80f4c4e757b49286bff58d98390ff9a0..8e794930517111ec3013f79f0f486c1ad7998265 100644 (file)
@@ -221,7 +221,7 @@ static struct hw_interrupt_type giuint_high_irq_type = {
        .end            = end_giuint_high_irq,
 };
 
-static int giu_get_irq(unsigned int irq, struct pt_regs *regs)
+static int giu_get_irq(unsigned int irq)
 {
        uint16_t pendl, pendh, maskl, maskh;
        int i;
index 5948863b592b7434d57117dadc381a7584c113be..bf25d0a55a9954f9683a28c301a918cff349c5e1 100644 (file)
@@ -77,7 +77,8 @@ static struct pci_dev *alim7101_pmu;
 
 static int nowayout = WATCHDOG_NOWAYOUT;
 module_param(nowayout, int, 0);
-MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
+                __stringify(CONFIG_WATCHDOG_NOWAYOUT) ")");
 
 /*
  *     Whack the dog
@@ -415,6 +416,16 @@ err_out:
 module_init(alim7101_wdt_init);
 module_exit(alim7101_wdt_unload);
 
+static struct pci_device_id alim7101_pci_tbl[] __devinitdata = {
+       { PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533,
+         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+       { PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101,
+         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+       { }
+};
+
+MODULE_DEVICE_TABLE(pci, alim7101_pci_tbl);
+
 MODULE_AUTHOR("Steve Hill");
 MODULE_DESCRIPTION("ALi M7101 PMU Computer Watchdog Timer driver");
 MODULE_LICENSE("GPL");
index 4f4269754c462fb21aa2573a23a1028323af98db..e228d6e173cead6243232be6a137c6f275776caa 100644 (file)
@@ -153,7 +153,7 @@ static void eurwdt_activate_timer(void)
  * Kernel methods.
  */
 
-static irqreturn_t eurwdt_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t eurwdt_interrupt(int irq, void *dev_id)
 {
        printk(KERN_CRIT "timeout WDT timeout\n");
 
index 02d336ace50477bdb85609329cebb44f6422efdb..3404a9c67f08c5b31e24ce3a2da324790ec6b1ef 100644 (file)
@@ -64,7 +64,7 @@ MODULE_PARM_DESC(mpcore_noboot, "MPcore watchdog action, set to 1 to ignore rebo
  *     This is the interrupt handler.  Note that we only use this
  *     in testing mode, so don't actually do a reboot here.
  */
-static irqreturn_t mpcore_wdt_fire(int irq, void *arg, struct pt_regs *regs)
+static irqreturn_t mpcore_wdt_fire(int irq, void *arg)
 {
        struct mpcore_wdt *wdt = arg;
 
index 77662cb0ac46e3962beb4f7d660ecaf16fc9bb4c..bda45334d802f71658147ee47968cf628aba617f 100644 (file)
@@ -158,7 +158,7 @@ static struct usb_driver usb_pcwd_driver = {
 };
 
 
-static void usb_pcwd_intr_done(struct urb *urb, struct pt_regs *regs)
+static void usb_pcwd_intr_done(struct urb *urb)
 {
        struct usb_pcwd_private *usb_pcwd = (struct usb_pcwd_private *)urb->context;
        unsigned char *data = usb_pcwd->intr_buffer;
index d54d0efe0756f675c441fce12a87eaee1565aa74..18cb050c38624b6eb76bc658849c8cecd107c950 100644 (file)
@@ -336,8 +336,7 @@ static struct miscdevice s3c2410wdt_miscdev = {
 
 /* interrupt handler code */
 
-static irqreturn_t s3c2410wdt_irq(int irqno, void *param,
-                                 struct pt_regs *regs)
+static irqreturn_t s3c2410wdt_irq(int irqno, void *param)
 {
        printk(KERN_INFO PFX "Watchdog timer expired!\n");
 
index 13f23f4a223347393173a86d7c4eb17648f5097a..517fbd8643f8f00a2b1970f8b7a63fb023f1fc38 100644 (file)
@@ -225,14 +225,13 @@ static int wdt_get_temperature(int *temperature)
  *     wdt_interrupt:
  *     @irq:           Interrupt number
  *     @dev_id:        Unused as we don't allow multiple devices.
- *     @regs:          Unused.
  *
  *     Handle an interrupt from the board. These are raised when the status
  *     map changes in what the board considers an interesting way. That means
  *     a failure condition occurring.
  */
 
-static irqreturn_t wdt_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t wdt_interrupt(int irq, void *dev_id)
 {
        /*
         *      Read the status register see what is up and
index 89a249e23fdee2b0377d3e5a04ade645ee7979bf..e4cf661dc890b4d05050e83a6191e6364986571e 100644 (file)
@@ -46,7 +46,7 @@ static unsigned long timer_alive;
 /*
  *     If the timer expires..
  */
-static void watchdog_fire(int irq, void *dev_id, struct pt_regs *regs)
+static void watchdog_fire(int irq, void *dev_id)
 {
        printk(KERN_CRIT "Watchdog: Would Reboot.\n");
        *CSR_TIMER4_CNTL = 0;
index 74d8cf836e13aa91fb11885dbb5e769ac5f2f49b..ce1261c5cbce9a7423ad0b0d3babcf74cc69dd59 100644 (file)
@@ -270,14 +270,13 @@ static int wdtpci_get_temperature(int *temperature)
  *     wdtpci_interrupt:
  *     @irq:           Interrupt number
  *     @dev_id:        Unused as we don't allow multiple devices.
- *     @regs:          Unused.
  *
  *     Handle an interrupt from the board. These are raised when the status
  *     map changes in what the board considers an interesting way. That means
  *     a failure condition occurring.
  */
 
-static irqreturn_t wdtpci_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t wdtpci_interrupt(int irq, void *dev_id)
 {
        /*
         *      Read the status register see what is up and
index 7ad3be8c0f49e4f0bfc1722418ba377e9712de74..7fcb77a9d0111855948d5a02003c2845e8f5a8b3 100644 (file)
@@ -54,8 +54,8 @@ static cycle_t acpi_pm_read_verified(void)
                v1 = read_pmtmr();
                v2 = read_pmtmr();
                v3 = read_pmtmr();
-       } while ((v1 > v2 && v1 < v3) || (v2 > v3 && v2 < v1)
-                       || (v3 > v1 && v3 < v2));
+       } while (unlikely((v1 > v2 && v1 < v3) || (v2 > v3 && v2 < v1)
+                         || (v3 > v1 && v3 < v2)));
 
        return (cycle_t)v2;
 }
@@ -138,6 +138,8 @@ static void __devinit acpi_pm_check_graylist(struct pci_dev *dev)
 }
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0,
                        acpi_pm_check_graylist);
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_LE,
+                       acpi_pm_check_graylist);
 #endif
 
 
index dbd4d6c3698e7761849dee0cb019ac7f3366c486..0358419a0e48b7870f044920ae318c6d50187ef3 100644 (file)
@@ -80,7 +80,7 @@ static int enumerate_dma_channels(struct ioat_device *device)
 
 static struct ioat_desc_sw *ioat_dma_alloc_descriptor(
        struct ioat_dma_chan *ioat_chan,
-       int flags)
+       gfp_t flags)
 {
        struct ioat_dma_descriptor *desc;
        struct ioat_desc_sw *desc_sw;
@@ -563,7 +563,7 @@ static struct pci_driver ioat_pci_drv = {
        .remove = __devexit_p(ioat_remove),
 };
 
-static irqreturn_t ioat_do_interrupt(int irq, void *data, struct pt_regs *regs)
+static irqreturn_t ioat_do_interrupt(int irq, void *data)
 {
        struct ioat_device *instance = data;
        unsigned long attnstatus;
@@ -686,7 +686,7 @@ static int __devinit ioat_probe(struct pci_dev *pdev,
 {
        int err;
        unsigned long mmio_start, mmio_len;
-       void *reg_base;
+       void __iomem *reg_base;
        struct ioat_device *device;
 
        err = pci_enable_device(pdev);
index a5d3b3644160f686c1737d429fd3a1ec3e64505f..62b26a9be4c9d01cb4d4abb364a1252d1c938c74 100644 (file)
@@ -44,7 +44,7 @@ extern struct list_head dma_client_list;
 
 struct ioat_device {
        struct pci_dev *pdev;
-       void *reg_base;
+       void __iomem *reg_base;
        struct pci_pool *dma_pool;
        struct pci_pool *completion_pool;
 
@@ -73,7 +73,7 @@ struct ioat_device {
 
 struct ioat_dma_chan {
 
-       void *reg_base;
+       void __iomem *reg_base;
 
        dma_cookie_t completed_cookie;
        unsigned long last_completion;
index 3a365e159d89d52df59b945d22bb7bd1408022f9..d944647c82c2e0dfc771fb286a3554569e0f487c 100644 (file)
@@ -226,14 +226,26 @@ static int __init eisa_init_device (struct eisa_root_device *root,
 
 static int __init eisa_register_device (struct eisa_device *edev)
 {
-       if (device_register (&edev->dev))
-               return -1;
+       int rc = device_register (&edev->dev);
+       if (rc)
+               return rc;
 
-       device_create_file (&edev->dev, &dev_attr_signature);
-       device_create_file (&edev->dev, &dev_attr_enabled);
-       device_create_file (&edev->dev, &dev_attr_modalias);
+       rc = device_create_file (&edev->dev, &dev_attr_signature);
+       if (rc) goto err_devreg;
+       rc = device_create_file (&edev->dev, &dev_attr_enabled);
+       if (rc) goto err_sig;
+       rc = device_create_file (&edev->dev, &dev_attr_modalias);
+       if (rc) goto err_enab;
 
        return 0;
+
+err_enab:
+       device_remove_file (&edev->dev, &dev_attr_enabled);
+err_sig:
+       device_remove_file (&edev->dev, &dev_attr_signature);
+err_devreg:
+       device_unregister(&edev->dev);
+       return rc;
 }
 
 static int __init eisa_request_resources (struct eisa_root_device *root,
index 3b07e0ca81cdf9b60ac26214d60c0a7169b33bfc..b09dfc78e5a2b10d34965ede7329ed7a8a311652 100644 (file)
@@ -334,7 +334,7 @@ update_out:
        }
 }
 
-static irqreturn_t soc_intr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t soc_intr(int irq, void *dev_id)
 {
        u32 cmd;
        unsigned long flags;
index 2b75edc5859d61dd6d62d883d2eec7e667005297..a6b1ae256e16b4006373233bb18afdce83d09d98 100644 (file)
@@ -404,7 +404,7 @@ update_out:
        }
 }
 
-static irqreturn_t socal_intr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t socal_intr(int irq, void *dev_id)
 {
        u32 cmd;
        unsigned long flags;
index 339f405ff708a999fa93018d400e4ebab2e52b25..1865b56fb141643878b50b4874c4be56f612ff0c 100644 (file)
@@ -8,7 +8,7 @@
  *
  *  See Documentation/dcdbas.txt for more information.
  *
- *  Copyright (C) 1995-2005 Dell Inc.
+ *  Copyright (C) 1995-2006 Dell Inc.
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License v2.0 as published by
@@ -40,7 +40,7 @@
 #include "dcdbas.h"
 
 #define DRIVER_NAME            "dcdbas"
-#define DRIVER_VERSION         "5.6.0-2"
+#define DRIVER_VERSION         "5.6.0-3.2"
 #define DRIVER_DESCRIPTION     "Dell Systems Management Base Driver"
 
 static struct platform_device *dcdbas_pdev;
@@ -175,6 +175,9 @@ static ssize_t smi_data_write(struct kobject *kobj, char *buf, loff_t pos,
 {
        ssize_t ret;
 
+       if ((pos + count) > MAX_SMI_DATA_BUF_SIZE)
+               return -EINVAL;
+
        mutex_lock(&smi_data_lock);
 
        ret = smi_data_buf_realloc(pos + count);
@@ -559,7 +562,7 @@ static int __devinit dcdbas_probe(struct platform_device *dev)
                        while (--i >= 0)
                                sysfs_remove_bin_file(&dev->dev.kobj,
                                                      dcdbas_bin_attrs[i]);
-                       sysfs_create_group(&dev->dev.kobj, &dcdbas_attr_group);
+                       sysfs_remove_group(&dev->dev.kobj, &dcdbas_attr_group);
                        return error;
                }
        }
index fc17599c905e001f055cec284d52bd3e1f86a25f..08b16179844308ab80b4406638ff43927156cf3d 100644 (file)
@@ -249,7 +249,7 @@ static int packetize_data(void *data, size_t length)
                if ((rc = create_packet(temp, packet_length)))
                        return rc;
 
-               pr_debug("%p:%lu\n", temp, (end - temp));
+               pr_debug("%p:%td\n", temp, (end - temp));
                temp += packet_length;
        }
 
@@ -718,14 +718,27 @@ static int __init dcdrbu_init(void)
                return -EIO;
        }
 
-       sysfs_create_bin_file(&rbu_device->dev.kobj, &rbu_data_attr);
-       sysfs_create_bin_file(&rbu_device->dev.kobj, &rbu_image_type_attr);
-       sysfs_create_bin_file(&rbu_device->dev.kobj,
+       rc = sysfs_create_bin_file(&rbu_device->dev.kobj, &rbu_data_attr);
+       if (rc)
+               goto out_devreg;
+       rc = sysfs_create_bin_file(&rbu_device->dev.kobj, &rbu_image_type_attr);
+       if (rc)
+               goto out_data;
+       rc = sysfs_create_bin_file(&rbu_device->dev.kobj,
                &rbu_packet_size_attr);
+       if (rc)
+               goto out_imtype;
 
        rbu_data.entry_created = 0;
-       return rc;
+       return 0;
 
+out_imtype:
+       sysfs_remove_bin_file(&rbu_device->dev.kobj, &rbu_image_type_attr);
+out_data:
+       sysfs_remove_bin_file(&rbu_device->dev.kobj, &rbu_data_attr);
+out_devreg:
+       platform_device_unregister(rbu_device);
+       return rc;
 }
 
 static __exit void dcdrbu_exit(void)
index b8b596d5778dbe03295395eccbad2176a25c3bfa..37deee6c0c1cc5aa4ca575797dea77d6ad792243 100644 (file)
@@ -326,6 +326,26 @@ char *dmi_get_system_info(int field)
 }
 EXPORT_SYMBOL(dmi_get_system_info);
 
+
+/**
+ *     dmi_name_in_vendors - Check if string is anywhere in the DMI vendor information.
+ *     @str:   Case sensitive Name
+ */
+int dmi_name_in_vendors(char *str)
+{
+       static int fields[] = { DMI_BIOS_VENDOR, DMI_BIOS_VERSION, DMI_SYS_VENDOR,
+                               DMI_PRODUCT_NAME, DMI_PRODUCT_VERSION, DMI_BOARD_VENDOR,
+                               DMI_BOARD_NAME, DMI_BOARD_VERSION, DMI_NONE };
+       int i;
+       for (i = 0; fields[i] != DMI_NONE; i++) {
+               int f = fields[i];
+               if (dmi_ident[f] && strstr(dmi_ident[f], str))
+                       return 1;
+       }
+       return 0;
+}
+EXPORT_SYMBOL(dmi_name_in_vendors);
+
 /**
  *     dmi_find_device - find onboard device by type/name
  *     @type: device type or %DMI_DEV_TYPE_ANY to match all device types
index 8ebce1c03ad77f887038924590ecfc009f782b1d..5ab5e393b882810556d80c6c7fa5071e444362b3 100644 (file)
@@ -639,7 +639,12 @@ efivar_create_sysfs_entry(unsigned long variable_name_size,
 
        kobject_set_name(&new_efivar->kobj, "%s", short_name);
        kobj_set_kset_s(new_efivar, vars_subsys);
-       kobject_register(&new_efivar->kobj);
+       i = kobject_register(&new_efivar->kobj);
+       if (i) {
+               kfree(short_name);
+               kfree(new_efivar);
+               return 1;
+       }
 
        kfree(short_name);
        short_name = NULL;
index 9b88b25b6edbdfb098dc189c1e54c0efb60e5b4b..e76d91906c99a3ab671dbb9e0736e3e197901efc 100644 (file)
@@ -95,11 +95,13 @@ config SENSORS_ADM9240
          will be called adm9240.
 
 config SENSORS_K8TEMP
-       tristate "AMD K8 processor sensor"
+       tristate "AMD Athlon64/FX or Opteron temperature sensor"
        depends on HWMON && X86 && PCI && EXPERIMENTAL
        help
          If you say yes here you get support for the temperature
-         sensor(s) inside your AMD K8 CPU.
+         sensor(s) inside your CPU. Supported is whole AMD K8
+         microarchitecture. Please note that you will need at least
+         lm-sensors 2.10.1 for proper userspace support.
 
          This driver can also be built as a module.  If so, the module
          will be called k8temp.
@@ -369,8 +371,8 @@ config SENSORS_SMSC47M1
        help
          If you say yes here you get support for the integrated fan
          monitoring and control capabilities of the SMSC LPC47B27x,
-         LPC47M10x, LPC47M13x, LPC47M14x, LPC47M15x, LPC47M192 and
-         LPC47M997 chips.
+         LPC47M10x, LPC47M112, LPC47M13x, LPC47M14x, LPC47M15x,
+         LPC47M192 and LPC47M997 chips.
 
          The temperature and voltage sensor features of the LPC47M192
          and LPC47M997 are supported by another driver, select also
index 377961c4a41eb7f737681388418324757a48e0e1..aad594adf0c726ab220967562ae89d99e5c0937d 100644 (file)
@@ -5,7 +5,7 @@
  * Copyright (C) 1999  Frodo Looijaard <frodol@dds.nl>
  *                     Philip Edelbrock <phil@netroedge.com>
  * Copyright (C) 2003  Michiel Rook <michiel@grendelproject.nl>
- * Copyright (C) 2005  Grant Coady <gcoady@gmail.com> with valuable
+ * Copyright (C) 2005  Grant Coady <gcoady.lk@gmail.com> with valuable
  *                             guidance from Jean Delvare
  *
  * Driver supports     Analog Devices          ADM9240
@@ -774,7 +774,7 @@ static void __exit sensors_adm9240_exit(void)
 }
 
 MODULE_AUTHOR("Michiel Rook <michiel@grendelproject.nl>, "
-               "Grant Coady <gcoady@gmail.com> and others");
+               "Grant Coady <gcoady.lk@gmail.com> and others");
 MODULE_DESCRIPTION("ADM9240/DS1780/LM81 driver");
 MODULE_LICENSE("GPL");
 
index ac1b746df6d0ad765b97bcb2fd77cb5bb99dabcb..73bc2ffc598d2cabf66664f34b43b9f9dbb2d9ce 100644 (file)
@@ -815,18 +815,18 @@ static int __init sm_lm78_init(void)
        if (res)
                return res;
 
-       res = i2c_isa_add_driver(&lm78_isa_driver);
-       if (res) {
-               i2c_del_driver(&lm78_driver);
-               return res;
-       }
+       /* Don't exit if this one fails, we still want the I2C variants
+          to work! */
+       if (i2c_isa_add_driver(&lm78_isa_driver))
+               isa_address = 0;
 
        return 0;
 }
 
 static void __exit sm_lm78_exit(void)
 {
-       i2c_isa_del_driver(&lm78_isa_driver);
+       if (isa_address)
+               i2c_isa_del_driver(&lm78_isa_driver);
        i2c_del_driver(&lm78_driver);
 }
 
index 47132fd26b1bf9a4f1948864fe95a34ecb5afdf2..beb881c4b2e8ce1f2c191f6ce2343655a0e57200 100644 (file)
@@ -2,8 +2,8 @@
     smsc47m1.c - Part of lm_sensors, Linux kernel modules
                  for hardware monitoring
 
-    Supports the SMSC LPC47B27x, LPC47M10x, LPC47M13x, LPC47M14x,
-    LPC47M15x, LPC47M192 and LPC47M997 Super-I/O chips.
+    Supports the SMSC LPC47B27x, LPC47M10x, LPC47M112, LPC47M13x,
+    LPC47M14x, LPC47M15x, LPC47M192 and LPC47M997 Super-I/O chips.
 
     Copyright (C) 2002 Mark D. Studebaker <mdsxyz123@yahoo.com>
     Copyright (C) 2004 Jean Delvare <khali@linux-fr.org>
@@ -380,8 +380,8 @@ static int __init smsc47m1_find(unsigned short *addr)
        val = superio_inb(SUPERIO_REG_DEVID);
 
        /*
-        * SMSC LPC47M10x/LPC47M13x (device id 0x59), LPC47M14x (device id
-        * 0x5F) and LPC47B27x (device id 0x51) have fan control.
+        * SMSC LPC47M10x/LPC47M112/LPC47M13x (device id 0x59), LPC47M14x
+        * (device id 0x5F) and LPC47B27x (device id 0x51) have fan control.
         * The LPC47M15x and LPC47M192 chips "with hardware monitoring block"
         * can do much more besides (device id 0x60).
         * The LPC47M997 is undocumented, but seems to be compatible with
@@ -390,7 +390,8 @@ static int __init smsc47m1_find(unsigned short *addr)
        if (val == 0x51)
                printk(KERN_INFO "smsc47m1: Found SMSC LPC47B27x\n");
        else if (val == 0x59)
-               printk(KERN_INFO "smsc47m1: Found SMSC LPC47M10x/LPC47M13x\n");
+               printk(KERN_INFO "smsc47m1: Found SMSC "
+                      "LPC47M10x/LPC47M112/LPC47M13x\n");
        else if (val == 0x5F)
                printk(KERN_INFO "smsc47m1: Found SMSC LPC47M14x\n");
        else if (val == 0x60)
index 833faa275ffaed22b8eb5caa57172a965595ca7a..2257806d0102b203bff43aa3e3c73530c7ef49dc 100644 (file)
@@ -354,6 +354,8 @@ static void w83627ehf_write_fan_div(struct i2c_client *client, int nr)
        case 0:
                reg = (w83627ehf_read_value(client, W83627EHF_REG_FANDIV1) & 0xcf)
                    | ((data->fan_div[0] & 0x03) << 4);
+               /* fan5 input control bit is write only, compute the value */
+               reg |= (data->has_fan & (1 << 4)) ? 1 : 0;
                w83627ehf_write_value(client, W83627EHF_REG_FANDIV1, reg);
                reg = (w83627ehf_read_value(client, W83627EHF_REG_VBAT) & 0xdf)
                    | ((data->fan_div[0] & 0x04) << 3);
@@ -362,6 +364,8 @@ static void w83627ehf_write_fan_div(struct i2c_client *client, int nr)
        case 1:
                reg = (w83627ehf_read_value(client, W83627EHF_REG_FANDIV1) & 0x3f)
                    | ((data->fan_div[1] & 0x03) << 6);
+               /* fan5 input control bit is write only, compute the value */
+               reg |= (data->has_fan & (1 << 4)) ? 1 : 0;
                w83627ehf_write_value(client, W83627EHF_REG_FANDIV1, reg);
                reg = (w83627ehf_read_value(client, W83627EHF_REG_VBAT) & 0xbf)
                    | ((data->fan_div[1] & 0x04) << 4);
@@ -1216,13 +1220,16 @@ static int w83627ehf_detect(struct i2c_adapter *adapter)
        superio_exit();
 
        /* It looks like fan4 and fan5 pins can be alternatively used
-          as fan on/off switches */
+          as fan on/off switches, but fan5 control is write only :/
+          We assume that if the serial interface is disabled, designers
+          connected fan5 as input unless they are emitting log 1, which
+          is not the default. */
 
        data->has_fan = 0x07; /* fan1, fan2 and fan3 */
        i = w83627ehf_read_value(client, W83627EHF_REG_FANDIV1);
        if ((i & (1 << 2)) && (!fan4pin))
                data->has_fan |= (1 << 3);
-       if ((i & (1 << 0)) && (!fan5pin))
+       if (!(i & (1 << 1)) && (!fan5pin))
                data->has_fan |= (1 << 4);
 
        /* Register sysfs hooks */
index a4584ec69842fba9910d234fc6c80bb58b2a357f..1232171c3aad804a97320e0a909bd1fa6ee3d362 100644 (file)
@@ -1099,7 +1099,8 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
           bank. */
        if (kind < 0) {
                if (w83781d_read_value(client, W83781D_REG_CONFIG) & 0x80) {
-                       dev_dbg(dev, "Detection failed at step 3\n");
+                       dev_dbg(&adapter->dev, "Detection of w83781d chip "
+                               "failed at step 3\n");
                        err = -ENODEV;
                        goto ERROR2;
                }
@@ -1109,7 +1110,8 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
                if ((!(val1 & 0x07)) &&
                    (((!(val1 & 0x80)) && (val2 != 0xa3) && (val2 != 0xc3))
                     || ((val1 & 0x80) && (val2 != 0x5c) && (val2 != 0x12)))) {
-                       dev_dbg(dev, "Detection failed at step 4\n");
+                       dev_dbg(&adapter->dev, "Detection of w83781d chip "
+                               "failed at step 4\n");
                        err = -ENODEV;
                        goto ERROR2;
                }
@@ -1119,7 +1121,8 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
                                  ((val1 & 0x80) && (val2 == 0x5c)))) {
                        if (w83781d_read_value
                            (client, W83781D_REG_I2C_ADDR) != address) {
-                               dev_dbg(dev, "Detection failed at step 5\n");
+                               dev_dbg(&adapter->dev, "Detection of w83781d "
+                                       "chip failed at step 5\n");
                                err = -ENODEV;
                                goto ERROR2;
                        }
@@ -1141,8 +1144,8 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
                else if (val2 == 0x12)
                        vendid = asus;
                else {
-                       dev_dbg(dev, "Chip was made by neither "
-                               "Winbond nor Asus?\n");
+                       dev_dbg(&adapter->dev, "w83781d chip vendor is "
+                               "neither Winbond nor Asus\n");
                        err = -ENODEV;
                        goto ERROR2;
                }
@@ -1161,10 +1164,9 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
                        kind = as99127f;
                else {
                        if (kind == 0)
-                               dev_warn(dev, "Ignoring 'force' "
+                               dev_warn(&adapter->dev, "Ignoring 'force' "
                                         "parameter for unknown chip at "
-                                        "adapter %d, address 0x%02x\n",
-                                        i2c_adapter_id(adapter), address);
+                                        "address 0x%02x\n", address);
                        err = -EINVAL;
                        goto ERROR2;
                }
@@ -1685,11 +1687,10 @@ sensors_w83781d_init(void)
        if (res)
                return res;
 
-       res = i2c_isa_add_driver(&w83781d_isa_driver);
-       if (res) {
-               i2c_del_driver(&w83781d_driver);
-               return res;
-       }
+       /* Don't exit if this one fails, we still want the I2C variants
+          to work! */
+       if (i2c_isa_add_driver(&w83781d_isa_driver))
+               isa_address = 0;
 
        return 0;
 }
@@ -1697,7 +1698,8 @@ sensors_w83781d_init(void)
 static void __exit
 sensors_w83781d_exit(void)
 {
-       i2c_isa_del_driver(&w83781d_isa_driver);
+       if (isa_address)
+               i2c_isa_del_driver(&w83781d_isa_driver);
        i2c_del_driver(&w83781d_driver);
 }
 
index 371ed4f69a97ea9f122b65ad489d74a2c60f210a..9e5f885368b4e3f8e697be2ef0138f9bc8eb03f0 100644 (file)
@@ -746,6 +746,52 @@ static ssize_t store_vrm_reg(struct device *dev,
 
 static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg);
 
+#define IN_UNIT_ATTRS(X) \
+       &sda_in_input[X].dev_attr.attr, \
+       &sda_in_min[X].dev_attr.attr,   \
+       &sda_in_max[X].dev_attr.attr
+
+#define FAN_UNIT_ATTRS(X) \
+       &sda_fan_input[X].dev_attr.attr,        \
+       &sda_fan_min[X].dev_attr.attr,          \
+       &sda_fan_div[X].dev_attr.attr
+
+#define TEMP_UNIT_ATTRS(X) \
+       &sda_temp_input[X].dev_attr.attr,       \
+       &sda_temp_max[X].dev_attr.attr,         \
+       &sda_temp_max_hyst[X].dev_attr.attr
+
+static struct attribute *w83791d_attributes[] = {
+       IN_UNIT_ATTRS(0),
+       IN_UNIT_ATTRS(1),
+       IN_UNIT_ATTRS(2),
+       IN_UNIT_ATTRS(3),
+       IN_UNIT_ATTRS(4),
+       IN_UNIT_ATTRS(5),
+       IN_UNIT_ATTRS(6),
+       IN_UNIT_ATTRS(7),
+       IN_UNIT_ATTRS(8),
+       IN_UNIT_ATTRS(9),
+       FAN_UNIT_ATTRS(0),
+       FAN_UNIT_ATTRS(1),
+       FAN_UNIT_ATTRS(2),
+       FAN_UNIT_ATTRS(3),
+       FAN_UNIT_ATTRS(4),
+       TEMP_UNIT_ATTRS(0),
+       TEMP_UNIT_ATTRS(1),
+       TEMP_UNIT_ATTRS(2),
+       &dev_attr_alarms.attr,
+       &sda_beep_ctrl[0].dev_attr.attr,
+       &sda_beep_ctrl[1].dev_attr.attr,
+       &dev_attr_cpu0_vid.attr,
+       &dev_attr_vrm.attr,
+       NULL
+};
+
+static const struct attribute_group w83791d_group = {
+       .attrs = w83791d_attributes,
+};
+
 /* This function is called when:
      * w83791d_driver is inserted (when this module is loaded), for each
        available adapter
@@ -967,41 +1013,20 @@ static int w83791d_detect(struct i2c_adapter *adapter, int address, int kind)
        }
 
        /* Register sysfs hooks */
+       if ((err = sysfs_create_group(&client->dev.kobj, &w83791d_group)))
+               goto error3;
+
+       /* Everything is ready, now register the working device */
        data->class_dev = hwmon_device_register(dev);
        if (IS_ERR(data->class_dev)) {
                err = PTR_ERR(data->class_dev);
-               goto error3;
+               goto error4;
        }
 
-       for (i = 0; i < NUMBER_OF_VIN; i++) {
-               device_create_file(dev, &sda_in_input[i].dev_attr);
-               device_create_file(dev, &sda_in_min[i].dev_attr);
-               device_create_file(dev, &sda_in_max[i].dev_attr);
-       }
-
-       for (i = 0; i < NUMBER_OF_FANIN; i++) {
-               device_create_file(dev, &sda_fan_input[i].dev_attr);
-               device_create_file(dev, &sda_fan_div[i].dev_attr);
-               device_create_file(dev, &sda_fan_min[i].dev_attr);
-       }
-
-       for (i = 0; i < NUMBER_OF_TEMPIN; i++) {
-               device_create_file(dev, &sda_temp_input[i].dev_attr);
-               device_create_file(dev, &sda_temp_max[i].dev_attr);
-               device_create_file(dev, &sda_temp_max_hyst[i].dev_attr);
-       }
-
-       device_create_file(dev, &dev_attr_alarms);
-
-       for (i = 0; i < ARRAY_SIZE(sda_beep_ctrl); i++) {
-               device_create_file(dev, &sda_beep_ctrl[i].dev_attr);
-       }
-
-       device_create_file(dev, &dev_attr_cpu0_vid);
-       device_create_file(dev, &dev_attr_vrm);
-
        return 0;
 
+error4:
+       sysfs_remove_group(&client->dev.kobj, &w83791d_group);
 error3:
        if (data->lm75[0] != NULL) {
                i2c_detach_client(data->lm75[0]);
@@ -1025,8 +1050,10 @@ static int w83791d_detach_client(struct i2c_client *client)
        int err;
 
        /* main client */
-       if (data)
+       if (data) {
                hwmon_device_unregister(data->class_dev);
+               sysfs_remove_group(&client->dev.kobj, &w83791d_group);
+       }
 
        if ((err = i2c_detach_client(client)))
                return err;
index caa8e5c8bfbbdc6f8d4cfc844b59237466867e6d..a591fe685f065dd972aa00bd46ed48d4c621d0b2 100644 (file)
@@ -131,7 +131,7 @@ static void pcf_isa_waitforpin(void) {
 }
 
 
-static irqreturn_t pcf_isa_handler(int this_irq, void *dev_id, struct pt_regs *regs) {
+static irqreturn_t pcf_isa_handler(int this_irq, void *dev_id) {
        spin_lock(&lock);
        pcf_pending = 1;
        spin_unlock(&lock);
index 80d4ba1bdfecd80e5edb400e046673de54026af4..781a99c1647a3875d06cab731bc022af8bd8c780 100644 (file)
@@ -320,7 +320,7 @@ err:
 /*
  * IIC interrupt handler
  */
-static irqreturn_t iic_handler(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t iic_handler(int irq, void *dev_id)
 {
        struct ibm_iic_private* dev = (struct ibm_iic_private*)dev_id;
        volatile struct iic_regs __iomem *iic = dev->vaddr;
index 4436c89be58eb838c6b05dba1ecffecbc8fb18b0..d108ab4974cc222bfb433b585868ba6b2f48b3af 100644 (file)
@@ -120,7 +120,7 @@ iop3xx_i2c_transaction_cleanup(struct i2c_algo_iop3xx_data *iop3xx_adap)
  * Then it passes the SR flags of interest to BH via adap data
  */
 static irqreturn_t 
-iop3xx_i2c_irq_handler(int this_irq, void *dev_id, struct pt_regs *regs
+iop3xx_i2c_irq_handler(int this_irq, void *dev_id) 
 {
        struct i2c_algo_iop3xx_data *iop3xx_adap = dev_id;
        u32 sr = __raw_readl(iop3xx_adap->ioaddr + SR_OFFSET);
index 4380653748a4c155065bb057148f91e1e1b7eddd..8ed59a2dff532124afc6e899f1df3d6a4622f106 100644 (file)
@@ -91,7 +91,7 @@ int i2c_isa_add_driver(struct i2c_driver *driver)
        /* Now look for clients */
        res = driver->attach_adapter(&isa_adapter);
        if (res) {
-               dev_err(&isa_adapter.dev,
+               dev_dbg(&isa_adapter.dev,
                        "Driver %s failed to attach adapter, unregistering\n",
                        driver->driver.name);
                driver_unregister(&driver->driver);
index 559a62b04ee9aa0269c69ae6104725b53aabe783..f7d71869b3b90a73baf4ee1d43c5e444c7cf2a83 100644 (file)
@@ -140,8 +140,7 @@ static void iic_ite_waitforpin(void) {
 }
 
 
-static irqreturn_t iic_ite_handler(int this_irq, void *dev_id,
-                                                       struct pt_regs *regs)
+static irqreturn_t iic_ite_handler(int this_irq, void *dev_id)
 {
        spin_lock(&lock);
        iic_pending = 1;
index 155a986de516616d2ed5d70074cb28240a1878dd..ee65aa1be13a95ac364567af0f7c0542af99af68 100644 (file)
@@ -63,7 +63,7 @@ static __inline__ void writeccr(struct mpc_i2c *i2c, u32 x)
        writeb(x, i2c->base + MPC_I2C_CR);
 }
 
-static irqreturn_t mpc_i2c_isr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t mpc_i2c_isr(int irq, void *dev_id)
 {
        struct mpc_i2c *i2c = dev_id;
        if (readb(i2c->base + MPC_I2C_SR) & CSR_MIF) {
index eacbaf745b64527798c74fc5ddd48acdbd8e11b6..bbc8e3a7ff556c1eb8306b56169f2e36c28d0f14 100644 (file)
@@ -278,7 +278,7 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data)
 }
 
 static int
-mv64xxx_i2c_intr(int irq, void *dev_id, struct pt_regs *regs)
+mv64xxx_i2c_intr(int irq, void *dev_id)
 {
        struct mv64xxx_i2c_data *drv_data = dev_id;
        unsigned long   flags;
index 3e276e958ef7de18d28d2937840635acf6ac5360..f28a76d1c0af2f0ee5bcc30f6dc65a363a0ac23d 100644 (file)
@@ -143,7 +143,7 @@ static void ocores_process(struct ocores_i2c *i2c)
        }
 }
 
-static irqreturn_t ocores_isr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t ocores_isr(int irq, void *dev_id)
 {
        struct ocores_i2c *i2c = dev_id;
 
index 81d87d2c2a2d6a177f3c2bbdb2dec083aa31e073..dec04da0455c1d4988f715b1868fb66a06512677 100644 (file)
@@ -400,7 +400,7 @@ omap_i2c_ack_stat(struct omap_i2c_dev *dev, u16 stat)
 }
 
 static irqreturn_t
-omap_i2c_rev1_isr(int this_irq, void *dev_id, struct pt_regs *regs)
+omap_i2c_rev1_isr(int this_irq, void *dev_id)
 {
        struct omap_i2c_dev *dev = dev_id;
        u16 iv, w;
@@ -452,7 +452,7 @@ omap_i2c_rev1_isr(int this_irq, void *dev_id, struct pt_regs *regs)
 }
 
 static irqreturn_t
-omap_i2c_isr(int this_irq, void *dev_id, struct pt_regs *regs)
+omap_i2c_isr(int this_irq, void *dev_id)
 {
        struct omap_i2c_dev *dev = dev_id;
        u16 bits;
index d9b4ddbad7e0471fde88ecf6ca51dbea35717162..407840b6a26040d2dbe26b7b32746041bb7be5b5 100644 (file)
@@ -99,7 +99,7 @@ static int pca_isa_waitforinterrupt(struct i2c_algo_pca_data *adap)
        return ret;
 }
 
-static irqreturn_t pca_handler(int this_irq, void *dev_id, struct pt_regs *regs) {
+static irqreturn_t pca_handler(int this_irq, void *dev_id) {
        wake_up_interruptible(&pca_wait);
        return IRQ_HANDLED;
 }
index a508cb962d244e89b4addc108f2c159212639364..648d55533d87e1a53a9b1d6a58bd21a7f17a77ab 100644 (file)
@@ -182,9 +182,9 @@ static const struct i2c_algorithm i2c_powermac_algorithm = {
 };
 
 
-static int i2c_powermac_remove(struct device *dev)
+static int i2c_powermac_remove(struct platform_device *dev)
 {
-       struct i2c_adapter      *adapter = dev_get_drvdata(dev);
+       struct i2c_adapter      *adapter = platform_get_drvdata(dev);
        struct pmac_i2c_bus     *bus = i2c_get_adapdata(adapter);
        int                     rc;
 
@@ -195,16 +195,16 @@ static int i2c_powermac_remove(struct device *dev)
        if (rc)
                printk("i2c-powermac.c: Failed to remove bus %s !\n",
                       adapter->name);
-       dev_set_drvdata(dev, NULL);
+       platform_set_drvdata(dev, NULL);
        kfree(adapter);
 
        return 0;
 }
 
 
-static int i2c_powermac_probe(struct device *dev)
+static int __devexit i2c_powermac_probe(struct platform_device *dev)
 {
-       struct pmac_i2c_bus *bus = dev->platform_data;
+       struct pmac_i2c_bus *bus = dev->dev.platform_data;
        struct device_node *parent = NULL;
        struct i2c_adapter *adapter;
        char name[32];
@@ -246,11 +246,11 @@ static int i2c_powermac_probe(struct device *dev)
                printk(KERN_ERR "i2c-powermac: can't allocate inteface !\n");
                return -ENOMEM;
        }
-       dev_set_drvdata(dev, adapter);
+       platform_set_drvdata(dev, adapter);
        strcpy(adapter->name, name);
        adapter->algo = &i2c_powermac_algorithm;
        i2c_set_adapdata(adapter, bus);
-       adapter->dev.parent = dev;
+       adapter->dev.parent = &dev->dev;
        pmac_i2c_attach_adapter(bus, adapter);
        rc = i2c_add_adapter(adapter);
        if (rc) {
@@ -265,23 +265,25 @@ static int i2c_powermac_probe(struct device *dev)
 }
 
 
-static struct device_driver i2c_powermac_driver = {
-       .name = "i2c-powermac",
-       .bus = &platform_bus_type,
+static struct platform_driver i2c_powermac_driver = {
        .probe = i2c_powermac_probe,
-       .remove = i2c_powermac_remove,
+       .remove = __devexit_p(i2c_powermac_remove),
+       .driver = {
+               .name = "i2c-powermac",
+               .bus = &platform_bus_type,
+       },
 };
 
 static int __init i2c_powermac_init(void)
 {
-       driver_register(&i2c_powermac_driver);
+       platform_driver_register(&i2c_powermac_driver);
        return 0;
 }
 
 
 static void __exit i2c_powermac_cleanup(void)
 {
-       driver_unregister(&i2c_powermac_driver);
+       platform_driver_unregister(&i2c_powermac_driver);
 }
 
 module_init(i2c_powermac_init);
index cd4ad98ad517f9f0315208564922dfef8d69fffe..81050d3c9b21935512f3db5f2a810245ebaafb4d 100644 (file)
@@ -850,7 +850,7 @@ static void i2c_pxa_irq_rxfull(struct pxa_i2c *i2c, u32 isr)
        ICR = icr;
 }
 
-static irqreturn_t i2c_pxa_handler(int this_irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t i2c_pxa_handler(int this_irq, void *dev_id)
 {
        struct pxa_i2c *i2c = dev_id;
        u32 isr = ISR;
index 0ebec3c1a54ef7426edcf1e8fcdde7d1d724994c..8764df06f51d57e282c9d88714a1dfcfafc6349a 100644 (file)
@@ -55,10 +55,10 @@ rpx_iic_init(struct i2c_algo_8xx_data *data)
        data->i2c = (i2c8xx_t *)&(((immap_t *)IMAP_ADDR)->im_i2c);
 }
 
-static int rpx_install_isr(int irq, void (*func)(void *, void *), void *data)
+static int rpx_install_isr(int irq, void (*func)(void *), void *data)
 {
        /* install interrupt handler */
-       cpm_install_handler(irq, (void (*)(void *, struct pt_regs *)) func, data);
+       cpm_install_handler(irq, func, data);
 
        return 0;
 }
index 9ebe429a0a0ffd2fc853b6268e5e1e0d1be1738d..4ca6de209b8b6225406f459f64969ef7db94fb25 100644 (file)
@@ -423,8 +423,7 @@ static int i2s_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat)
  * top level IRQ servicing routine
 */
 
-static irqreturn_t s3c24xx_i2c_irq(int irqno, void *dev_id,
-                                  struct pt_regs *regs)
+static irqreturn_t s3c24xx_i2c_irq(int irqno, void *dev_id)
 {
        struct s3c24xx_i2c *i2c = dev_id;
        unsigned long status;
index 182f04953466080e5f443e6b091bbbd2766a23ad..ccdf3e90862ba4b979736b6955113067c69c248f 100644 (file)
@@ -669,7 +669,7 @@ pulldown:
        dump_regs(isp, "otg->isp1301");
 }
 
-static irqreturn_t omap_otg_irq(int irq, void *_isp, struct pt_regs *regs)
+static irqreturn_t omap_otg_irq(int irq, void *_isp)
 {
        u16             otg_irq = OTG_IRQ_SRC_REG;
        u32             otg_ctrl;
@@ -1181,7 +1181,7 @@ isp1301_work(void *data)
        isp->working = 0;
 }
 
-static irqreturn_t isp1301_irq(int irq, void *isp, struct pt_regs *regs)
+static irqreturn_t isp1301_irq(int irq, void *isp)
 {
        isp1301_defer_work(isp, WORK_UPDATE_OTG);
        return IRQ_HANDLED;
index 6a7578217177ba4808f97dbbc35ebf45b68440f9..60bef94cd25f795892f0392f6d3493f86a3fa257 100644 (file)
@@ -446,7 +446,7 @@ static void tps65010_work(void *_tps)
        mutex_unlock(&tps->lock);
 }
 
-static irqreturn_t tps65010_irq(int irq, void *_tps, struct pt_regs *regs)
+static irqreturn_t tps65010_irq(int irq, void *_tps)
 {
        struct tps65010         *tps = _tps;
 
index 69bbb6206a00ef5673638c0ccfb4a59bfa272b1d..bddfebdf91d8aea8a14ee0c0de25e0016e74ef63 100644 (file)
@@ -597,7 +597,7 @@ static void cdrom_prepare_request(ide_drive_t *drive, struct request *rq)
        struct cdrom_info *cd = drive->driver_data;
 
        ide_init_drive_cmd(rq);
-       rq->cmd_type = REQ_TYPE_BLOCK_PC;
+       rq->cmd_type = REQ_TYPE_ATA_PC;
        rq->rq_disk = cd->disk;
 }
 
@@ -716,7 +716,7 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
                ide_error(drive, "request sense failure", stat);
                return 1;
 
-       } else if (blk_pc_request(rq)) {
+       } else if (blk_pc_request(rq) || rq->cmd_type == REQ_TYPE_ATA_PC) {
                /* All other functions, except for READ. */
                unsigned long flags;
 
@@ -2023,7 +2023,8 @@ ide_do_rw_cdrom (ide_drive_t *drive, struct request *rq, sector_t block)
                }
                info->last_block = block;
                return action;
-       } else if (rq->cmd_type == REQ_TYPE_SENSE) {
+       } else if (rq->cmd_type == REQ_TYPE_SENSE ||
+                  rq->cmd_type == REQ_TYPE_ATA_PC) {
                return cdrom_do_packet_command(drive);
        } else if (blk_pc_request(rq)) {
                return cdrom_do_block_pc(drive, rq);
index ba6039b55b41ebb348223db10dc4f9a9ea9cfd0e..2614f41b5074ea2d203767be2eefa6a4b5505f45 100644 (file)
@@ -1562,7 +1562,7 @@ static void unexpected_intr (int irq, ide_hwgroup_t *hwgroup)
  *     on the hwgroup and the process begins again.
  */
  
-irqreturn_t ide_intr (int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t ide_intr (int irq, void *dev_id)
 {
        unsigned long flags;
        ide_hwgroup_t *hwgroup = (ide_hwgroup_t *)dev_id;
index 1d0470c1f9579d262f0e93c2fcebab6dd89ad399..30175c7688e877016e0bd666bcfa4b8ca5e92ad4 100644 (file)
@@ -524,8 +524,8 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
        task_ioreg_t *hobsptr   = args.hobRegister;
        int err                 = 0;
        int tasksize            = sizeof(struct ide_task_request_s);
-       int taskin              = 0;
-       int taskout             = 0;
+       unsigned int taskin     = 0;
+       unsigned int taskout    = 0;
        u8 io_32bit             = drive->io_32bit;
        char __user *buf = (char __user *)arg;
 
@@ -538,8 +538,13 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
                return -EFAULT;
        }
 
-       taskout = (int) req_task->out_size;
-       taskin  = (int) req_task->in_size;
+       taskout = req_task->out_size;
+       taskin  = req_task->in_size;
+       
+       if (taskin > 65536 || taskout > 65536) {
+               err = -EINVAL;
+               goto abort;
+       }
 
        if (taskout) {
                int outtotal = tasksize;
index 4ab93114567389122323e22a413280216c5729d1..b1d5291531b7af2d8153c35e79e0ae0b9a3edf6b 100644 (file)
@@ -673,7 +673,7 @@ static int hd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
  * be forgotten about...
  */
 
-static irqreturn_t hd_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t hd_interrupt(int irq, void *dev_id)
 {
        void (*handler)(void) = do_hd;
 
index d655da749144e10d3fd8a04823a884e02852668a..b1730d7e414c3ec1f53ad1dfa71bf855d8131cc0 100644 (file)
@@ -78,7 +78,7 @@ int macide_ack_intr(ide_hwif_t* hwif)
 }
 
 #ifdef CONFIG_BLK_DEV_MAC_MEDIABAY
-static void macide_mediabay_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static void macide_mediabay_interrupt(int irq, void *dev_id)
 {
        int state = baboon->mb_status & 0x04;
 
index 66f6064f4640325007813fca1c479ce7992ec498..09c9e7936b0dff79c5d44f84732a003f910ca2f5 100644 (file)
@@ -4,6 +4,7 @@
  *     Author: Manish Lachwani, mlachwani@mvista.com
  * Copyright (C) 2004  MIPS Technologies, Inc.  All rights reserved.
  *     Author: Maciej W. Rozycki <macro@mips.com>
+ * Copyright (c) 2006  Maciej W. Rozycki
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -127,6 +128,7 @@ static int __devinit swarm_ide_probe(struct device *dev)
        memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports));
        hwif->irq = hwif->hw.irq;
 
+       probe_hwif_init(hwif);
        dev_set_drvdata(dev, hwif);
 
        return 0;
index 965c43659e35c60e807516d07621b3c254685a01..ad418ce882cae837a77537fc8e54f2b909bfac7f 100644 (file)
 
 static int ide_generic_all;            /* Set to claim all devices */
 
+/*
+ * the module_param_named() was added for the modular case
+ * the __setup() is left as compatibility for existing setups
+ */
+#ifndef MODULE
+static int __init ide_generic_all_on(char *unused)
+{
+       ide_generic_all = 1;
+       printk(KERN_INFO "IDE generic will claim all unknown PCI IDE storage controllers.");
+       return 1;
+}
+__setup("all-generic-ide", ide_generic_all_on);
+#endif
 module_param_named(all_generic_ide, ide_generic_all, bool, 0444);
 MODULE_PARM_DESC(all_generic_ide, "IDE generic will claim all unknown PCI IDE storage controllers.");
 
@@ -237,10 +250,12 @@ static int __devinit generic_init_one(struct pci_dev *dev, const struct pci_devi
        if (dev->vendor == PCI_VENDOR_ID_JMICRON && PCI_FUNC(dev->devfn) != 1)
                goto out;
 
-       pci_read_config_word(dev, PCI_COMMAND, &command);
-       if (!(command & PCI_COMMAND_IO)) {
-               printk(KERN_INFO "Skipping disabled %s IDE controller.\n", d->name);
-               goto out;
+       if (dev->vendor != PCI_VENDOR_ID_JMICRON) {
+               pci_read_config_word(dev, PCI_COMMAND, &command);
+               if (!(command & PCI_COMMAND_IO)) {
+                       printk(KERN_INFO "Skipping disabled %s IDE controller.\n", d->name);
+                       goto out;
+               }
        }
        ret = ide_setup_pci_device(dev, d);
 out:
index f3fe287fbd89ba6b5d65deb92b42ba1ca9f875e2..244f7eb7006d43ea5f7f691a170e93ff057fc6c0 100644 (file)
@@ -774,7 +774,7 @@ ioc4_ide_exit(void)
        ioc4_unregister_submodule(&ioc4_ide_submodule);
 }
 
-module_init(ioc4_ide_init);
+late_initcall(ioc4_ide_init); /* Call only after IDE init is done */
 module_exit(ioc4_ide_exit);
 
 MODULE_AUTHOR("Aniket Malatpure/Jeremy Higdon");
index 3e7974c5744326464e4f26eda25a4eef69e4468e..8e7b83f84485a1933b209d4017a74a288d19b64a 100644 (file)
@@ -1614,7 +1614,7 @@ static int nodemgr_host_thread(void *__hi)
 {
        struct host_info *hi = (struct host_info *)__hi;
        struct hpsb_host *host = hi->host;
-       unsigned int g, generation = get_hpsb_generation(host) - 1;
+       unsigned int g, generation = 0;
        int i, reset_cycles = 0;
 
        /* Setup our device-model entries */
index 8fd0030475ba70db16de13164e5af5aa293c0ed2..dea13525df88976337f6ac8acbbd17a9eb8c3747 100644 (file)
@@ -2301,8 +2301,7 @@ static void ohci_schedule_iso_tasklets(struct ti_ohci *ohci,
        spin_unlock_irqrestore(&ohci->iso_tasklet_list_lock, flags);
 }
 
-static irqreturn_t ohci_irq_handler(int irq, void *dev_id,
-                             struct pt_regs *regs_are_unused)
+static irqreturn_t ohci_irq_handler(int irq, void *dev_id)
 {
        quadlet_t event, node_id;
        struct ti_ohci *ohci = (struct ti_ohci *)dev_id;
index b4f146f2c951c9f7f2f208d8ec972d29e95f77eb..0a7412e27eb49bf18e67408c81b6c56b4192346e 100644 (file)
@@ -839,8 +839,7 @@ static int lynx_devctl(struct hpsb_host *host, enum devctl_cmd cmd, int arg)
  ********************************************************/
 
 
-static irqreturn_t lynx_irq_handler(int irq, void *dev_id,
-                             struct pt_regs *regs_are_unused)
+static irqreturn_t lynx_irq_handler(int irq, void *dev_id)
 {
         struct ti_lynx *lynx = (struct ti_lynx *)dev_id;
         struct hpsb_host *host = lynx->host;
index f35fcc4c06389e77f260254cd8b2943b6e5d77de..25b1018a476ceecb71739909324c11257d998fae 100644 (file)
@@ -75,6 +75,7 @@ static struct ib_cm {
        struct rb_root remote_sidr_table;
        struct idr local_id_table;
        __be32 random_id_operand;
+       struct list_head timewait_list;
        struct workqueue_struct *wq;
 } cm;
 
@@ -112,6 +113,7 @@ struct cm_work {
 
 struct cm_timewait_info {
        struct cm_work work;                    /* Must be first. */
+       struct list_head list;
        struct rb_node remote_qp_node;
        struct rb_node remote_id_node;
        __be64 remote_ca_guid;
@@ -647,13 +649,6 @@ static inline int cm_convert_to_ms(int iba_time)
 
 static void cm_cleanup_timewait(struct cm_timewait_info *timewait_info)
 {
-       unsigned long flags;
-
-       if (!timewait_info->inserted_remote_id &&
-           !timewait_info->inserted_remote_qp)
-           return;
-
-       spin_lock_irqsave(&cm.lock, flags);
        if (timewait_info->inserted_remote_id) {
                rb_erase(&timewait_info->remote_id_node, &cm.remote_id_table);
                timewait_info->inserted_remote_id = 0;
@@ -663,7 +658,6 @@ static void cm_cleanup_timewait(struct cm_timewait_info *timewait_info)
                rb_erase(&timewait_info->remote_qp_node, &cm.remote_qp_table);
                timewait_info->inserted_remote_qp = 0;
        }
-       spin_unlock_irqrestore(&cm.lock, flags);
 }
 
 static struct cm_timewait_info * cm_create_timewait_info(__be32 local_id)
@@ -684,8 +678,12 @@ static struct cm_timewait_info * cm_create_timewait_info(__be32 local_id)
 static void cm_enter_timewait(struct cm_id_private *cm_id_priv)
 {
        int wait_time;
+       unsigned long flags;
 
+       spin_lock_irqsave(&cm.lock, flags);
        cm_cleanup_timewait(cm_id_priv->timewait_info);
+       list_add_tail(&cm_id_priv->timewait_info->list, &cm.timewait_list);
+       spin_unlock_irqrestore(&cm.lock, flags);
 
        /*
         * The cm_id could be destroyed by the user before we exit timewait.
@@ -701,9 +699,13 @@ static void cm_enter_timewait(struct cm_id_private *cm_id_priv)
 
 static void cm_reset_to_idle(struct cm_id_private *cm_id_priv)
 {
+       unsigned long flags;
+
        cm_id_priv->id.state = IB_CM_IDLE;
        if (cm_id_priv->timewait_info) {
+               spin_lock_irqsave(&cm.lock, flags);
                cm_cleanup_timewait(cm_id_priv->timewait_info);
+               spin_unlock_irqrestore(&cm.lock, flags);
                kfree(cm_id_priv->timewait_info);
                cm_id_priv->timewait_info = NULL;
        }
@@ -1307,6 +1309,7 @@ static struct cm_id_private * cm_match_req(struct cm_work *work,
        if (timewait_info) {
                cur_cm_id_priv = cm_get_id(timewait_info->work.local_id,
                                           timewait_info->work.remote_id);
+               cm_cleanup_timewait(cm_id_priv->timewait_info);
                spin_unlock_irqrestore(&cm.lock, flags);
                if (cur_cm_id_priv) {
                        cm_dup_req_handler(work, cur_cm_id_priv);
@@ -1315,7 +1318,8 @@ static struct cm_id_private * cm_match_req(struct cm_work *work,
                        cm_issue_rej(work->port, work->mad_recv_wc,
                                     IB_CM_REJ_STALE_CONN, CM_MSG_RESPONSE_REQ,
                                     NULL, 0);
-               goto error;
+               listen_cm_id_priv = NULL;
+               goto out;
        }
 
        /* Find matching listen request. */
@@ -1323,21 +1327,20 @@ static struct cm_id_private * cm_match_req(struct cm_work *work,
                                           req_msg->service_id,
                                           req_msg->private_data);
        if (!listen_cm_id_priv) {
+               cm_cleanup_timewait(cm_id_priv->timewait_info);
                spin_unlock_irqrestore(&cm.lock, flags);
                cm_issue_rej(work->port, work->mad_recv_wc,
                             IB_CM_REJ_INVALID_SERVICE_ID, CM_MSG_RESPONSE_REQ,
                             NULL, 0);
-               goto error;
+               goto out;
        }
        atomic_inc(&listen_cm_id_priv->refcount);
        atomic_inc(&cm_id_priv->refcount);
        cm_id_priv->id.state = IB_CM_REQ_RCVD;
        atomic_inc(&cm_id_priv->work_count);
        spin_unlock_irqrestore(&cm.lock, flags);
+out:
        return listen_cm_id_priv;
-
-error: cm_cleanup_timewait(cm_id_priv->timewait_info);
-       return NULL;
 }
 
 static int cm_req_handler(struct cm_work *work)
@@ -1899,6 +1902,32 @@ out:     spin_unlock_irqrestore(&cm_id_priv->lock, flags);
 }
 EXPORT_SYMBOL(ib_send_cm_drep);
 
+static int cm_issue_drep(struct cm_port *port,
+                        struct ib_mad_recv_wc *mad_recv_wc)
+{
+       struct ib_mad_send_buf *msg = NULL;
+       struct cm_dreq_msg *dreq_msg;
+       struct cm_drep_msg *drep_msg;
+       int ret;
+
+       ret = cm_alloc_response_msg(port, mad_recv_wc, &msg);
+       if (ret)
+               return ret;
+
+       dreq_msg = (struct cm_dreq_msg *) mad_recv_wc->recv_buf.mad;
+       drep_msg = (struct cm_drep_msg *) msg->mad;
+
+       cm_format_mad_hdr(&drep_msg->hdr, CM_DREP_ATTR_ID, dreq_msg->hdr.tid);
+       drep_msg->remote_comm_id = dreq_msg->local_comm_id;
+       drep_msg->local_comm_id = dreq_msg->remote_comm_id;
+
+       ret = ib_post_send_mad(msg, NULL);
+       if (ret)
+               cm_free_msg(msg);
+
+       return ret;
+}
+
 static int cm_dreq_handler(struct cm_work *work)
 {
        struct cm_id_private *cm_id_priv;
@@ -1910,8 +1939,10 @@ static int cm_dreq_handler(struct cm_work *work)
        dreq_msg = (struct cm_dreq_msg *)work->mad_recv_wc->recv_buf.mad;
        cm_id_priv = cm_acquire_id(dreq_msg->remote_comm_id,
                                   dreq_msg->local_comm_id);
-       if (!cm_id_priv)
+       if (!cm_id_priv) {
+               cm_issue_drep(work->port, work->mad_recv_wc);
                return -EINVAL;
+       }
 
        work->cm_event.private_data = &dreq_msg->private_data;
 
@@ -2601,28 +2632,29 @@ static int cm_timewait_handler(struct cm_work *work)
 {
        struct cm_timewait_info *timewait_info;
        struct cm_id_private *cm_id_priv;
-       unsigned long flags;
        int ret;
 
        timewait_info = (struct cm_timewait_info *)work;
-       cm_cleanup_timewait(timewait_info);
+       spin_lock_irq(&cm.lock);
+       list_del(&timewait_info->list);
+       spin_unlock_irq(&cm.lock);
 
        cm_id_priv = cm_acquire_id(timewait_info->work.local_id,
                                   timewait_info->work.remote_id);
        if (!cm_id_priv)
                return -EINVAL;
 
-       spin_lock_irqsave(&cm_id_priv->lock, flags);
+       spin_lock_irq(&cm_id_priv->lock);
        if (cm_id_priv->id.state != IB_CM_TIMEWAIT ||
            cm_id_priv->remote_qpn != timewait_info->remote_qpn) {
-               spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+               spin_unlock_irq(&cm_id_priv->lock);
                goto out;
        }
        cm_id_priv->id.state = IB_CM_IDLE;
        ret = atomic_inc_and_test(&cm_id_priv->work_count);
        if (!ret)
                list_add_tail(&work->list, &cm_id_priv->work_list);
-       spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+       spin_unlock_irq(&cm_id_priv->lock);
 
        if (ret)
                cm_process_work(cm_id_priv, work);
@@ -3374,6 +3406,7 @@ static int __init ib_cm_init(void)
        idr_init(&cm.local_id_table);
        get_random_bytes(&cm.random_id_operand, sizeof cm.random_id_operand);
        idr_pre_get(&cm.local_id_table, GFP_KERNEL);
+       INIT_LIST_HEAD(&cm.timewait_list);
 
        cm.wq = create_workqueue("ib_cm");
        if (!cm.wq)
@@ -3391,7 +3424,20 @@ error:
 
 static void __exit ib_cm_cleanup(void)
 {
+       struct cm_timewait_info *timewait_info, *tmp;
+
+       spin_lock_irq(&cm.lock);
+       list_for_each_entry(timewait_info, &cm.timewait_list, list)
+               cancel_delayed_work(&timewait_info->work.work);
+       spin_unlock_irq(&cm.lock);
+
        destroy_workqueue(cm.wq);
+
+       list_for_each_entry_safe(timewait_info, tmp, &cm.timewait_list, list) {
+               list_del(&timewait_info->list);
+               kfree(timewait_info);
+       }
+
        ib_unregister_client(&cm_client);
        idr_destroy(&cm.local_id_table);
 }
index 9e9120f36019d4656380688d019789dce8ddfecd..9e7bd94b958ad528b28b0d06e2bd7f02e4855c76 100644 (file)
@@ -72,7 +72,7 @@ static int c2_down(struct net_device *netdev);
 static int c2_xmit_frame(struct sk_buff *skb, struct net_device *netdev);
 static void c2_tx_interrupt(struct net_device *netdev);
 static void c2_rx_interrupt(struct net_device *netdev);
-static irqreturn_t c2_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t c2_interrupt(int irq, void *dev_id);
 static void c2_tx_timeout(struct net_device *netdev);
 static int c2_change_mtu(struct net_device *netdev, int new_mtu);
 static void c2_reset(struct c2_port *c2_port);
@@ -544,7 +544,7 @@ static void c2_rx_interrupt(struct net_device *netdev)
 /*
  * Handle netisr0 TX & RX interrupts.
  */
-static irqreturn_t c2_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t c2_interrupt(int irq, void *dev_id)
 {
        unsigned int netisr0, dmaisr;
        int handled = 0;
@@ -1243,7 +1243,7 @@ static struct pci_driver c2_pci_driver = {
 
 static int __init c2_init_module(void)
 {
-       return pci_module_init(&c2_pci_driver);
+       return pci_register_driver(&c2_pci_driver);
 }
 
 static void __exit c2_exit_module(void)
index 3aae4978e1cbc574eb4e816b2fdb74cc18c7dd55..a31439bd3b67d005c89c3752b0df5a1733b477f1 100644 (file)
@@ -66,7 +66,6 @@ static int c2_convert_cm_status(u32 c2_status)
        }
 }
 
-#ifdef DEBUG
 static const char* to_event_str(int event)
 {
        static const char* event_str[] = {
@@ -144,7 +143,6 @@ static const char *to_qp_state_str(int state)
                return "<invalid QP state>";
        };
 }
-#endif
 
 void c2_ae_event(struct c2_dev *c2dev, u32 mq_index)
 {
index 12261132b0778edd8ea9a59a35016cf0103f1862..5bcf697aa335bace362fcb3ecc86de5ed58e0eb5 100644 (file)
@@ -35,6 +35,8 @@
  *
  */
 
+#include <linux/delay.h>
+
 #include "c2.h"
 #include "c2_vq.h"
 #include "c2_status.h"
@@ -705,10 +707,8 @@ static inline void c2_activity(struct c2_dev *c2dev, u32 mq_index, u16 shared)
         * cannot get on the bus and the card and system hang in a
         * deadlock -- thus the need for this code. [TOT]
         */
-       while (readl(c2dev->regs + PCI_BAR0_ADAPTER_HINT) & 0x80000000) {
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               schedule_timeout(0);
-       }
+       while (readl(c2dev->regs + PCI_BAR0_ADAPTER_HINT) & 0x80000000)
+               udelay(10);
 
        __raw_writel(C2_HINT_MAKE(mq_index, shared),
                     c2dev->regs + PCI_BAR0_ADAPTER_HINT);
@@ -766,6 +766,7 @@ int c2_post_send(struct ib_qp *ibqp, struct ib_send_wr *ib_wr,
        struct c2_dev *c2dev = to_c2dev(ibqp->device);
        struct c2_qp *qp = to_c2qp(ibqp);
        union c2wr wr;
+       unsigned long lock_flags;
        int err = 0;
 
        u32 flags;
@@ -881,8 +882,10 @@ int c2_post_send(struct ib_qp *ibqp, struct ib_send_wr *ib_wr,
                /*
                 * Post the puppy!
                 */
+               spin_lock_irqsave(&qp->lock, lock_flags);
                err = qp_wr_post(&qp->sq_mq, &wr, qp, msg_size);
                if (err) {
+                       spin_unlock_irqrestore(&qp->lock, lock_flags);
                        break;
                }
 
@@ -890,6 +893,7 @@ int c2_post_send(struct ib_qp *ibqp, struct ib_send_wr *ib_wr,
                 * Enqueue mq index to activity FIFO.
                 */
                c2_activity(c2dev, qp->sq_mq.index, qp->sq_mq.hint_count);
+               spin_unlock_irqrestore(&qp->lock, lock_flags);
 
                ib_wr = ib_wr->next;
        }
@@ -905,6 +909,7 @@ int c2_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *ib_wr,
        struct c2_dev *c2dev = to_c2dev(ibqp->device);
        struct c2_qp *qp = to_c2qp(ibqp);
        union c2wr wr;
+       unsigned long lock_flags;
        int err = 0;
 
        if (qp->state > IB_QPS_RTS)
@@ -945,8 +950,10 @@ int c2_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *ib_wr,
                        break;
                }
 
+               spin_lock_irqsave(&qp->lock, lock_flags);
                err = qp_wr_post(&qp->rq_mq, &wr, qp, qp->rq_mq.msg_size);
                if (err) {
+                       spin_unlock_irqrestore(&qp->lock, lock_flags);
                        break;
                }
 
@@ -954,6 +961,7 @@ int c2_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *ib_wr,
                 * Enqueue mq index to activity FIFO
                 */
                c2_activity(c2dev, qp->rq_mq.index, qp->rq_mq.hint_count);
+               spin_unlock_irqrestore(&qp->lock, lock_flags);
 
                ib_wr = ib_wr->next;
        }
index e37c5688c2146c969a609cc9a913d01319b86700..30409e179606e0b5d05609bf96b8b671910ac558 100644 (file)
@@ -150,8 +150,8 @@ static int c2_rnic_query(struct c2_dev *c2dev, struct ib_device_attr *props)
            (struct c2wr_rnic_query_rep *) (unsigned long) (vq_req->reply_msg);
        if (!reply)
                err = -ENOMEM;
-
-       err = c2_errno(reply);
+       else
+               err = c2_errno(reply);
        if (err)
                goto bail2;
 
index 2a65b5be19790f180d80b1ad4cbdd85bdad42d0a..048cc443d1e7ab863e01bc05b4968ade64652b1d 100644 (file)
@@ -360,7 +360,7 @@ static inline void reset_eq_pending(struct ehca_cq *cq)
        return;
 }
 
-irqreturn_t ehca_interrupt_neq(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t ehca_interrupt_neq(int irq, void *dev_id)
 {
        struct ehca_shca *shca = (struct ehca_shca*)dev_id;
 
@@ -393,7 +393,7 @@ void ehca_tasklet_neq(unsigned long data)
        return;
 }
 
-irqreturn_t ehca_interrupt_eq(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t ehca_interrupt_eq(int irq, void *dev_id)
 {
        struct ehca_shca *shca = (struct ehca_shca*)dev_id;
 
index 85bf1fe16fe41249958c4618e27d1a7b5c0ac1f9..be579cc0adf632f23283aedf74668a5714a0a2c9 100644 (file)
@@ -51,10 +51,10 @@ struct ehca_shca;
 
 int ehca_error_data(struct ehca_shca *shca, void *data, u64 resource);
 
-irqreturn_t ehca_interrupt_neq(int irq, void *dev_id, struct pt_regs *regs);
+irqreturn_t ehca_interrupt_neq(int irq, void *dev_id);
 void ehca_tasklet_neq(unsigned long data);
 
-irqreturn_t ehca_interrupt_eq(int irq, void *dev_id, struct pt_regs *regs);
+irqreturn_t ehca_interrupt_eq(int irq, void *dev_id);
 void ehca_tasklet_eq(unsigned long data);
 
 struct ehca_cpu_comp_task {
index 29958b6e0214a672905bab6dc61a50e7f8a021d0..28c087b824c2846c7d6e971e59359295618587b0 100644 (file)
@@ -67,19 +67,54 @@ static struct file_operations diag_file_ops = {
        .release = ipath_diag_release
 };
 
+static ssize_t ipath_diagpkt_write(struct file *fp,
+                                  const char __user *data,
+                                  size_t count, loff_t *off);
+
+static struct file_operations diagpkt_file_ops = {
+       .owner = THIS_MODULE,
+       .write = ipath_diagpkt_write,
+};
+
+static atomic_t diagpkt_count = ATOMIC_INIT(0);
+static struct cdev *diagpkt_cdev;
+static struct class_device *diagpkt_class_dev;
+
 int ipath_diag_add(struct ipath_devdata *dd)
 {
        char name[16];
+       int ret = 0;
+
+       if (atomic_inc_return(&diagpkt_count) == 1) {
+               ret = ipath_cdev_init(IPATH_DIAGPKT_MINOR,
+                                     "ipath_diagpkt", &diagpkt_file_ops,
+                                     &diagpkt_cdev, &diagpkt_class_dev);
+
+               if (ret) {
+                       ipath_dev_err(dd, "Couldn't create ipath_diagpkt "
+                                     "device: %d", ret);
+                       goto done;
+               }
+       }
 
        snprintf(name, sizeof(name), "ipath_diag%d", dd->ipath_unit);
 
-       return ipath_cdev_init(IPATH_DIAG_MINOR_BASE + dd->ipath_unit, name,
-                              &diag_file_ops, &dd->diag_cdev,
-                              &dd->diag_class_dev);
+       ret = ipath_cdev_init(IPATH_DIAG_MINOR_BASE + dd->ipath_unit, name,
+                             &diag_file_ops, &dd->diag_cdev,
+                             &dd->diag_class_dev);
+       if (ret)
+               ipath_dev_err(dd, "Couldn't create %s device: %d",
+                             name, ret);
+
+done:
+       return ret;
 }
 
 void ipath_diag_remove(struct ipath_devdata *dd)
 {
+       if (atomic_dec_and_test(&diagpkt_count))
+               ipath_cdev_cleanup(&diagpkt_cdev, &diagpkt_class_dev);
+
        ipath_cdev_cleanup(&dd->diag_cdev, &dd->diag_class_dev);
 }
 
@@ -275,30 +310,6 @@ bail:
        return ret;
 }
 
-static ssize_t ipath_diagpkt_write(struct file *fp,
-                                  const char __user *data,
-                                  size_t count, loff_t *off);
-
-static struct file_operations diagpkt_file_ops = {
-       .owner = THIS_MODULE,
-       .write = ipath_diagpkt_write,
-};
-
-static struct cdev *diagpkt_cdev;
-static struct class_device *diagpkt_class_dev;
-
-int __init ipath_diagpkt_add(void)
-{
-       return ipath_cdev_init(IPATH_DIAGPKT_MINOR,
-                              "ipath_diagpkt", &diagpkt_file_ops,
-                              &diagpkt_cdev, &diagpkt_class_dev);
-}
-
-void __exit ipath_diagpkt_remove(void)
-{
-       ipath_cdev_cleanup(&diagpkt_cdev, &diagpkt_class_dev);
-}
-
 /**
  * ipath_diagpkt_write - write an IB packet
  * @fp: the diag data device file pointer
index 12cefa658f3ba888f808c79b902f9fb018fb380c..b4ffaa7bcbb752467591e384d052041fcdf1b2f4 100644 (file)
@@ -2005,18 +2005,8 @@ static int __init infinipath_init(void)
                goto bail_group;
        }
 
-       ret = ipath_diagpkt_add();
-       if (ret < 0) {
-               printk(KERN_ERR IPATH_DRV_NAME ": Unable to create "
-                      "diag data device: error %d\n", -ret);
-               goto bail_ipathfs;
-       }
-
        goto bail;
 
-bail_ipathfs:
-       ipath_exit_ipathfs();
-
 bail_group:
        ipath_driver_remove_group(&ipath_driver.driver);
 
index 6bee53ce5f334a84352847ce014c9a3d2502f322..d9079ee120308633c49b012988bd0b752df362eb 100644 (file)
@@ -839,7 +839,7 @@ static void handle_urcv(struct ipath_devdata *dd, u32 istat)
        }
 }
 
-irqreturn_t ipath_intr(int irq, void *data, struct pt_regs *regs)
+irqreturn_t ipath_intr(int irq, void *data)
 {
        struct ipath_devdata *dd = data;
        u32 istat, chk0rcv = 0;
index d7540b71b451b624dd580deb7c074a61c61dbe6f..06d5020a2f60625882920c1b52c74d680fa15660 100644 (file)
@@ -606,7 +606,7 @@ struct sk_buff *ipath_alloc_skb(struct ipath_devdata *dd, gfp_t);
 
 extern int ipath_diag_inuse;
 
-irqreturn_t ipath_intr(int irq, void *devid, struct pt_regs *regs);
+irqreturn_t ipath_intr(int irq, void *devid);
 void ipath_decode_err(char *buf, size_t blen, ipath_err_t err);
 #if __IPATH_INFO || __IPATH_DBG
 extern const char *ipath_ibcstatus_str[];
@@ -869,9 +869,6 @@ int ipath_device_create_group(struct device *, struct ipath_devdata *);
 void ipath_device_remove_group(struct device *, struct ipath_devdata *);
 int ipath_expose_reset(struct device *);
 
-int ipath_diagpkt_add(void);
-void ipath_diagpkt_remove(void);
-
 int ipath_init_ipathfs(void);
 void ipath_exit_ipathfs(void);
 int ipathfs_add_device(struct ipath_devdata *);
index e393681ba7d46a1988508c3f5d25e27b2cd4261d..149b3690123968ced42384ca1173be972ef710be 100644 (file)
@@ -39,6 +39,8 @@
 #include <linux/init.h>
 #include <linux/hardirq.h>
 
+#include <asm/io.h>
+
 #include <rdma/ib_pack.h>
 
 #include "mthca_dev.h"
@@ -210,6 +212,11 @@ static inline void update_cons_index(struct mthca_dev *dev, struct mthca_cq *cq,
                mthca_write64(doorbell,
                              dev->kar + MTHCA_CQ_DOORBELL,
                              MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
+               /*
+                * Make sure doorbells don't leak out of CQ spinlock
+                * and reach the HCA out of order:
+                */
+               mmiowb();
        }
 }
 
index a29b1b6d82b1758c2d1c5328057059e27e6e1631..e284e0613a94e6c35da211a914496ac406038852 100644 (file)
@@ -405,7 +405,7 @@ static int mthca_eq_int(struct mthca_dev *dev, struct mthca_eq *eq)
        return eqes_found;
 }
 
-static irqreturn_t mthca_tavor_interrupt(int irq, void *dev_ptr, struct pt_regs *regs)
+static irqreturn_t mthca_tavor_interrupt(int irq, void *dev_ptr)
 {
        struct mthca_dev *dev = dev_ptr;
        u32 ecr;
@@ -432,8 +432,7 @@ static irqreturn_t mthca_tavor_interrupt(int irq, void *dev_ptr, struct pt_regs
        return IRQ_HANDLED;
 }
 
-static irqreturn_t mthca_tavor_msi_x_interrupt(int irq, void *eq_ptr,
-                                        struct pt_regs *regs)
+static irqreturn_t mthca_tavor_msi_x_interrupt(int irq, void *eq_ptr)
 {
        struct mthca_eq  *eq  = eq_ptr;
        struct mthca_dev *dev = eq->dev;
@@ -446,7 +445,7 @@ static irqreturn_t mthca_tavor_msi_x_interrupt(int irq, void *eq_ptr,
        return IRQ_HANDLED;
 }
 
-static irqreturn_t mthca_arbel_interrupt(int irq, void *dev_ptr, struct pt_regs *regs)
+static irqreturn_t mthca_arbel_interrupt(int irq, void *dev_ptr)
 {
        struct mthca_dev *dev = dev_ptr;
        int work = 0;
@@ -467,8 +466,7 @@ static irqreturn_t mthca_arbel_interrupt(int irq, void *dev_ptr, struct pt_regs
        return IRQ_RETVAL(work);
 }
 
-static irqreturn_t mthca_arbel_msi_x_interrupt(int irq, void *eq_ptr,
-                                              struct pt_regs *regs)
+static irqreturn_t mthca_arbel_msi_x_interrupt(int irq, void *eq_ptr)
 {
        struct mthca_eq  *eq  = eq_ptr;
        struct mthca_dev *dev = eq->dev;
index 981fe2eebdfa36228693781627c65464286aadb3..fc67f780581b284f4552c5d3ca72d05813cc48a0 100644 (file)
@@ -179,6 +179,8 @@ static int mthca_query_port(struct ib_device *ibdev,
        props->max_mtu           = out_mad->data[41] & 0xf;
        props->active_mtu        = out_mad->data[36] >> 4;
        props->subnet_timeout    = out_mad->data[51] & 0x1f;
+       props->max_vl_num        = out_mad->data[37] >> 4;
+       props->init_type_reply   = out_mad->data[41] >> 4;
 
  out:
        kfree(in_mad);
index 5e5c58b9920b5c3d53b6d0a61a3afcaee037e281..6a7822e0fc19a94ca67fc306d5207aabdc865466 100644 (file)
@@ -39,6 +39,8 @@
 #include <linux/string.h>
 #include <linux/slab.h>
 
+#include <asm/io.h>
+
 #include <rdma/ib_verbs.h>
 #include <rdma/ib_cache.h>
 #include <rdma/ib_pack.h>
@@ -1732,6 +1734,11 @@ out:
                mthca_write64(doorbell,
                              dev->kar + MTHCA_SEND_DOORBELL,
                              MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
+               /*
+                * Make sure doorbells don't leak out of SQ spinlock
+                * and reach the HCA out of order:
+                */
+               mmiowb();
        }
 
        qp->sq.next_ind = ind;
@@ -1851,6 +1858,12 @@ out:
        qp->rq.next_ind = ind;
        qp->rq.head    += nreq;
 
+       /*
+        * Make sure doorbells don't leak out of RQ spinlock and reach
+        * the HCA out of order:
+        */
+       mmiowb();
+
        spin_unlock_irqrestore(&qp->rq.lock, flags);
        return err;
 }
@@ -2112,6 +2125,12 @@ out:
                              MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
        }
 
+       /*
+        * Make sure doorbells don't leak out of SQ spinlock and reach
+        * the HCA out of order:
+        */
+       mmiowb();
+
        spin_unlock_irqrestore(&qp->sq.lock, flags);
        return err;
 }
index 0f316c87bf642397eb0844469c5c179b17076c1c..f5d7677d107969ee59b68b815d4926d7a5685cbf 100644 (file)
@@ -35,6 +35,8 @@
 #include <linux/slab.h>
 #include <linux/string.h>
 
+#include <asm/io.h>
+
 #include "mthca_dev.h"
 #include "mthca_cmd.h"
 #include "mthca_memfree.h"
@@ -201,6 +203,8 @@ int mthca_alloc_srq(struct mthca_dev *dev, struct mthca_pd *pd,
 
        if (mthca_is_memfree(dev))
                srq->max = roundup_pow_of_two(srq->max + 1);
+       else
+               srq->max = srq->max + 1;
 
        ds = max(64UL,
                 roundup_pow_of_two(sizeof (struct mthca_next_seg) +
@@ -277,7 +281,7 @@ int mthca_alloc_srq(struct mthca_dev *dev, struct mthca_pd *pd,
        srq->first_free = 0;
        srq->last_free  = srq->max - 1;
 
-       attr->max_wr    = (mthca_is_memfree(dev)) ? srq->max - 1 : srq->max;
+       attr->max_wr    = srq->max - 1;
        attr->max_sge   = srq->max_gs;
 
        return 0;
@@ -413,7 +417,7 @@ int mthca_query_srq(struct ib_srq *ibsrq, struct ib_srq_attr *srq_attr)
                srq_attr->srq_limit = be16_to_cpu(tavor_ctx->limit_watermark);
        }
 
-       srq_attr->max_wr  = (mthca_is_memfree(dev)) ? srq->max - 1 : srq->max;
+       srq_attr->max_wr  = srq->max - 1;
        srq_attr->max_sge = srq->max_gs;
 
 out:
@@ -593,6 +597,12 @@ int mthca_tavor_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
                              MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
        }
 
+       /*
+        * Make sure doorbells don't leak out of SRQ spinlock and
+        * reach the HCA out of order:
+        */
+       mmiowb();
+
        spin_unlock_irqrestore(&srq->lock, flags);
        return err;
 }
index f426a69d9a436cce55addba00be1d1d2cdd7ff30..8bf5e9ec7c9522345696a2819ee99f444af341e7 100644 (file)
@@ -355,6 +355,11 @@ void ipoib_send(struct net_device *dev, struct sk_buff *skb,
        tx_req->skb = skb;
        addr = dma_map_single(priv->ca->dma_device, skb->data, skb->len,
                              DMA_TO_DEVICE);
+       if (unlikely(dma_mapping_error(addr))) {
+               ++priv->stats.tx_errors;
+               dev_kfree_skb_any(skb);
+               return;
+       }
        pci_unmap_addr_set(tx_req, mapping, addr);
 
        if (unlikely(post_send(priv, priv->tx_head & (ipoib_sendq_size - 1),
index 44b9e5be6687941757e62ac0a7fd9be231dcda68..4b09147f438f5d44a93d46eba3ccf6de6ed345bc 100644 (file)
@@ -343,29 +343,32 @@ static int srp_send_req(struct srp_target_port *target)
         */
        if (target->io_class == SRP_REV10_IB_IO_CLASS) {
                memcpy(req->priv.initiator_port_id,
-                      target->srp_host->initiator_port_id + 8, 8);
+                      &target->path.sgid.global.interface_id, 8);
                memcpy(req->priv.initiator_port_id + 8,
-                      target->srp_host->initiator_port_id, 8);
+                      &target->initiator_ext, 8);
                memcpy(req->priv.target_port_id,     &target->ioc_guid, 8);
                memcpy(req->priv.target_port_id + 8, &target->id_ext, 8);
        } else {
                memcpy(req->priv.initiator_port_id,
-                      target->srp_host->initiator_port_id, 16);
+                      &target->initiator_ext, 8);
+               memcpy(req->priv.initiator_port_id + 8,
+                      &target->path.sgid.global.interface_id, 8);
                memcpy(req->priv.target_port_id,     &target->id_ext, 8);
                memcpy(req->priv.target_port_id + 8, &target->ioc_guid, 8);
        }
 
        /*
         * Topspin/Cisco SRP targets will reject our login unless we
-        * zero out the first 8 bytes of our initiator port ID.  The
-        * second 8 bytes must be our local node GUID, but we always
-        * use that anyway.
+        * zero out the first 8 bytes of our initiator port ID and set
+        * the second 8 bytes to the local node GUID.
         */
        if (topspin_workarounds && !memcmp(&target->ioc_guid, topspin_oui, 3)) {
                printk(KERN_DEBUG PFX "Topspin/Cisco initiator port ID workaround "
                       "activated for target GUID %016llx\n",
                       (unsigned long long) be64_to_cpu(target->ioc_guid));
                memset(req->priv.initiator_port_id, 0, 8);
+               memcpy(req->priv.initiator_port_id + 8,
+                      &target->srp_host->dev->dev->node_guid, 8);
        }
 
        status = ib_send_cm_req(target->cm_id, &req->param);
@@ -1553,6 +1556,7 @@ enum {
        SRP_OPT_MAX_SECT        = 1 << 5,
        SRP_OPT_MAX_CMD_PER_LUN = 1 << 6,
        SRP_OPT_IO_CLASS        = 1 << 7,
+       SRP_OPT_INITIATOR_EXT   = 1 << 8,
        SRP_OPT_ALL             = (SRP_OPT_ID_EXT       |
                                   SRP_OPT_IOC_GUID     |
                                   SRP_OPT_DGID         |
@@ -1569,6 +1573,7 @@ static match_table_t srp_opt_tokens = {
        { SRP_OPT_MAX_SECT,             "max_sect=%d"           },
        { SRP_OPT_MAX_CMD_PER_LUN,      "max_cmd_per_lun=%d"    },
        { SRP_OPT_IO_CLASS,             "io_class=%x"           },
+       { SRP_OPT_INITIATOR_EXT,        "initiator_ext=%s"      },
        { SRP_OPT_ERR,                  NULL                    }
 };
 
@@ -1668,6 +1673,12 @@ static int srp_parse_options(const char *buf, struct srp_target_port *target)
                        target->io_class = token;
                        break;
 
+               case SRP_OPT_INITIATOR_EXT:
+                       p = match_strdup(args);
+                       target->initiator_ext = cpu_to_be64(simple_strtoull(p, NULL, 16));
+                       kfree(p);
+                       break;
+
                default:
                        printk(KERN_WARNING PFX "unknown parameter or missing value "
                               "'%s' in target creation request\n", p);
@@ -1708,7 +1719,6 @@ static ssize_t srp_create_target(struct class_device *class_dev,
        target_host->max_lun = SRP_MAX_LUN;
 
        target = host_to_target(target_host);
-       memset(target, 0, sizeof *target);
 
        target->io_class   = SRP_REV16A_IB_IO_CLASS;
        target->scsi_host  = target_host;
@@ -1815,9 +1825,6 @@ static struct srp_host *srp_add_port(struct srp_device *device, u8 port)
        host->dev  = device;
        host->port = port;
 
-       host->initiator_port_id[7] = port;
-       memcpy(host->initiator_port_id + 8, &device->dev->node_guid, 8);
-
        host->class_dev.class = &srp_class;
        host->class_dev.dev   = device->dev->dma_device;
        snprintf(host->class_dev.class_id, BUS_ID_SIZE, "srp-%s-%d",
index 5b581fb8eb0d08addeea3f9a5fff4763592f1ed6..d4e35ef51374db17ece91fa2b13a4d1556002ca8 100644 (file)
@@ -91,7 +91,6 @@ struct srp_device {
 };
 
 struct srp_host {
-       u8                      initiator_port_id[16];
        struct srp_device      *dev;
        u8                      port;
        struct class_device     class_dev;
@@ -122,6 +121,7 @@ struct srp_target_port {
        __be64                  id_ext;
        __be64                  ioc_guid;
        __be64                  service_id;
+       __be64                  initiator_ext;
        u16                     io_class;
        struct srp_host        *srp_host;
        struct Scsi_Host       *scsi_host;
index 90de5afe03c21a40c95383d01f919e2b15699eb8..1dec00e20dbc0f28c2274bec2984d28bb947ac44 100644 (file)
@@ -82,17 +82,19 @@ static int __devinit fm801_gp_probe(struct pci_dev *pci, const struct pci_device
 {
        struct fm801_gp *gp;
        struct gameport *port;
+       int error;
 
        gp = kzalloc(sizeof(struct fm801_gp), GFP_KERNEL);
        port = gameport_allocate_port();
        if (!gp || !port) {
                printk(KERN_ERR "fm801-gp: Memory allocation failed\n");
-               kfree(gp);
-               gameport_free_port(port);
-               return -ENOMEM;
+               error = -ENOMEM;
+               goto err_out_free;
        }
 
-       pci_enable_device(pci);
+       error = pci_enable_device(pci);
+       if (error)
+               goto err_out_free;
 
        port->open = fm801_gp_open;
 #ifdef HAVE_COOKED
@@ -108,9 +110,8 @@ static int __devinit fm801_gp_probe(struct pci_dev *pci, const struct pci_device
        if (!gp->res_port) {
                printk(KERN_DEBUG "fm801-gp: unable to grab region 0x%x-0x%x\n",
                        port->io, port->io + 0x0f);
-               gameport_free_port(port);
-               kfree(gp);
-               return -EBUSY;
+               error = -EBUSY;
+               goto err_out_disable_dev;
        }
 
        pci_set_drvdata(pci, gp);
@@ -119,6 +120,13 @@ static int __devinit fm801_gp_probe(struct pci_dev *pci, const struct pci_device
        gameport_register_port(port);
 
        return 0;
+
+ err_out_disable_dev:
+       pci_disable_device(pci);
+ err_out_free:
+       gameport_free_port(port);
+       kfree(gp);
+       return error;
 }
 
 static void __devexit fm801_gp_remove(struct pci_dev *pci)
index 3f47ae55c6f3892f7c6b6952e9cf38ccf7d8585f..a0af97efe6ac0e23fd440cc1608db170890a005d 100644 (file)
@@ -191,6 +191,8 @@ static void gameport_run_poll_handler(unsigned long d)
 
 static void gameport_bind_driver(struct gameport *gameport, struct gameport_driver *drv)
 {
+       int error;
+
        down_write(&gameport_bus.subsys.rwsem);
 
        gameport->dev.driver = &drv->driver;
@@ -198,8 +200,20 @@ static void gameport_bind_driver(struct gameport *gameport, struct gameport_driv
                gameport->dev.driver = NULL;
                goto out;
        }
-       device_bind_driver(&gameport->dev);
-out:
+
+       error = device_bind_driver(&gameport->dev);
+       if (error) {
+               printk(KERN_WARNING
+                       "gameport: device_bind_driver() failed "
+                       "for %s (%s) and %s, error: %d\n",
+                       gameport->phys, gameport->name,
+                       drv->description, error);
+               drv->disconnect(gameport);
+               gameport->dev.driver = NULL;
+               goto out;
+       }
+
+ out:
        up_write(&gameport_bus.subsys.rwsem);
 }
 
index 7249d324297b8d441a64113ffb2debd2131cb45c..650acf3a30b70878b8075e58c8ac9d265600ee1d 100644 (file)
@@ -57,7 +57,7 @@ static DEFINE_MUTEX(amijoy_mutex);
 static struct input_dev *amijoy_dev[2];
 static char *amijoy_phys[2] = { "amijoy/input0", "amijoy/input1" };
 
-static irqreturn_t amijoy_interrupt(int irq, void *dummy, struct pt_regs *fp)
+static irqreturn_t amijoy_interrupt(int irq, void *dummy)
 {
        int i, data = 0, button = 0;
 
@@ -69,8 +69,6 @@ static irqreturn_t amijoy_interrupt(int irq, void *dummy, struct pt_regs *fp)
                                case 1: data = ~amiga_custom.joy1dat; button = (~ciaa.pra >> 7) & 1; break;
                        }
 
-                       input_regs(amijoy_dev[i], fp);
-
                        input_report_key(amijoy_dev[i], BTN_TRIGGER, button);
 
                        input_report_abs(amijoy_dev[i], ABS_X, ((data >> 1) & 1) - ((data >> 9) & 1));
index 8632d47a7fbe588eed1a10cfa7f14b59845cef58..808f05932a6fbd24b5d59b6af37dcb56ea96f312 100644 (file)
@@ -155,7 +155,7 @@ static int mark_core_as_ready(struct iforce *iforce, unsigned short addr)
        return -1;
 }
 
-void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data, struct pt_regs *regs)
+void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data)
 {
        struct input_dev *dev = iforce->dev;
        int i;
@@ -183,9 +183,6 @@ void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data,
 
                case 0x01:      /* joystick position data */
                case 0x03:      /* wheel position data */
-
-                       input_regs(dev, regs);
-
                        if (HI(cmd) == 1) {
                                input_report_abs(dev, ABS_X, (__s16) (((__s16)data[1] << 8) | data[0]));
                                input_report_abs(dev, ABS_Y, (__s16) (((__s16)data[3] << 8) | data[2]));
@@ -224,7 +221,6 @@ void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data,
                        break;
 
                case 0x02:      /* status report */
-                       input_regs(dev, regs);
                        input_report_key(dev, BTN_DEAD, data[0] & 0x02);
                        input_sync(dev);
 
index 64a78c5154847bfaf574ba8d510a24d9441d190f..ca08f45c2040a5338e7987bd177a490c42eeac72 100644 (file)
@@ -81,7 +81,7 @@ static void iforce_serio_write_wakeup(struct serio *serio)
 }
 
 static irqreturn_t iforce_serio_irq(struct serio *serio,
-               unsigned char data, unsigned int flags, struct pt_regs *regs)
+               unsigned char data, unsigned int flags)
 {
        struct iforce *iforce = serio_get_drvdata(serio);
 
@@ -115,7 +115,7 @@ static irqreturn_t iforce_serio_irq(struct serio *serio,
        }
 
        if (iforce->idx == iforce->len) {
-               iforce_process_packet(iforce, (iforce->id << 8) | iforce->idx, iforce->data, regs);
+               iforce_process_packet(iforce, (iforce->id << 8) | iforce->idx, iforce->data);
                iforce->pkt = 0;
                iforce->id  = 0;
                iforce->len = 0;
index fe79d158456d8256c0301ece36dc5ba87510d513..105112fb7b57584903266fe3d35982dd897b0a4e 100644 (file)
@@ -74,7 +74,7 @@ void iforce_usb_xmit(struct iforce *iforce)
        spin_unlock_irqrestore(&iforce->xmit_lock, flags);
 }
 
-static void iforce_usb_irq(struct urb *urb, struct pt_regs *regs)
+static void iforce_usb_irq(struct urb *urb)
 {
        struct iforce *iforce = urb->context;
        int status;
@@ -96,7 +96,7 @@ static void iforce_usb_irq(struct urb *urb, struct pt_regs *regs)
        }
 
        iforce_process_packet(iforce,
-               (iforce->data[0] << 8) | (urb->actual_length - 1), iforce->data + 1, regs);
+               (iforce->data[0] << 8) | (urb->actual_length - 1), iforce->data + 1);
 
 exit:
        status = usb_submit_urb (urb, GFP_ATOMIC);
@@ -105,7 +105,7 @@ exit:
                     __FUNCTION__, status);
 }
 
-static void iforce_usb_out(struct urb *urb, struct pt_regs *regs)
+static void iforce_usb_out(struct urb *urb)
 {
        struct iforce *iforce = urb->context;
 
@@ -119,7 +119,7 @@ static void iforce_usb_out(struct urb *urb, struct pt_regs *regs)
        wake_up(&iforce->wait);
 }
 
-static void iforce_usb_ctrl(struct urb *urb, struct pt_regs *regs)
+static void iforce_usb_ctrl(struct urb *urb)
 {
        struct iforce *iforce = urb->context;
        if (urb->status) return;
index 947df273984399384fd0e8aece218ac388cadb43..ffaeaefa1a42d3192a8f123cc63eed26aa86423a 100644 (file)
@@ -160,7 +160,7 @@ void iforce_delete_device(struct iforce *iforce);
 
 /* iforce-packets.c */
 int iforce_control_playback(struct iforce*, u16 id, unsigned int);
-void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data, struct pt_regs *regs);
+void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data);
 int iforce_send_packet(struct iforce *iforce, u16 cmd, unsigned char* data);
 void iforce_dump_packet(char *msg, u16 cmd, unsigned char *data) ;
 int iforce_get_id_packet(struct iforce *iforce, char *packet);
index 168b1061a03bd35fd3399658d841c814407bb1e1..e3d19444ba2e42300c38ceacf7a5b336fea838bd 100644 (file)
@@ -82,7 +82,7 @@ static int magellan_crunch_nibbles(unsigned char *data, int count)
        return 0;
 }
 
-static void magellan_process_packet(struct magellan* magellan, struct pt_regs *regs)
+static void magellan_process_packet(struct magellan* magellan)
 {
        struct input_dev *dev = magellan->dev;
        unsigned char *data = magellan->data;
@@ -90,8 +90,6 @@ static void magellan_process_packet(struct magellan* magellan, struct pt_regs *r
 
        if (!magellan->idx) return;
 
-       input_regs(dev, regs);
-
        switch (magellan->data[0]) {
 
                case 'd':                               /* Axis data */
@@ -115,12 +113,12 @@ static void magellan_process_packet(struct magellan* magellan, struct pt_regs *r
 }
 
 static irqreturn_t magellan_interrupt(struct serio *serio,
-               unsigned char data, unsigned int flags, struct pt_regs *regs)
+               unsigned char data, unsigned int flags)
 {
        struct magellan* magellan = serio_get_drvdata(serio);
 
        if (data == '\r') {
-               magellan_process_packet(magellan, regs);
+               magellan_process_packet(magellan);
                magellan->idx = 0;
        } else {
                if (magellan->idx < MAGELLAN_MAX_LENGTH)
index 7a19ee052972ab4c50bd5b4a0c106c25d8f4a6cd..2a9808cf826f146182e8e4e9bc33e9883c08610e 100644 (file)
@@ -82,7 +82,7 @@ struct spaceball {
  * SpaceBall.
  */
 
-static void spaceball_process_packet(struct spaceball* spaceball, struct pt_regs *regs)
+static void spaceball_process_packet(struct spaceball* spaceball)
 {
        struct input_dev *dev = spaceball->dev;
        unsigned char *data = spaceball->data;
@@ -90,8 +90,6 @@ static void spaceball_process_packet(struct spaceball* spaceball, struct pt_regs
 
        if (spaceball->idx < 2) return;
 
-       input_regs(dev, regs);
-
        switch (spaceball->data[0]) {
 
                case 'D':                                       /* Ball data */
@@ -151,13 +149,13 @@ static void spaceball_process_packet(struct spaceball* spaceball, struct pt_regs
  */
 
 static irqreturn_t spaceball_interrupt(struct serio *serio,
-               unsigned char data, unsigned int flags, struct pt_regs *regs)
+               unsigned char data, unsigned int flags)
 {
        struct spaceball *spaceball = serio_get_drvdata(serio);
 
        switch (data) {
                case 0xd:
-                       spaceball_process_packet(spaceball, regs);
+                       spaceball_process_packet(spaceball);
                        spaceball->idx = 0;
                        spaceball->escape = 0;
                        break;
index 3e2782e79834cc24397eb93e8ad3223b1a4afef0..c4db0247c5fb13b8a4c1ba499665307ae874c46f 100644 (file)
@@ -74,7 +74,7 @@ static unsigned char *spaceorb_errors[] = { "EEPROM storing 0 failed", "Receive
  * SpaceOrb.
  */
 
-static void spaceorb_process_packet(struct spaceorb *spaceorb, struct pt_regs *regs)
+static void spaceorb_process_packet(struct spaceorb *spaceorb)
 {
        struct input_dev *dev = spaceorb->dev;
        unsigned char *data = spaceorb->data;
@@ -86,8 +86,6 @@ static void spaceorb_process_packet(struct spaceorb *spaceorb, struct pt_regs *r
        for (i = 0; i < spaceorb->idx; i++) c ^= data[i];
        if (c) return;
 
-       input_regs(dev, regs);
-
        switch (data[0]) {
 
                case 'R':                               /* Reset packet */
@@ -131,12 +129,12 @@ static void spaceorb_process_packet(struct spaceorb *spaceorb, struct pt_regs *r
 }
 
 static irqreturn_t spaceorb_interrupt(struct serio *serio,
-               unsigned char data, unsigned int flags, struct pt_regs *regs)
+               unsigned char data, unsigned int flags)
 {
        struct spaceorb* spaceorb = serio_get_drvdata(serio);
 
        if (~data & 0x80) {
-               if (spaceorb->idx) spaceorb_process_packet(spaceorb, regs);
+               if (spaceorb->idx) spaceorb_process_packet(spaceorb);
                spaceorb->idx = 0;
        }
        if (spaceorb->idx < SPACEORB_MAX_LENGTH)
index 011ec4858e15553f60df86057eb42699f20a80b3..1ffb0322331112cf4f38126aef36fb1600c64270 100644 (file)
@@ -64,15 +64,13 @@ struct stinger {
  * Stinger. It updates the data accordingly.
  */
 
-static void stinger_process_packet(struct stinger *stinger, struct pt_regs *regs)
+static void stinger_process_packet(struct stinger *stinger)
 {
        struct input_dev *dev = stinger->dev;
        unsigned char *data = stinger->data;
 
        if (!stinger->idx) return;
 
-       input_regs(dev, regs);
-
        input_report_key(dev, BTN_A,      ((data[0] & 0x20) >> 5));
        input_report_key(dev, BTN_B,      ((data[0] & 0x10) >> 4));
        input_report_key(dev, BTN_C,      ((data[0] & 0x08) >> 3));
@@ -99,7 +97,7 @@ static void stinger_process_packet(struct stinger *stinger, struct pt_regs *regs
  */
 
 static irqreturn_t stinger_interrupt(struct serio *serio,
-       unsigned char data, unsigned int flags, struct pt_regs *regs)
+       unsigned char data, unsigned int flags)
 {
        struct stinger *stinger = serio_get_drvdata(serio);
 
@@ -109,7 +107,7 @@ static irqreturn_t stinger_interrupt(struct serio *serio,
                stinger->data[stinger->idx++] = data;
 
        if (stinger->idx == 4) {
-               stinger_process_packet(stinger, regs);
+               stinger_process_packet(stinger);
                stinger->idx = 0;
        }
 
index 076f237d965471eab6c76a7f9599147daa202e14..49085df2d63156eded4d4388ba94230a6a9e7d0b 100644 (file)
@@ -104,7 +104,7 @@ struct twidjoy {
  * Twiddler. It updates the data accordingly.
  */
 
-static void twidjoy_process_packet(struct twidjoy *twidjoy, struct pt_regs *regs)
+static void twidjoy_process_packet(struct twidjoy *twidjoy)
 {
        struct input_dev *dev = twidjoy->dev;
        unsigned char *data = twidjoy->data;
@@ -113,8 +113,6 @@ static void twidjoy_process_packet(struct twidjoy *twidjoy, struct pt_regs *regs
 
        button_bits = ((data[1] & 0x7f) << 7) | (data[0] & 0x7f);
 
-       input_regs(dev, regs);
-
        for (bp = twidjoy_buttons; bp->bitmask; bp++) {
                int value = (button_bits & (bp->bitmask << bp->bitshift)) >> bp->bitshift;
                int i;
@@ -141,7 +139,7 @@ static void twidjoy_process_packet(struct twidjoy *twidjoy, struct pt_regs *regs
  * packet processing routine.
  */
 
-static irqreturn_t twidjoy_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs)
+static irqreturn_t twidjoy_interrupt(struct serio *serio, unsigned char data, unsigned int flags)
 {
        struct twidjoy *twidjoy = serio_get_drvdata(serio);
 
@@ -158,7 +156,7 @@ static irqreturn_t twidjoy_interrupt(struct serio *serio, unsigned char data, un
                twidjoy->data[twidjoy->idx++] = data;
 
        if (twidjoy->idx == TWIDJOY_MAX_LENGTH) {
-               twidjoy_process_packet(twidjoy, regs);
+               twidjoy_process_packet(twidjoy);
                twidjoy->idx = 0;
        }
 
index f9c1a03214eb6ddd04ac2cdf1e5bd5d97cccb94a..35edea1ab955cd81688cccd17a2de87195e6c69d 100644 (file)
@@ -64,15 +64,13 @@ struct warrior {
  * Warrior. It updates the data accordingly.
  */
 
-static void warrior_process_packet(struct warrior *warrior, struct pt_regs *regs)
+static void warrior_process_packet(struct warrior *warrior)
 {
        struct input_dev *dev = warrior->dev;
        unsigned char *data = warrior->data;
 
        if (!warrior->idx) return;
 
-       input_regs(dev, regs);
-
        switch ((data[0] >> 4) & 7) {
                case 1:                                 /* Button data */
                        input_report_key(dev, BTN_TRIGGER,  data[3]       & 1);
@@ -101,12 +99,12 @@ static void warrior_process_packet(struct warrior *warrior, struct pt_regs *regs
  */
 
 static irqreturn_t warrior_interrupt(struct serio *serio,
-               unsigned char data, unsigned int flags, struct pt_regs *regs)
+               unsigned char data, unsigned int flags)
 {
        struct warrior *warrior = serio_get_drvdata(serio);
 
        if (data & 0x80) {
-               if (warrior->idx) warrior_process_packet(warrior, regs);
+               if (warrior->idx) warrior_process_packet(warrior);
                warrior->idx = 0;
                warrior->len = warrior_lengths[(data >> 4) & 7];
        }
@@ -115,7 +113,7 @@ static irqreturn_t warrior_interrupt(struct serio *serio,
                warrior->data[warrior->idx++] = data;
 
        if (warrior->idx == warrior->len) {
-               if (warrior->idx) warrior_process_packet(warrior, regs);
+               if (warrior->idx) warrior_process_packet(warrior);
                warrior->idx = 0;
                warrior->len = 0;
        }
index 679bde34d2478f058330711322ca03c7bf51b6ba..81a333f7301052590c0c82b94b41dcd3939a0b7c 100644 (file)
@@ -166,7 +166,7 @@ config KEYBOARD_AMIGA
 
 config KEYBOARD_HIL_OLD
        tristate "HP HIL keyboard support (simple driver)"
-       depends on GSC
+       depends on GSC || HP300
        default y
        help
          The "Human Interface Loop" is a older, 8-channel USB-like
@@ -183,7 +183,7 @@ config KEYBOARD_HIL_OLD
 
 config KEYBOARD_HIL
        tristate "HP HIL keyboard support"
-       depends on GSC
+       depends on GSC || HP300
        default y
        select HP_SDC
        select HIL_MLC
index f1f9db9d282c6eafa636761bbc0c772d217efdf6..8abdbd0ee8f9cfca5da18e959e5c3b3e75e9de45 100644 (file)
@@ -158,7 +158,7 @@ static const char *amikbd_messages[8] = {
 
 static struct input_dev *amikbd_dev;
 
-static irqreturn_t amikbd_interrupt(int irq, void *dummy, struct pt_regs *fp)
+static irqreturn_t amikbd_interrupt(int irq, void *dummy)
 {
        unsigned char scancode, down;
 
@@ -171,8 +171,6 @@ static irqreturn_t amikbd_interrupt(int irq, void *dummy, struct pt_regs *fp)
        scancode >>= 1;
 
        if (scancode < 0x78) {          /* scancodes < 0x78 are keys */
-               input_regs(amikbd_dev, fp);
-
                if (scancode == 98) {   /* CapsLock is a toggle switch key on Amiga */
                        input_report_key(amikbd_dev, scancode, 1);
                        input_report_key(amikbd_dev, scancode, 0);
index 40244d4ce0f1696e6dc3179c7ab13e260884851a..cbb93669d1cef7b9a3188ee74a008de927c1f2c7 100644 (file)
@@ -221,6 +221,7 @@ struct atkbd {
        unsigned long xl_bit;
        unsigned int last;
        unsigned long time;
+       unsigned long err_count;
 
        struct work_struct event_work;
        struct mutex event_mutex;
@@ -234,11 +235,13 @@ static ssize_t atkbd_attr_set_helper(struct device *dev, const char *buf, size_t
 #define ATKBD_DEFINE_ATTR(_name)                                               \
 static ssize_t atkbd_show_##_name(struct atkbd *, char *);                     \
 static ssize_t atkbd_set_##_name(struct atkbd *, const char *, size_t);                \
-static ssize_t atkbd_do_show_##_name(struct device *d, struct device_attribute *attr, char *b)                 \
+static ssize_t atkbd_do_show_##_name(struct device *d,                         \
+                               struct device_attribute *attr, char *b)         \
 {                                                                              \
        return atkbd_attr_show_helper(d, b, atkbd_show_##_name);                \
 }                                                                              \
-static ssize_t atkbd_do_set_##_name(struct device *d, struct device_attribute *attr, const char *b, size_t s)  \
+static ssize_t atkbd_do_set_##_name(struct device *d,                          \
+                       struct device_attribute *attr, const char *b, size_t s) \
 {                                                                              \
        return atkbd_attr_set_helper(d, b, s, atkbd_set_##_name);               \
 }                                                                              \
@@ -251,6 +254,32 @@ ATKBD_DEFINE_ATTR(set);
 ATKBD_DEFINE_ATTR(softrepeat);
 ATKBD_DEFINE_ATTR(softraw);
 
+#define ATKBD_DEFINE_RO_ATTR(_name)                                            \
+static ssize_t atkbd_show_##_name(struct atkbd *, char *);                     \
+static ssize_t atkbd_do_show_##_name(struct device *d,                         \
+                               struct device_attribute *attr, char *b)         \
+{                                                                              \
+       return atkbd_attr_show_helper(d, b, atkbd_show_##_name);                \
+}                                                                              \
+static struct device_attribute atkbd_attr_##_name =                            \
+       __ATTR(_name, S_IRUGO, atkbd_do_show_##_name, NULL);
+
+ATKBD_DEFINE_RO_ATTR(err_count);
+
+static struct attribute *atkbd_attributes[] = {
+       &atkbd_attr_extra.attr,
+       &atkbd_attr_scroll.attr,
+       &atkbd_attr_set.attr,
+       &atkbd_attr_softrepeat.attr,
+       &atkbd_attr_softraw.attr,
+       &atkbd_attr_err_count.attr,
+       NULL
+};
+
+static struct attribute_group atkbd_attribute_group = {
+       .attrs  = atkbd_attributes,
+};
+
 static const unsigned int xl_table[] = {
        ATKBD_RET_BAT, ATKBD_RET_ERR, ATKBD_RET_ACK,
        ATKBD_RET_NAK, ATKBD_RET_HANJA, ATKBD_RET_HANGEUL,
@@ -318,7 +347,7 @@ static unsigned int atkbd_compat_scancode(struct atkbd *atkbd, unsigned int code
  */
 
 static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
-                       unsigned int flags, struct pt_regs *regs)
+                       unsigned int flags)
 {
        struct atkbd *atkbd = serio_get_drvdata(serio);
        struct input_dev *dev = atkbd->dev;
@@ -396,7 +425,10 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
                        add_release_event = 1;
                        break;
                case ATKBD_RET_ERR:
+                       atkbd->err_count++;
+#ifdef ATKBD_DEBUG
                        printk(KERN_DEBUG "atkbd.c: Keyboard on %s reports too many keys pressed.\n", serio->phys);
+#endif
                        goto out;
        }
 
@@ -458,7 +490,6 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
                                atkbd->time = jiffies + msecs_to_jiffies(dev->rep[REP_DELAY]) / 2;
                        }
 
-                       input_regs(dev, regs);
                        input_event(dev, EV_KEY, keycode, value);
                        input_sync(dev);
 
@@ -469,7 +500,6 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
        }
 
        if (atkbd->scroll) {
-               input_regs(dev, regs);
                if (click != -1)
                        input_report_key(dev, BTN_MIDDLE, click);
                input_report_rel(dev, REL_WHEEL, scroll);
@@ -788,12 +818,7 @@ static void atkbd_disconnect(struct serio *serio)
        synchronize_sched();  /* Allow atkbd_interrupt()s to complete. */
        flush_scheduled_work();
 
-       device_remove_file(&serio->dev, &atkbd_attr_extra);
-       device_remove_file(&serio->dev, &atkbd_attr_scroll);
-       device_remove_file(&serio->dev, &atkbd_attr_set);
-       device_remove_file(&serio->dev, &atkbd_attr_softrepeat);
-       device_remove_file(&serio->dev, &atkbd_attr_softraw);
-
+       sysfs_remove_group(&serio->dev.kobj, &atkbd_attribute_group);
        input_unregister_device(atkbd->dev);
        serio_close(serio);
        serio_set_drvdata(serio, NULL);
@@ -963,11 +988,7 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv)
        atkbd_set_keycode_table(atkbd);
        atkbd_set_device_attrs(atkbd);
 
-       device_create_file(&serio->dev, &atkbd_attr_extra);
-       device_create_file(&serio->dev, &atkbd_attr_scroll);
-       device_create_file(&serio->dev, &atkbd_attr_set);
-       device_create_file(&serio->dev, &atkbd_attr_softrepeat);
-       device_create_file(&serio->dev, &atkbd_attr_softraw);
+       sysfs_create_group(&serio->dev.kobj, &atkbd_attribute_group);
 
        atkbd_enable(atkbd);
 
@@ -1261,6 +1282,11 @@ static ssize_t atkbd_set_softraw(struct atkbd *atkbd, const char *buf, size_t co
        return count;
 }
 
+static ssize_t atkbd_show_err_count(struct atkbd *atkbd, char *buf)
+{
+       return sprintf(buf, "%lu\n", atkbd->err_count);
+}
+
 
 static int __init atkbd_init(void)
 {
index 1e03153b9bca99348c11e55e2d85ced8c05ad84b..befdd6006b500d093be9036386b491da39496c9b 100644 (file)
@@ -129,7 +129,7 @@ static inline void corgikbd_reset_col(int col)
  */
 
 /* Scan the hardware keyboard and push any changes up through the input layer */
-static void corgikbd_scankeyboard(struct corgikbd *corgikbd_data, struct pt_regs *regs)
+static void corgikbd_scankeyboard(struct corgikbd *corgikbd_data)
 {
        unsigned int row, col, rowd;
        unsigned long flags;
@@ -140,9 +140,6 @@ static void corgikbd_scankeyboard(struct corgikbd *corgikbd_data, struct pt_regs
 
        spin_lock_irqsave(&corgikbd_data->lock, flags);
 
-       if (regs)
-               input_regs(corgikbd_data->input, regs);
-
        num_pressed = 0;
        for (col = 0; col < KB_COLS; col++) {
                /*
@@ -191,14 +188,14 @@ static void corgikbd_scankeyboard(struct corgikbd *corgikbd_data, struct pt_regs
 /*
  * corgi keyboard interrupt handler.
  */
-static irqreturn_t corgikbd_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t corgikbd_interrupt(int irq, void *dev_id)
 {
        struct corgikbd *corgikbd_data = dev_id;
 
        if (!timer_pending(&corgikbd_data->timer)) {
                /** wait chattering delay **/
                udelay(20);
-               corgikbd_scankeyboard(corgikbd_data, regs);
+               corgikbd_scankeyboard(corgikbd_data);
        }
 
        return IRQ_HANDLED;
@@ -210,7 +207,7 @@ static irqreturn_t corgikbd_interrupt(int irq, void *dev_id, struct pt_regs *reg
 static void corgikbd_timer_callback(unsigned long data)
 {
        struct corgikbd *corgikbd_data = (struct corgikbd *) data;
-       corgikbd_scankeyboard(corgikbd_data, NULL);
+       corgikbd_scankeyboard(corgikbd_data);
 }
 
 /*
index 2e4abdc26367622c537bed24d99c2d92d8c83718..e774dd31e99b7bf2ca7d2503f5d84decb08b1daa 100644 (file)
@@ -198,7 +198,7 @@ static void hil_kbd_process_err(struct hil_kbd *kbd) {
 }
 
 static irqreturn_t hil_kbd_interrupt(struct serio *serio, 
-             unsigned char data, unsigned int flags, struct pt_regs *regs)
+             unsigned char data, unsigned int flags)
 {
        struct hil_kbd *kbd;
        hil_packet packet;
@@ -328,7 +328,7 @@ static int hil_kbd_connect(struct serio *serio, struct serio_driver *drv)
        kbd->dev->id.vendor     = PCI_VENDOR_ID_HP;
        kbd->dev->id.product    = 0x0001; /* TODO: get from kbd->rsc */
        kbd->dev->id.version    = 0x0100; /* TODO: get from kbd->rsc */
-       kbd->dev->dev           = &serio->dev;
+       kbd->dev->cdev.dev      = &serio->dev;
 
        for (i = 0; i < 128; i++) {
                set_bit(hil_kbd_set1[i], kbd->dev->keybit);
index d22c7c6242968ad1cc12c2f1b95bf94065ee1466..54bc569db4b014e999068a57c5ae11b1f41f6a69 100644 (file)
@@ -150,7 +150,7 @@ static inline void handle_data(unsigned char s, unsigned char c)
 /* 
  * Handle HIL interrupts.
  */
-static irqreturn_t hil_interrupt(int irq, void *handle, struct pt_regs *regs)
+static irqreturn_t hil_interrupt(int irq, void *handle)
 {
        unsigned char s, c;
        
index 5174224cadb469ece8be256dbeff4d7699f4cf2e..708d5a1bc3d28466e8fcb93c7d357cdc1222d36b 100644 (file)
@@ -453,8 +453,7 @@ lkkbd_detection_done (struct lkkbd *lk)
  * is received.
  */
 static irqreturn_t
-lkkbd_interrupt (struct serio *serio, unsigned char data, unsigned int flags,
-               struct pt_regs *regs)
+lkkbd_interrupt (struct serio *serio, unsigned char data, unsigned int flags)
 {
        struct lkkbd *lk = serio_get_drvdata (serio);
        int i;
@@ -473,7 +472,6 @@ lkkbd_interrupt (struct serio *serio, unsigned char data, unsigned int flags,
 
        switch (data) {
                case LK_ALL_KEYS_UP:
-                       input_regs (lk->dev, regs);
                        for (i = 0; i < ARRAY_SIZE (lkkbd_keycode); i++)
                                if (lk->keycode[i] != KEY_RESERVED)
                                        input_report_key (lk->dev, lk->keycode[i], 0);
@@ -501,7 +499,6 @@ lkkbd_interrupt (struct serio *serio, unsigned char data, unsigned int flags,
 
                default:
                        if (lk->keycode[data] != KEY_RESERVED) {
-                               input_regs (lk->dev, regs);
                                if (!test_bit (lk->keycode[data], lk->dev->key))
                                        input_report_key (lk->dev, lk->keycode[data], 1);
                                else
index 83906f80ba21c31aa0cc5eb443926b972cdefd37..5788dbc317bba3226266b28e78dc0890fe7125e7 100644 (file)
@@ -126,7 +126,7 @@ static inline void locomokbd_reset_col(unsigned long membase, int col)
  */
 
 /* Scan the hardware keyboard and push any changes up through the input layer */
-static void locomokbd_scankeyboard(struct locomokbd *locomokbd, struct pt_regs *regs)
+static void locomokbd_scankeyboard(struct locomokbd *locomokbd)
 {
        unsigned int row, col, rowd, scancode;
        unsigned long flags;
@@ -135,8 +135,6 @@ static void locomokbd_scankeyboard(struct locomokbd *locomokbd, struct pt_regs *
 
        spin_lock_irqsave(&locomokbd->lock, flags);
 
-       input_regs(locomokbd->input, regs);
-
        locomokbd_charge_all(membase);
 
        num_pressed = 0;
@@ -171,13 +169,13 @@ static void locomokbd_scankeyboard(struct locomokbd *locomokbd, struct pt_regs *
 /*
  * LoCoMo keyboard interrupt handler.
  */
-static irqreturn_t locomokbd_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t locomokbd_interrupt(int irq, void *dev_id)
 {
        struct locomokbd *locomokbd = dev_id;
        /** wait chattering delay **/
        udelay(100);
 
-       locomokbd_scankeyboard(locomokbd, regs);
+       locomokbd_scankeyboard(locomokbd);
 
        return IRQ_HANDLED;
 }
@@ -188,7 +186,7 @@ static irqreturn_t locomokbd_interrupt(int irq, void *dev_id, struct pt_regs *re
 static void locomokbd_timer_callback(unsigned long data)
 {
        struct locomokbd *locomokbd = (struct locomokbd *) data;
-       locomokbd_scankeyboard(locomokbd, NULL);
+       locomokbd_scankeyboard(locomokbd);
 }
 
 static int locomokbd_probe(struct locomo_dev *dev)
index 40a3f551247e2db3dfd279ea3f74017a488a1c6e..9282e4e082bd10ad8fb499d8dc5f47b3909f85af 100644 (file)
@@ -65,13 +65,12 @@ struct nkbd {
 };
 
 static irqreturn_t nkbd_interrupt(struct serio *serio,
-               unsigned char data, unsigned int flags, struct pt_regs *regs)
+               unsigned char data, unsigned int flags)
 {
        struct nkbd *nkbd = serio_get_drvdata(serio);
 
        /* invalid scan codes are probably the init sequence, so we ignore them */
        if (nkbd->keycode[data & NKBD_KEY]) {
-               input_regs(nkbd->dev, regs);
                input_report_key(nkbd->dev, nkbd->keycode[data & NKBD_KEY], data & NKBD_PRESS);
                input_sync(nkbd->dev);
        }
index d436287d1d2edcc5ff62abdfb77f3202e7c577ae..5680a6d95b2b335c36c8bd6eed067ee87d2d085e 100644 (file)
@@ -97,8 +97,7 @@ static u8 get_row_gpio_val(struct omap_kp *omap_kp)
 #define                get_row_gpio_val(x)     0
 #endif
 
-static irqreturn_t omap_kp_interrupt(int irq, void *dev_id,
-                                    struct pt_regs *regs)
+static irqreturn_t omap_kp_interrupt(int irq, void *dev_id)
 {
        struct omap_kp *omap_kp = dev_id;
 
index e385710233f4fe18bc89eab48c4885fad18cfc40..28b2748e82d087bf4255d40c9ecca17f779811d6 100644 (file)
@@ -176,7 +176,7 @@ static inline int spitzkbd_get_row_status(int col)
  */
 
 /* Scan the hardware keyboard and push any changes up through the input layer */
-static void spitzkbd_scankeyboard(struct spitzkbd *spitzkbd_data, struct pt_regs *regs)
+static void spitzkbd_scankeyboard(struct spitzkbd *spitzkbd_data)
 {
        unsigned int row, col, rowd;
        unsigned long flags;
@@ -187,8 +187,6 @@ static void spitzkbd_scankeyboard(struct spitzkbd *spitzkbd_data, struct pt_regs
 
        spin_lock_irqsave(&spitzkbd_data->lock, flags);
 
-       input_regs(spitzkbd_data->input, regs);
-
        num_pressed = 0;
        for (col = 0; col < KB_COLS; col++) {
                /*
@@ -239,14 +237,14 @@ static void spitzkbd_scankeyboard(struct spitzkbd *spitzkbd_data, struct pt_regs
 /*
  * spitz keyboard interrupt handler.
  */
-static irqreturn_t spitzkbd_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t spitzkbd_interrupt(int irq, void *dev_id)
 {
        struct spitzkbd *spitzkbd_data = dev_id;
 
        if (!timer_pending(&spitzkbd_data->timer)) {
                /** wait chattering delay **/
                udelay(20);
-               spitzkbd_scankeyboard(spitzkbd_data, regs);
+               spitzkbd_scankeyboard(spitzkbd_data);
        }
 
        return IRQ_HANDLED;
@@ -259,7 +257,7 @@ static void spitzkbd_timer_callback(unsigned long data)
 {
        struct spitzkbd *spitzkbd_data = (struct spitzkbd *) data;
 
-       spitzkbd_scankeyboard(spitzkbd_data, NULL);
+       spitzkbd_scankeyboard(spitzkbd_data);
 }
 
 /*
@@ -267,7 +265,7 @@ static void spitzkbd_timer_callback(unsigned long data)
  * We debounce the switches and pass them to the input system.
  */
 
-static irqreturn_t spitzkbd_hinge_isr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t spitzkbd_hinge_isr(int irq, void *dev_id)
 {
        struct spitzkbd *spitzkbd_data = dev_id;
 
index 04c54c57f25c6f0bf661cd3d5273238c39f195f8..e60937d17b1c286a6341b0d3adf3b0645352a079 100644 (file)
@@ -71,13 +71,12 @@ struct skbd {
 };
 
 static irqreturn_t skbd_interrupt(struct serio *serio, unsigned char data,
-                                 unsigned int flags, struct pt_regs *regs)
+                                 unsigned int flags)
 {
        struct skbd *skbd = serio_get_drvdata(serio);
        struct input_dev *dev = skbd->dev;
 
        if (skbd->keycode[data & SKBD_KEY_MASK]) {
-               input_regs(dev, regs);
                input_report_key(dev, skbd->keycode[data & SKBD_KEY_MASK],
                                 !(data & SKBD_RELEASE));
                input_sync(dev);
index 9dbd7b85686d52af9eafaaca6ca35f54b6b935cb..cac4781103c3ed1cb45a31d22bc0486aa5492e02 100644 (file)
@@ -94,7 +94,7 @@ struct sunkbd {
  */
 
 static irqreturn_t sunkbd_interrupt(struct serio *serio,
-               unsigned char data, unsigned int flags, struct pt_regs *regs)
+               unsigned char data, unsigned int flags)
 {
        struct sunkbd* sunkbd = serio_get_drvdata(serio);
 
@@ -129,7 +129,6 @@ static irqreturn_t sunkbd_interrupt(struct serio *serio,
                                break;
 
                        if (sunkbd->keycode[data & SUNKBD_KEY]) {
-                               input_regs(sunkbd->dev, regs);
                                 input_report_key(sunkbd->dev, sunkbd->keycode[data & SUNKBD_KEY], !(data & SUNKBD_RELEASE));
                                input_sync(sunkbd->dev);
                         } else {
index 0821d53cf0c1d8d9d9538fa0af73f051e14b5d68..8c11dc935454bba0b02758e4f2045f5f104823fc 100644 (file)
@@ -64,7 +64,7 @@ struct xtkbd {
 };
 
 static irqreturn_t xtkbd_interrupt(struct serio *serio,
-       unsigned char data, unsigned int flags, struct pt_regs *regs)
+       unsigned char data, unsigned int flags)
 {
        struct xtkbd *xtkbd = serio_get_drvdata(serio);
 
@@ -75,7 +75,6 @@ static irqreturn_t xtkbd_interrupt(struct serio *serio,
                default:
 
                        if (xtkbd->keycode[data & XTKBD_KEY]) {
-                               input_regs(xtkbd->dev, regs);
                                input_report_key(xtkbd->dev, xtkbd->keycode[data & XTKBD_KEY], !(data & XTKBD_RELEASE));
                                input_sync(xtkbd->dev);
                        } else {
index a6dfc74557339c46e13d6cac040443c63ccec68d..ba0e88c64e1ef93befa1c6e0f4483845cb88ebb2 100644 (file)
@@ -73,7 +73,7 @@ config INPUT_UINPUT
 
 config HP_SDC_RTC
        tristate "HP SDC Real Time Clock"       
-       depends on GSC
+       depends on GSC || HP300
        select HP_SDC
        help
          Say Y here if you want to support the built-in real time clock
index 1be963961c15734bfd923c07c589ab6a1a8f2a47..ab4da79ee560d9279afc989d129715c45dd1593c 100644 (file)
@@ -60,7 +60,7 @@ static struct fasync_struct *hp_sdc_rtc_async_queue;
 
 static DECLARE_WAIT_QUEUE_HEAD(hp_sdc_rtc_wait);
 
-static ssize_t hp_sdc_rtc_read(struct file *file, char *buf,
+static ssize_t hp_sdc_rtc_read(struct file *file, char __user *buf,
                               size_t count, loff_t *ppos);
 
 static int hp_sdc_rtc_ioctl(struct inode *inode, struct file *file,
@@ -385,14 +385,14 @@ static int hp_sdc_rtc_set_i8042timer (struct timeval *setto, uint8_t setcmd)
        return 0;
 }
 
-static ssize_t hp_sdc_rtc_read(struct file *file, char *buf,
+static ssize_t hp_sdc_rtc_read(struct file *file, char __user *buf,
                               size_t count, loff_t *ppos) {
        ssize_t retval;
 
         if (count < sizeof(unsigned long))
                 return -EINVAL;
 
-       retval = put_user(68, (unsigned long *)buf);
+       retval = put_user(68, (unsigned long __user *)buf);
        return retval;
 }
 
@@ -696,7 +696,7 @@ static int __init hp_sdc_rtc_init(void)
        if ((ret = hp_sdc_request_timer_irq(&hp_sdc_rtc_isr)))
                return ret;
        misc_register(&hp_sdc_rtc_dev);
-        create_proc_read_entry ("driver/rtc", 0, 0, 
+        create_proc_read_entry ("driver/rtc", 0, NULL,
                                hp_sdc_rtc_read_proc, NULL);
 
        printk(KERN_INFO "HP i8042 SDC + MSM-58321 RTC support loaded "
index 805b636e73d909927d91f6edc977337428b41385..105c6fc27823e368cd445d63a8787b5fdfe9ac28 100644 (file)
@@ -79,7 +79,7 @@ static int ixp4xx_spkr_event(struct input_dev *dev, unsigned int type, unsigned
        return 0;
 }
 
-static irqreturn_t ixp4xx_spkr_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t ixp4xx_spkr_interrupt(int irq, void *dev_id)
 {
        /* clear interrupt */
        *IXP4XX_OSST = IXP4XX_OSST_TIMER_2_PEND;
index 4639537336fc116c9eeb62dcbb5741027e342e7b..7b9d1c1da41a7d676737e7adc92c1f1700e1d6a1 100644 (file)
@@ -17,7 +17,7 @@
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 59 Temple Place Suite 330, Boston, MA 02111-1307, USA.
  */
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/dmi.h>
 #include <linux/init.h>
 #include <linux/input.h>
index f15ccf781688dd7973c5fd16a422bb31c5c28af1..35d998c3e578a7194900c7e76567781ef32103b9 100644 (file)
@@ -119,7 +119,7 @@ config MOUSE_VSXXXAA
 
 config MOUSE_HIL
        tristate "HIL pointers (mice etc)."     
-       depends on GSC
+       depends on GSC || HP300
        select HP_SDC
        select HIL_MLC
        help
index 450b68a619fd4ab375db67d0b85567a1ef5455de..4e71a66fc7fc441cbaff02fd7eaf611a159a7ded 100644 (file)
@@ -76,7 +76,7 @@ static const struct alps_model_info alps_model_data[] = {
  * on a dualpoint, etc.
  */
 
-static void alps_process_packet(struct psmouse *psmouse, struct pt_regs *regs)
+static void alps_process_packet(struct psmouse *psmouse)
 {
        struct alps_data *priv = psmouse->private;
        unsigned char *packet = psmouse->packet;
@@ -85,8 +85,6 @@ static void alps_process_packet(struct psmouse *psmouse, struct pt_regs *regs)
        int x, y, z, ges, fin, left, right, middle;
        int back = 0, forward = 0;
 
-       input_regs(dev, regs);
-
        if ((packet[0] & 0xc8) == 0x08) {   /* 3-byte PS/2 packet */
                input_report_key(dev2, BTN_LEFT,   packet[0] & 1);
                input_report_key(dev2, BTN_RIGHT,  packet[0] & 2);
@@ -181,13 +179,13 @@ static void alps_process_packet(struct psmouse *psmouse, struct pt_regs *regs)
        input_sync(dev);
 }
 
-static psmouse_ret_t alps_process_byte(struct psmouse *psmouse, struct pt_regs *regs)
+static psmouse_ret_t alps_process_byte(struct psmouse *psmouse)
 {
        struct alps_data *priv = psmouse->private;
 
        if ((psmouse->packet[0] & 0xc8) == 0x08) { /* PS/2 packet */
                if (psmouse->pktcnt == 3) {
-                       alps_process_packet(psmouse, regs);
+                       alps_process_packet(psmouse);
                        return PSMOUSE_FULL_PACKET;
                }
                return PSMOUSE_GOOD_DATA;
@@ -202,7 +200,7 @@ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse, struct pt_regs *
                return PSMOUSE_BAD_DATA;
 
        if (psmouse->pktcnt == 6) {
-               alps_process_packet(psmouse, regs);
+               alps_process_packet(psmouse);
                return PSMOUSE_FULL_PACKET;
        }
 
index c8b2cc9f184c7355b1004d913cc5c0f7ace57c29..599a7b2dc5191f7f057f0b4a2996a32c1c162d10 100644 (file)
@@ -36,7 +36,7 @@ MODULE_LICENSE("GPL");
 static int amimouse_lastx, amimouse_lasty;
 static struct input_dev *amimouse_dev;
 
-static irqreturn_t amimouse_interrupt(int irq, void *dummy, struct pt_regs *fp)
+static irqreturn_t amimouse_interrupt(int irq, void *dummy)
 {
        unsigned short joy0dat, potgor;
        int nx, ny, dx, dy;
@@ -59,8 +59,6 @@ static irqreturn_t amimouse_interrupt(int irq, void *dummy, struct pt_regs *fp)
 
        potgor = amiga_custom.potgor;
 
-       input_regs(amimouse_dev, fp);
-
        input_report_rel(amimouse_dev, REL_X, dx);
        input_report_rel(amimouse_dev, REL_Y, dy);
 
index 69f02178c528c87178a3ae188181ea3c2ae581d9..4f2b503c1ac72ee1d05ab2533f97f46d1193a3e2 100644 (file)
@@ -190,7 +190,7 @@ static void hil_ptr_process_err(struct hil_ptr *ptr) {
 }
 
 static irqreturn_t hil_ptr_interrupt(struct serio *serio, 
-        unsigned char data, unsigned int flags, struct pt_regs *regs)
+        unsigned char data, unsigned int flags)
 {
        struct hil_ptr *ptr;
        hil_packet packet;
@@ -375,7 +375,7 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver)
        ptr->dev->id.vendor     = PCI_VENDOR_ID_HP;
        ptr->dev->id.product    = 0x0001; /* TODO: get from ptr->rsc */
        ptr->dev->id.version    = 0x0100; /* TODO: get from ptr->rsc */
-       ptr->dev->dev           = &serio->dev;
+       ptr->dev->cdev.dev      = &serio->dev;
 
        input_register_device(ptr->dev);
        printk(KERN_INFO "input: %s (%s), ID: %d\n",
index 50f1fed10be404f759a8b138f6a35f6c9e9c38b9..e1252fa9a10788b88f38005b0eb78ebd3cfa41c3 100644 (file)
@@ -88,15 +88,13 @@ __obsolete_setup("inport_irq=");
 
 static struct input_dev *inport_dev;
 
-static irqreturn_t inport_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t inport_interrupt(int irq, void *dev_id)
 {
        unsigned char buttons;
 
        outb(INPORT_REG_MODE, INPORT_CONTROL_PORT);
        outb(INPORT_MODE_HOLD | INPORT_MODE_IRQ | INPORT_MODE_BASE, INPORT_DATA_PORT);
 
-       input_regs(inport_dev, regs);
-
        outb(INPORT_REG_X, INPORT_CONTROL_PORT);
        input_report_rel(inport_dev, REL_X, inb(INPORT_DATA_PORT));
 
index 5e9d25067513850920d4589c029f4056f4fd3625..c57e8853b94900a42d795ddaf4af86f38aa59f7e 100644 (file)
@@ -62,7 +62,7 @@ static struct dmi_system_id lifebook_dmi_table[] = {
 };
 
 
-static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse, struct pt_regs *regs)
+static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse)
 {
        unsigned char *packet = psmouse->packet;
        struct input_dev *dev = psmouse->dev;
@@ -70,8 +70,6 @@ static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse, struct pt_re
        if (psmouse->pktcnt != 3)
                return PSMOUSE_GOOD_DATA;
 
-       input_regs(dev, regs);
-
        /* calculate X and Y */
        if ((packet[0] & 0x08) == 0x00) {
                input_report_abs(dev, ABS_X,
index 9c7ce38806d7ca74a29d3481661cccb8730f03d8..8e9c2f3d69a860a7017e4459881043327bb174c3 100644 (file)
@@ -79,7 +79,7 @@ __obsolete_setup("logibm_irq=");
 
 static struct input_dev *logibm_dev;
 
-static irqreturn_t logibm_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t logibm_interrupt(int irq, void *dev_id)
 {
        char dx, dy;
        unsigned char buttons;
@@ -95,7 +95,6 @@ static irqreturn_t logibm_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        dy |= (buttons & 0xf) << 4;
        buttons = ~buttons >> 5;
 
-       input_regs(logibm_dev, regs);
        input_report_rel(logibm_dev, REL_X, dx);
        input_report_rel(logibm_dev, REL_Y, dy);
        input_report_key(logibm_dev, BTN_RIGHT,  buttons & 1);
index 7972eecbcfe4184863bdb84e0a3dda6eff31f854..8a4f862709e7490c33cdeba1a3d2adb3ac8737d5 100644 (file)
@@ -39,7 +39,7 @@ struct ps2pp_info {
  * Process a PS2++ or PS2T++ packet.
  */
 
-static psmouse_ret_t ps2pp_process_byte(struct psmouse *psmouse, struct pt_regs *regs)
+static psmouse_ret_t ps2pp_process_byte(struct psmouse *psmouse)
 {
        struct input_dev *dev = psmouse->dev;
        unsigned char *packet = psmouse->packet;
@@ -51,8 +51,6 @@ static psmouse_ret_t ps2pp_process_byte(struct psmouse *psmouse, struct pt_regs
  * Full packet accumulated, process it
  */
 
-       input_regs(dev, regs);
-
        if ((packet[0] & 0x48) == 0x48 && (packet[1] & 0x02) == 0x02) {
 
                /* Logitech extended packet */
index d284ea7121516c9ebfb114732e69f3c699a32115..8c075aa7223b58978f61bd7924cb77b17f1f7237 100644 (file)
@@ -57,7 +57,7 @@ static struct input_dev *pc110pad_dev;
 static int pc110pad_data[3];
 static int pc110pad_count;
 
-static irqreturn_t pc110pad_interrupt(int irq, void *ptr, struct pt_regs *regs)
+static irqreturn_t pc110pad_interrupt(int irq, void *ptr)
 {
        int value     = inb_p(pc110pad_io);
        int handshake = inb_p(pc110pad_io + 2);
@@ -71,7 +71,6 @@ static irqreturn_t pc110pad_interrupt(int irq, void *ptr, struct pt_regs *regs)
        if (pc110pad_count < 3)
                return IRQ_HANDLED;
 
-       input_regs(pc110pad_dev, regs);
        input_report_key(pc110pad_dev, BTN_TOUCH,
                pc110pad_data[0] & 0x01);
        input_report_abs(pc110pad_dev, ABS_X,
@@ -91,9 +90,9 @@ static void pc110pad_close(struct input_dev *dev)
 
 static int pc110pad_open(struct input_dev *dev)
 {
-       pc110pad_interrupt(0, NULL, NULL);
-       pc110pad_interrupt(0, NULL, NULL);
-       pc110pad_interrupt(0, NULL, NULL);
+       pc110pad_interrupt(0, NULL);
+       pc110pad_interrupt(0, NULL);
+       pc110pad_interrupt(0, NULL);
        outb(PC110PAD_ON, pc110pad_io + 2);
        pc110pad_count = 0;
 
index 9fb7eb6b0f71f3bb9f5d7972e99627146a463fa7..6f9b2c7cc9c28903c05a51b682975c112996d129 100644 (file)
@@ -124,7 +124,7 @@ struct psmouse_protocol {
  * relevant events to the input module once full packet has arrived.
  */
 
-static psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse, struct pt_regs *regs)
+static psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse)
 {
        struct input_dev *dev = psmouse->dev;
        unsigned char *packet = psmouse->packet;
@@ -136,8 +136,6 @@ static psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse, struct pt_reg
  * Full packet accumulated, process it
  */
 
-       input_regs(dev, regs);
-
 /*
  * Scroll wheel on IntelliMice, scroll buttons on NetMice
  */
@@ -231,9 +229,9 @@ static void psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_st
  * by calling corresponding protocol handler.
  */
 
-static int psmouse_handle_byte(struct psmouse *psmouse, struct pt_regs *regs)
+static int psmouse_handle_byte(struct psmouse *psmouse)
 {
-       psmouse_ret_t rc = psmouse->protocol_handler(psmouse, regs);
+       psmouse_ret_t rc = psmouse->protocol_handler(psmouse);
 
        switch (rc) {
                case PSMOUSE_BAD_DATA:
@@ -271,7 +269,7 @@ static int psmouse_handle_byte(struct psmouse *psmouse, struct pt_regs *regs)
  */
 
 static irqreturn_t psmouse_interrupt(struct serio *serio,
-               unsigned char data, unsigned int flags, struct pt_regs *regs)
+               unsigned char data, unsigned int flags)
 {
        struct psmouse *psmouse = serio_get_drvdata(serio);
 
@@ -327,7 +325,7 @@ static irqreturn_t psmouse_interrupt(struct serio *serio,
  * Not a new device, try processing first byte normally
  */
                psmouse->pktcnt = 1;
-               if (psmouse_handle_byte(psmouse, regs))
+               if (psmouse_handle_byte(psmouse))
                        goto out;
 
                psmouse->packet[psmouse->pktcnt++] = data;
@@ -346,7 +344,7 @@ static irqreturn_t psmouse_interrupt(struct serio *serio,
        }
 
        psmouse->last = jiffies;
-       psmouse_handle_byte(psmouse, regs);
+       psmouse_handle_byte(psmouse);
 
  out:
        return IRQ_HANDLED;
@@ -940,7 +938,7 @@ static void psmouse_resync(void *p)
                        psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);
                        for (i = 0; i < psmouse->pktsize; i++) {
                                psmouse->pktcnt++;
-                               rc = psmouse->protocol_handler(psmouse, NULL);
+                               rc = psmouse->protocol_handler(psmouse);
                                if (rc != PSMOUSE_GOOD_DATA)
                                        break;
                        }
index 4d9107fba6a10e8da641a3b5e5630924b66fe110..1b74cae8a556d5ed1287c9881ddbfc50aebd254f 100644 (file)
@@ -62,7 +62,7 @@ struct psmouse {
        unsigned int resync_time;
        unsigned int smartscroll;       /* Logitech only */
 
-       psmouse_ret_t (*protocol_handler)(struct psmouse *psmouse, struct pt_regs *regs);
+       psmouse_ret_t (*protocol_handler)(struct psmouse *psmouse);
        void (*set_rate)(struct psmouse *psmouse, unsigned int rate);
        void (*set_resolution)(struct psmouse *psmouse, unsigned int resolution);
 
index 872b30bf7aadce2fc8f267048d44dbfc3d06b5db..ea0468569610a13065e432283612903dc582fd15 100644 (file)
@@ -36,7 +36,7 @@ MODULE_LICENSE("GPL");
 static short rpcmouse_lastx, rpcmouse_lasty;
 static struct input_dev *rpcmouse_dev;
 
-static irqreturn_t rpcmouse_irq(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t rpcmouse_irq(int irq, void *dev_id)
 {
        struct input_dev *dev = dev_id;
        short x, y, dx, dy, b;
@@ -51,8 +51,6 @@ static irqreturn_t rpcmouse_irq(int irq, void *dev_id, struct pt_regs *regs)
        rpcmouse_lastx = x;
        rpcmouse_lasty = y;
 
-       input_regs(dev, regs);
-
        input_report_rel(dev, REL_X, dx);
        input_report_rel(dev, REL_Y, -dy);
 
index 680b323538847cbc53dfa7a99f9d5ae9b97d97ce..2a272c5daf08b2284f4a6f24f10e70813c38c822 100644 (file)
@@ -61,13 +61,11 @@ struct sermouse {
  * second, which is as good as a PS/2 or USB mouse.
  */
 
-static void sermouse_process_msc(struct sermouse *sermouse, signed char data, struct pt_regs *regs)
+static void sermouse_process_msc(struct sermouse *sermouse, signed char data)
 {
        struct input_dev *dev = sermouse->dev;
        signed char *buf = sermouse->buf;
 
-       input_regs(dev, regs);
-
        switch (sermouse->count) {
 
                case 0:
@@ -104,15 +102,13 @@ static void sermouse_process_msc(struct sermouse *sermouse, signed char data, st
  * standard 3-byte packets and 1200 bps.
  */
 
-static void sermouse_process_ms(struct sermouse *sermouse, signed char data, struct pt_regs *regs)
+static void sermouse_process_ms(struct sermouse *sermouse, signed char data)
 {
        struct input_dev *dev = sermouse->dev;
        signed char *buf = sermouse->buf;
 
        if (data & 0x40) sermouse->count = 0;
 
-       input_regs(dev, regs);
-
        switch (sermouse->count) {
 
                case 0:
@@ -206,7 +202,7 @@ static void sermouse_process_ms(struct sermouse *sermouse, signed char data, str
  */
 
 static irqreturn_t sermouse_interrupt(struct serio *serio,
-               unsigned char data, unsigned int flags, struct pt_regs *regs)
+               unsigned char data, unsigned int flags)
 {
        struct sermouse *sermouse = serio_get_drvdata(serio);
 
@@ -214,9 +210,9 @@ static irqreturn_t sermouse_interrupt(struct serio *serio,
        sermouse->last = jiffies;
 
        if (sermouse->type > SERIO_SUN)
-               sermouse_process_ms(sermouse, data, regs);
+               sermouse_process_ms(sermouse, data);
        else
-               sermouse_process_msc(sermouse, data, regs);
+               sermouse_process_msc(sermouse, data);
        return IRQ_HANDLED;
 }
 
index 392108c436baca504abd345b4013ae90799e41e5..49ac696d6cff5c8f234e1536cafee778a3ccfecd 100644 (file)
@@ -216,13 +216,13 @@ static void synaptics_pass_pt_packet(struct serio *ptport, unsigned char *packet
        struct psmouse *child = serio_get_drvdata(ptport);
 
        if (child && child->state == PSMOUSE_ACTIVATED) {
-               serio_interrupt(ptport, packet[1], 0, NULL);
-               serio_interrupt(ptport, packet[4], 0, NULL);
-               serio_interrupt(ptport, packet[5], 0, NULL);
+               serio_interrupt(ptport, packet[1], 0);
+               serio_interrupt(ptport, packet[4], 0);
+               serio_interrupt(ptport, packet[5], 0);
                if (child->pktsize == 4)
-                       serio_interrupt(ptport, packet[2], 0, NULL);
+                       serio_interrupt(ptport, packet[2], 0);
        } else
-               serio_interrupt(ptport, packet[1], 0, NULL);
+               serio_interrupt(ptport, packet[1], 0);
 }
 
 static void synaptics_pt_activate(struct psmouse *psmouse)
@@ -469,13 +469,10 @@ static unsigned char synaptics_detect_pkt_type(struct psmouse *psmouse)
        return SYN_NEWABS_STRICT;
 }
 
-static psmouse_ret_t synaptics_process_byte(struct psmouse *psmouse, struct pt_regs *regs)
+static psmouse_ret_t synaptics_process_byte(struct psmouse *psmouse)
 {
-       struct input_dev *dev = psmouse->dev;
        struct synaptics_data *priv = psmouse->private;
 
-       input_regs(dev, regs);
-
        if (psmouse->pktcnt >= 6) { /* Full packet received */
                if (unlikely(priv->pkt_type == SYN_NEWABS))
                        priv->pkt_type = synaptics_detect_pkt_type(psmouse);
index 47edcfd022ba840bc4b1d65a4cfc1509216b8de5..ffdb50eee93d6df28f0df7e7ac27fd4dca21dde0 100644 (file)
@@ -211,7 +211,7 @@ vsxxxaa_smells_like_packet (struct vsxxxaa *mouse, unsigned char type, size_t le
 }
 
 static void
-vsxxxaa_handle_REL_packet (struct vsxxxaa *mouse, struct pt_regs *regs)
+vsxxxaa_handle_REL_packet (struct vsxxxaa *mouse)
 {
        struct input_dev *dev = mouse->dev;
        unsigned char *buf = mouse->buf;
@@ -258,7 +258,6 @@ vsxxxaa_handle_REL_packet (struct vsxxxaa *mouse, struct pt_regs *regs)
        /*
         * Report what we've found so far...
         */
-       input_regs (dev, regs);
        input_report_key (dev, BTN_LEFT, left);
        input_report_key (dev, BTN_MIDDLE, middle);
        input_report_key (dev, BTN_RIGHT, right);
@@ -269,7 +268,7 @@ vsxxxaa_handle_REL_packet (struct vsxxxaa *mouse, struct pt_regs *regs)
 }
 
 static void
-vsxxxaa_handle_ABS_packet (struct vsxxxaa *mouse, struct pt_regs *regs)
+vsxxxaa_handle_ABS_packet (struct vsxxxaa *mouse)
 {
        struct input_dev *dev = mouse->dev;
        unsigned char *buf = mouse->buf;
@@ -312,7 +311,6 @@ vsxxxaa_handle_ABS_packet (struct vsxxxaa *mouse, struct pt_regs *regs)
        /*
         * Report what we've found so far...
         */
-       input_regs (dev, regs);
        input_report_key (dev, BTN_LEFT, left);
        input_report_key (dev, BTN_MIDDLE, middle);
        input_report_key (dev, BTN_RIGHT, right);
@@ -323,7 +321,7 @@ vsxxxaa_handle_ABS_packet (struct vsxxxaa *mouse, struct pt_regs *regs)
 }
 
 static void
-vsxxxaa_handle_POR_packet (struct vsxxxaa *mouse, struct pt_regs *regs)
+vsxxxaa_handle_POR_packet (struct vsxxxaa *mouse)
 {
        struct input_dev *dev = mouse->dev;
        unsigned char *buf = mouse->buf;
@@ -367,7 +365,6 @@ vsxxxaa_handle_POR_packet (struct vsxxxaa *mouse, struct pt_regs *regs)
 
        if (error <= 0x1f) {
                /* No (serious) error. Report buttons */
-               input_regs (dev, regs);
                input_report_key (dev, BTN_LEFT, left);
                input_report_key (dev, BTN_MIDDLE, middle);
                input_report_key (dev, BTN_RIGHT, right);
@@ -395,7 +392,7 @@ vsxxxaa_handle_POR_packet (struct vsxxxaa *mouse, struct pt_regs *regs)
 }
 
 static void
-vsxxxaa_parse_buffer (struct vsxxxaa *mouse, struct pt_regs *regs)
+vsxxxaa_parse_buffer (struct vsxxxaa *mouse)
 {
        unsigned char *buf = mouse->buf;
        int stray_bytes;
@@ -432,7 +429,7 @@ vsxxxaa_parse_buffer (struct vsxxxaa *mouse, struct pt_regs *regs)
                                continue;
                        }
 
-                       vsxxxaa_handle_REL_packet (mouse, regs);
+                       vsxxxaa_handle_REL_packet (mouse);
                        continue; /* More to parse? */
                }
 
@@ -446,7 +443,7 @@ vsxxxaa_parse_buffer (struct vsxxxaa *mouse, struct pt_regs *regs)
                                continue;
                        }
 
-                       vsxxxaa_handle_ABS_packet (mouse, regs);
+                       vsxxxaa_handle_ABS_packet (mouse);
                        continue; /* More to parse? */
                }
 
@@ -460,7 +457,7 @@ vsxxxaa_parse_buffer (struct vsxxxaa *mouse, struct pt_regs *regs)
                                continue;
                        }
 
-                       vsxxxaa_handle_POR_packet (mouse, regs);
+                       vsxxxaa_handle_POR_packet (mouse);
                        continue; /* More to parse? */
                }
 
@@ -469,13 +466,12 @@ vsxxxaa_parse_buffer (struct vsxxxaa *mouse, struct pt_regs *regs)
 }
 
 static irqreturn_t
-vsxxxaa_interrupt (struct serio *serio, unsigned char data, unsigned int flags,
-               struct pt_regs *regs)
+vsxxxaa_interrupt (struct serio *serio, unsigned char data, unsigned int flags)
 {
        struct vsxxxaa *mouse = serio_get_drvdata (serio);
 
        vsxxxaa_queue_byte (mouse, data);
-       vsxxxaa_parse_buffer (mouse, regs);
+       vsxxxaa_parse_buffer (mouse);
 
        return IRQ_HANDLED;
 }
index 8cdbfeca5903e84b6cf82b0ad54a036a83efd920..adef447f23ea601fd4bb61d1b7935b61b1c7ee75 100644 (file)
@@ -112,7 +112,7 @@ config SERIO_GSCPS2
 
 config HP_SDC
        tristate "HP System Device Controller i8042 Support"
-       depends on GSC && SERIO
+       depends on (GSC || HP300) && SERIO
        default y
        ---help---
          This option enables support for the "System Device
index 3df5eedf8f31fe06a4347a37dcdff8c1f2e9ad6c..5a7b49c35539dc7a942882e3cf2065d3f8201427 100644 (file)
@@ -37,14 +37,14 @@ struct amba_kmi_port {
        unsigned int            open;
 };
 
-static irqreturn_t amba_kmi_int(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t amba_kmi_int(int irq, void *dev_id)
 {
        struct amba_kmi_port *kmi = dev_id;
        unsigned int status = readb(KMIIR);
        int handled = IRQ_NONE;
 
        while (status & KMIIR_RXINTR) {
-               serio_interrupt(kmi->io, readb(KMIDATA), 0, regs);
+               serio_interrupt(kmi->io, readb(KMIDATA), 0);
                status = readb(KMIIR);
                handled = IRQ_HANDLED;
        }
index bc6e87add093258cc1364736e358fa5c0b6d4903..0d35018c23a96e450c9f652a30072b8e2860f33b 100644 (file)
@@ -71,9 +71,9 @@ static struct resource ct82c710_iores;
  * is waiting in the 82C710.
  */
 
-static irqreturn_t ct82c710_interrupt(int cpl, void *dev_id, struct pt_regs * regs)
+static irqreturn_t ct82c710_interrupt(int cpl, void *dev_id)
 {
-       return serio_interrupt(ct82c710_port, inb(CT82C710_DATA), 0, regs);
+       return serio_interrupt(ct82c710_port, inb(CT82C710_DATA), 0);
 }
 
 /*
index cde036a92168150a8219a595437efe8c3cd8c0f1..74f14e097789d193fe1bf6b8ffc52a248aba3875 100644 (file)
@@ -82,7 +82,7 @@ MODULE_DEVICE_TABLE(parisc, gscps2_device_tbl);
 #define GSC_ID_MOUSE           1
 
 
-static irqreturn_t gscps2_interrupt(int irq, void *dev, struct pt_regs *regs);
+static irqreturn_t gscps2_interrupt(int irq, void *dev);
 
 #define BUFFER_SIZE 0x0f
 
@@ -166,7 +166,7 @@ static inline int gscps2_writeb_output(struct gscps2port *ps2port, u8 data)
 
        /* make sure any received data is returned as fast as possible */
        /* this is important e.g. when we set the LEDs on the keyboard */
-       gscps2_interrupt(0, NULL, NULL);
+       gscps2_interrupt(0, NULL);
 
        return 1;
 }
@@ -226,7 +226,7 @@ static LIST_HEAD(ps2port_list);
  * later.
  */
 
-static irqreturn_t gscps2_interrupt(int irq, void *dev, struct pt_regs *regs)
+static irqreturn_t gscps2_interrupt(int irq, void *dev)
 {
        struct gscps2port *ps2port;
 
@@ -267,7 +267,7 @@ static irqreturn_t gscps2_interrupt(int irq, void *dev, struct pt_regs *regs)
            rxflags =   ((status & GSC_STAT_TERR) ? SERIO_TIMEOUT : 0 ) |
                        ((status & GSC_STAT_PERR) ? SERIO_PARITY  : 0 );
 
-           serio_interrupt(ps2port->port, data, rxflags, regs);
+           serio_interrupt(ps2port->port, data, rxflags);
 
          } /* while() */
 
@@ -306,7 +306,7 @@ static int gscps2_open(struct serio *port)
        /* enable it */
        gscps2_enable(ps2port, ENABLE);
 
-       gscps2_interrupt(0, NULL, NULL);
+       gscps2_interrupt(0, NULL);
 
        return 0;
 }
index bbbe15e219044fb6f9aadbcc60795f90ddc74d17..49e11e2c1d5dd24e08c8c0caab91d270e805c19e 100644 (file)
@@ -162,10 +162,10 @@ static void hil_mlc_send_polls(hil_mlc *mlc) {
                if (did != (p & HIL_PKT_ADDR_MASK) >> 8) {
                        if (drv == NULL || drv->interrupt == NULL) goto skip;
 
-                       drv->interrupt(serio, 0, 0, NULL);
-                       drv->interrupt(serio, HIL_ERR_INT >> 16, 0, NULL);
-                       drv->interrupt(serio, HIL_PKT_CMD >> 8,  0, NULL);
-                       drv->interrupt(serio, HIL_CMD_POL + cnt, 0, NULL);
+                       drv->interrupt(serio, 0, 0);
+                       drv->interrupt(serio, HIL_ERR_INT >> 16, 0);
+                       drv->interrupt(serio, HIL_PKT_CMD >> 8,  0);
+                       drv->interrupt(serio, HIL_CMD_POL + cnt, 0);
                skip:
                        did = (p & HIL_PKT_ADDR_MASK) >> 8;
                        serio = did ? mlc->serio[mlc->di_map[did-1]] : NULL;
@@ -174,10 +174,10 @@ static void hil_mlc_send_polls(hil_mlc *mlc) {
                }
                cnt++; i++;
                if (drv == NULL || drv->interrupt == NULL) continue;
-               drv->interrupt(serio, (p >> 24), 0, NULL);
-               drv->interrupt(serio, (p >> 16) & 0xff, 0, NULL);
-               drv->interrupt(serio, (p >> 8) & ~HIL_PKT_ADDR_MASK, 0, NULL);
-               drv->interrupt(serio, p & 0xff, 0, NULL);
+               drv->interrupt(serio, (p >> 24), 0);
+               drv->interrupt(serio, (p >> 16) & 0xff, 0);
+               drv->interrupt(serio, (p >> 8) & ~HIL_PKT_ADDR_MASK, 0);
+               drv->interrupt(serio, p & 0xff, 0);
        }
 }
 
@@ -391,23 +391,23 @@ static int hilse_operate(hil_mlc *mlc, int repoll) {
 }
 
 #define FUNC(funct, funct_arg, zero_rc, neg_rc, pos_rc) \
-{ HILSE_FUNC,          { func: &funct }, funct_arg, zero_rc, neg_rc, pos_rc },
+{ HILSE_FUNC,          { .func = funct }, funct_arg, zero_rc, neg_rc, pos_rc },
 #define OUT(pack) \
-{ HILSE_OUT,           { packet: pack }, 0, HILSEN_NEXT, HILSEN_DOZE, 0 },
+{ HILSE_OUT,           { .packet = pack }, 0, HILSEN_NEXT, HILSEN_DOZE, 0 },
 #define CTS \
-{ HILSE_CTS,           { packet: 0    }, 0, HILSEN_NEXT | HILSEN_SCHED | HILSEN_BREAK, HILSEN_DOZE, 0 },
+{ HILSE_CTS,           { .packet = 0    }, 0, HILSEN_NEXT | HILSEN_SCHED | HILSEN_BREAK, HILSEN_DOZE, 0 },
 #define EXPECT(comp, to, got, got_wrong, timed_out) \
-{ HILSE_EXPECT,                { packet: comp }, to, got, got_wrong, timed_out },
+{ HILSE_EXPECT,                { .packet = comp }, to, got, got_wrong, timed_out },
 #define EXPECT_LAST(comp, to, got, got_wrong, timed_out) \
-{ HILSE_EXPECT_LAST,   { packet: comp }, to, got, got_wrong, timed_out },
+{ HILSE_EXPECT_LAST,   { .packet = comp }, to, got, got_wrong, timed_out },
 #define EXPECT_DISC(comp, to, got, got_wrong, timed_out) \
-{ HILSE_EXPECT_DISC,   { packet: comp }, to, got, got_wrong, timed_out },
+{ HILSE_EXPECT_DISC,   { .packet = comp }, to, got, got_wrong, timed_out },
 #define IN(to, got, got_error, timed_out) \
-{ HILSE_IN,            { packet: 0    }, to, got, got_error, timed_out },
+{ HILSE_IN,            { .packet = 0    }, to, got, got_error, timed_out },
 #define OUT_DISC(pack) \
-{ HILSE_OUT_DISC,      { packet: pack }, 0, 0, 0, 0 },
+{ HILSE_OUT_DISC,      { .packet = pack }, 0, 0, 0, 0 },
 #define OUT_LAST(pack) \
-{ HILSE_OUT_LAST,      { packet: pack }, 0, 0, 0, 0 },
+{ HILSE_OUT_LAST,      { .packet = pack }, 0, 0, 0, 0 },
 
 struct hilse_node hil_mlc_se[HILSEN_END] = {
 
@@ -780,16 +780,16 @@ static int hil_mlc_serio_write(struct serio *serio, unsigned char c) {
        while ((last != idx) && (*last == 0)) last--;
 
        while (idx != last) {
-               drv->interrupt(serio, 0, 0, NULL);
-               drv->interrupt(serio, HIL_ERR_INT >> 16, 0, NULL);
-               drv->interrupt(serio, 0, 0, NULL);
-               drv->interrupt(serio, *idx, 0, NULL);
+               drv->interrupt(serio, 0, 0);
+               drv->interrupt(serio, HIL_ERR_INT >> 16, 0);
+               drv->interrupt(serio, 0, 0);
+               drv->interrupt(serio, *idx, 0);
                idx++;
        }
-       drv->interrupt(serio, 0, 0, NULL);
-       drv->interrupt(serio, HIL_ERR_INT >> 16, 0, NULL);
-       drv->interrupt(serio, HIL_PKT_CMD >> 8, 0, NULL);
-       drv->interrupt(serio, *idx, 0, NULL);
+       drv->interrupt(serio, 0, 0);
+       drv->interrupt(serio, HIL_ERR_INT >> 16, 0);
+       drv->interrupt(serio, HIL_PKT_CMD >> 8, 0);
+       drv->interrupt(serio, *idx, 0);
        
        mlc->serio_oidx[map->didx] = 0;
        mlc->serio_opacket[map->didx] = 0;
index a10348bb25e983e4a69cc16ed648e4f4bc904c90..9907ad3bea23252547a6a26c6cfd4d4dafae1269 100644 (file)
@@ -202,7 +202,7 @@ static void hp_sdc_take (int irq, void *dev_id, uint8_t status, uint8_t data) {
        }
 }
 
-static irqreturn_t hp_sdc_isr(int irq, void *dev_id, struct pt_regs * regs) {
+static irqreturn_t hp_sdc_isr(int irq, void *dev_id) {
        uint8_t status, data;
 
        status = hp_sdc_status_in8();
@@ -253,7 +253,7 @@ static irqreturn_t hp_sdc_isr(int irq, void *dev_id, struct pt_regs * regs) {
 }
 
 
-static irqreturn_t hp_sdc_nmisr(int irq, void *dev_id, struct pt_regs * regs) {
+static irqreturn_t hp_sdc_nmisr(int irq, void *dev_id) {
        int status;
        
        status = hp_sdc_status_in8();
@@ -310,7 +310,7 @@ static void hp_sdc_tasklet(unsigned long foo) {
                                 * in tasklet/bh context.
                                 */
                                if (curr->act.irqhook) 
-                                       curr->act.irqhook(0, 0, 0, 0);
+                                       curr->act.irqhook(0, NULL, 0, 0);
                        }
                        curr->actidx = curr->idx;
                        curr->idx++;
@@ -525,7 +525,7 @@ actdone:
                up(curr->act.semaphore);
        }
        else if (act & HP_SDC_ACT_CALLBACK) {
-               curr->act.irqhook(0,0,0,0);
+               curr->act.irqhook(0,NULL,0,0);
        }
        if (curr->idx >= curr->endidx) { /* This transaction is over. */
                if (act & HP_SDC_ACT_DEALLOC) kfree(curr);
index 1bb0c76a9259b182c2153a86472965712b134c6d..7e3141f37e32a7907fa2d00b15266652b2b6bb9e 100644 (file)
@@ -106,9 +106,10 @@ static unsigned char i8042_ctr;
 static unsigned char i8042_mux_present;
 static unsigned char i8042_kbd_irq_registered;
 static unsigned char i8042_aux_irq_registered;
+static unsigned char i8042_suppress_kbd_ack;
 static struct platform_device *i8042_platform_device;
 
-static irqreturn_t i8042_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t i8042_interrupt(int irq, void *dev_id);
 
 /*
  * The i8042_wait_read() and i8042_wait_write functions wait for the i8042 to
@@ -271,7 +272,7 @@ static int i8042_aux_write(struct serio *serio, unsigned char c)
  * characters later.
  */
 
-       i8042_interrupt(0, NULL, NULL);
+       i8042_interrupt(0, NULL);
        return retval;
 }
 
@@ -309,14 +310,14 @@ static void i8042_stop(struct serio *serio)
  * to the upper layers.
  */
 
-static irqreturn_t i8042_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t i8042_interrupt(int irq, void *dev_id)
 {
        struct i8042_port *port;
        unsigned long flags;
        unsigned char str, data;
        unsigned int dfl;
        unsigned int port_no;
-       int ret;
+       int ret = 1;
 
        spin_lock_irqsave(&i8042_lock, flags);
        str = i8042_read_status();
@@ -378,10 +379,16 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id, struct pt_regs *regs)
            dfl & SERIO_PARITY ? ", bad parity" : "",
            dfl & SERIO_TIMEOUT ? ", timeout" : "");
 
+       if (unlikely(i8042_suppress_kbd_ack))
+               if (port_no == I8042_KBD_PORT_NO &&
+                   (data == 0xfa || data == 0xfe)) {
+                       i8042_suppress_kbd_ack = 0;
+                       goto out;
+               }
+
        if (likely(port->exists))
-               serio_interrupt(port->serio, data, dfl, regs);
+               serio_interrupt(port->serio, data, dfl);
 
-       ret = 1;
  out:
        return IRQ_RETVAL(ret);
 }
@@ -519,7 +526,7 @@ static int __devinit i8042_check_mux(void)
 static struct completion i8042_aux_irq_delivered __devinitdata;
 static int i8042_irq_being_tested __devinitdata;
 
-static irqreturn_t __devinit i8042_aux_test_irq(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t __devinit i8042_aux_test_irq(int irq, void *dev_id)
 {
        unsigned long flags;
        unsigned char str, data;
@@ -842,11 +849,13 @@ static long i8042_panic_blink(long count)
        led ^= 0x01 | 0x04;
        while (i8042_read_status() & I8042_STR_IBF)
                DELAY;
+       i8042_suppress_kbd_ack = 1;
        i8042_write_data(0xed); /* set leds */
        DELAY;
        while (i8042_read_status() & I8042_STR_IBF)
                DELAY;
        DELAY;
+       i8042_suppress_kbd_ack = 1;
        i8042_write_data(led);
        DELAY;
        last_blink = count;
@@ -905,7 +914,7 @@ static int i8042_resume(struct platform_device *dev)
        if (i8042_ports[I8042_KBD_PORT_NO].serio)
                i8042_enable_kbd_port();
 
-       i8042_interrupt(0, NULL, NULL);
+       i8042_interrupt(0, NULL);
 
        return 0;
 }
index dcb16b5cbec084716050232f88c16fc53942b19f..e5b1b60757bb8d7a965aa92a87ffbae2e0264042 100644 (file)
@@ -189,7 +189,7 @@ int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command)
                return -1;
        }
 
-       mutex_lock_nested(&ps2dev->cmd_mutex, SINGLE_DEPTH_NESTING);
+       mutex_lock(&ps2dev->cmd_mutex);
 
        serio_pause_rx(ps2dev->serio);
        ps2dev->flags = command == PS2_CMD_GETID ? PS2_FLAG_WAITID : 0;
@@ -296,6 +296,7 @@ EXPORT_SYMBOL(ps2_schedule_command);
 void ps2_init(struct ps2dev *ps2dev, struct serio *serio)
 {
        mutex_init(&ps2dev->cmd_mutex);
+       lockdep_set_subclass(&ps2dev->cmd_mutex, serio->depth);
        init_waitqueue_head(&ps2dev->wait);
        ps2dev->serio = serio;
 }
index f08a5d0cd5fae5c148a8bd697e6c93af213db3ba..558200e96d0f22a1d586f578f5df62944646b21d 100644 (file)
@@ -72,8 +72,7 @@ static int maceps2_write(struct serio *dev, unsigned char val)
        return -1;
 }
 
-static irqreturn_t maceps2_interrupt(int irq, void *dev_id,
-                                    struct pt_regs *regs)
+static irqreturn_t maceps2_interrupt(int irq, void *dev_id)
 {
        struct serio *dev = dev_id;
        struct mace_ps2port *port = ((struct maceps2_data *)dev->port_data)->port;
@@ -81,7 +80,7 @@ static irqreturn_t maceps2_interrupt(int irq, void *dev_id,
 
        if (port->status & PS2_STATUS_RX_FULL) {
                byte = port->rx;
-               serio_interrupt(dev, byte & 0xff, 0, regs);
+               serio_interrupt(dev, byte & 0xff, 0);
         }
 
        return IRQ_HANDLED;
index a5c1fb3a4a51961749f5a0f9aa8998e729dc0864..688610e86a3e4c9fd96a5969828b6a6b5e4a9967 100644 (file)
@@ -102,7 +102,7 @@ static int parkbd_write(struct serio *port, unsigned char c)
        return 0;
 }
 
-static void parkbd_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static void parkbd_interrupt(int irq, void *dev_id)
 {
 
        if (parkbd_writing) {
@@ -134,7 +134,7 @@ static void parkbd_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                parkbd_buffer |= (parkbd_readlines() >> 1) << parkbd_counter++;
 
                if (parkbd_counter == parkbd_mode + 10)
-                       serio_interrupt(parkbd_port, (parkbd_buffer >> (2 - parkbd_mode)) & 0xff, 0, regs);
+                       serio_interrupt(parkbd_port, (parkbd_buffer >> (2 - parkbd_mode)) & 0xff, 0);
        }
 
        parkbd_last = jiffies;
index fb727c66525356524ee90a6f7c801a12fb31b4ef..ea5e3c6ddb627dfdff7aa159dd0454a1caeb3a9c 100644 (file)
@@ -58,7 +58,7 @@ static int pcips2_write(struct serio *io, unsigned char val)
        return 0;
 }
 
-static irqreturn_t pcips2_interrupt(int irq, void *devid, struct pt_regs *regs)
+static irqreturn_t pcips2_interrupt(int irq, void *devid)
 {
        struct pcips2_data *ps2if = devid;
        unsigned char status, scancode;
@@ -80,7 +80,7 @@ static irqreturn_t pcips2_interrupt(int irq, void *devid, struct pt_regs *regs)
                if (hweight8(scancode) & 1)
                        flag ^= SERIO_PARITY;
 
-               serio_interrupt(ps2if->io, scancode, flag, regs);
+               serio_interrupt(ps2if->io, scancode, flag);
        } while (1);
        return IRQ_RETVAL(handled);
 }
index d3827c5fe119735834e161493749619936e63582..cb89aff2e1603c30711a7900a6bbbb39b5fd83e6 100644 (file)
@@ -53,14 +53,14 @@ DEFINE_SPINLOCK(q40kbd_lock);
 static struct serio *q40kbd_port;
 static struct platform_device *q40kbd_device;
 
-static irqreturn_t q40kbd_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t q40kbd_interrupt(int irq, void *dev_id)
 {
        unsigned long flags;
 
        spin_lock_irqsave(&q40kbd_lock, flags);
 
        if (Q40_IRQ_KEYB_MASK & master_inb(INTERRUPT_REG))
-               serio_interrupt(q40kbd_port, master_inb(KEYCODE_REG), 0, regs);
+               serio_interrupt(q40kbd_port, master_inb(KEYCODE_REG), 0);
 
        master_outb(-1, KEYBOARD_UNLOCK_REG);
 
index 513d37fc1acfc2380a1b6732ec780c4987c1eab6..49f84315cb32953ff7cee9066635800a9940a8b8 100644 (file)
@@ -56,7 +56,7 @@ static int rpckbd_write(struct serio *port, unsigned char val)
        return 0;
 }
 
-static irqreturn_t rpckbd_rx(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t rpckbd_rx(int irq, void *dev_id)
 {
        struct serio *port = dev_id;
        unsigned int byte;
@@ -65,13 +65,13 @@ static irqreturn_t rpckbd_rx(int irq, void *dev_id, struct pt_regs *regs)
        while (iomd_readb(IOMD_KCTRL) & (1 << 5)) {
                byte = iomd_readb(IOMD_KARTRX);
 
-               serio_interrupt(port, byte, 0, regs);
+               serio_interrupt(port, byte, 0);
                handled = IRQ_HANDLED;
        }
        return handled;
 }
 
-static irqreturn_t rpckbd_tx(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t rpckbd_tx(int irq, void *dev_id)
 {
        return IRQ_HANDLED;
 }
index ebd9976fc811b08efb2714ede9815c77936b0bd3..559508795af1887df6ac98c028cd22ebd5eb5bed 100644 (file)
@@ -40,7 +40,7 @@ struct ps2if {
  * at the most one, but we loop for safety.  If there was a
  * framing error, we have to manually clear the status.
  */
-static irqreturn_t ps2_rxint(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t ps2_rxint(int irq, void *dev_id)
 {
        struct ps2if *ps2if = dev_id;
        unsigned int scancode, flag, status;
@@ -58,7 +58,7 @@ static irqreturn_t ps2_rxint(int irq, void *dev_id, struct pt_regs *regs)
                if (hweight8(scancode) & 1)
                        flag ^= SERIO_PARITY;
 
-               serio_interrupt(ps2if->io, scancode, flag, regs);
+               serio_interrupt(ps2if->io, scancode, flag);
 
                status = sa1111_readl(ps2if->base + SA1111_PS2STAT);
         }
@@ -69,7 +69,7 @@ static irqreturn_t ps2_rxint(int irq, void *dev_id, struct pt_regs *regs)
 /*
  * Completion of ps2 write
  */
-static irqreturn_t ps2_txint(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t ps2_txint(int irq, void *dev_id)
 {
        struct ps2if *ps2if = dev_id;
        unsigned int status;
index 3e76ad71c9a027386923be8cdf576b943f69bc77..211943f85cb66e1dee2b77aac5c3e30ce3d6c07a 100644 (file)
@@ -118,6 +118,8 @@ static int serio_match_port(const struct serio_device_id *ids, struct serio *ser
 
 static void serio_bind_driver(struct serio *serio, struct serio_driver *drv)
 {
+       int error;
+
        down_write(&serio_bus.subsys.rwsem);
 
        if (serio_match_port(drv->id_table, serio)) {
@@ -126,9 +128,19 @@ static void serio_bind_driver(struct serio *serio, struct serio_driver *drv)
                        serio->dev.driver = NULL;
                        goto out;
                }
-               device_bind_driver(&serio->dev);
+               error = device_bind_driver(&serio->dev);
+               if (error) {
+                       printk(KERN_WARNING
+                               "serio: device_bind_driver() failed "
+                               "for %s (%s) and %s, error: %d\n",
+                               serio->phys, serio->name,
+                               drv->description, error);
+                       serio_disconnect_driver(serio);
+                       serio->dev.driver = NULL;
+                       goto out;
+               }
        }
-out:
+ out:
        up_write(&serio_bus.subsys.rwsem);
 }
 
@@ -538,8 +550,12 @@ static void serio_init_port(struct serio *serio)
                 "serio%ld", (long)atomic_inc_return(&serio_no) - 1);
        serio->dev.bus = &serio_bus;
        serio->dev.release = serio_release_port;
-       if (serio->parent)
+       if (serio->parent) {
                serio->dev.parent = &serio->parent->dev;
+               serio->depth = serio->parent->depth + 1;
+       } else
+               serio->depth = 0;
+       lockdep_set_subclass(&serio->lock, serio->depth);
 }
 
 /*
@@ -911,7 +927,7 @@ void serio_close(struct serio *serio)
 }
 
 irqreturn_t serio_interrupt(struct serio *serio,
-               unsigned char data, unsigned int dfl, struct pt_regs *regs)
+               unsigned char data, unsigned int dfl)
 {
        unsigned long flags;
        irqreturn_t ret = IRQ_NONE;
@@ -919,7 +935,7 @@ irqreturn_t serio_interrupt(struct serio *serio,
        spin_lock_irqsave(&serio->lock, flags);
 
         if (likely(serio->drv)) {
-                ret = serio->drv->interrupt(serio, data, dfl, regs);
+                ret = serio->drv->interrupt(serio, data, dfl);
        } else if (!dfl && serio->registered) {
                serio_rescan(serio);
                ret = IRQ_HANDLED;
index 71a8eea816cb1466f698288e36943d45c4db41fb..ba2a2035d6483467680d94dd54df397f0780526a 100644 (file)
@@ -250,7 +250,7 @@ static struct file_operations serio_raw_fops = {
  *********************************************************************/
 
 static irqreturn_t serio_raw_interrupt(struct serio *serio, unsigned char data,
-                                       unsigned int dfl, struct pt_regs *regs)
+                                       unsigned int dfl)
 {
        struct serio_raw *serio_raw = serio_get_drvdata(serio);
        struct serio_raw_list *list;
index 54a680cc704d29bebdf3135f75d02c2069f2f1cf..e1a3a79ab3f90ca309e92c9cc2bd2565b6c06211 100644 (file)
@@ -117,9 +117,6 @@ static void serport_ldisc_close(struct tty_struct *tty)
  * serport_ldisc_receive() is called by the low level tty driver when characters
  * are ready for us. We forward the characters, one by one to the 'interrupt'
  * routine.
- *
- * FIXME: We should get pt_regs from the tty layer and forward them to
- *       serio_interrupt here.
  */
 
 static void serport_ldisc_receive(struct tty_struct *tty, const unsigned char *cp, char *fp, int count)
@@ -134,7 +131,7 @@ static void serport_ldisc_receive(struct tty_struct *tty, const unsigned char *c
                goto out;
 
        for (i = 0; i < count; i++)
-               serio_interrupt(serport->serio, cp[i], 0, NULL);
+               serio_interrupt(serport->serio, cp[i], 0);
 
 out:
        spin_unlock_irqrestore(&serport->lock, flags);
index 66e411badf70c9f2752a2a557d973587aa5c074b..f56d6a0f0624ad06c602e52e52e39833959d0e17 100644 (file)
@@ -487,7 +487,7 @@ static void ads7846_timer(unsigned long handle)
        spin_unlock_irq(&ts->lock);
 }
 
-static irqreturn_t ads7846_irq(int irq, void *handle, struct pt_regs *regs)
+static irqreturn_t ads7846_irq(int irq, void *handle)
 {
        struct ads7846 *ts = handle;
        unsigned long flags;
index 9b66271d3ba82feefd4104f59473b4c3f53f95cc..66121f6a89ad1969ad54dab4e9233b9e275d3a0e 100644 (file)
@@ -173,7 +173,7 @@ static int read_xydata(struct corgi_ts *corgi_ts)
        return 1;
 }
 
-static void new_data(struct corgi_ts *corgi_ts, struct pt_regs *regs)
+static void new_data(struct corgi_ts *corgi_ts)
 {
        if (corgi_ts->power_mode != PWR_MODE_ACTIVE)
                return;
@@ -181,7 +181,6 @@ static void new_data(struct corgi_ts *corgi_ts, struct pt_regs *regs)
        if (!corgi_ts->tc.pressure && corgi_ts->pendown == 0)
                return;
 
-       input_regs(corgi_ts->input, regs);
        input_report_abs(corgi_ts->input, ABS_X, corgi_ts->tc.x);
        input_report_abs(corgi_ts->input, ABS_Y, corgi_ts->tc.y);
        input_report_abs(corgi_ts->input, ABS_PRESSURE, corgi_ts->tc.pressure);
@@ -189,14 +188,14 @@ static void new_data(struct corgi_ts *corgi_ts, struct pt_regs *regs)
        input_sync(corgi_ts->input);
 }
 
-static void ts_interrupt_main(struct corgi_ts *corgi_ts, int isTimer, struct pt_regs *regs)
+static void ts_interrupt_main(struct corgi_ts *corgi_ts, int isTimer)
 {
        if ((GPLR(IRQ_TO_GPIO(corgi_ts->irq_gpio)) & GPIO_bit(IRQ_TO_GPIO(corgi_ts->irq_gpio))) == 0) {
                /* Disable Interrupt */
                set_irq_type(corgi_ts->irq_gpio, IRQT_NOEDGE);
                if (read_xydata(corgi_ts)) {
                        corgi_ts->pendown = 1;
-                       new_data(corgi_ts, regs);
+                       new_data(corgi_ts);
                }
                mod_timer(&corgi_ts->timer, jiffies + HZ / 100);
        } else {
@@ -208,7 +207,7 @@ static void ts_interrupt_main(struct corgi_ts *corgi_ts, int isTimer, struct pt_
 
                if (corgi_ts->pendown) {
                        corgi_ts->tc.pressure = 0;
-                       new_data(corgi_ts, regs);
+                       new_data(corgi_ts);
                }
 
                /* Enable Falling Edge */
@@ -220,13 +219,13 @@ static void ts_interrupt_main(struct corgi_ts *corgi_ts, int isTimer, struct pt_
 static void corgi_ts_timer(unsigned long data)
 {
        struct corgi_ts *corgits_data = (struct corgi_ts *) data;
-       ts_interrupt_main(corgits_data, 1, NULL);
+       ts_interrupt_main(corgits_data, 1);
 }
 
-static irqreturn_t ts_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t ts_interrupt(int irq, void *dev_id)
 {
        struct corgi_ts *corgits_data = dev_id;
-       ts_interrupt_main(corgits_data, 0, regs);
+       ts_interrupt_main(corgits_data, 0);
        return IRQ_HANDLED;
 }
 
@@ -238,7 +237,7 @@ static int corgits_suspend(struct platform_device *dev, pm_message_t state)
        if (corgi_ts->pendown) {
                del_timer_sync(&corgi_ts->timer);
                corgi_ts->tc.pressure = 0;
-               new_data(corgi_ts, NULL);
+               new_data(corgi_ts);
                corgi_ts->pendown = 0;
        }
        corgi_ts->power_mode = PWR_MODE_SUSPEND;
index ab565335ee44131a69830fc9ac47b1213f58ce14..913e1b73bb0e6780b44a57dcfd16f5b6d06b6a51 100644 (file)
@@ -67,7 +67,7 @@ struct elo {
        char phys[32];
 };
 
-static void elo_process_data_10(struct elo *elo, unsigned char data, struct pt_regs *regs)
+static void elo_process_data_10(struct elo *elo, unsigned char data)
 {
        struct input_dev *dev = elo->dev;
 
@@ -95,7 +95,6 @@ static void elo_process_data_10(struct elo *elo, unsigned char data, struct pt_r
                                break;
                        }
                        if (likely(elo->data[1] == ELO10_TOUCH_PACKET)) {
-                               input_regs(dev, regs);
                                input_report_abs(dev, ABS_X, (elo->data[4] << 8) | elo->data[3]);
                                input_report_abs(dev, ABS_Y, (elo->data[6] << 8) | elo->data[5]);
                                if (elo->data[2] & ELO10_PRESSURE)
@@ -116,7 +115,7 @@ static void elo_process_data_10(struct elo *elo, unsigned char data, struct pt_r
        elo->csum += data;
 }
 
-static void elo_process_data_6(struct elo *elo, unsigned char data, struct pt_regs *regs)
+static void elo_process_data_6(struct elo *elo, unsigned char data)
 {
        struct input_dev *dev = elo->dev;
 
@@ -134,7 +133,6 @@ static void elo_process_data_6(struct elo *elo, unsigned char data, struct pt_re
                                break;
                        }
 
-                       input_regs(dev, regs);
                        input_report_abs(dev, ABS_X, ((elo->data[0] & 0x3f) << 6) | (elo->data[1] & 0x3f));
                        input_report_abs(dev, ABS_Y, ((elo->data[2] & 0x3f) << 6) | (elo->data[3] & 0x3f));
 
@@ -164,7 +162,7 @@ static void elo_process_data_6(struct elo *elo, unsigned char data, struct pt_re
        }
 }
 
-static void elo_process_data_3(struct elo *elo, unsigned char data, struct pt_regs *regs)
+static void elo_process_data_3(struct elo *elo, unsigned char data)
 {
        struct input_dev *dev = elo->dev;
 
@@ -177,7 +175,6 @@ static void elo_process_data_3(struct elo *elo, unsigned char data, struct pt_re
                                elo->idx = 0;
                        break;
                case 2:
-                       input_regs(dev, regs);
                        input_report_key(dev, BTN_TOUCH, !(elo->data[1] & 0x80));
                        input_report_abs(dev, ABS_X, elo->data[1]);
                        input_report_abs(dev, ABS_Y, elo->data[2]);
@@ -188,22 +185,22 @@ static void elo_process_data_3(struct elo *elo, unsigned char data, struct pt_re
 }
 
 static irqreturn_t elo_interrupt(struct serio *serio,
-               unsigned char data, unsigned int flags, struct pt_regs *regs)
+               unsigned char data, unsigned int flags)
 {
        struct elo *elo = serio_get_drvdata(serio);
 
        switch(elo->id) {
                case 0:
-                       elo_process_data_10(elo, data, regs);
+                       elo_process_data_10(elo, data);
                        break;
 
                case 1:
                case 2:
-                       elo_process_data_6(elo, data, regs);
+                       elo_process_data_6(elo, data);
                        break;
 
                case 3:
-                       elo_process_data_3(elo, data, regs);
+                       elo_process_data_3(elo, data);
                        break;
        }
 
index b769b21973b78eff160567c2c27dc4fe5da3bea6..817c2198933dbe6f31b4a854f478402d5a1fabae 100644 (file)
@@ -60,7 +60,7 @@ struct gunze {
        char phys[32];
 };
 
-static void gunze_process_packet(struct gunze* gunze, struct pt_regs *regs)
+static void gunze_process_packet(struct gunze* gunze)
 {
        struct input_dev *dev = gunze->dev;
 
@@ -70,7 +70,6 @@ static void gunze_process_packet(struct gunze* gunze, struct pt_regs *regs)
                return;
        }
 
-       input_regs(dev, regs);
        input_report_abs(dev, ABS_X, simple_strtoul(gunze->data + 1, NULL, 10));
        input_report_abs(dev, ABS_Y, 1024 - simple_strtoul(gunze->data + 6, NULL, 10));
        input_report_key(dev, BTN_TOUCH, gunze->data[0] == 'T');
@@ -78,12 +77,12 @@ static void gunze_process_packet(struct gunze* gunze, struct pt_regs *regs)
 }
 
 static irqreturn_t gunze_interrupt(struct serio *serio,
-               unsigned char data, unsigned int flags, struct pt_regs *regs)
+               unsigned char data, unsigned int flags)
 {
        struct gunze* gunze = serio_get_drvdata(serio);
 
        if (data == '\r') {
-               gunze_process_packet(gunze, regs);
+               gunze_process_packet(gunze);
                gunze->idx = 0;
        } else {
                if (gunze->idx < GUNZE_MAX_LENGTH)
index e2b91001877368a0f491bc0f5f08f981d4341b02..d9e61ee05ea94dfdf35e9307bb2de1f4808545fd 100644 (file)
@@ -106,19 +106,18 @@ struct h3600_dev {
        char phys[32];
 };
 
-static irqreturn_t action_button_handler(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t action_button_handler(int irq, void *dev_id)
 {
        int down = (GPLR & GPIO_BITSY_ACTION_BUTTON) ? 0 : 1;
        struct input_dev *dev = (struct input_dev *) dev_id;
 
-       input_regs(dev, regs);
        input_report_key(dev, KEY_ENTER, down);
        input_sync(dev);
 
        return IRQ_HANDLED;
 }
 
-static irqreturn_t npower_button_handler(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t npower_button_handler(int irq, void *dev_id)
 {
        int down = (GPLR & GPIO_BITSY_NPOWER_BUTTON) ? 0 : 1;
        struct input_dev *dev = (struct input_dev *) dev_id;
@@ -127,7 +126,6 @@ static irqreturn_t npower_button_handler(int irq, void *dev_id, struct pt_regs *
         * This interrupt is only called when we release the key. So we have
         * to fake a key press.
         */
-       input_regs(dev, regs);
        input_report_key(dev, KEY_SUSPEND, 1);
        input_report_key(dev, KEY_SUSPEND, down);
        input_sync(dev);
@@ -165,14 +163,12 @@ unsigned int h3600_flite_power(struct input_dev *dev, enum flite_pwr pwr)
  * packets. Some packets coming from serial are not touchscreen related. In
  * this case we send them off to be processed elsewhere.
  */
-static void h3600ts_process_packet(struct h3600_dev *ts, struct pt_regs *regs)
+static void h3600ts_process_packet(struct h3600_dev *ts)
 {
        struct input_dev *dev = ts->dev;
        static int touched = 0;
        int key, down = 0;
 
-       input_regs(dev, regs);
-
        switch (ts->event) {
                /*
                   Buttons - returned as a single byte
@@ -301,7 +297,7 @@ static int state;
 #define STATE_EOF       3       /* state where we decode checksum or EOF */
 
 static irqreturn_t h3600ts_interrupt(struct serio *serio, unsigned char data,
-                                     unsigned int flags, struct pt_regs *regs)
+                                     unsigned int flags)
 {
        struct h3600_dev *ts = serio_get_drvdata(serio);
 
@@ -333,7 +329,7 @@ static irqreturn_t h3600ts_interrupt(struct serio *serio, unsigned char data,
                case STATE_EOF:
                        state = STATE_SOF;
                        if (data == CHAR_EOF || data == ts->chksum)
-                               h3600ts_process_packet(ts, regs);
+                               h3600ts_process_packet(ts);
                        break;
                default:
                        printk("Error3\n");
index ee6c2f40cdf6d6c5ca14603ace5e7d69a6e7029d..58fca316786c274a8d5ef473abd7ad12414b4642 100644 (file)
@@ -6,7 +6,7 @@
 #include <asm/io.h>
 #include <asm/delay.h>
 #include <asm/adc.h>
-#include <asm/hp6xx/hp6xx.h>
+#include <asm/hp6xx.h>
 
 #define MODNAME "hp680_ts_input"
 
@@ -66,7 +66,7 @@ static void do_softint(void *data)
        enable_irq(HP680_TS_IRQ);
 }
 
-static irqreturn_t hp680_ts_interrupt(int irq, void *dev, struct pt_regs *regs)
+static irqreturn_t hp680_ts_interrupt(int irq, void *dev)
 {
        disable_irq_nosync(irq);
        schedule_delayed_work(&work, HZ / 20);
index 3226830eea08432d144a0c04e208039632cf8b83..4cbcaa6a71e5d0d72c157e4430feb5fff53ec588 100644 (file)
@@ -80,7 +80,7 @@ MODULE_PARM_DESC(irq, "IRQ of MK712 touchscreen controller");
 static struct input_dev *mk712_dev;
 static DEFINE_SPINLOCK(mk712_lock);
 
-static irqreturn_t mk712_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t mk712_interrupt(int irq, void *dev_id)
 {
        unsigned char status;
        static int debounce = 1;
@@ -88,7 +88,6 @@ static irqreturn_t mk712_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        static unsigned short last_y;
 
        spin_lock(&mk712_lock);
-       input_regs(mk712_dev, regs);
 
        status = inb(mk712_io + MK712_STATUS);
 
index 8647a905df80a58bd1ce0da4a02e92236ce8fd9c..3b4c61664b631f6eba87b016acc051690a7e835c 100644 (file)
@@ -63,12 +63,11 @@ struct mtouch {
        char phys[32];
 };
 
-static void mtouch_process_format_tablet(struct mtouch *mtouch, struct pt_regs *regs)
+static void mtouch_process_format_tablet(struct mtouch *mtouch)
 {
        struct input_dev *dev = mtouch->dev;
 
        if (MTOUCH_FORMAT_TABLET_LENGTH == ++mtouch->idx) {
-               input_regs(dev, regs);
                input_report_abs(dev, ABS_X, MTOUCH_GET_XC(mtouch->data));
                input_report_abs(dev, ABS_Y, MTOUCH_MAX_YC - MTOUCH_GET_YC(mtouch->data));
                input_report_key(dev, BTN_TOUCH, MTOUCH_GET_TOUCHED(mtouch->data));
@@ -78,7 +77,7 @@ static void mtouch_process_format_tablet(struct mtouch *mtouch, struct pt_regs *
        }
 }
 
-static void mtouch_process_response(struct mtouch *mtouch, struct pt_regs *regs)
+static void mtouch_process_response(struct mtouch *mtouch)
 {
        if (MTOUCH_RESPONSE_END_BYTE == mtouch->data[mtouch->idx++]) {
                /* FIXME - process response */
@@ -90,16 +89,16 @@ static void mtouch_process_response(struct mtouch *mtouch, struct pt_regs *regs)
 }
 
 static irqreturn_t mtouch_interrupt(struct serio *serio,
-               unsigned char data, unsigned int flags, struct pt_regs *regs)
+               unsigned char data, unsigned int flags)
 {
        struct mtouch* mtouch = serio_get_drvdata(serio);
 
        mtouch->data[mtouch->idx] = data;
 
        if (MTOUCH_FORMAT_TABLET_STATUS_BIT & mtouch->data[0])
-               mtouch_process_format_tablet(mtouch, regs);
+               mtouch_process_format_tablet(mtouch);
        else if (MTOUCH_RESPONSE_BEGIN_BYTE == mtouch->data[0])
-               mtouch_process_response(mtouch, regs);
+               mtouch_process_response(mtouch);
        else
                printk(KERN_DEBUG "mtouch.c: unknown/unsynchronized data from device, byte %x\n",mtouch->data[0]);
 
index f7370109d43ebb16a6e7b20b527bc14acff4699d..6c7d0c2c76ccd79e976bee8e260ae43a6eda098e 100644 (file)
@@ -46,7 +46,7 @@ struct pm {
 };
 
 static irqreturn_t pm_interrupt(struct serio *serio,
-               unsigned char data, unsigned int flags, struct pt_regs *regs)
+               unsigned char data, unsigned int flags)
 {
        struct pm *pm = serio_get_drvdata(serio);
        struct input_dev *dev = pm->dev;
@@ -55,7 +55,6 @@ static irqreturn_t pm_interrupt(struct serio *serio,
 
        if (pm->data[0] & 0x80) {
                if (PM_MAX_LENGTH == ++pm->idx) {
-                       input_regs(dev, regs);
                        input_report_abs(dev, ABS_X, pm->data[2] * 128 + pm->data[1]);
                        input_report_abs(dev, ABS_Y, pm->data[4] * 128 + pm->data[3]);
                        input_report_key(dev, BTN_TOUCH, !!(pm->data[0] & 0x40));
index 1c89fa5386510d86ab175fb8c29bc978b33ff080..c74f74e57af02fb1678880a236de82529b80e1da 100644 (file)
@@ -56,7 +56,7 @@ struct tr {
 };
 
 static irqreturn_t tr_interrupt(struct serio *serio,
-               unsigned char data, unsigned int flags, struct pt_regs *regs)
+               unsigned char data, unsigned int flags)
 {
        struct tr *tr = serio_get_drvdata(serio);
        struct input_dev *dev = tr->dev;
@@ -65,7 +65,6 @@ static irqreturn_t tr_interrupt(struct serio *serio,
 
        if ((tr->data[0] & TR_FORMAT_STATUS_MASK) == TR_FORMAT_STATUS_BYTE) {
                if (++tr->idx == TR_LENGTH) {
-                       input_regs(dev, regs);
                        input_report_abs(dev, ABS_X,
                                (tr->data[1] << 5) | (tr->data[2] >> 1));
                        input_report_abs(dev, ABS_Y,
index a7b4c755958e3a2fe2775a9263c3ea7d0d7de453..9911820fa2fe9f67123f6eb580101abad77d5629 100644 (file)
@@ -60,7 +60,7 @@ struct tw {
 };
 
 static irqreturn_t tw_interrupt(struct serio *serio,
-               unsigned char data, unsigned int flags, struct pt_regs *regs)
+               unsigned char data, unsigned int flags)
 {
        struct tw *tw = serio_get_drvdata(serio);
        struct input_dev *dev = tw->dev;
@@ -70,7 +70,6 @@ static irqreturn_t tw_interrupt(struct serio *serio,
                tw->data[tw->idx++] = data;
                /* verify length and that the two Y's are the same */
                if (tw->idx == TW_LENGTH && tw->data[1] == tw->data[2]) {
-                       input_regs(dev, regs);
                        input_report_abs(dev, ABS_X, tw->data[0]);
                        input_report_abs(dev, ABS_Y, tw->data[1]);
                        input_report_key(dev, BTN_TOUCH, 1);
index bc98d77c5ecdc0f8179bceccfd1f544832008b97..3cac23739344cbae32ecf27b50c6b6f4da987535 100644 (file)
@@ -16,8 +16,6 @@
 #include "act2000_isa.h"
 #include "capi.h"
 
-static act2000_card *irq2card_map[16];
-
 /*
  * Reset Controller, then try to read the Card's signature.
  + Return:
@@ -63,16 +61,11 @@ act2000_isa_detect(unsigned short portbase)
 }
 
 static irqreturn_t
-act2000_isa_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+act2000_isa_interrupt(int irq, void *dev_id)
 {
-        act2000_card *card = irq2card_map[irq];
+        act2000_card *card = dev_id;
         u_char istatus;
 
-        if (!card) {
-                printk(KERN_WARNING
-                       "act2000: Spurious interrupt!\n");
-                return IRQ_NONE;
-        }
         istatus = (inb(ISA_PORT_ISR) & 0x07);
         if (istatus & ISA_ISR_OUT) {
                 /* RX fifo has data */
@@ -139,17 +132,15 @@ int
 act2000_isa_config_irq(act2000_card * card, short irq)
 {
         if (card->flags & ACT2000_FLAGS_IVALID) {
-                free_irq(card->irq, NULL);
-                irq2card_map[card->irq] = NULL;
+                free_irq(card->irq, card);
         }
         card->flags &= ~ACT2000_FLAGS_IVALID;
         outb(ISA_COR_IRQOFF, ISA_PORT_COR);
         if (!irq)
                 return 0;
 
-       if (!request_irq(irq, &act2000_isa_interrupt, 0, card->regname, NULL)) {
+       if (!request_irq(irq, &act2000_isa_interrupt, 0, card->regname, card)) {
                card->irq = irq;
-               irq2card_map[card->irq] = card;
                card->flags |= ACT2000_FLAGS_IVALID;
                 printk(KERN_WARNING
                        "act2000: Could not request irq %d\n",irq);
@@ -188,10 +179,9 @@ act2000_isa_release(act2000_card * card)
         unsigned long flags;
 
         spin_lock_irqsave(&card->lock, flags);
-        if (card->flags & ACT2000_FLAGS_IVALID) {
-                free_irq(card->irq, NULL);
-                irq2card_map[card->irq] = NULL;
-        }
+        if (card->flags & ACT2000_FLAGS_IVALID)
+                free_irq(card->irq, card);
+
         card->flags &= ~ACT2000_FLAGS_IVALID;
         if (card->flags & ACT2000_FLAGS_PVALID)
                 release_region(card->port, ISA_REGION);
index d10c8b82e6aaeac3587361efb531cb92de5ef150..b6f9476c0501d75abd98916098726d070c1436be 100644 (file)
@@ -1907,7 +1907,8 @@ static int if_readstat(u8 __user *buf, int len, int id, int channel)
        }
 
        for (p=buf, count=0; count < len; p++, count++) {
-               put_user(*card->q931_read++, p);
+               if (put_user(*card->q931_read++, p))
+                       return -EFAULT;
                if (card->q931_read > card->q931_end)
                        card->q931_read = card->q931_buf;
        }
index 5cfbe6a380101cb2f099b83acbb124e4b09e70a2..0c937325a1b36ce937d8ca99ea20d2587da1dcbe 100644 (file)
@@ -454,7 +454,7 @@ inline static int update_basstate(struct bas_cardstate *ucs,
  *     urb     USB request block
  *             urb->context = inbuf structure for controller state
  */
-static void read_ctrl_callback(struct urb *urb, struct pt_regs *regs)
+static void read_ctrl_callback(struct urb *urb)
 {
        struct inbuf_t *inbuf = urb->context;
        struct cardstate *cs = inbuf->cs;
@@ -596,7 +596,7 @@ static int atread_submit(struct cardstate *cs, int timeout)
  *     urb     USB request block
  *             urb->context = controller state structure
  */
-static void read_int_callback(struct urb *urb, struct pt_regs *regs)
+static void read_int_callback(struct urb *urb)
 {
        struct cardstate *cs = urb->context;
        struct bas_cardstate *ucs = cs->hw.bas;
@@ -762,7 +762,7 @@ resubmit:
  *     urb     USB request block of completed request
  *             urb->context = bc_state structure
  */
-static void read_iso_callback(struct urb *urb, struct pt_regs *regs)
+static void read_iso_callback(struct urb *urb)
 {
        struct bc_state *bcs;
        struct bas_bc_state *ubc;
@@ -827,7 +827,7 @@ static void read_iso_callback(struct urb *urb, struct pt_regs *regs)
  *     urb     USB request block of completed request
  *             urb->context = isow_urbctx_t structure
  */
-static void write_iso_callback(struct urb *urb, struct pt_regs *regs)
+static void write_iso_callback(struct urb *urb)
 {
        struct isow_urbctx_t *ucx;
        struct bas_bc_state *ubc;
@@ -1415,7 +1415,7 @@ static void req_timeout(unsigned long data)
  *     urb     USB request block of completed request
  *             urb->context = hardware specific controller state structure
  */
-static void write_ctrl_callback(struct urb *urb, struct pt_regs *regs)
+static void write_ctrl_callback(struct urb *urb)
 {
        struct bas_cardstate *ucs = urb->context;
        int rc;
@@ -1661,7 +1661,7 @@ static void complete_cb(struct cardstate *cs)
  *     urb     USB request block of completed request
  *             urb->context = controller state structure
  */
-static void write_command_callback(struct urb *urb, struct pt_regs *regs)
+static void write_command_callback(struct urb *urb)
 {
        struct cardstate *cs = urb->context;
        struct bas_cardstate *ucs = cs->hw.bas;
index 6e05d9d4a51ad13ad0acd55a4b9b9c6a26b3eaa9..4ffa9eb1c28e70826e559c2c1d11c7b21fe86fe4 100644 (file)
@@ -362,7 +362,7 @@ static void gigaset_modem_fill(unsigned long data)
  *
  *     It is called if the data was received from the device.
  */
-static void gigaset_read_int_callback(struct urb *urb, struct pt_regs *regs)
+static void gigaset_read_int_callback(struct urb *urb)
 {
        struct inbuf_t *inbuf = urb->context;
        struct cardstate *cs = inbuf->cs;
@@ -420,7 +420,7 @@ static void gigaset_read_int_callback(struct urb *urb, struct pt_regs *regs)
 
 
 /* This callback routine is called when data was transmitted to the device. */
-static void gigaset_write_bulk_callback(struct urb *urb, struct pt_regs *regs)
+static void gigaset_write_bulk_callback(struct urb *urb)
 {
        struct cardstate *cs = urb->context;
        unsigned long flags;
index 3b431723c7cb6c4222c411c70226769e448e4d3c..d964f07e4a566e3f60b13664e49784adc3f360c9 100644 (file)
@@ -554,7 +554,7 @@ void b1_register_appl(struct capi_ctr *ctrl, u16 appl,
 void b1_release_appl(struct capi_ctr *ctrl, u16 appl);
 u16  b1_send_message(struct capi_ctr *ctrl, struct sk_buff *skb);
 void b1_parse_version(avmctrl_info *card);
-irqreturn_t b1_interrupt(int interrupt, void *devptr, struct pt_regs *regs);
+irqreturn_t b1_interrupt(int interrupt, void *devptr);
 
 int b1ctl_read_proc(char *page, char **start, off_t off,
                        int count, int *eof, struct capi_ctr *ctrl);
@@ -567,7 +567,7 @@ void avmcard_dma_free(avmcard_dmainfo *);
 int b1pciv4_detect(avmcard *card);
 int t1pci_detect(avmcard *card);
 void b1dma_reset(avmcard *card);
-irqreturn_t b1dma_interrupt(int interrupt, void *devptr, struct pt_regs *regs);
+irqreturn_t b1dma_interrupt(int interrupt, void *devptr);
 
 int b1dma_load_firmware(struct capi_ctr *ctrl, capiloaddata *data);
 void b1dma_reset_ctr(struct capi_ctr *ctrl);
index 0c7061d550273792c749e83d40dc1b86ff53896a..da2729247713b2d2d2bbdc2683e3b06e41105d93 100644 (file)
@@ -485,7 +485,7 @@ void b1_parse_version(avmctrl_info *cinfo)
 
 /* ------------------------------------------------------------- */
 
-irqreturn_t b1_interrupt(int interrupt, void *devptr, struct pt_regs *regs)
+irqreturn_t b1_interrupt(int interrupt, void *devptr)
 {
        avmcard *card = devptr;
        avmctrl_info *cinfo = &card->ctrlinfo[0];
index a4beeb46c8597dd1da932d4a7a454c6160a65df8..ddd47cdfdb1f498b8c50dfa503099b97d250882a 100644 (file)
@@ -628,7 +628,7 @@ static void b1dma_handle_interrupt(avmcard *card)
        spin_unlock(&card->lock);
 }
 
-irqreturn_t b1dma_interrupt(int interrupt, void *devptr, struct pt_regs *regs)
+irqreturn_t b1dma_interrupt(int interrupt, void *devptr)
 {
        avmcard *card = devptr;
 
index 6c3d5f5f1f4bb40545b562e7689a6067da0bc0ea..2a3eb38f0ebb34b84da227a339ab5d78755a2187 100644 (file)
@@ -713,7 +713,7 @@ static irqreturn_t c4_handle_interrupt(avmcard *card)
        return IRQ_HANDLED;
 }
 
-static irqreturn_t c4_interrupt(int interrupt, void *devptr, struct pt_regs *regs)
+static irqreturn_t c4_interrupt(int interrupt, void *devptr)
 {
        avmcard *card = devptr;
 
index 5a2f854d55b5c8317de59f09c10e864a12ac9af5..e47c60b0a8ec6b9d80fe16cbfba08a1052e9a582 100644 (file)
@@ -131,7 +131,7 @@ static int t1_detectandinit(unsigned int base, unsigned irq, int cardnr)
         return 0;
 }
 
-static irqreturn_t t1isa_interrupt(int interrupt, void *devptr, struct pt_regs *regs)
+static irqreturn_t t1isa_interrupt(int interrupt, void *devptr)
 {
        avmcard *card = devptr;
        avmctrl_info *cinfo = &card->ctrlinfo[0];
index 8ab8027f33c0ae2fe28c18ba4949203879fd1423..ffa2afa77c2f199b8b2128d86d29597472f77694 100644 (file)
@@ -71,8 +71,6 @@ DivaIdiReqFunc(29)
 DivaIdiReqFunc(30)
 DivaIdiReqFunc(31)
 
-struct pt_regs;
-
 /*
 **  LOCALS
 */
@@ -515,7 +513,7 @@ diva_xdi_read(void *adapter, void *os_handle, void __user *dst,
 }
 
 
-irqreturn_t diva_os_irq_wrapper(int irq, void *context, struct pt_regs *regs)
+irqreturn_t diva_os_irq_wrapper(int irq, void *context)
 {
        diva_os_xdi_adapter_t *a = (diva_os_xdi_adapter_t *) context;
        diva_xdi_clear_interrupts_proc_t clear_int_proc;
index b7dadba13e828c325a358e0630cc1ff24f8c4e77..dae2e83dd5e86604a819c39f2b897467f5396f2f 100644 (file)
@@ -58,8 +58,7 @@ static char *DRIVERLNAME = "divas";
 static char *DEVNAME = "Divas";
 char *DRIVERRELEASE_DIVAS = "2.0";
 
-extern irqreturn_t diva_os_irq_wrapper(int irq, void *context,
-                               struct pt_regs *regs);
+extern irqreturn_t diva_os_irq_wrapper(int irq, void *context);
 extern int create_divas_proc(void);
 extern void remove_divas_proc(void);
 extern void diva_get_vserial_number(PISDN_ADAPTER IoAdapter, char *buf);
index 8ae08c41c853ef8f65b8010688a658ad9f79957e..bec59010bc66f3d65f4e433f8fc18eec860452f2 100644 (file)
@@ -733,7 +733,7 @@ dbusy_timer_handler(struct IsdnCardState *cs)
                        wByteAMD(cs, 0x21, 0x82);
                        wByteAMD(cs, 0x21, 0x02);
                        spin_unlock_irqrestore(&cs->lock, flags);
-                       cs->irq_func(cs->irq, cs, NULL);
+                       cs->irq_func(cs->irq, cs);
 
                         if (cs->debug & L1_DEB_ISAC)
                                debugl1(cs, "Amd7930: dbusy_timer_handler: Transmitter reset");
index 93ff941c48f1f74023b0ab664e48f1c5527cd617..61e69e9c4aa98dd8cd6e925e5ec937390e105a12 100644 (file)
@@ -156,7 +156,7 @@ WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value)
 #include "hscx_irq.c"
 
 static irqreturn_t
-asuscom_interrupt(int intno, void *dev_id, struct pt_regs *regs)
+asuscom_interrupt(int intno, void *dev_id)
 {
        struct IsdnCardState *cs = dev_id;
        u_char val;
@@ -194,7 +194,7 @@ asuscom_interrupt(int intno, void *dev_id, struct pt_regs *regs)
 }
 
 static irqreturn_t
-asuscom_interrupt_ipac(int intno, void *dev_id, struct pt_regs *regs)
+asuscom_interrupt_ipac(int intno, void *dev_id)
 {
        struct IsdnCardState *cs = dev_id;
        u_char ista, val, icnt = 5;
index 729e906bdc61265596008a1b3a30043fd67525f1..d9028e9b9b8f2736116cf20c3332fd4d1021414b 100644 (file)
@@ -101,7 +101,7 @@ WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value)
 #include "hscx_irq.c"
 
 static irqreturn_t
-avm_a1_interrupt(int intno, void *dev_id, struct pt_regs *regs)
+avm_a1_interrupt(int intno, void *dev_id)
 {
        struct IsdnCardState *cs = dev_id;
        u_char val, sval;
index 574e252dfa43b884eb1dbb0246c8441044dc6031..c87fa3f9b298f4f6aa25b338b82ff492d8a6cfde 100644 (file)
@@ -140,7 +140,7 @@ WriteHSCXfifo(struct IsdnCardState *cs, int hscx, u_char * data, int size)
 #include "hscx_irq.c"
 
 static irqreturn_t
-avm_a1p_interrupt(int intno, void *dev_id, struct pt_regs *regs)
+avm_a1p_interrupt(int intno, void *dev_id)
 {
        struct IsdnCardState *cs = dev_id;
        u_char val, sval;
index 369afd3a3a4b42c2196a1b52ec34ed25bb37ec17..b04a178e502102e96270963a1028e22c7c5cae83 100644 (file)
@@ -651,7 +651,7 @@ inithdlc(struct IsdnCardState *cs)
 }
 
 static irqreturn_t
-avm_pcipnp_interrupt(int intno, void *dev_id, struct pt_regs *regs)
+avm_pcipnp_interrupt(int intno, void *dev_id)
 {
        struct IsdnCardState *cs = dev_id;
        u_long flags;
index 87a630128a6cd8a1190dcc39ebfc571572dffbd6..871310d56a6e2cc7eb27c58047883815890db404 100644 (file)
@@ -125,7 +125,7 @@ WriteJADE(struct IsdnCardState *cs, int jade, u_char offset, u_char value)
 #include "jade_irq.c"
 
 static irqreturn_t
-bkm_interrupt(int intno, void *dev_id, struct pt_regs *regs)
+bkm_interrupt(int intno, void *dev_id)
 {
        struct IsdnCardState *cs = dev_id;
        u_char val = 0;
index dae090a9a489bad7abdc2b3edfa2fd130bee1e58..34031064534612018d85f19e1e914b4e9949ec41 100644 (file)
@@ -140,7 +140,7 @@ set_ipac_active(struct IsdnCardState *cs, u_int active)
 #include "hscx_irq.c"
 
 static irqreturn_t
-bkm_interrupt_ipac(int intno, void *dev_id, struct pt_regs *regs)
+bkm_interrupt_ipac(int intno, void *dev_id)
 {
        struct IsdnCardState *cs = dev_id;
        u_char ista, val, icnt = 5;
index e4823ab2b12702b6085a48cec68ac1ad077c9dbc..785b08554fcaa3685a3115a965be95bccc1d72e1 100644 (file)
@@ -631,7 +631,8 @@ static int HiSax_readstatus(u_char __user *buf, int len, int id, int channel)
                count = cs->status_end - cs->status_read + 1;
                if (count >= len)
                        count = len;
-               copy_to_user(p, cs->status_read, count);
+               if (copy_to_user(p, cs->status_read, count))
+                       return -EFAULT;
                cs->status_read += count;
                if (cs->status_read > cs->status_end)
                        cs->status_read = cs->status_buf;
@@ -642,7 +643,8 @@ static int HiSax_readstatus(u_char __user *buf, int len, int id, int channel)
                                cnt = HISAX_STATUS_BUFSIZE;
                        else
                                cnt = count;
-                       copy_to_user(p, cs->status_read, cnt);
+                       if (copy_to_user(p, cs->status_read, cnt))
+                               return -EFAULT;
                        p += cnt;
                        cs->status_read += cnt % HISAX_STATUS_BUFSIZE;
                        count -= cnt;
index e294fa3918f3799dbbf5adbe266e1d77f1d8bbff..3dacfff93f5fb6c51ff0c873278f800bfed9c8e6 100644 (file)
@@ -289,7 +289,7 @@ MemWriteHSCX_IPACX(struct IsdnCardState *cs, int hscx, u_char offset, u_char val
 #include "hscx_irq.c"
 
 static irqreturn_t
-diva_interrupt(int intno, void *dev_id, struct pt_regs *regs)
+diva_interrupt(int intno, void *dev_id)
 {
        struct IsdnCardState *cs = dev_id;
        u_char val, sval;
@@ -319,7 +319,7 @@ diva_interrupt(int intno, void *dev_id, struct pt_regs *regs)
 }
 
 static irqreturn_t
-diva_irq_ipac_isa(int intno, void *dev_id, struct pt_regs *regs)
+diva_irq_ipac_isa(int intno, void *dev_id)
 {
        struct IsdnCardState *cs = dev_id;
        u_char ista,val;
@@ -630,7 +630,7 @@ Memhscx_int_main(struct IsdnCardState *cs, u_char val)
 }
 
 static irqreturn_t
-diva_irq_ipac_pci(int intno, void *dev_id, struct pt_regs *regs)
+diva_irq_ipac_pci(int intno, void *dev_id)
 {
        struct IsdnCardState *cs = dev_id;
        u_char ista,val;
@@ -685,7 +685,7 @@ Start_IPACPCI:
 }
 
 static irqreturn_t
-diva_irq_ipacx_pci(int intno, void *dev_id, struct pt_regs *regs)
+diva_irq_ipacx_pci(int intno, void *dev_id)
 {
        struct IsdnCardState *cs = dev_id;
        u_char val;
@@ -716,8 +716,10 @@ release_io_diva(struct IsdnCardState *cs)
 
                *cfg = 0; /* disable INT0/1 */ 
                *cfg = 2; /* reset pending INT0 */
-               iounmap((void *)cs->hw.diva.cfg_reg);
-               iounmap((void *)cs->hw.diva.pci_cfg);
+               if (cs->hw.diva.cfg_reg)
+                       iounmap((void *)cs->hw.diva.cfg_reg);
+               if (cs->hw.diva.pci_cfg)
+                       iounmap((void *)cs->hw.diva.pci_cfg);
                return;
        } else if (cs->subtyp != DIVA_IPAC_ISA) {
                del_timer(&cs->hw.diva.tl);
@@ -733,6 +735,23 @@ release_io_diva(struct IsdnCardState *cs)
        }
 }
 
+static void
+iounmap_diva(struct IsdnCardState *cs)
+{
+       if ((cs->subtyp == DIVA_IPAC_PCI) || (cs->subtyp == DIVA_IPACX_PCI)) {
+               if (cs->hw.diva.cfg_reg) {
+                       iounmap((void *)cs->hw.diva.cfg_reg);
+                       cs->hw.diva.cfg_reg = 0;
+               }
+               if (cs->hw.diva.pci_cfg) {
+                       iounmap((void *)cs->hw.diva.pci_cfg);
+                       cs->hw.diva.pci_cfg = 0;
+               }
+       }
+
+       return;
+}
+
 static void
 reset_diva(struct IsdnCardState *cs)
 {
@@ -1069,11 +1088,13 @@ setup_diva(struct IsdnCard *card)
 
                if (!cs->irq) {
                        printk(KERN_WARNING "Diva: No IRQ for PCI card found\n");
+                       iounmap_diva(cs);
                        return(0);
                }
 
                if (!cs->hw.diva.cfg_reg) {
                        printk(KERN_WARNING "Diva: No IO-Adr for PCI card found\n");
+                       iounmap_diva(cs);
                        return(0);
                }
                cs->irq_flags |= IRQF_SHARED;
@@ -1123,6 +1144,7 @@ ready:
                               CardType[card->typ],
                               cs->hw.diva.cfg_reg,
                               cs->hw.diva.cfg_reg + bytecnt);
+                       iounmap_diva(cs);
                        return (0);
                }
        }
index 3b3e318f6076ebf059ef61291400de58f8b5a15f..fab3e4ea05957c1b7abe9fa147011d871355c045 100644 (file)
@@ -282,7 +282,7 @@ TimerRun(struct IsdnCardState *cs)
 #include "hscx_irq.c"
 
 static irqreturn_t
-elsa_interrupt(int intno, void *dev_id, struct pt_regs *regs)
+elsa_interrupt(int intno, void *dev_id)
 {
        struct IsdnCardState *cs = dev_id;
        u_long flags;
@@ -361,7 +361,7 @@ elsa_interrupt(int intno, void *dev_id, struct pt_regs *regs)
 }
 
 static irqreturn_t
-elsa_interrupt_ipac(int intno, void *dev_id, struct pt_regs *regs)
+elsa_interrupt_ipac(int intno, void *dev_id)
 {
        struct IsdnCardState *cs = dev_id;
        u_long flags;
index 76c7d29d1b2fb43461fb67b8f0ee74d9e409171d..b45de9d408d150eca9e91d60baef0ceb2e13b6a3 100644 (file)
@@ -240,7 +240,7 @@ enpci_card_msg(struct IsdnCardState *cs, int mt, void *arg)
 }
 
 static irqreturn_t
-enpci_interrupt(int intno, void *dev_id, struct pt_regs *regs)
+enpci_interrupt(int intno, void *dev_id)
 {
        struct IsdnCardState *cs = dev_id;
        unsigned char s0val, s1val, ir;
index fe29372677777f99e6c3835f35bdcb2977703fee..3efa719b6d29f73ef38890bbeb0ba9224cddf168 100644 (file)
@@ -243,7 +243,7 @@ WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value)
 #include "hscx_irq.c"
 
 static irqreturn_t
-gazel_interrupt(int intno, void *dev_id, struct pt_regs *regs)
+gazel_interrupt(int intno, void *dev_id)
 {
 #define MAXCOUNT 5
        struct IsdnCardState *cs = dev_id;
@@ -274,7 +274,7 @@ gazel_interrupt(int intno, void *dev_id, struct pt_regs *regs)
 
 
 static irqreturn_t
-gazel_interrupt_ipac(int intno, void *dev_id, struct pt_regs *regs)
+gazel_interrupt_ipac(int intno, void *dev_id)
 {
        struct IsdnCardState *cs = dev_id;
        u_char ista, val;
index 0ca5e66d2f5ab482fd78370ae29843cc4ce68d51..d852c9d998b2bd51ae022bf870b5062298b3615c 100644 (file)
@@ -1268,7 +1268,7 @@ hfc4s8s_bh(hfc4s8s_hw * hw)
 /* interrupt handler */
 /*********************/
 static irqreturn_t
-hfc4s8s_interrupt(int intno, void *dev_id, struct pt_regs *regs)
+hfc4s8s_interrupt(int intno, void *dev_id)
 {
        hfc4s8s_hw *hw = dev_id;
        u_char b, ovr;
index 1df60ca9481f0b557010b158549b4dd3f37eb872..93f60b563515c6ea385e516a880fe7e977be25b7 100644 (file)
@@ -931,7 +931,7 @@ receive_emsg(struct IsdnCardState *cs)
 /* Interrupt handler */
 /*********************/
 static irqreturn_t
-hfcpci_interrupt(int intno, void *dev_id, struct pt_regs *regs)
+hfcpci_interrupt(int intno, void *dev_id)
 {
        u_long flags;
        struct IsdnCardState *cs = dev_id;
index b7e8e23be3371b7aa8f61d6dfd975cae26628379..954d1536db1ffa8d6ede0b7e1b4927f5722c0f6f 100644 (file)
@@ -691,7 +691,7 @@ receive_emsg(struct IsdnCardState *cs)
 /* Interrupt handler */
 /*********************/
 static irqreturn_t
-hfcsx_interrupt(int intno, void *dev_id, struct pt_regs *regs)
+hfcsx_interrupt(int intno, void *dev_id)
 {
        struct IsdnCardState *cs = dev_id;
        u_char exval;
index 6b88ecb5047dbf459de4de0a6f21f33cc640dd07..7105b043add8b66f9e02d5cd0e2808381a331955 100644 (file)
@@ -276,7 +276,7 @@ control_action_handler(hfcusb_data * hfc, int reg, int val, int action)
 /* control completion routine handling background control cmds */
 /***************************************************************/
 static void
-ctrl_complete(struct urb *urb, struct pt_regs *regs)
+ctrl_complete(struct urb *urb)
 {
        hfcusb_data *hfc = (hfcusb_data *) urb->context;
        ctrl_buft *buf;
@@ -603,7 +603,7 @@ static int iso_packets[8] =
 /* transmit completion routine for all ISO tx fifos */
 /*****************************************************/
 static void
-tx_iso_complete(struct urb *urb, struct pt_regs *regs)
+tx_iso_complete(struct urb *urb)
 {
        iso_urb_struct *context_iso_urb = (iso_urb_struct *) urb->context;
        usb_fifo *fifo = context_iso_urb->owner_fifo;
@@ -726,7 +726,7 @@ tx_iso_complete(struct urb *urb, struct pt_regs *regs)
 /* receive completion routine for all ISO tx fifos   */
 /*****************************************************/
 static void
-rx_iso_complete(struct urb *urb, struct pt_regs *regs)
+rx_iso_complete(struct urb *urb)
 {
        iso_urb_struct *context_iso_urb = (iso_urb_struct *) urb->context;
        usb_fifo *fifo = context_iso_urb->owner_fifo;
@@ -919,7 +919,7 @@ collect_rx_frame(usb_fifo * fifo, __u8 * data, int len, int finish)
 /* receive completion routine for all rx fifos */
 /***********************************************/
 static void
-rx_complete(struct urb *urb, struct pt_regs *regs)
+rx_complete(struct urb *urb)
 {
        int len;
        int status;
index 4e7f472877e9ddea4b14bedbea3cda06dab4c18a..57670dc5034dc6815ced7bddef7256172cbba786 100644 (file)
@@ -21,7 +21,7 @@ extern const char *CardType[];
 static const char *hfcs_revision = "$Revision: 1.10.2.4 $";
 
 static irqreturn_t
-hfcs_interrupt(int intno, void *dev_id, struct pt_regs *regs)
+hfcs_interrupt(int intno, void *dev_id)
 {
        struct IsdnCardState *cs = dev_id;
        u_char val, stat;
index 2f9d5118ceaf8b1d545264a3dbab8d24415aa6d8..159c5896061eb6b4ea456e0b12ea344460d26fea 100644 (file)
@@ -941,7 +941,7 @@ struct IsdnCardState {
        int             (*cardmsg) (struct IsdnCardState *, int, void *);
        void            (*setstack_d) (struct PStack *, struct IsdnCardState *);
        void            (*DC_Close) (struct IsdnCardState *);
-       int             (*irq_func) (int, void *, struct pt_regs *);
+       int             (*irq_func) (int, void *);
        int             (*auxcmd) (struct IsdnCardState *, isdn_ctrl *);
        struct Channel  channel[2+MAX_WAITING_CALLS];
        struct BCState  bcs[2+MAX_WAITING_CALLS];
index 881a4165cfb47d8855b7a03d5d7af821a1f02602..f6db55a752c4e6deb2395be3259d1400234bc70a 100644 (file)
@@ -651,7 +651,7 @@ static void fritz_b_l2l1(struct hisax_if *ifc, int pr, void *arg)
 // ----------------------------------------------------------------------
 
 static irqreturn_t
-fcpci2_irq(int intno, void *dev, struct pt_regs *regs)
+fcpci2_irq(int intno, void *dev)
 {
        struct fritz_adapter *adapter = dev;
        unsigned char val;
@@ -671,7 +671,7 @@ fcpci2_irq(int intno, void *dev, struct pt_regs *regs)
 }
 
 static irqreturn_t
-fcpci_irq(int intno, void *dev, struct pt_regs *regs)
+fcpci_irq(int intno, void *dev)
 {
        struct fritz_adapter *adapter = dev;
        unsigned char sval;
index 2cf7b665609e5804824863c64b8d4caeda6f7940..da706925d54d63a074532f6dfe15dd331b0e8d39 100644 (file)
@@ -608,7 +608,7 @@ dbusy_timer_handler(struct IsdnCardState *cs)
                                debugl1(cs, "D-Channel Busy no skb");
                        }
                        cs->writeisac(cs, ICC_CMDR, 0x01); /* Transmitter reset */
-                       cs->irq_func(cs->irq, cs, NULL);
+                       cs->irq_func(cs->irq, cs);
                }
        }
 }
index 565b7892c2672780dc31d773e8d5a492b37a6229..282f349408bc42c2e4e2ed38eac92317887eb466 100644 (file)
@@ -609,7 +609,7 @@ dbusy_timer_handler(struct IsdnCardState *cs)
                                debugl1(cs, "D-Channel Busy no skb");
                        }
                        cs->writeisac(cs, ISAC_CMDR, 0x01); /* Transmitter reset */
-                       cs->irq_func(cs->irq, cs, NULL);
+                       cs->irq_func(cs->irq, cs);
                }
        }
 }
index 715a1a8cd6944a4ab12851a9cbcedeebfc99ae9a..55de06953540339103bad27f8a3ec18d2469f002 100644 (file)
@@ -83,7 +83,7 @@ WriteISAR(struct IsdnCardState *cs, int mode, u_char offset, u_char value)
 }
 
 static irqreturn_t
-isurf_interrupt(int intno, void *dev_id, struct pt_regs *regs)
+isurf_interrupt(int intno, void *dev_id)
 {
        struct IsdnCardState *cs = dev_id;
        u_char val;
index 39717506c678a778e32807fbb0253543ba4a9716..252d79de5e5e3e87341805e6b39451f36594dd01 100644 (file)
@@ -125,7 +125,7 @@ WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value)
 #include "hscx_irq.c"
 
 static irqreturn_t
-ix1micro_interrupt(int intno, void *dev_id, struct pt_regs *regs)
+ix1micro_interrupt(int intno, void *dev_id)
 {
        struct IsdnCardState *cs = dev_id;
        u_char val;
index 8c82519593a8df7b1e342d483d2fd1f545e49199..a81d175d9f643ec0b66cfe93e17a0c144439d884 100644 (file)
@@ -120,7 +120,7 @@ WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value)
 #include "hscx_irq.c"
 
 static irqreturn_t
-mic_interrupt(int intno, void *dev_id, struct pt_regs *regs)
+mic_interrupt(int intno, void *dev_id)
 {
        struct IsdnCardState *cs = dev_id;
        u_char val;
index 1080508f3c6aa88e592676a77875529c786109a4..4d89d3ea4173f99ebfb3f7967cbb594b4dc678a8 100644 (file)
@@ -66,7 +66,7 @@ void read_tiger(struct IsdnCardState *cs);
 void write_tiger(struct IsdnCardState *cs);
 
 void netjet_fill_dma(struct BCState *bcs);
-void netjet_interrupt(int intno, void *dev_id, struct pt_regs *regs);
+void netjet_interrupt(int intno, void *dev_id);
 void inittiger(struct IsdnCardState *cs);
 void release_io_netjet(struct IsdnCardState *cs);
 
index 0945336c28daa61762225e324361400cf7e0d641..e5918c6fe73d09bfb99a4dc91f05ca2c4b09646b 100644 (file)
@@ -122,8 +122,7 @@ static void WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset,
 
 #include "hscx_irq.c"
 
-static irqreturn_t niccy_interrupt(int intno, void *dev_id,
-               struct pt_regs *regs)
+static irqreturn_t niccy_interrupt(int intno, void *dev_id)
 {
        struct IsdnCardState *cs = dev_id;
        u_char val;
index 80025fd890f4db070d7e894af4ff1ee5f4b38ed5..c09ffb135330ef1363f74edb207302a14ba4364e 100644 (file)
@@ -26,7 +26,7 @@ static void dummywr(struct IsdnCardState *cs, int chan, u_char off, u_char value
 }
 
 static irqreturn_t
-netjet_s_interrupt(int intno, void *dev_id, struct pt_regs *regs)
+netjet_s_interrupt(int intno, void *dev_id)
 {
        struct IsdnCardState *cs = dev_id;
        u_char val, s1val, s0val;
index 37497162d53952d94e47ded94262b030aa59030d..8202cf34ecae729a9f2641f55fc991696f00cd83 100644 (file)
@@ -26,7 +26,7 @@ static void dummywr(struct IsdnCardState *cs, int chan, u_char off, u_char value
 }
 
 static irqreturn_t
-netjet_u_interrupt(int intno, void *dev_id, struct pt_regs *regs)
+netjet_u_interrupt(int intno, void *dev_id)
 {
        struct IsdnCardState *cs = dev_id;
        u_char val, sval;
index e76042d323ea8416d243db874d2b135e26aea4fc..150ef68b4ae27a5a0a2369f1c304f10e5bb50d84 100644 (file)
@@ -141,7 +141,7 @@ WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value)
 #include "hscx_irq.c"
 
 static irqreturn_t
-s0box_interrupt(int intno, void *dev_id, struct pt_regs *regs)
+s0box_interrupt(int intno, void *dev_id)
 {
 #define MAXCOUNT 5
        struct IsdnCardState *cs = dev_id;
index d943d365890b27995ea92364b3b9a6ab085d6d6c..c99b16690fb32e6ed986ac5d0902e969177bde97 100644 (file)
@@ -117,7 +117,7 @@ WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value)
 #include "hscx_irq.c"
 
 static irqreturn_t
-saphir_interrupt(int intno, void *dev_id, struct pt_regs *regs)
+saphir_interrupt(int intno, void *dev_id)
 {
        struct IsdnCardState *cs = dev_id;
        u_char val;
index 8d8e8a299892381762140653beed8148dad2e175..9522141f435147bee8dc6d449fecac5b273a8ba0 100644 (file)
@@ -260,7 +260,7 @@ WriteISAR(struct IsdnCardState *cs, int mode, u_char offset, u_char value)
 #include "hscx_irq.c"
 
 static irqreturn_t
-sedlbauer_interrupt(int intno, void *dev_id, struct pt_regs *regs)
+sedlbauer_interrupt(int intno, void *dev_id)
 {
        struct IsdnCardState *cs = dev_id;
        u_char val;
@@ -306,7 +306,7 @@ sedlbauer_interrupt(int intno, void *dev_id, struct pt_regs *regs)
 }
 
 static irqreturn_t
-sedlbauer_interrupt_ipac(int intno, void *dev_id, struct pt_regs *regs)
+sedlbauer_interrupt_ipac(int intno, void *dev_id)
 {
        struct IsdnCardState *cs = dev_id;
        u_char ista, val, icnt = 5;
@@ -353,7 +353,7 @@ Start_IPAC:
 }
 
 static irqreturn_t
-sedlbauer_interrupt_isar(int intno, void *dev_id, struct pt_regs *regs)
+sedlbauer_interrupt_isar(int intno, void *dev_id)
 {
        struct IsdnCardState *cs = dev_id;
        u_char val;
index a49b694eb7309f6653b7966a84f6edde130354da..02209500b3b7e1445081430e87ad211eeb1fc171 100644 (file)
@@ -99,7 +99,7 @@ WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value)
 #include "hscx_irq.c"
 
 static irqreturn_t
-sportster_interrupt(int intno, void *dev_id, struct pt_regs *regs)
+sportster_interrupt(int intno, void *dev_id)
 {
        struct IsdnCardState *cs = dev_id;
        u_char val;
index aca2a3954b1454dfd65a28036f0e06a3ff33879e..75d0f248e4eeb231ada591529771904c3565cf43 100644 (file)
@@ -161,7 +161,7 @@ static void led_blink(struct st5481_adapter *adapter)
        st5481_usb_device_ctrl_msg(adapter, GPIO_OUT, leds, NULL, NULL);
 }
 
-static void usb_b_out_complete(struct urb *urb, struct pt_regs *regs)
+static void usb_b_out_complete(struct urb *urb)
 {
        struct st5481_bcs *bcs = urb->context;
        struct st5481_b_out *b_out = &bcs->b_out;
index 98adec4405906cffca26bf479927a69d40a7d440..1d8c2618366c385c4ea285765922aae12603a09c 100644 (file)
@@ -370,7 +370,7 @@ static void fifo_reseted(void *context)
        FsmEvent(&adapter->d_out.fsm, EV_DOUT_RESETED, NULL);
 }
 
-static void usb_d_out_complete(struct urb *urb, struct pt_regs *regs)
+static void usb_d_out_complete(struct urb *urb)
 {
        struct st5481_adapter *adapter = urb->context;
        struct st5481_d_out *d_out = &adapter->d_out;
index b096b64b0253cd2e95806356d698d128af5b2b2b..ff159512204880f35a90c8eee8a9c747191a4e68 100644 (file)
@@ -125,7 +125,7 @@ void st5481_ph_command(struct st5481_adapter *adapter, unsigned int command)
  * Call the user provided completion routine and try
  * to send the next request.
  */
-static void usb_ctrl_complete(struct urb *urb, struct pt_regs *regs)
+static void usb_ctrl_complete(struct urb *urb)
 {
        struct st5481_adapter *adapter = urb->context;
        struct st5481_ctrl *ctrl = &adapter->ctrl;
@@ -179,7 +179,7 @@ static void usb_ctrl_complete(struct urb *urb, struct pt_regs *regs)
  * Decode the register values and schedule a private event.
  * Called at interrupt.
  */
-static void usb_int_complete(struct urb *urb, struct pt_regs *regs)
+static void usb_int_complete(struct urb *urb)
 {
        u8 *data = urb->transfer_buffer;
        u8 irqbyte;
@@ -483,7 +483,7 @@ void st5481_release_isocpipes(struct urb* urb[2])
  * called 50 times per second with 20 ISOC descriptors. 
  * Called at interrupt.
  */
-static void usb_in_complete(struct urb *urb, struct pt_regs *regs)
+static void usb_in_complete(struct urb *urb)
 {
        struct st5481_in *in = urb->context;
        unsigned char *ptr;
index e94dc6f5bd62b7711027e9e91bf49327fda015af..0909662b745855de25ba95593fdbbc1afa51c5f5 100644 (file)
@@ -157,7 +157,7 @@ WriteHFC(struct IsdnCardState *cs, int data, u_char reg, u_char value)
 }
 
 static irqreturn_t
-TeleInt_interrupt(int intno, void *dev_id, struct pt_regs *regs)
+TeleInt_interrupt(int intno, void *dev_id)
 {
        struct IsdnCardState *cs = dev_id;
        u_char val;
index f94af0930a1731824a599747764ab1d5727c6216..48581335f43c991fab4f415e5c7942cc0105022a 100644 (file)
@@ -144,7 +144,7 @@ WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value)
 #include "hscx_irq.c"
 
 static irqreturn_t
-teles0_interrupt(int intno, void *dev_id, struct pt_regs *regs)
+teles0_interrupt(int intno, void *dev_id)
 {
        struct IsdnCardState *cs = dev_id;
        u_char val;
index 5cb712437da4ce9f5e37ff51baa9735d3fae68eb..6a5e379e077418a385b7aaa453c17e9df9ee8d41 100644 (file)
@@ -101,7 +101,7 @@ WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value)
 #include "hscx_irq.c"
 
 static irqreturn_t
-teles3_interrupt(int intno, void *dev_id, struct pt_regs *regs)
+teles3_interrupt(int intno, void *dev_id)
 {
 #define MAXCOUNT 5
        struct IsdnCardState *cs = dev_id;
index dca446865f24b8de70d7afb5f4b9052505ad1652..d09f6d033f156c96c46a8411a5e41dc14c3abf88 100644 (file)
@@ -226,7 +226,7 @@ WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value)
 #include "hscx_irq.c"
 
 static irqreturn_t
-telespci_interrupt(int intno, void *dev_id, struct pt_regs *regs)
+telespci_interrupt(int intno, void *dev_id)
 {
        struct IsdnCardState *cs = dev_id;
        u_char hval, ival;
index 0595293b8659be94a5235cfc3aea12bac02423b7..1655341797a97816f510c9b90148a1862376ded4 100644 (file)
@@ -400,7 +400,7 @@ W6692B_interrupt(struct IsdnCardState *cs, u_char bchan)
 }
 
 static irqreturn_t
-W6692_interrupt(int intno, void *dev_id, struct pt_regs *regs)
+W6692_interrupt(int intno, void *dev_id)
 {
        struct IsdnCardState    *cs = dev_id;
        u_char                  val, exval, v1;
@@ -715,7 +715,7 @@ dbusy_timer_handler(struct IsdnCardState *cs)
                        }
                        cs->writeW6692(cs, W_D_CMDR, W_D_CMDR_XRST);    /* Transmitter reset */
                        spin_unlock_irqrestore(&cs->lock, flags);
-                       cs->irq_func(cs->irq, cs, NULL);
+                       cs->irq_func(cs->irq, cs);
                        return;
                }
        }
index 73afebdf80bdf868bb734517199c35b257698a3d..82e42a80dc4b01f24deafa97e4eaadfcd32de798 100644 (file)
@@ -33,7 +33,7 @@
 /* The cards interrupt handler. Called from system */
 /***************************************************/
 static irqreturn_t
-ergo_interrupt(int intno, void *dev_id, struct pt_regs *regs)
+ergo_interrupt(int intno, void *dev_id)
 {
        hysdn_card *card = dev_id;      /* parameter from irq */
        tErgDpram *dpr;
@@ -45,11 +45,10 @@ ergo_interrupt(int intno, void *dev_id, struct pt_regs *regs)
        if (!card->irq_enabled)
                return IRQ_NONE;                /* other device interrupting or irq switched off */
 
-       save_flags(flags);
-       cli();                  /* no further irqs allowed */
+       spin_lock_irqsave(&card->hysdn_lock, flags); /* no further irqs allowed */
 
        if (!(bytein(card->iobase + PCI9050_INTR_REG) & PCI9050_INTR_REG_STAT1)) {
-               restore_flags(flags);   /* restore old state */
+               spin_unlock_irqrestore(&card->hysdn_lock, flags);       /* restore old state */
                return IRQ_NONE;                /* no interrupt requested by E1 */
        }
        /* clear any pending ints on the board */
@@ -61,7 +60,7 @@ ergo_interrupt(int intno, void *dev_id, struct pt_regs *regs)
        /* start kernel task immediately after leaving all interrupts */
        if (!card->hw_lock)
                schedule_work(&card->irq_queue);
-       restore_flags(flags);
+       spin_unlock_irqrestore(&card->hysdn_lock, flags);
        return IRQ_HANDLED;
 }                              /* ergo_interrupt */
 
@@ -83,10 +82,9 @@ ergo_irq_bh(hysdn_card * card)
 
        dpr = card->dpram;      /* point to DPRAM */
 
-       save_flags(flags);
-       cli();
+       spin_lock_irqsave(&card->hysdn_lock, flags);
        if (card->hw_lock) {
-               restore_flags(flags);   /* hardware currently unavailable */
+               spin_unlock_irqrestore(&card->hysdn_lock, flags);       /* hardware currently unavailable */
                return;
        }
        card->hw_lock = 1;      /* we now lock the hardware */
@@ -120,7 +118,7 @@ ergo_irq_bh(hysdn_card * card)
                        card->hw_lock = 0;      /* free hardware again */
        } while (again);        /* until nothing more to do */
 
-       restore_flags(flags);
+       spin_unlock_irqrestore(&card->hysdn_lock, flags);
 }                              /* ergo_irq_bh */
 
 
@@ -137,8 +135,7 @@ ergo_stopcard(hysdn_card * card)
 #ifdef CONFIG_HYSDN_CAPI
        hycapi_capi_stop(card);
 #endif /* CONFIG_HYSDN_CAPI */
-       save_flags(flags);
-       cli();
+       spin_lock_irqsave(&card->hysdn_lock, flags);
        val = bytein(card->iobase + PCI9050_INTR_REG);  /* get actual value */
        val &= ~(PCI9050_INTR_REG_ENPCI | PCI9050_INTR_REG_EN1);        /* mask irq */
        byteout(card->iobase + PCI9050_INTR_REG, val);
@@ -147,7 +144,7 @@ ergo_stopcard(hysdn_card * card)
        card->state = CARD_STATE_UNUSED;
        card->err_log_state = ERRLOG_STATE_OFF;         /* currently no log active */
 
-       restore_flags(flags);
+       spin_unlock_irqrestore(&card->hysdn_lock, flags);
 }                              /* ergo_stopcard */
 
 /**************************************************************************/
@@ -162,12 +159,11 @@ ergo_set_errlog_state(hysdn_card * card, int on)
                card->err_log_state = ERRLOG_STATE_OFF;         /* must be off */
                return;
        }
-       save_flags(flags);
-       cli();
+       spin_lock_irqsave(&card->hysdn_lock, flags);
 
        if (((card->err_log_state == ERRLOG_STATE_OFF) && !on) ||
            ((card->err_log_state == ERRLOG_STATE_ON) && on)) {
-               restore_flags(flags);
+               spin_unlock_irqrestore(&card->hysdn_lock, flags);
                return;         /* nothing to do */
        }
        if (on)
@@ -175,7 +171,7 @@ ergo_set_errlog_state(hysdn_card * card, int on)
        else
                card->err_log_state = ERRLOG_STATE_STOP;        /* request stop */
 
-       restore_flags(flags);
+       spin_unlock_irqrestore(&card->hysdn_lock, flags);
        schedule_work(&card->irq_queue);
 }                              /* ergo_set_errlog_state */
 
@@ -356,8 +352,7 @@ ergo_waitpofready(struct HYSDN_CARD *card)
 
                        if (card->debug_flags & LOG_POF_RECORD)
                                hysdn_addlog(card, "ERGO: pof boot success");
-                       save_flags(flags);
-                       cli();
+                       spin_lock_irqsave(&card->hysdn_lock, flags);
 
                        card->state = CARD_STATE_RUN;   /* now card is running */
                        /* enable the cards interrupt */
@@ -370,7 +365,7 @@ ergo_waitpofready(struct HYSDN_CARD *card)
                        dpr->ToHyInt = 1;
                        dpr->ToPcInt = 1;       /* interrupt to E1 for all cards */
 
-                       restore_flags(flags);
+                       spin_unlock_irqrestore(&card->hysdn_lock, flags);
                        if ((hynet_enable & (1 << card->myid)) 
                            && (i = hysdn_net_create(card))) 
                        {
@@ -408,7 +403,7 @@ ergo_releasehardware(hysdn_card * card)
        free_irq(card->irq, card);      /* release interrupt */
        release_region(card->iobase + PCI9050_INTR_REG, 1);     /* release all io ports */
        release_region(card->iobase + PCI9050_USER_IO, 1);
-       vfree(card->dpram);
+       iounmap(card->dpram);
        card->dpram = NULL;     /* release shared mem */
 }                              /* ergo_releasehardware */
 
@@ -448,6 +443,7 @@ ergo_inithardware(hysdn_card * card)
        card->waitpofready = ergo_waitpofready;
        card->set_errlog_state = ergo_set_errlog_state;
        INIT_WORK(&card->irq_queue, (void *) (void *) ergo_irq_bh, card);
+       card->hysdn_lock = SPIN_LOCK_UNLOCKED;
 
        return (0);
 }                              /* ergo_inithardware */
index 461e831592ddd28710c36c8d422ae0f286645445..729df40893857789284f831afe43fe4bf0a943de 100644 (file)
@@ -188,6 +188,8 @@ typedef struct HYSDN_CARD {
        /* init and deinit stopcard for booting, too */
        void (*stopcard) (struct HYSDN_CARD *);
        void (*releasehardware) (struct HYSDN_CARD *);
+
+       spinlock_t hysdn_lock;
 #ifdef CONFIG_HYSDN_CAPI
        struct hycapictrl_info {
                char cardname[32];
index c4301e8338eff58a4a01fc7f2120fbfeefe5dd3a..fcd49920b2203ab9d33359a204e1c35f082337bd 100644 (file)
@@ -116,8 +116,7 @@ put_log_buffer(hysdn_card * card, char *cp)
        strcpy(ib->log_start, cp);      /* set output string */
        ib->next = NULL;
        ib->proc_ctrl = pd;     /* point to own control structure */
-       save_flags(flags);
-       cli();
+       spin_lock_irqsave(&card->hysdn_lock, flags);
        ib->usage_cnt = pd->if_used;
        if (!pd->log_head)
                pd->log_head = ib;      /* new head */
@@ -125,7 +124,7 @@ put_log_buffer(hysdn_card * card, char *cp)
                pd->log_tail->next = ib;        /* follows existing messages */
        pd->log_tail = ib;      /* new tail */
        i = pd->del_lock++;     /* get lock state */
-       restore_flags(flags);
+       spin_unlock_irqrestore(&card->hysdn_lock, flags);
 
        /* delete old entrys */
        if (!i)
@@ -270,14 +269,13 @@ hysdn_log_open(struct inode *ino, struct file *filep)
        } else if ((filep->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) {
 
                /* read access -> log/debug read */
-               save_flags(flags);
-               cli();
+               spin_lock_irqsave(&card->hysdn_lock, flags);
                pd->if_used++;
                if (pd->log_head)
                        filep->private_data = &pd->log_tail->next;
                else
                        filep->private_data = &pd->log_head;
-               restore_flags(flags);
+               spin_unlock_irqrestore(&card->hysdn_lock, flags);
        } else {                /* simultaneous read/write access forbidden ! */
                unlock_kernel();
                return (-EPERM);        /* no permission this time */
@@ -301,7 +299,7 @@ hysdn_log_close(struct inode *ino, struct file *filep)
        hysdn_card *card;
        int retval = 0;
        unsigned long flags;
-
+       spinlock_t hysdn_lock = SPIN_LOCK_UNLOCKED;
 
        lock_kernel();
        if ((filep->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_WRITE) {
@@ -311,8 +309,7 @@ hysdn_log_close(struct inode *ino, struct file *filep)
                /* read access -> log/debug read, mark one further file as closed */
 
                pd = NULL;
-               save_flags(flags);
-               cli();
+               spin_lock_irqsave(&hysdn_lock, flags);
                inf = *((struct log_data **) filep->private_data);      /* get first log entry */
                if (inf)
                        pd = (struct procdata *) inf->proc_ctrl;        /* still entries there */
@@ -335,7 +332,7 @@ hysdn_log_close(struct inode *ino, struct file *filep)
                        inf->usage_cnt--;       /* decrement usage count for buffers */
                        inf = inf->next;
                }
-               restore_flags(flags);
+               spin_unlock_irqrestore(&hysdn_lock, flags);
 
                if (pd)
                        if (pd->if_used <= 0)   /* delete buffers if last file closed */
index 1c0d54ac12abeb8cb2686ea87adea4619b51e24f..1fadf0133e9b6355e4e994b03e6f795d955bc130 100644 (file)
@@ -155,8 +155,7 @@ hysdn_tx_cfgline(hysdn_card *card, unsigned char *line, unsigned short chan)
        if (card->debug_flags & LOG_SCHED_ASYN)
                hysdn_addlog(card, "async tx-cfg chan=%d len=%d", chan, strlen(line) + 1);
 
-       save_flags(flags);
-       cli();
+       spin_lock_irqsave(&card->hysdn_lock, flags);
        while (card->async_busy) {
                sti();
 
@@ -165,7 +164,7 @@ hysdn_tx_cfgline(hysdn_card *card, unsigned char *line, unsigned short chan)
 
                msleep_interruptible(20);               /* Timeout 20ms */
                if (!--cnt) {
-                       restore_flags(flags);
+                       spin_unlock_irqrestore(&card->hysdn_lock, flags);
                        return (-ERR_ASYNC_TIME);       /* timed out */
                }
                cli();
@@ -194,13 +193,13 @@ hysdn_tx_cfgline(hysdn_card *card, unsigned char *line, unsigned short chan)
 
                msleep_interruptible(20);               /* Timeout 20ms */
                if (!--cnt) {
-                       restore_flags(flags);
+                       spin_unlock_irqrestore(&card->hysdn_lock, flags);
                        return (-ERR_ASYNC_TIME);       /* timed out */
                }
                cli();
        }                       /* wait for buffer to become free again */
 
-       restore_flags(flags);
+       spin_unlock_irqrestore(&card->hysdn_lock, flags);
 
        if (card->debug_flags & LOG_SCHED_ASYN)
                hysdn_addlog(card, "async tx-cfg data send");
index c3d79eef9e3245ef0f8e8a28b015dd2bb8db39d7..69aee2602aa62aac22a3c6e41442a4d1810a7ee5 100644 (file)
@@ -1134,9 +1134,12 @@ isdn_read(struct file *file, char __user *buf, size_t count, loff_t * off)
                if (dev->drv[drvidx]->interface->readstat) {
                        if (count > dev->drv[drvidx]->stavail)
                                count = dev->drv[drvidx]->stavail;
-                       len = dev->drv[drvidx]->interface->
-                               readstat(buf, count, drvidx,
-                                        isdn_minor2chan(minor));
+                       len = dev->drv[drvidx]->interface->readstat(buf, count,
+                                               drvidx, isdn_minor2chan(minor));
+                       if (len < 0) {
+                               retval = len;
+                               goto out;
+                       }
                } else {
                        len = 0;
                }
index 6649f8bc99512247cdbfb6142dbfcce40f0669b0..730bbd07ebc7ca2e842e5cde6080fdd466203027 100644 (file)
@@ -1010,7 +1010,8 @@ icn_readstatus(u_char __user *buf, int len, icn_card * card)
        for (p = buf, count = 0; count < len; p++, count++) {
                if (card->msg_buf_read == card->msg_buf_write)
                        return count;
-               put_user(*card->msg_buf_read++, p);
+               if (put_user(*card->msg_buf_read++, p))
+                       return -EFAULT;
                if (card->msg_buf_read > card->msg_buf_end)
                        card->msg_buf_read = card->msg_buf;
        }
index fabbd461603e217befac34687aa5eb08f7ebb575..c3ae2edaf6fa5812cf039ef00ef8e7b467aed901 100644 (file)
@@ -100,12 +100,11 @@ isdnloop_pollbchan(unsigned long data)
                isdnloop_bchan_send(card, 1);
        if (card->flags & (ISDNLOOP_FLAGS_B1ACTIVE | ISDNLOOP_FLAGS_B2ACTIVE)) {
                /* schedule b-channel polling again */
-               save_flags(flags);
-               cli();
+               spin_lock_irqsave(&card->isdnloop_lock, flags);
                card->rb_timer.expires = jiffies + ISDNLOOP_TIMER_BCREAD;
                add_timer(&card->rb_timer);
                card->flags |= ISDNLOOP_FLAGS_RBTIMER;
-               restore_flags(flags);
+               spin_unlock_irqrestore(&card->isdnloop_lock, flags);
        } else
                card->flags &= ~ISDNLOOP_FLAGS_RBTIMER;
 }
@@ -281,8 +280,7 @@ isdnloop_putmsg(isdnloop_card * card, unsigned char c)
 {
        ulong flags;
 
-       save_flags(flags);
-       cli();
+       spin_lock_irqsave(&card->isdnloop_lock, flags);
        *card->msg_buf_write++ = (c == 0xff) ? '\n' : c;
        if (card->msg_buf_write == card->msg_buf_read) {
                if (++card->msg_buf_read > card->msg_buf_end)
@@ -290,7 +288,7 @@ isdnloop_putmsg(isdnloop_card * card, unsigned char c)
        }
        if (card->msg_buf_write > card->msg_buf_end)
                card->msg_buf_write = card->msg_buf;
-       restore_flags(flags);
+       spin_unlock_irqrestore(&card->isdnloop_lock, flags);
 }
 
 /*
@@ -372,21 +370,19 @@ isdnloop_polldchan(unsigned long data)
                if (!(card->flags & ISDNLOOP_FLAGS_RBTIMER)) {
                        /* schedule b-channel polling */
                        card->flags |= ISDNLOOP_FLAGS_RBTIMER;
-                       save_flags(flags);
-                       cli();
+                       spin_lock_irqsave(&card->isdnloop_lock, flags);
                        del_timer(&card->rb_timer);
                        card->rb_timer.function = isdnloop_pollbchan;
                        card->rb_timer.data = (unsigned long) card;
                        card->rb_timer.expires = jiffies + ISDNLOOP_TIMER_BCREAD;
                        add_timer(&card->rb_timer);
-                       restore_flags(flags);
+                       spin_unlock_irqrestore(&card->isdnloop_lock, flags);
                }
        /* schedule again */
-       save_flags(flags);
-       cli();
+       spin_lock_irqsave(&card->isdnloop_lock, flags);
        card->st_timer.expires = jiffies + ISDNLOOP_TIMER_DCREAD;
        add_timer(&card->st_timer);
-       restore_flags(flags);
+       spin_unlock_irqrestore(&card->isdnloop_lock, flags);
 }
 
 /*
@@ -416,8 +412,7 @@ isdnloop_sendbuf(int channel, struct sk_buff *skb, isdnloop_card * card)
                        return 0;
                if (card->sndcount[channel] > ISDNLOOP_MAX_SQUEUE)
                        return 0;
-               save_flags(flags);
-               cli();
+               spin_lock_irqsave(&card->isdnloop_lock, flags);
                nskb = dev_alloc_skb(skb->len);
                if (nskb) {
                        memcpy(skb_put(nskb, len), skb->data, len);
@@ -426,7 +421,7 @@ isdnloop_sendbuf(int channel, struct sk_buff *skb, isdnloop_card * card)
                } else
                        len = 0;
                card->sndcount[channel] += len;
-               restore_flags(flags);
+               spin_unlock_irqrestore(&card->isdnloop_lock, flags);
        }
        return len;
 }
@@ -451,7 +446,8 @@ isdnloop_readstatus(u_char __user *buf, int len, isdnloop_card * card)
        for (p = buf, count = 0; count < len; p++, count++) {
                if (card->msg_buf_read == card->msg_buf_write)
                        return count;
-               put_user(*card->msg_buf_read++, p);
+               if (put_user(*card->msg_buf_read++, p))
+                       return -EFAULT;
                if (card->msg_buf_read > card->msg_buf_end)
                        card->msg_buf_read = card->msg_buf;
        }
@@ -576,8 +572,7 @@ isdnloop_atimeout(isdnloop_card * card, int ch)
        unsigned long flags;
        char buf[60];
 
-       save_flags(flags);
-       cli();
+       spin_lock_irqsave(&card->isdnloop_lock, flags);
        if (card->rcard) {
                isdnloop_fake(card->rcard[ch], "DDIS_I", card->rch[ch] + 1);
                card->rcard[ch]->rcard[card->rch[ch]] = NULL;
@@ -587,7 +582,7 @@ isdnloop_atimeout(isdnloop_card * card, int ch)
        /* No user responding */
        sprintf(buf, "CAU%s", isdnloop_unicause(card, 1, 3));
        isdnloop_fake(card, buf, ch + 1);
-       restore_flags(flags);
+       spin_unlock_irqrestore(&card->isdnloop_lock, flags);
 }
 
 /*
@@ -622,8 +617,7 @@ isdnloop_start_ctimer(isdnloop_card * card, int ch)
 {
        unsigned long flags;
 
-       save_flags(flags);
-       cli();
+       spin_lock_irqsave(&card->isdnloop_lock, flags);
        init_timer(&card->c_timer[ch]);
        card->c_timer[ch].expires = jiffies + ISDNLOOP_TIMER_ALERTWAIT;
        if (ch)
@@ -632,7 +626,7 @@ isdnloop_start_ctimer(isdnloop_card * card, int ch)
                card->c_timer[ch].function = isdnloop_atimeout0;
        card->c_timer[ch].data = (unsigned long) card;
        add_timer(&card->c_timer[ch]);
-       restore_flags(flags);
+       spin_unlock_irqrestore(&card->isdnloop_lock, flags);
 }
 
 /*
@@ -647,10 +641,9 @@ isdnloop_kill_ctimer(isdnloop_card * card, int ch)
 {
        unsigned long flags;
 
-       save_flags(flags);
-       cli();
+       spin_lock_irqsave(&card->isdnloop_lock, flags);
        del_timer(&card->c_timer[ch]);
-       restore_flags(flags);
+       spin_unlock_irqrestore(&card->isdnloop_lock, flags);
 }
 
 static u_char si2bit[] =
@@ -706,13 +699,12 @@ isdnloop_try_call(isdnloop_card * card, char *p, int lch, isdn_ctrl * cmd)
                                        }
                        }
                        if (num_match) {
-                               save_flags(flags);
-                               cli();
+                               spin_lock_irqsave(&card->isdnloop_lock, flags);
                                /* channel idle? */
                                if (!(cc->rcard[ch])) {
                                        /* Check SI */
                                        if (!(si2bit[cmd->parm.setup.si1] & cc->sil[ch])) {
-                                               restore_flags(flags);
+                                               spin_unlock_irqrestore(&card->isdnloop_lock, flags);
                                                return 3;
                                        }
                                        /* ch is idle, si and number matches */
@@ -720,10 +712,10 @@ isdnloop_try_call(isdnloop_card * card, char *p, int lch, isdn_ctrl * cmd)
                                        cc->rch[ch] = lch;
                                        card->rcard[lch] = cc;
                                        card->rch[lch] = ch;
-                                       restore_flags(flags);
+                                       spin_unlock_irqrestore(&card->isdnloop_lock, flags);
                                        return 0;
                                } else {
-                                       restore_flags(flags);
+                                       spin_unlock_irqrestore(&card->isdnloop_lock, flags);
                                        /* num matches, but busy */
                                        if (ch == 1)
                                                return 1;
@@ -1027,8 +1019,7 @@ isdnloop_stopcard(isdnloop_card * card)
        unsigned long flags;
        isdn_ctrl cmd;
 
-       save_flags(flags);
-       cli();
+       spin_lock_irqsave(&card->isdnloop_lock, flags);
        if (card->flags & ISDNLOOP_FLAGS_RUNNING) {
                card->flags &= ~ISDNLOOP_FLAGS_RUNNING;
                del_timer(&card->st_timer);
@@ -1039,7 +1030,7 @@ isdnloop_stopcard(isdnloop_card * card)
                cmd.driver = card->myid;
                card->interface.statcallb(&cmd);
        }
-       restore_flags(flags);
+       spin_unlock_irqrestore(&card->isdnloop_lock, flags);
 }
 
 /*
@@ -1078,18 +1069,17 @@ isdnloop_start(isdnloop_card * card, isdnloop_sdef * sdefp)
                return -EBUSY;
        if (copy_from_user((char *) &sdef, (char *) sdefp, sizeof(sdef)))
                return -EFAULT;
-       save_flags(flags);
-       cli();
+       spin_lock_irqsave(&card->isdnloop_lock, flags);
        switch (sdef.ptype) {
                case ISDN_PTYPE_EURO:
                        if (isdnloop_fake(card, "DRV1.23EC-Q.931-CAPI-CNS-BASIS-20.02.96",
                                          -1)) {
-                               restore_flags(flags);
+                               spin_unlock_irqrestore(&card->isdnloop_lock, flags);
                                return -ENOMEM;
                        }
                        card->sil[0] = card->sil[1] = 4;
                        if (isdnloop_fake(card, "TEI OK", 0)) {
-                               restore_flags(flags);
+                               spin_unlock_irqrestore(&card->isdnloop_lock, flags);
                                return -ENOMEM;
                        }
                        for (i = 0; i < 3; i++)
@@ -1098,12 +1088,12 @@ isdnloop_start(isdnloop_card * card, isdnloop_sdef * sdefp)
                case ISDN_PTYPE_1TR6:
                        if (isdnloop_fake(card, "DRV1.04TC-1TR6-CAPI-CNS-BASIS-29.11.95",
                                          -1)) {
-                               restore_flags(flags);
+                               spin_unlock_irqrestore(&card->isdnloop_lock, flags);
                                return -ENOMEM;
                        }
                        card->sil[0] = card->sil[1] = 4;
                        if (isdnloop_fake(card, "TEI OK", 0)) {
-                               restore_flags(flags);
+                               spin_unlock_irqrestore(&card->isdnloop_lock, flags);
                                return -ENOMEM;
                        }
                        strcpy(card->s0num[0], sdef.num[0]);
@@ -1111,7 +1101,7 @@ isdnloop_start(isdnloop_card * card, isdnloop_sdef * sdefp)
                        card->s0num[2][0] = '\0';
                        break;
                default:
-                       restore_flags(flags);
+                       spin_unlock_irqrestore(&card->isdnloop_lock, flags);
                        printk(KERN_WARNING "isdnloop: Illegal D-channel protocol %d\n",
                               sdef.ptype);
                        return -EINVAL;
@@ -1122,7 +1112,7 @@ isdnloop_start(isdnloop_card * card, isdnloop_sdef * sdefp)
        card->st_timer.data = (unsigned long) card;
        add_timer(&card->st_timer);
        card->flags |= ISDNLOOP_FLAGS_RUNNING;
-       restore_flags(flags);
+       spin_unlock_irqrestore(&card->isdnloop_lock, flags);
        return 0;
 }
 
@@ -1472,6 +1462,7 @@ isdnloop_initcard(char *id)
                skb_queue_head_init(&card->bqueue[i]);
        }
        skb_queue_head_init(&card->dqueue);
+       card->isdnloop_lock = SPIN_LOCK_UNLOCKED;
        card->next = cards;
        cards = card;
        if (!register_isdn(&card->interface)) {
index d699fe53e1c37a4ae906323aa415e89f420cf4ec..0d458a86f5299b086e6b5792b9814b35915e2c4f 100644 (file)
@@ -94,6 +94,7 @@ typedef struct isdnloop_card {
        struct sk_buff_head
         bqueue[ISDNLOOP_BCH];  /* B-Channel queues                 */
        struct sk_buff_head dqueue;     /* D-Channel queue                  */
+       spinlock_t isdnloop_lock;
 } isdnloop_card;
 
 /*
index 94f21486bb24d667b4c22b29e2c507e30262919b..6ead5e1508b705fd682c28c2a57c9a581ab5e611 100644 (file)
@@ -725,23 +725,27 @@ static int pcbit_stat(u_char __user *buf, int len, int driver, int channel)
 
        if (stat_st < stat_end)
        {
-               copy_to_user(buf, statbuf + stat_st, len);
+               if (copy_to_user(buf, statbuf + stat_st, len))
+                       return -EFAULT;
                stat_st += len;    
        }
        else
        {
                if (len > STATBUF_LEN - stat_st)
                {
-                       copy_to_user(buf, statbuf + stat_st, 
-                                      STATBUF_LEN - stat_st);
-                       copy_to_user(buf, statbuf, 
-                                      len - (STATBUF_LEN - stat_st));
+                       if (copy_to_user(buf, statbuf + stat_st,
+                                      STATBUF_LEN - stat_st))
+                               return -EFAULT;
+                       if (copy_to_user(buf, statbuf,
+                                      len - (STATBUF_LEN - stat_st)))
+                               return -EFAULT;
 
                        stat_st = len - (STATBUF_LEN - stat_st);
                }
                else
                {
-                       copy_to_user(buf, statbuf + stat_st, len);
+                       if (copy_to_user(buf, statbuf + stat_st, len))
+                               return -EFAULT;
 
                        stat_st += len;
                        
index ba766930f0885a5fb340278606691a3a867dc49c..937fd21203816b7521aa92b660672b424e8f6dc3 100644 (file)
@@ -311,6 +311,7 @@ pcbit_deliver(void *data)
                dev->read_queue = frame->next;
                spin_unlock_irqrestore(&dev->lock, flags);
 
+               msg = 0;
                SET_MSG_CPU(msg, 0);
                SET_MSG_PROC(msg, 0);
                SET_MSG_CMD(msg, frame->skb->data[2]);
@@ -512,7 +513,7 @@ pcbit_firmware_bug(struct pcbit_dev *dev)
 }
 
 irqreturn_t
-pcbit_irq_handler(int interrupt, void *devptr, struct pt_regs *regs)
+pcbit_irq_handler(int interrupt, void *devptr)
 {
        struct pcbit_dev *dev;
        u_char info,
index 0d99da3a3e2b91bc5f9beaacb1e57cc151fec1b5..2ac295e1a6e554d998d63cd240ddc44fff71806c 100644 (file)
@@ -124,7 +124,7 @@ struct frame_buf {
 extern int pcbit_l2_write(struct pcbit_dev * dev, ulong msg, ushort refnum, 
                           struct sk_buff *skb, unsigned short hdr_len);
 
-extern irqreturn_t pcbit_irq_handler(int interrupt, void *, struct pt_regs *regs);
+extern irqreturn_t pcbit_irq_handler(int interrupt, void *);
 
 extern struct pcbit_dev * dev_pcbit[MAX_PCBIT_CARDS];
 
index a627e68023f64e228671d02c20b3e96ed94eb666..06c9872e8c6a5c5b503117d86fdd05dbd3286e65 100644 (file)
@@ -35,7 +35,7 @@ module_param_array(irq, int, NULL, 0);
 module_param_array(ram, int, NULL, 0);
 module_param(do_reset, bool, 0);
 
-extern irqreturn_t interrupt_handler(int, void *, struct pt_regs *);
+extern irqreturn_t interrupt_handler(int, void *);
 extern int sndpkt(int, int, int, struct sk_buff *);
 extern int command(isdn_ctrl *);
 extern int indicate_status(int, int, ulong, char*);
@@ -98,13 +98,14 @@ static int __init sc_init(void)
                         * Confirm the I/O Address with a test
                         */
                        if(io[b] == 0) {
-                               pr_debug("I/O Address 0x%x is in use.\n");
+                               pr_debug("I/O Address invalid.\n");
                                continue;
                        }
 
                        outb(0x18, io[b] + 0x400 * EXP_PAGE0);
                        if(inb(io[b] + 0x400 * EXP_PAGE0) != 0x18) {
-                               pr_debug("I/O Base 0x%x fails test\n");
+                               pr_debug("I/O Base 0x%x fails test\n",
+                                        io[b] + 0x400 * EXP_PAGE0);
                                continue;
                        }
                }
@@ -158,8 +159,8 @@ static int __init sc_init(void)
                        outb(0xFF, io[b] + RESET_OFFSET);
                        msleep_interruptible(10000);
                }
-               pr_debug("RAM Base for board %d is 0x%x, %s probe\n", b, ram[b],
-                       ram[b] == 0 ? "will" : "won't");
+               pr_debug("RAM Base for board %d is 0x%lx, %s probe\n", b,
+                       ram[b], ram[b] == 0 ? "will" : "won't");
 
                if(ram[b]) {
                        /*
@@ -168,7 +169,7 @@ static int __init sc_init(void)
                         * board model
                         */
                        if(request_region(ram[b], SRAM_PAGESIZE, "sc test")) {
-                               pr_debug("request_region for RAM base 0x%x succeeded\n", ram[b]);
+                               pr_debug("request_region for RAM base 0x%lx succeeded\n", ram[b]);
                                model = identify_board(ram[b], io[b]);
                                release_region(ram[b], SRAM_PAGESIZE);
                        }
@@ -204,7 +205,7 @@ static int __init sc_init(void)
                         * Nope, there was no place in RAM for the
                         * board, or it couldn't be identified
                         */
-                        pr_debug("Failed to find an adapter at 0x%x\n", ram[b]);
+                        pr_debug("Failed to find an adapter at 0x%lx\n", ram[b]);
                         continue;
                }
 
@@ -451,7 +452,7 @@ static int identify_board(unsigned long rambase, unsigned int iobase)
        HWConfig_pl hwci;
        int x;
 
-       pr_debug("Attempting to identify adapter @ 0x%x io 0x%x\n",
+       pr_debug("Attempting to identify adapter @ 0x%lx io 0x%x\n",
                rambase, iobase);
 
        /*
@@ -490,7 +491,7 @@ static int identify_board(unsigned long rambase, unsigned int iobase)
        outb(PRI_BASEPG_VAL, pgport);
        msleep_interruptible(1000);
        sig = readl(rambase + SIG_OFFSET);
-       pr_debug("Looking for a signature, got 0x%x\n", sig);
+       pr_debug("Looking for a signature, got 0x%lx\n", sig);
        if(sig == SIGNATURE)
                return PRI_BOARD;
 
@@ -500,7 +501,7 @@ static int identify_board(unsigned long rambase, unsigned int iobase)
        outb(BRI_BASEPG_VAL, pgport);
        msleep_interruptible(1000);
        sig = readl(rambase + SIG_OFFSET);
-       pr_debug("Looking for a signature, got 0x%x\n", sig);
+       pr_debug("Looking for a signature, got 0x%lx\n", sig);
        if(sig == SIGNATURE)
                return BRI_BOARD;
 
@@ -510,7 +511,7 @@ static int identify_board(unsigned long rambase, unsigned int iobase)
         * Try to spot a card
         */
        sig = readl(rambase + SIG_OFFSET);
-       pr_debug("Looking for a signature, got 0x%x\n", sig);
+       pr_debug("Looking for a signature, got 0x%lx\n", sig);
        if(sig != SIGNATURE)
                return -1;
 
@@ -540,7 +541,7 @@ static int identify_board(unsigned long rambase, unsigned int iobase)
        memcpy_fromio(&rcvmsg, &(dpm->rsp_queue[dpm->rsp_tail]), MSG_LEN);
        pr_debug("Got HWConfig response, status = 0x%x\n", rcvmsg.rsp_status);
        memcpy(&hwci, &(rcvmsg.msg_data.HWCresponse), sizeof(HWConfig_pl));
-       pr_debug("Hardware Config: Interface: %s, RAM Size: %d, Serial: %s\n"
+       pr_debug("Hardware Config: Interface: %s, RAM Size: %ld, Serial: %s\n"
                 "                 Part: %s, Rev: %s\n",
                 hwci.st_u_sense ? "S/T" : "U", hwci.ram_size,
                 hwci.serial_no, hwci.part_no, hwci.rev_no);
index ae6263125ac2ef04dbcf8c4ff04c9af340a80ab9..cd17de18cb76df0907659168e516bdb8d3bcc502 100644 (file)
@@ -45,7 +45,7 @@ static int get_card_from_irq(int irq)
 /*
  * 
  */
-irqreturn_t interrupt_handler(int interrupt, void *cardptr, struct pt_regs *regs)
+irqreturn_t interrupt_handler(int interrupt, void *cardptr)
 {
 
        RspMessage rcvmsg;
index f50defc38ae5b47baac92c6117b39d9a3bab1b04..1e04676b016b212b07d0397b5493c04bb1058c39 100644 (file)
@@ -44,7 +44,7 @@ int sndpkt(int devId, int channel, struct sk_buff *data)
                return -ENODEV;
        }
 
-       pr_debug("%s: sndpkt: frst = 0x%x nxt = %d  f = %d n = %d\n",
+       pr_debug("%s: sndpkt: frst = 0x%lx nxt = %d  f = %d n = %d\n",
                sc_adapter[card]->devicename,
                sc_adapter[card]->channel[channel].first_sendbuf,
                sc_adapter[card]->channel[channel].next_sendbuf,
@@ -66,7 +66,7 @@ int sndpkt(int devId, int channel, struct sk_buff *data)
        ReqLnkWrite.buff_offset = sc_adapter[card]->channel[channel].next_sendbuf *
                BUFFER_SIZE + sc_adapter[card]->channel[channel].first_sendbuf;
        ReqLnkWrite.msg_len = data->len; /* sk_buff size */
-       pr_debug("%s: writing %d bytes to buffer offset 0x%x\n",
+       pr_debug("%s: writing %d bytes to buffer offset 0x%lx\n",
                        sc_adapter[card]->devicename,
                        ReqLnkWrite.msg_len, ReqLnkWrite.buff_offset);
        memcpy_toshmem(card, (char *)ReqLnkWrite.buff_offset, data->data, ReqLnkWrite.msg_len);
@@ -74,7 +74,7 @@ int sndpkt(int devId, int channel, struct sk_buff *data)
        /*
         * sendmessage
         */
-       pr_debug("%s: sndpkt size=%d, buf_offset=0x%x buf_indx=%d\n",
+       pr_debug("%s: sndpkt size=%d, buf_offset=0x%lx buf_indx=%d\n",
                sc_adapter[card]->devicename,
                ReqLnkWrite.msg_len, ReqLnkWrite.buff_offset,
                sc_adapter[card]->channel[channel].next_sendbuf);
@@ -124,7 +124,7 @@ void rcvpkt(int card, RspMessage *rcvmsg)
                        return;
                }
                skb_put(skb, rcvmsg->msg_data.response.msg_len);
-               pr_debug("%s: getting data from offset: 0x%x\n",
+               pr_debug("%s: getting data from offset: 0x%lx\n",
                        sc_adapter[card]->devicename,
                        rcvmsg->msg_data.response.buff_offset);
                memcpy_fromshmem(card,
@@ -143,7 +143,7 @@ void rcvpkt(int card, RspMessage *rcvmsg)
 /*             memset_shmem(card, rcvmsg->msg_data.response.buff_offset, 0, BUFFER_SIZE); */
                newll.buff_offset = rcvmsg->msg_data.response.buff_offset;
                newll.msg_len = BUFFER_SIZE;
-               pr_debug("%s: recycled buffer at offset 0x%x size %d\n",
+               pr_debug("%s: recycled buffer at offset 0x%lx size %d\n",
                        sc_adapter[card]->devicename,
                        newll.buff_offset, newll.msg_len);
                sendmessage(card, CEPID, ceReqTypeLnk, ceReqClass1, ceReqLnkRead,
@@ -186,7 +186,7 @@ int setup_buffers(int card, int c)
        sc_adapter[card]->channel[c-1].num_sendbufs = nBuffers / 2;
        sc_adapter[card]->channel[c-1].free_sendbufs = nBuffers / 2;
        sc_adapter[card]->channel[c-1].next_sendbuf = 0;
-       pr_debug("%s: send buffer setup complete: first=0x%x n=%d f=%d, nxt=%d\n",
+       pr_debug("%s: send buffer setup complete: first=0x%lx n=%d f=%d, nxt=%d\n",
                                sc_adapter[card]->devicename,
                                sc_adapter[card]->channel[c-1].first_sendbuf,
                                sc_adapter[card]->channel[c-1].num_sendbufs,
@@ -203,7 +203,7 @@ int setup_buffers(int card, int c)
                        ((sc_adapter[card]->channel[c-1].first_sendbuf +
                        (nBuffers / 2) * buffer_size) + (buffer_size * i));
                RcvBuffOffset.msg_len = buffer_size;
-               pr_debug("%s: adding RcvBuffer #%d offset=0x%x sz=%d bufsz:%d\n",
+               pr_debug("%s: adding RcvBuffer #%d offset=0x%lx sz=%d bufsz:%d\n",
                                sc_adapter[card]->devicename,
                                i + 1, RcvBuffOffset.buff_offset, 
                                RcvBuffOffset.msg_len,buffer_size);
index 24854826ca4599842fd7165f4de12f548f1f9b45..6f58862992dbf9079fe978c2f0ccda31fcfd77e1 100644 (file)
@@ -61,7 +61,7 @@ void memcpy_toshmem(int card, void *dest, const void *src, size_t n)
        spin_unlock_irqrestore(&sc_adapter[card]->lock, flags);
        pr_debug("%s: set page to %#x\n",sc_adapter[card]->devicename,
                ((sc_adapter[card]->shmem_magic + ch * SRAM_PAGESIZE)>>14)|0x80);
-       pr_debug("%s: copying %d bytes from %#x to %#x\n",
+       pr_debug("%s: copying %d bytes from %#lx to %#lx\n",
                sc_adapter[card]->devicename, n,
                (unsigned long) src,
                sc_adapter[card]->rambase + ((unsigned long) dest %0x4000));
index aecbbe2e89a92673fb600e0d0500194cde5dcff9..3c1711210e38a375f7ec1064c6bd59aeb7d74206 100644 (file)
@@ -91,6 +91,8 @@ EXPORT_SYMBOL_GPL(led_classdev_resume);
  */
 int led_classdev_register(struct device *parent, struct led_classdev *led_cdev)
 {
+       int rc;
+
        led_cdev->class_dev = class_device_create(leds_class, NULL, 0,
                                                parent, "%s", led_cdev->name);
        if (unlikely(IS_ERR(led_cdev->class_dev)))
@@ -99,8 +101,10 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev)
        class_set_devdata(led_cdev->class_dev, led_cdev);
 
        /* register the attributes */
-       class_device_create_file(led_cdev->class_dev,
-                               &class_device_attr_brightness);
+       rc = class_device_create_file(led_cdev->class_dev,
+                                     &class_device_attr_brightness);
+       if (rc)
+               goto err_out;
 
        /* add to the list of leds */
        write_lock(&leds_list_lock);
@@ -110,16 +114,28 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev)
 #ifdef CONFIG_LEDS_TRIGGERS
        rwlock_init(&led_cdev->trigger_lock);
 
-       led_trigger_set_default(led_cdev);
+       rc = class_device_create_file(led_cdev->class_dev,
+                                     &class_device_attr_trigger);
+       if (rc)
+               goto err_out_led_list;
 
-       class_device_create_file(led_cdev->class_dev,
-                               &class_device_attr_trigger);
+       led_trigger_set_default(led_cdev);
 #endif
 
        printk(KERN_INFO "Registered led device: %s\n",
                        led_cdev->class_dev->class_id);
 
        return 0;
+
+#ifdef CONFIG_LEDS_TRIGGERS
+err_out_led_list:
+       class_device_remove_file(led_cdev->class_dev,
+                               &class_device_attr_brightness);
+       list_del(&led_cdev->node);
+#endif
+err_out:
+       class_device_unregister(led_cdev->class_dev);
+       return rc;
 }
 EXPORT_SYMBOL_GPL(led_classdev_register);
 
index 179c2876b5416cf871dbb7c3c3ce08ecebe8b137..29a8818a32ec23e71fda137f1e634e46de538559 100644 (file)
@@ -123,6 +123,7 @@ static CLASS_DEVICE_ATTR(delay_off, 0644, led_delay_off_show,
 static void timer_trig_activate(struct led_classdev *led_cdev)
 {
        struct timer_trig_data *timer_data;
+       int rc;
 
        timer_data = kzalloc(sizeof(struct timer_trig_data), GFP_KERNEL);
        if (!timer_data)
@@ -134,10 +135,21 @@ static void timer_trig_activate(struct led_classdev *led_cdev)
        timer_data->timer.function = led_timer_function;
        timer_data->timer.data = (unsigned long) led_cdev;
 
-       class_device_create_file(led_cdev->class_dev,
+       rc = class_device_create_file(led_cdev->class_dev,
                                &class_device_attr_delay_on);
-       class_device_create_file(led_cdev->class_dev,
+       if (rc) goto err_out;
+       rc = class_device_create_file(led_cdev->class_dev,
                                &class_device_attr_delay_off);
+       if (rc) goto err_out_delayon;
+
+       return;
+
+err_out_delayon:
+       class_device_remove_file(led_cdev->class_dev,
+                               &class_device_attr_delay_on);
+err_out:
+       led_cdev->trigger_data = NULL;
+       kfree(timer_data);
 }
 
 static void timer_trig_deactivate(struct led_classdev *led_cdev)
index d56d400b6aaa52644fe610ef5042b00cddfa538e..17ef5d3c01b45cb1c581eec128c5ff901ce53eb1 100644 (file)
@@ -30,7 +30,7 @@
 
 /*#define DEBUG_ADB_IOP*/
 
-extern void iop_ism_irq(int, void *, struct pt_regs *);
+extern void iop_ism_irq(int, void *);
 
 static struct adb_request *current_req;
 static struct adb_request *last_req;
@@ -78,7 +78,7 @@ static void adb_iop_end_req(struct adb_request *req, int state)
  * This will be called when a packet has been successfully sent.
  */
 
-static void adb_iop_complete(struct iop_msg *msg, struct pt_regs *regs)
+static void adb_iop_complete(struct iop_msg *msg)
 {
        struct adb_request *req;
        uint flags;
@@ -100,7 +100,7 @@ static void adb_iop_complete(struct iop_msg *msg, struct pt_regs *regs)
  * commands or autopoll packets) are received.
  */
 
-static void adb_iop_listen(struct iop_msg *msg, struct pt_regs *regs)
+static void adb_iop_listen(struct iop_msg *msg)
 {
        struct adb_iopmsg *amsg = (struct adb_iopmsg *) msg->message;
        struct adb_request *req;
@@ -143,7 +143,7 @@ static void adb_iop_listen(struct iop_msg *msg, struct pt_regs *regs)
                        req->reply_len = amsg->count + 1;
                        memcpy(req->reply, &amsg->cmd, req->reply_len);
                } else {
-                       adb_input(&amsg->cmd, amsg->count + 1, regs,
+                       adb_input(&amsg->cmd, amsg->count + 1,
                                  amsg->flags & ADB_IOP_AUTOPOLL);
                }
                memcpy(msg->reply, msg->message, IOP_MSG_LEN);
@@ -266,7 +266,7 @@ int adb_iop_autopoll(int devs)
 void adb_iop_poll(void)
 {
        if (adb_iop_state == idle) adb_iop_start();
-       iop_ism_irq(0, (void *) ADB_IOP, NULL);
+       iop_ism_irq(0, (void *) ADB_IOP);
 }
 
 int adb_iop_reset_bus(void)
index 360f93f6fcdb55de9941c14e38349c82a59f516b..be0bd34ff6f90f7c311557f086b309da61b86fa1 100644 (file)
@@ -103,7 +103,7 @@ static void adbdev_init(void);
 static int try_handler_change(int, int);
 
 static struct adb_handler {
-       void (*handler)(unsigned char *, int, struct pt_regs *, int);
+       void (*handler)(unsigned char *, int, int);
        int original_address;
        int handler_id;
        int busy;
@@ -522,7 +522,7 @@ bail:
     the handler_id id it doesn't match. */
 int
 adb_register(int default_id, int handler_id, struct adb_ids *ids,
-            void (*handler)(unsigned char *, int, struct pt_regs *, int))
+            void (*handler)(unsigned char *, int, int))
 {
        int i;
 
@@ -570,13 +570,13 @@ adb_unregister(int index)
 }
 
 void
-adb_input(unsigned char *buf, int nb, struct pt_regs *regs, int autopoll)
+adb_input(unsigned char *buf, int nb, int autopoll)
 {
        int i, id;
        static int dump_adb_input = 0;
        unsigned long flags;
        
-       void (*handler)(unsigned char *, int, struct pt_regs *, int);
+       void (*handler)(unsigned char *, int, int);
 
        /* We skip keystrokes and mouse moves when the sleep process
         * has been started. We stop autopoll, but this is another security
@@ -597,7 +597,7 @@ adb_input(unsigned char *buf, int nb, struct pt_regs *regs, int autopoll)
                adb_handler[id].busy = 1;
        write_unlock_irqrestore(&adb_handler_lock, flags);
        if (handler != NULL) {
-               (*handler)(buf, nb, regs, autopoll);
+               (*handler)(buf, nb, autopoll);
                wmb();
                adb_handler[id].busy = 0;
        }
index b7fb367808d862edbb61badfc22b21c8fd66d923..5066e7a8ea9cd1ca10cb7978516f3c656007a4f5 100644 (file)
@@ -222,7 +222,7 @@ static struct adbhid *adbhid[16];
 
 static void adbhid_probe(void);
 
-static void adbhid_input_keycode(int, int, int, struct pt_regs *);
+static void adbhid_input_keycode(int, int, int);
 
 static void init_trackpad(int id);
 static void init_trackball(int id);
@@ -253,7 +253,7 @@ static struct adb_ids buttons_ids;
 #define ADBMOUSE_MACALLY2      9       /* MacAlly 2-button mouse */
 
 static void
-adbhid_keyboard_input(unsigned char *data, int nb, struct pt_regs *regs, int apoll)
+adbhid_keyboard_input(unsigned char *data, int nb, int apoll)
 {
        int id = (data[0] >> 4) & 0x0f;
 
@@ -266,13 +266,13 @@ adbhid_keyboard_input(unsigned char *data, int nb, struct pt_regs *regs, int apo
        /* first check this is from register 0 */
        if (nb != 3 || (data[0] & 3) != KEYB_KEYREG)
                return;         /* ignore it */
-       adbhid_input_keycode(id, data[1], 0, regs);
+       adbhid_input_keycode(id, data[1], 0);
        if (!(data[2] == 0xff || (data[2] == 0x7f && data[1] == 0x7f)))
-               adbhid_input_keycode(id, data[2], 0, regs);
+               adbhid_input_keycode(id, data[2], 0);
 }
 
 static void
-adbhid_input_keycode(int id, int keycode, int repeat, struct pt_regs *regs)
+adbhid_input_keycode(int id, int keycode, int repeat)
 {
        struct adbhid *ahid = adbhid[id];
        int up_flag;
@@ -282,7 +282,6 @@ adbhid_input_keycode(int id, int keycode, int repeat, struct pt_regs *regs)
 
        switch (keycode) {
        case ADB_KEY_CAPSLOCK: /* Generate down/up events for CapsLock everytime. */
-               input_regs(ahid->input, regs);
                input_report_key(ahid->input, KEY_CAPSLOCK, 1);
                input_report_key(ahid->input, KEY_CAPSLOCK, 0);
                input_sync(ahid->input);
@@ -338,7 +337,6 @@ adbhid_input_keycode(int id, int keycode, int repeat, struct pt_regs *regs)
        }
 
        if (adbhid[id]->keycode[keycode]) {
-               input_regs(adbhid[id]->input, regs);
                input_report_key(adbhid[id]->input,
                                 adbhid[id]->keycode[keycode], !up_flag);
                input_sync(adbhid[id]->input);
@@ -349,7 +347,7 @@ adbhid_input_keycode(int id, int keycode, int repeat, struct pt_regs *regs)
 }
 
 static void
-adbhid_mouse_input(unsigned char *data, int nb, struct pt_regs *regs, int autopoll)
+adbhid_mouse_input(unsigned char *data, int nb, int autopoll)
 {
        int id = (data[0] >> 4) & 0x0f;
 
@@ -432,8 +430,6 @@ adbhid_mouse_input(unsigned char *data, int nb, struct pt_regs *regs, int autopo
                 break;
        }
 
-       input_regs(adbhid[id]->input, regs);
-
        input_report_key(adbhid[id]->input, BTN_LEFT,   !((data[1] >> 7) & 1));
        input_report_key(adbhid[id]->input, BTN_MIDDLE, !((data[2] >> 7) & 1));
 
@@ -449,7 +445,7 @@ adbhid_mouse_input(unsigned char *data, int nb, struct pt_regs *regs, int autopo
 }
 
 static void
-adbhid_buttons_input(unsigned char *data, int nb, struct pt_regs *regs, int autopoll)
+adbhid_buttons_input(unsigned char *data, int nb, int autopoll)
 {
        int id = (data[0] >> 4) & 0x0f;
 
@@ -458,8 +454,6 @@ adbhid_buttons_input(unsigned char *data, int nb, struct pt_regs *regs, int auto
                return;
        }
 
-       input_regs(adbhid[id]->input, regs);
-
        switch (adbhid[id]->original_handler_id) {
        default:
        case 0x02: /* Adjustable keyboard button device */
index 4b08852c35eecc24cfde1153f113edfc90ed0547..797cef72258f317a06340a08107e0f357326d73c 100644 (file)
@@ -64,7 +64,7 @@ static DEFINE_SPINLOCK(macio_lock);
 
 static int macio_probe(void);
 static int macio_init(void);
-static irqreturn_t macio_adb_interrupt(int irq, void *arg, struct pt_regs *regs);
+static irqreturn_t macio_adb_interrupt(int irq, void *arg);
 static int macio_send_request(struct adb_request *req, int sync);
 static int macio_adb_autopoll(int devs);
 static void macio_adb_poll(void);
@@ -189,8 +189,7 @@ static int macio_send_request(struct adb_request *req, int sync)
        return 0;
 }
 
-static irqreturn_t macio_adb_interrupt(int irq, void *arg,
-                                      struct pt_regs *regs)
+static irqreturn_t macio_adb_interrupt(int irq, void *arg)
 {
        int i, n, err;
        struct adb_request *req = NULL;
@@ -260,7 +259,7 @@ static irqreturn_t macio_adb_interrupt(int irq, void *arg,
                (*done)(req);
        }
        if (ibuf_len)
-               adb_input(ibuf, ibuf_len, regs, autopoll);
+               adb_input(ibuf, ibuf_len, autopoll);
 
        return IRQ_RETVAL(handled);
 }
@@ -271,6 +270,6 @@ static void macio_adb_poll(void)
 
        local_irq_save(flags);
        if (in_8(&adb->intr.r) != 0)
-               macio_adb_interrupt(0, NULL, NULL);
+               macio_adb_interrupt(0, NULL);
        local_irq_restore(flags);
 }
index c0f9d82e46625593773f77733cfbe4fe3f979700..ade25b3fbb35bd5057b17a623c801ef76a762a5c 100644 (file)
@@ -145,7 +145,7 @@ static void smu_start_cmd(void)
 }
 
 
-static irqreturn_t smu_db_intr(int irq, void *arg, struct pt_regs *regs)
+static irqreturn_t smu_db_intr(int irq, void *arg)
 {
        unsigned long flags;
        struct smu_cmd *cmd;
@@ -224,7 +224,7 @@ static irqreturn_t smu_db_intr(int irq, void *arg, struct pt_regs *regs)
 }
 
 
-static irqreturn_t smu_msg_intr(int irq, void *arg, struct pt_regs *regs)
+static irqreturn_t smu_msg_intr(int irq, void *arg)
 {
        /* I don't quite know what to do with this one, we seem to never
         * receive it, so I suspect we have to arm it someway in the SMU
@@ -309,7 +309,7 @@ void smu_poll(void)
 
        gpio = pmac_do_feature_call(PMAC_FTR_READ_GPIO, NULL, smu->doorbell);
        if ((gpio & 7) == 7)
-               smu_db_intr(smu->db_irq, smu, NULL);
+               smu_db_intr(smu->db_irq, smu);
 }
 EXPORT_SYMBOL(smu_poll);
 
index 7512d1c1520761560d0517add1e6c50703d69475..df66291b1322651a2053637dfa41a9b6818732fc 100644 (file)
@@ -98,8 +98,8 @@ static int cuda_reset_adb_bus(void);
 
 static int cuda_init_via(void);
 static void cuda_start(void);
-static irqreturn_t cuda_interrupt(int irq, void *arg, struct pt_regs *regs);
-static void cuda_input(unsigned char *buf, int nb, struct pt_regs *regs);
+static irqreturn_t cuda_interrupt(int irq, void *arg);
+static void cuda_input(unsigned char *buf, int nb);
 void cuda_poll(void);
 static int cuda_write(struct adb_request *req);
 
@@ -437,12 +437,12 @@ cuda_poll(void)
      * disable_irq(), would that work on m68k ? --BenH
      */
     local_irq_save(flags);
-    cuda_interrupt(0, NULL, NULL);
+    cuda_interrupt(0, NULL);
     local_irq_restore(flags);
 }
 
 static irqreturn_t
-cuda_interrupt(int irq, void *arg, struct pt_regs *regs)
+cuda_interrupt(int irq, void *arg)
 {
     int status;
     struct adb_request *req = NULL;
@@ -594,12 +594,12 @@ cuda_interrupt(int irq, void *arg, struct pt_regs *regs)
                (*done)(req);
     }
     if (ibuf_len)
-       cuda_input(ibuf, ibuf_len, regs);
+       cuda_input(ibuf, ibuf_len);
     return IRQ_HANDLED;
 }
 
 static void
-cuda_input(unsigned char *buf, int nb, struct pt_regs *regs)
+cuda_input(unsigned char *buf, int nb)
 {
     int i;
 
@@ -615,7 +615,7 @@ cuda_input(unsigned char *buf, int nb, struct pt_regs *regs)
        }
 #endif /* CONFIG_XMON */
 #ifdef CONFIG_ADB
-       adb_input(buf+2, nb-2, regs, buf[1] & 0x40);
+       adb_input(buf+2, nb-2, buf[1] & 0x40);
 #endif /* CONFIG_ADB */
        break;
 
index 2a2ffe060169a5f96d9679466b745f8341ee5397..5d88d5b0ad9931c3f400efbe5c2ec6c48d6ec0c2 100644 (file)
@@ -77,7 +77,7 @@ static volatile unsigned char *via;
 
 static int  macii_init_via(void);
 static void macii_start(void);
-static irqreturn_t macii_interrupt(int irq, void *arg, struct pt_regs *regs);
+static irqreturn_t macii_interrupt(int irq, void *arg);
 static void macii_retransmit(int);
 static void macii_queue_poll(void);
 
@@ -295,7 +295,7 @@ static void macii_poll(void)
        unsigned long flags;
 
        local_irq_save(flags);
-       if (via[IFR] & SR_INT) macii_interrupt(0, NULL, NULL);
+       if (via[IFR] & SR_INT) macii_interrupt(0, NULL);
        local_irq_restore(flags);
 }
 
@@ -410,7 +410,7 @@ static void macii_start(void)
  * Note: As of 21/10/97, the MacII ADB part works including timeout detection
  * and retransmit (Talk to the last active device).
  */
-static irqreturn_t macii_interrupt(int irq, void *arg, struct pt_regs *regs)
+static irqreturn_t macii_interrupt(int irq, void *arg)
 {
        int x, adbdir;
        unsigned long flags;
@@ -602,8 +602,7 @@ static irqreturn_t macii_interrupt(int irq, void *arg, struct pt_regs *regs)
                                current_req = req->next;
                                if (req->done) (*req->done)(req);
                        } else {
-                               adb_input(reply_buf, reply_ptr - reply_buf,
-                                         regs, 0);
+                               adb_input(reply_buf, reply_ptr - reply_buf, 0);
                        }
 
                        /*
index 0129fcc3b183b050cd797910b9571cb2d9dccb5c..1f0aa5dc9aa576eac1060a6ba3e1da55a9ec24b6 100644 (file)
@@ -84,8 +84,8 @@ static int maciisi_init(void);
 static int maciisi_send_request(struct adb_request* req, int sync);
 static void maciisi_sync(struct adb_request *req);
 static int maciisi_write(struct adb_request* req);
-static irqreturn_t maciisi_interrupt(int irq, void* arg, struct pt_regs* regs);
-static void maciisi_input(unsigned char *buf, int nb, struct pt_regs *regs);
+static irqreturn_t maciisi_interrupt(int irq, void* arg);
+static void maciisi_input(unsigned char *buf, int nb);
 static int maciisi_init_via(void);
 static void maciisi_poll(void);
 static int maciisi_start(void);
@@ -421,7 +421,7 @@ maciisi_poll(void)
 
        local_irq_save(flags);
        if (via[IFR] & SR_INT) {
-               maciisi_interrupt(0, NULL, NULL);
+               maciisi_interrupt(0, NULL);
        }
        else /* avoid calling this function too quickly in a loop */
                udelay(ADB_DELAY);
@@ -433,7 +433,7 @@ maciisi_poll(void)
    register is either full or empty. In practice, I have no idea what
    it means :( */
 static irqreturn_t
-maciisi_interrupt(int irq, void* arg, struct pt_regs* regs)
+maciisi_interrupt(int irq, void* arg)
 {
        int status;
        struct adb_request *req;
@@ -612,7 +612,7 @@ maciisi_interrupt(int irq, void* arg, struct pt_regs* regs)
                        /* Obviously, we got it */
                        reading_reply = 0;
                } else {
-                       maciisi_input(maciisi_rbuf, reply_ptr - maciisi_rbuf, regs);
+                       maciisi_input(maciisi_rbuf, reply_ptr - maciisi_rbuf);
                }
                maciisi_state = idle;
                status = via[B] & (TIP|TREQ);
@@ -657,7 +657,7 @@ maciisi_interrupt(int irq, void* arg, struct pt_regs* regs)
 }
 
 static void
-maciisi_input(unsigned char *buf, int nb, struct pt_regs *regs)
+maciisi_input(unsigned char *buf, int nb)
 {
 #ifdef DEBUG_MACIISI_ADB
     int i;
@@ -665,7 +665,7 @@ maciisi_input(unsigned char *buf, int nb, struct pt_regs *regs)
 
     switch (buf[0]) {
     case ADB_PACKET:
-           adb_input(buf+2, nb-2, regs, buf[1] & 0x40);
+           adb_input(buf+2, nb-2, buf[1] & 0x40);
            break;
     default:
 #ifdef DEBUG_MACIISI_ADB
index 4f04fd0956a006a5bb9097cc558912b2df77f4df..e63ea1c1f3c1de9833ac155d8e3e7587d5ff8693 100644 (file)
@@ -191,8 +191,8 @@ static int pmu_adb_reset_bus(void);
 
 static int init_pmu(void);
 static void pmu_start(void);
-static irqreturn_t via_pmu_interrupt(int irq, void *arg, struct pt_regs *regs);
-static irqreturn_t gpio1_interrupt(int irq, void *arg, struct pt_regs *regs);
+static irqreturn_t via_pmu_interrupt(int irq, void *arg);
+static irqreturn_t gpio1_interrupt(int irq, void *arg);
 static int proc_get_info(char *page, char **start, off_t off,
                          int count, int *eof, void *data);
 static int proc_get_irqstats(char *page, char **start, off_t off,
@@ -555,7 +555,7 @@ init_pmu(void)
                }
                if (pmu_state == idle)
                        adb_int_pending = 1;
-               via_pmu_interrupt(0, NULL, NULL);
+               via_pmu_interrupt(0, NULL);
                udelay(10);
        }
 
@@ -1215,7 +1215,7 @@ pmu_poll(void)
                return;
        if (disable_poll)
                return;
-       via_pmu_interrupt(0, NULL, NULL);
+       via_pmu_interrupt(0, NULL);
 }
 
 void
@@ -1228,7 +1228,7 @@ pmu_poll_adb(void)
        /* Kicks ADB read when PMU is suspended */
        adb_int_pending = 1;
        do {
-               via_pmu_interrupt(0, NULL, NULL);
+               via_pmu_interrupt(0, NULL);
        } while (pmu_suspended && (adb_int_pending || pmu_state != idle
                || req_awaiting_reply));
 }
@@ -1239,7 +1239,7 @@ pmu_wait_complete(struct adb_request *req)
        if (!via)
                return;
        while((pmu_state != idle && pmu_state != locked) || !req->complete)
-               via_pmu_interrupt(0, NULL, NULL);
+               via_pmu_interrupt(0, NULL);
 }
 
 /* This function loops until the PMU is idle and prevents it from
@@ -1268,7 +1268,7 @@ pmu_suspend(void)
                spin_unlock_irqrestore(&pmu_lock, flags);
                if (req_awaiting_reply)
                        adb_int_pending = 1;
-               via_pmu_interrupt(0, NULL, NULL);
+               via_pmu_interrupt(0, NULL);
                spin_lock_irqsave(&pmu_lock, flags);
                if (!adb_int_pending && pmu_state == idle && !req_awaiting_reply) {
 #ifdef SUSPEND_USES_PMU
@@ -1318,7 +1318,7 @@ pmu_resume(void)
 
 /* Interrupt data could be the result data from an ADB cmd */
 static void
-pmu_handle_data(unsigned char *data, int len, struct pt_regs *regs)
+pmu_handle_data(unsigned char *data, int len)
 {
        unsigned char ints, pirq;
        int i = 0;
@@ -1393,7 +1393,7 @@ next:
                        if (!(pmu_kind == PMU_OHARE_BASED && len == 4
                              && data[1] == 0x2c && data[3] == 0xff
                              && (data[2] & ~1) == 0xf4))
-                               adb_input(data+1, len-1, regs, 1);
+                               adb_input(data+1, len-1, 1);
 #endif /* CONFIG_ADB */                
                }
        }
@@ -1431,7 +1431,7 @@ next:
 }
 
 static struct adb_request*
-pmu_sr_intr(struct pt_regs *regs)
+pmu_sr_intr(void)
 {
        struct adb_request *req;
        int bite = 0;
@@ -1537,7 +1537,7 @@ pmu_sr_intr(struct pt_regs *regs)
 }
 
 static irqreturn_t
-via_pmu_interrupt(int irq, void *arg, struct pt_regs *regs)
+via_pmu_interrupt(int irq, void *arg)
 {
        unsigned long flags;
        int intr;
@@ -1567,7 +1567,7 @@ via_pmu_interrupt(int irq, void *arg, struct pt_regs *regs)
                        pmu_irq_stats[0]++;
                }
                if (intr & SR_INT) {
-                       req = pmu_sr_intr(regs);
+                       req = pmu_sr_intr();
                        if (req)
                                break;
                }
@@ -1613,7 +1613,7 @@ no_free_slot:
                
        /* Deal with interrupt datas outside of the lock */
        if (int_data >= 0) {
-               pmu_handle_data(interrupt_data[int_data], interrupt_data_len[int_data], regs);
+               pmu_handle_data(interrupt_data[int_data], interrupt_data_len[int_data]);
                spin_lock_irqsave(&pmu_lock, flags);
                ++disable_poll;
                int_data_state[int_data] = int_data_empty;
@@ -1638,7 +1638,7 @@ pmu_unlock(void)
 
 
 static irqreturn_t
-gpio1_interrupt(int irq, void *arg, struct pt_regs *regs)
+gpio1_interrupt(int irq, void *arg)
 {
        unsigned long flags;
 
@@ -1651,7 +1651,7 @@ gpio1_interrupt(int irq, void *arg, struct pt_regs *regs)
                pmu_irq_stats[1]++;
                adb_int_pending = 1;
                spin_unlock_irqrestore(&pmu_lock, flags);
-               via_pmu_interrupt(0, NULL, NULL);
+               via_pmu_interrupt(0, NULL);
                return IRQ_HANDLED;
        }
        return IRQ_NONE;
@@ -2116,7 +2116,7 @@ pmac_wakeup_devices(void)
 
        /* Force a poll of ADB interrupts */
        adb_int_pending = 1;
-       via_pmu_interrupt(0, NULL, NULL);
+       via_pmu_interrupt(0, NULL);
 
        /* Restart jiffies & scheduling */
        wakeup_decrementer();
index 9f4eff1d1a0f672f0b3714b2ec2460ea177be3d1..d9986f3a3fbf37c29b815e51ab9c44b015d43a7b 100644 (file)
@@ -107,7 +107,7 @@ BLOCKING_NOTIFIER_HEAD(sleep_notifier_list);
 static int pmu_probe(void);
 static int pmu_init(void);
 static void pmu_start(void);
-static irqreturn_t pmu_interrupt(int irq, void *arg, struct pt_regs *regs);
+static irqreturn_t pmu_interrupt(int irq, void *arg);
 static int pmu_send_request(struct adb_request *req, int sync);
 static int pmu_autopoll(int devs);
 void pmu_poll(void);
@@ -118,8 +118,7 @@ static void pmu_start(void);
 static void send_byte(int x);
 static void recv_byte(void);
 static void pmu_done(struct adb_request *req);
-static void pmu_handle_data(unsigned char *data, int len,
-                           struct pt_regs *regs);
+static void pmu_handle_data(unsigned char *data, int len);
 static void set_volume(int level);
 static void pmu_enable_backlight(int on);
 static void pmu_set_brightness(int level);
@@ -222,7 +221,7 @@ pmu_init(void)
                }
                if (pmu_state == idle) {
                        adb_int_pending = 1;
-                       pmu_interrupt(0, NULL, NULL);
+                       pmu_interrupt(0, NULL);
                }
                pmu_poll();
                udelay(10);
@@ -563,17 +562,17 @@ pmu_poll(void)
        local_irq_save(flags);
        if (via1[IFR] & SR_INT) {
                via1[IFR] = SR_INT;
-               pmu_interrupt(IRQ_MAC_ADB_SR, NULL, NULL);
+               pmu_interrupt(IRQ_MAC_ADB_SR, NULL);
        }
        if (via1[IFR] & CB1_INT) {
                via1[IFR] = CB1_INT;
-               pmu_interrupt(IRQ_MAC_ADB_CL, NULL, NULL);
+               pmu_interrupt(IRQ_MAC_ADB_CL, NULL);
        }
        local_irq_restore(flags);
 }
 
 static irqreturn_t
-pmu_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+pmu_interrupt(int irq, void *dev_id)
 {
        struct adb_request *req;
        int timeout, bite = 0;  /* to prevent compiler warning */
@@ -657,7 +656,7 @@ pmu_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                        }
 
                        if (pmu_state == reading_intr) {
-                               pmu_handle_data(interrupt_data, data_index, regs);
+                               pmu_handle_data(interrupt_data, data_index);
                        } else {
                                req = current_req;
                                current_req = req->next;
@@ -701,7 +700,7 @@ pmu_done(struct adb_request *req)
 
 /* Interrupt data could be the result data from an ADB cmd */
 static void 
-pmu_handle_data(unsigned char *data, int len, struct pt_regs *regs)
+pmu_handle_data(unsigned char *data, int len)
 {
        static int show_pmu_ints = 1;
 
@@ -726,7 +725,7 @@ pmu_handle_data(unsigned char *data, int len, struct pt_regs *regs)
                        }
                        pmu_done(req);
                } else {
-                       adb_input(data+1, len-1, regs, 1);
+                       adb_input(data+1, len-1, 1);
                }
        } else {
                if (data[0] == 0x08 && len == 3) {
index ef66bf2778ecab42565e2da225c368b8af056aee..fa4b13f89369031de1984f5c9be6d3875212df06 100644 (file)
@@ -650,24 +650,26 @@ static struct notifier_block pm112_events = {
        .notifier_call = pm112_wf_notify,
 };
 
-static int wf_pm112_probe(struct device *dev)
+static int wf_pm112_probe(struct platform_device *dev)
 {
        wf_register_client(&pm112_events);
        return 0;
 }
 
-static int wf_pm112_remove(struct device *dev)
+static int __devexit wf_pm112_remove(struct platform_device *dev)
 {
        wf_unregister_client(&pm112_events);
        /* should release all sensors and controls */
        return 0;
 }
 
-static struct device_driver wf_pm112_driver = {
-       .name = "windfarm",
-       .bus = &platform_bus_type,
+static struct platform_driver wf_pm112_driver = {
        .probe = wf_pm112_probe,
-       .remove = wf_pm112_remove,
+       .remove = __devexit_p(wf_pm112_remove),
+       .driver = {
+               .name = "windfarm",
+               .bus = &platform_bus_type,
+       },
 };
 
 static int __init wf_pm112_init(void)
@@ -683,13 +685,13 @@ static int __init wf_pm112_init(void)
                ++nr_cores;
 
        printk(KERN_INFO "windfarm: initializing for dual-core desktop G5\n");
-       driver_register(&wf_pm112_driver);
+       platform_driver_register(&wf_pm112_driver);
        return 0;
 }
 
 static void __exit wf_pm112_exit(void)
 {
-       driver_unregister(&wf_pm112_driver);
+       platform_driver_unregister(&wf_pm112_driver);
 }
 
 module_init(wf_pm112_init);
index 2ff546e4c92f789ad6921c911cbb61f63abe7d61..2a944851b8e10193090f85f4db01c03f820e2207 100644 (file)
 
 static int wf_smu_mach_model;  /* machine model id */
 
-static struct device *wf_smu_dev;
-
 /* Controls & sensors */
 static struct wf_sensor        *sensor_cpu_power;
 static struct wf_sensor        *sensor_cpu_temp;
@@ -717,16 +715,14 @@ static int wf_init_pm(void)
        return 0;
 }
 
-static int wf_smu_probe(struct device *ddev)
+static int wf_smu_probe(struct platform_device *ddev)
 {
-       wf_smu_dev = ddev;
-
        wf_register_client(&wf_smu_events);
 
        return 0;
 }
 
-static int wf_smu_remove(struct device *ddev)
+static int __devexit wf_smu_remove(struct platform_device *ddev)
 {
        wf_unregister_client(&wf_smu_events);
 
@@ -766,16 +762,16 @@ static int wf_smu_remove(struct device *ddev)
        if (wf_smu_cpu_fans)
                kfree(wf_smu_cpu_fans);
 
-       wf_smu_dev = NULL;
-
        return 0;
 }
 
-static struct device_driver wf_smu_driver = {
-        .name = "windfarm",
-        .bus = &platform_bus_type,
+static struct platform_driver wf_smu_driver = {
         .probe = wf_smu_probe,
-        .remove = wf_smu_remove,
+        .remove = __devexit_p(wf_smu_remove),
+       .driver = {
+               .name = "windfarm",
+               .bus = &platform_bus_type,
+       },
 };
 
 
@@ -794,7 +790,7 @@ static int __init wf_smu_init(void)
                request_module("windfarm_lm75_sensor");
 
 #endif /* MODULE */
-               driver_register(&wf_smu_driver);
+               platform_driver_register(&wf_smu_driver);
        }
 
        return rc;
@@ -803,7 +799,7 @@ static int __init wf_smu_init(void)
 static void __exit wf_smu_exit(void)
 {
 
-       driver_unregister(&wf_smu_driver);
+       platform_driver_unregister(&wf_smu_driver);
 }
 
 
index 59e9ffe37c395a57429904399f3c4a930acebb3a..9961a67b4f851333b9c00f952ed60c2e8f881642 100644 (file)
@@ -63,8 +63,6 @@
  */
 #undef HACKED_OVERTEMP
 
-static struct device *wf_smu_dev;
-
 /* Controls & sensors */
 static struct wf_sensor        *sensor_cpu_power;
 static struct wf_sensor        *sensor_cpu_temp;
@@ -641,16 +639,14 @@ static int wf_init_pm(void)
        return 0;
 }
 
-static int wf_smu_probe(struct device *ddev)
+static int wf_smu_probe(struct platform_device *ddev)
 {
-       wf_smu_dev = ddev;
-
        wf_register_client(&wf_smu_events);
 
        return 0;
 }
 
-static int wf_smu_remove(struct device *ddev)
+static int __devexit wf_smu_remove(struct platform_device *ddev)
 {
        wf_unregister_client(&wf_smu_events);
 
@@ -698,16 +694,16 @@ static int wf_smu_remove(struct device *ddev)
        if (wf_smu_cpu_fans)
                kfree(wf_smu_cpu_fans);
 
-       wf_smu_dev = NULL;
-
        return 0;
 }
 
-static struct device_driver wf_smu_driver = {
-        .name = "windfarm",
-        .bus = &platform_bus_type,
+static struct platform_driver wf_smu_driver = {
         .probe = wf_smu_probe,
-        .remove = wf_smu_remove,
+        .remove = __devexit_p(wf_smu_remove),
+       .driver = {
+               .name = "windfarm",
+               .bus = &platform_bus_type,
+       },
 };
 
 
@@ -725,7 +721,7 @@ static int __init wf_smu_init(void)
                request_module("windfarm_lm75_sensor");
 
 #endif /* MODULE */
-               driver_register(&wf_smu_driver);
+               platform_driver_register(&wf_smu_driver);
        }
 
        return rc;
@@ -734,7 +730,7 @@ static int __init wf_smu_init(void)
 static void __exit wf_smu_exit(void)
 {
 
-       driver_unregister(&wf_smu_driver);
+       platform_driver_unregister(&wf_smu_driver);
 }
 
 
index 09baa43b259975f05c3a28fe0e5f17a551418537..da862e4632dd0535b1c6047c3be5377b8f1bf1f8 100644 (file)
@@ -100,6 +100,7 @@ static DEVICE_ATTR(pos, S_IRUGO, mca_show_pos, NULL);
 int __init mca_register_device(int bus, struct mca_device *mca_dev)
 {
        struct mca_bus *mca_bus = mca_root_busses[bus];
+       int rc;
 
        mca_dev->dev.parent = &mca_bus->dev;
        mca_dev->dev.bus = &mca_bus_type;
@@ -108,13 +109,23 @@ int __init mca_register_device(int bus, struct mca_device *mca_dev)
        mca_dev->dev.dma_mask = &mca_dev->dma_mask;
        mca_dev->dev.coherent_dma_mask = mca_dev->dma_mask;
 
-       if (device_register(&mca_dev->dev))
-               return 0;
+       rc = device_register(&mca_dev->dev);
+       if (rc)
+               goto err_out;
 
-       device_create_file(&mca_dev->dev, &dev_attr_id);
-       device_create_file(&mca_dev->dev, &dev_attr_pos);
+       rc = device_create_file(&mca_dev->dev, &dev_attr_id);
+       if (rc) goto err_out_devreg;
+       rc = device_create_file(&mca_dev->dev, &dev_attr_pos);
+       if (rc) goto err_out_id;
 
        return 1;
+
+err_out_id:
+       device_remove_file(&mca_dev->dev, &dev_attr_id);
+err_out_devreg:
+       device_unregister(&mca_dev->dev);
+err_out:
+       return 0;
 }
 
 /* */
@@ -130,13 +141,16 @@ struct mca_bus * __devinit mca_attach_bus(int bus)
                return NULL;
        }
 
-       mca_bus = kmalloc(sizeof(struct mca_bus), GFP_KERNEL);
+       mca_bus = kzalloc(sizeof(struct mca_bus), GFP_KERNEL);
        if (!mca_bus)
                return NULL;
-       memset(mca_bus, 0, sizeof(struct mca_bus));
+
        sprintf(mca_bus->dev.bus_id,"mca%d",bus);
        sprintf(mca_bus->name,"Host %s MCA Bridge", bus ? "Secondary" : "Primary");
-       device_register(&mca_bus->dev);
+       if (device_register(&mca_bus->dev)) {
+               kfree(mca_bus);
+               return NULL;
+       }
 
        mca_root_busses[bus] = mca_bus;
 
index 8e67634e79a0d1f16d033e9e7ecdf3bcdd416f56..d6f614738bbd732e24cd039af3a05ffb01e01373 100644 (file)
@@ -536,7 +536,7 @@ static int bitmap_read_sb(struct bitmap *bitmap)
                printk(KERN_INFO "%s: bitmap file is out of date (%llu < %llu) "
                        "-- forcing full recovery\n", bmname(bitmap), events,
                        (unsigned long long) bitmap->mddev->events);
-               sb->state |= BITMAP_STALE;
+               sb->state |= cpu_to_le32(BITMAP_STALE);
        }
 success:
        /* assign fields using values from superblock */
@@ -544,11 +544,11 @@ success:
        bitmap->daemon_sleep = daemon_sleep;
        bitmap->daemon_lastrun = jiffies;
        bitmap->max_write_behind = write_behind;
-       bitmap->flags |= sb->state;
+       bitmap->flags |= le32_to_cpu(sb->state);
        if (le32_to_cpu(sb->version) == BITMAP_MAJOR_HOSTENDIAN)
                bitmap->flags |= BITMAP_HOSTENDIAN;
        bitmap->events_cleared = le64_to_cpu(sb->events_cleared);
-       if (sb->state & BITMAP_STALE)
+       if (sb->state & cpu_to_le32(BITMAP_STALE))
                bitmap->events_cleared = bitmap->mddev->events;
        err = 0;
 out:
@@ -578,9 +578,9 @@ static void bitmap_mask_state(struct bitmap *bitmap, enum bitmap_state bits,
        spin_unlock_irqrestore(&bitmap->lock, flags);
        sb = (bitmap_super_t *)kmap_atomic(bitmap->sb_page, KM_USER0);
        switch (op) {
-               case MASK_SET: sb->state |= bits;
+               case MASK_SET: sb->state |= cpu_to_le32(bits);
                                break;
-               case MASK_UNSET: sb->state &= ~bits;
+               case MASK_UNSET: sb->state &= cpu_to_le32(~bits);
                                break;
                default: BUG();
        }
@@ -1413,7 +1413,7 @@ int bitmap_create(mddev_t *mddev)
        int err;
        sector_t start;
 
-       BUG_ON(sizeof(bitmap_super_t) != 256);
+       BUILD_BUG_ON(sizeof(bitmap_super_t) != 256);
 
        if (!file && !mddev->bitmap_offset) /* bitmap disabled, nothing to do */
                return 0;
index 655d816760e591f0d007a6721fd557265004a791..a625576fdeeb3eb5c5ac1c7ebc15f3aea841df39 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/slab.h>
 #include <linux/crypto.h>
 #include <linux/workqueue.h>
+#include <linux/backing-dev.h>
 #include <asm/atomic.h>
 #include <linux/scatterlist.h>
 #include <asm/page.h>
@@ -602,7 +603,7 @@ static void process_write(struct crypt_io *io)
 
                /* out of memory -> run queues */
                if (remaining)
-                       blk_congestion_wait(bio_data_dir(clone), HZ/100);
+                       congestion_wait(bio_data_dir(clone), HZ/100);
        }
 }
 
index cb8281605be8f7d23bbd0769309268b5f69d7c1a..7daa7b1e145f32d3736a48e7e9ee6e81f94c5bb8 100644 (file)
@@ -974,12 +974,13 @@ static void super_90_sync(mddev_t *mddev, mdk_rdev_t *rdev)
  * version 1 superblock
  */
 
-static unsigned int calc_sb_1_csum(struct mdp_superblock_1 * sb)
+static __le32 calc_sb_1_csum(struct mdp_superblock_1 * sb)
 {
-       unsigned int disk_csum, csum;
+       __le32 disk_csum;
+       u32 csum;
        unsigned long long newcsum;
        int size = 256 + le32_to_cpu(sb->max_dev)*2;
-       unsigned int *isuper = (unsigned int*)sb;
+       __le32 *isuper = (__le32*)sb;
        int i;
 
        disk_csum = sb->sb_csum;
@@ -989,7 +990,7 @@ static unsigned int calc_sb_1_csum(struct mdp_superblock_1 * sb)
                newcsum += le32_to_cpu(*isuper++);
 
        if (size == 2)
-               newcsum += le16_to_cpu(*(unsigned short*) isuper);
+               newcsum += le16_to_cpu(*(__le16*) isuper);
 
        csum = (newcsum & 0xffffffff) + (newcsum >> 32);
        sb->sb_csum = disk_csum;
@@ -1106,7 +1107,7 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version)
        if (le32_to_cpu(sb->chunksize))
                rdev->size &= ~((sector_t)le32_to_cpu(sb->chunksize)/2 - 1);
 
-       if (le32_to_cpu(sb->size) > rdev->size*2)
+       if (le64_to_cpu(sb->size) > rdev->size*2)
                return -EINVAL;
        return ret;
 }
@@ -1228,7 +1229,7 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev)
        else
                sb->resync_offset = cpu_to_le64(0);
 
-       sb->cnt_corrected_read = atomic_read(&rdev->corrected_errors);
+       sb->cnt_corrected_read = cpu_to_le32(atomic_read(&rdev->corrected_errors));
 
        sb->raid_disks = cpu_to_le32(mddev->raid_disks);
        sb->size = cpu_to_le64(mddev->size<<1);
@@ -3849,6 +3850,7 @@ static int hot_add_disk(mddev_t * mddev, dev_t dev)
        }
        clear_bit(In_sync, &rdev->flags);
        rdev->desc_nr = -1;
+       rdev->saved_raid_disk = -1;
        err = bind_rdev_to_array(rdev, mddev);
        if (err)
                goto abort_export;
@@ -4911,6 +4913,7 @@ static unsigned int mdstat_poll(struct file *filp, poll_table *wait)
 }
 
 static struct file_operations md_seq_fops = {
+       .owner          = THIS_MODULE,
        .open           = md_seq_open,
        .read           = seq_read,
        .llseek         = seq_lseek,
index 171ff41b52b053e7acdc2f6c78e0ef34ed2bd695..a6260f0e3b9e57bf756ac32c8e75f15c37d47f12 100644 (file)
@@ -501,7 +501,7 @@ static int multipath_run (mddev_t *mddev)
                        mdname(mddev));
                goto out_free_conf;
        }
-       mddev->degraded = conf->raid_disks = conf->working_disks;
+       mddev->degraded = conf->raid_disks - conf->working_disks;
 
        conf->pool = mempool_create_kzalloc_pool(NR_RESERVED_BUFS,
                                                 sizeof(struct multipath_bh));
index 1250f0eab4afaf7b2c946a3c3767c25efc062bfc..74f17a9a6ebb78cca440a4c08b317b3f74a414a3 100644 (file)
@@ -2079,7 +2079,7 @@ static int run(mddev_t *mddev)
                disk = conf->mirrors + i;
 
                if (!disk->rdev ||
-                   !test_bit(In_sync, &rdev->flags)) {
+                   !test_bit(In_sync, &disk->rdev->flags)) {
                        disk->head_position = 0;
                        mddev->degraded++;
                }
index b88451e33c09cc67219a112cd78fb123cdd8a82f..86cbdbcf9d7db1f005e9cfa37a44b76088c59c61 100644 (file)
@@ -230,7 +230,7 @@ int saa7146_pgtable_build_single(struct pci_dev *pci, struct saa7146_pgtable *pt
 
 /********************************************************************************/
 /* interrupt handler */
-static irqreturn_t interrupt_hw(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t interrupt_hw(int irq, void *dev_id)
 {
        struct saa7146_dev *dev = dev_id;
        u32 isr = 0;
index eb2e6432c8c210c9e663cf6a4e98ebf75b422914..06893243f3d4c038ccda257778f58531a01133e5 100644 (file)
@@ -122,7 +122,7 @@ static void flexcop_pci_irq_check_work(void *data)
 /* When PID filtering is turned on, we use the timer IRQ, because small amounts
  * of data need to be passed to the user space instantly as well. When PID
  * filtering is turned off, we use the page-change-IRQ */
-static irqreturn_t flexcop_pci_isr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t flexcop_pci_isr(int irq, void *dev_id)
 {
        struct flexcop_pci *fc_pci = dev_id;
        struct flexcop_device *fc = fc_pci->fc_dev;
index 515954f96c9a6afa11eb5e708963216590ee5bdb..2853ea1bdaf1e7014e6cae070366e89c89ac30cd 100644 (file)
@@ -328,7 +328,7 @@ static void flexcop_usb_process_frame(struct flexcop_usb *fc_usb, u8 *buffer, in
        fc_usb->tmp_buffer_length = l;
 }
 
-static void flexcop_usb_urb_complete(struct urb *urb, struct pt_regs *ptregs)
+static void flexcop_usb_urb_complete(struct urb *urb)
 {
        struct flexcop_usb *fc_usb = urb->context;
        int i;
index 755822ee6e9ba1a981cd09e39805eb853b518006..329a51c185626db52076c30a6e764c79ca79ee1e 100644 (file)
@@ -266,7 +266,7 @@ EXPORT_SYMBOL(bt878_stop);
 /* Interrupt service routine */
 /*****************************/
 
-static irqreturn_t bt878_irq(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t bt878_irq(int irq, void *dev_id)
 {
        u32 stat, astat, mask;
        int count;
index fb6c4cc8477db818d04fb061f0893584b428690e..14e69a736edae5f50bf3207b9c1b0a205199faff 100644 (file)
@@ -665,6 +665,10 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
        case BTTV_BOARD_TWINHAN_DST:
                /*      DST is not a frontend driver !!!                */
                state = (struct dst_state *) kmalloc(sizeof (struct dst_state), GFP_KERNEL);
+               if (!state) {
+                       printk("dvb_bt8xx: No memory\n");
+                       break;
+               }
                /*      Setup the Card                                  */
                state->config = &dst_config;
                state->i2c = card->i2c_adapter;
index 410fa6d620ff930daa43744a54e6a53880d28cf5..ff7d4f56ced399880c1f1083b759e984a68bdb2f 100644 (file)
@@ -238,7 +238,7 @@ static void cinergyt2_sleep (struct cinergyt2 *cinergyt2, int sleep)
        cinergyt2->sleeping = sleep;
 }
 
-static void cinergyt2_stream_irq (struct urb *urb, struct pt_regs *regs);
+static void cinergyt2_stream_irq (struct urb *urb);
 
 static int cinergyt2_submit_stream_urb (struct cinergyt2 *cinergyt2, struct urb *urb)
 {
@@ -258,7 +258,7 @@ static int cinergyt2_submit_stream_urb (struct cinergyt2 *cinergyt2, struct urb
        return err;
 }
 
-static void cinergyt2_stream_irq (struct urb *urb, struct pt_regs *regs)
+static void cinergyt2_stream_irq (struct urb *urb)
 {
        struct cinergyt2 *cinergyt2 = urb->context;
 
index e46eae3b9be2624690746413bbb2c74601e2af54..1990eda10c469a52471495d8c865d7fa6d908985 100644 (file)
@@ -19,6 +19,6 @@ config DVB_CORE_ATTACH
          allow the card drivers to only load the frontend modules
          they require. This saves several KBytes of memory.
 
-         Note: You will need moudule-init-tools v3.2 or later for this feature.
+         Note: You will need module-init-tools v3.2 or later for this feature.
 
          If unsure say Y.
index fd3a9902f98d472662f69ee96690c5d11d673814..5143e426d283cc539043e0234d108f8eb7d7915c 100644 (file)
@@ -169,7 +169,7 @@ EXPORT_SYMBOL(dibusb_read_eeprom_byte);
 // Config Adjacent channels  Perf -cal22
 static struct dibx000_agc_config dib3000p_mt2060_agc_config = {
        .band_caps = BAND_VHF | BAND_UHF,
-       .setup     = (0 << 15) | (0 << 14) | (1 << 13) | (1 << 12) | (29 << 0),
+       .setup     = (1 << 8) | (5 << 5) | (1 << 4) | (1 << 3) | (0 << 2) | (2 << 0),
 
        .agc1_max = 48497,
        .agc1_min = 23593,
@@ -196,10 +196,14 @@ static struct dib3000mc_config stk3000p_dib3000p_config = {
        .ln_adc_level = 0x1cc7,
 
        .output_mpeg2_in_188_bytes = 1,
+
+       .agc_command1 = 1,
+       .agc_command2 = 1,
 };
 
 static struct dibx000_agc_config dib3000p_panasonic_agc_config = {
-       .setup    = (0 << 15) | (0 << 14) | (1 << 13) | (1 << 12) | (29 << 0),
+       .band_caps = BAND_VHF | BAND_UHF,
+       .setup     = (1 << 8) | (5 << 5) | (1 << 4) | (1 << 3) | (0 << 2) | (2 << 0),
 
        .agc1_max = 56361,
        .agc1_min = 22282,
@@ -226,6 +230,9 @@ static struct dib3000mc_config mod3000p_dib3000p_config = {
        .ln_adc_level = 0x1cc7,
 
        .output_mpeg2_in_188_bytes = 1,
+
+       .agc_command1 = 1,
+       .agc_command2 = 1,
 };
 
 int dibusb_dib3000mc_frontend_attach(struct dvb_usb_adapter *adap)
index 5153fb943da1fce0e429648acb495d644e2cba7c..b607810327426f17bdc7a961974971b815da5253 100644 (file)
@@ -99,7 +99,9 @@
 struct dibusb_state {
        struct dib_fe_xfer_ops ops;
        int mt2060_present;
+};
 
+struct dibusb_device_state {
        /* for RC5 remote control */
        int old_toggle;
        int last_repeat_count;
index a9219bf69b8927faf0da389c1dddddc06742ef7e..a58874c790b20505d7db03213995b8bb14b66bcc 100644 (file)
@@ -75,7 +75,7 @@ static int nova_t_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
        u8 key[5],cmd[2] = { DIBUSB_REQ_POLL_REMOTE, 0x35 }, data,toggle,custom;
        u16 raw;
        int i;
-       struct dibusb_state *st = d->priv;
+       struct dibusb_device_state *st = d->priv;
 
        dvb_usb_generic_rw(d,cmd,2,key,5,0);
 
@@ -184,6 +184,7 @@ static struct dvb_usb_device_properties nova_t_properties = {
                        .size_of_priv     = sizeof(struct dibusb_state),
                }
        },
+       .size_of_priv     = sizeof(struct dibusb_device_state),
 
        .power_ctrl       = dibusb2_0_power_ctrl,
        .read_mac_address = nova_t_read_mac_address,
index 572b2d9aa66a7300c8b2b37816ab8d8de0369bb2..78035ee824caf59e26fc50eefaf9fcc899e63da8 100644 (file)
@@ -11,7 +11,7 @@
 #include "dvb-usb-common.h"
 
 /* URB stuff for streaming */
-static void usb_urb_complete(struct urb *urb, struct pt_regs *ptregs)
+static void usb_urb_complete(struct urb *urb)
 {
        struct usb_data_stream *stream = urb->context;
        int ptype = usb_pipetype(urb->pipe);
index ccc813b525d6d084217bc952a7bffe3bc2d63302..3561a777568c8cd3cee259c2db59c559744a8332 100644 (file)
@@ -345,7 +345,7 @@ static int dib3000mc_init(struct dvb_frontend *demod)
 
        /* agc */
        dib3000mc_write_word(state, 36, state->cfg->max_time);
-       dib3000mc_write_word(state, 37, agc->setup);
+       dib3000mc_write_word(state, 37, (state->cfg->agc_command1 << 13) | (state->cfg->agc_command2 << 12) | (0x1d << 0));
        dib3000mc_write_word(state, 38, state->cfg->pwm3_value);
        dib3000mc_write_word(state, 39, state->cfg->ln_adc_level);
 
index b198cd5b18436c65890bcef1a507f3a53dc0f6fe..0d6fdef775385e2269ae378d02afe0215ac4ee36 100644 (file)
@@ -28,6 +28,9 @@ struct dib3000mc_config {
        u16 max_time;
        u16 ln_adc_level;
 
+       u8 agc_command1 :1;
+       u8 agc_command2 :1;
+
        u8 mobile_mode;
 
        u8 output_mpeg2_in_188_bytes;
index e8061db1112361c4ff910b38b4a28cbd8eef6358..18457adee30bd08511394098fb2d55ae07e194ca 100644 (file)
@@ -35,7 +35,16 @@ struct tda10086_config
        u8 invert;
 };
 
+#if defined(CONFIG_DVB_TDA10086) || defined(CONFIG_DVB_TDA10086_MODULE)
 extern struct dvb_frontend* tda10086_attach(const struct tda10086_config* config,
                                            struct i2c_adapter* i2c);
+#else
+static inline struct dvb_frontend* tda10086_attach(const struct tda10086_config* config,
+                                                  struct i2c_adapter* i2c)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+       return NULL;
+}
+#endif // CONFIG_DVB_TDA10086
 
 #endif // TDA10086_H
index 3307607632b0c2e4872a08e46d3f09cc74b7597a..83998c001196659deb242cf3161a76e77022bef0 100644 (file)
  * @param has_loopthrough Set to 1 if the card has a loopthrough RF connector.
  * @return FE pointer on success, NULL on failure.
  */
-extern struct dvb_frontend *tda826x_attach(struct dvb_frontend *fe, int addr, struct i2c_adapter *i2c, int has_loopthrough);
-
-#endif
+#if defined(CONFIG_DVB_TDA826X) || defined(CONFIG_DVB_TDA826X_MODULE)
+extern struct dvb_frontend* tda826x_attach(struct dvb_frontend *fe, int addr,
+                                          struct i2c_adapter *i2c,
+                                          int has_loopthrough);
+#else
+static inline struct dvb_frontend* tda826x_attach(struct dvb_frontend *fe,
+                                                 int addr,
+                                                 struct i2c_adapter *i2c,
+                                                 int has_loopthrough)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+       return NULL;
+}
+#endif // CONFIG_DVB_TDA826X
+
+#endif // __DVB_TDA826X_H__
index 2310b2bfed4e539fdd1ec16d148f6dd2eb99b94b..8e4ce101eb22e8d284ad43662d0fcd3e68a03c28 100644 (file)
@@ -306,7 +306,7 @@ static void pluto_dma_end(struct pluto *pluto, unsigned int nbpackets)
                        TS_DMA_BYTES, PCI_DMA_FROMDEVICE);
 }
 
-static irqreturn_t pluto_irq(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t pluto_irq(int irq, void *dev_id)
 {
        struct pluto *pluto = dev_id;
        u32 tscr;
index 234199875f53f77c094251969c1713eb91dcb34d..60820deb900b3958e2cc0c43faaa1b5360eab34f 100644 (file)
@@ -732,7 +732,7 @@ static void ttusb_process_frame(struct ttusb *ttusb, u8 * data, int len)
        }
 }
 
-static void ttusb_iso_irq(struct urb *urb, struct pt_regs *ptregs)
+static void ttusb_iso_irq(struct urb *urb)
 {
        struct ttusb *ttusb = urb->context;
 
index de077a757192de57915dda6aecb3297e123e6cf7..a1c9fa9919ea1dcb4996b93dc52b2f0bd49e8945 100644 (file)
@@ -203,7 +203,7 @@ static u16 rc_keys[] = {
 static void ttusb_dec_set_model(struct ttusb_dec *dec,
                                enum ttusb_dec_model model);
 
-static void ttusb_dec_handle_irq( struct urb *urb, struct pt_regs *regs)
+static void ttusb_dec_handle_irq( struct urb *urb)
 {
        struct ttusb_dec * dec = urb->context;
        char *buffer = dec->irq_buffer;
@@ -755,7 +755,7 @@ static void ttusb_dec_process_urb_frame_list(unsigned long data)
        }
 }
 
-static void ttusb_dec_process_urb(struct urb *urb, struct pt_regs *ptregs)
+static void ttusb_dec_process_urb(struct urb *urb)
 {
        struct ttusb_dec *dec = urb->context;
 
index afb734df6e0591ac461572c9d998f670a633aac5..fbe5b6168cc29c287416926ae42bbb26b587725c 100644 (file)
@@ -677,6 +677,8 @@ config VIDEO_M32R_AR_M64278
 menu "V4L USB devices"
        depends on USB && VIDEO_DEV
 
+source "drivers/media/video/pvrusb2/Kconfig"
+
 source "drivers/media/video/em28xx/Kconfig"
 
 source "drivers/media/video/usbvideo/Kconfig"
index 5c5e682a30042f0528348219fbd3c4ad754a24f6..4861799eb4308ce7a6384766caf22263eb17a8f3 100644 (file)
@@ -549,7 +549,7 @@ static int ar_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
 /*
  * Interrupt handler
  */
-static void ar_interrupt(int irq, void *dev, struct pt_regs *regs)
+static void ar_interrupt(int irq, void *dev)
 {
        struct ar_device *ar = dev;
        unsigned int line_count;
index 50dde82844ec6f431dcc2079339e97b0711204e5..6e1ddad9f0c1135d492f9c788496ebc4ebfbb578 100644 (file)
@@ -3753,7 +3753,7 @@ bttv_irq_switch_vbi(struct bttv *btv)
        spin_unlock(&btv->s_lock);
 }
 
-static irqreturn_t bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
+static irqreturn_t bttv_irq(int irq, void *dev_id)
 {
        u32 stat,astat;
        u32 dstat;
index f4da029414936bf43551077e7911b78bc5ed8cb8..28dc6a1a1e43b0156b5de717f044d5782de39315 100644 (file)
@@ -49,7 +49,7 @@ static int frame_sizes[] = {
 #define FRAME_SIZE_PER_DESC   frame_sizes[cam->cur_alt]
 
 static void process_frame(struct camera_data *cam);
-static void cpia2_usb_complete(struct urb *urb, struct pt_regs *);
+static void cpia2_usb_complete(struct urb *urb);
 static int cpia2_usb_probe(struct usb_interface *intf,
                           const struct usb_device_id *id);
 static void cpia2_usb_disconnect(struct usb_interface *intf);
@@ -199,7 +199,7 @@ static void add_COM(struct camera_data *cam)
  *
  *  callback when incoming packet is received
  *****************************************************************************/
-static void cpia2_usb_complete(struct urb *urb, struct pt_regs *regs)
+static void cpia2_usb_complete(struct urb *urb)
 {
        int i;
        unsigned char *cdata;
index 2ee34a3b92807bf96654c4ce6cd89aa79a8b6ca7..9da4726eb9b981a21250565bbaaa8ed190052c3b 100644 (file)
@@ -109,7 +109,7 @@ static struct cpia_camera_ops cpia_usb_ops = {
 static LIST_HEAD(cam_list);
 static spinlock_t cam_list_lock_usb;
 
-static void cpia_usb_complete(struct urb *urb, struct pt_regs *regs)
+static void cpia_usb_complete(struct urb *urb)
 {
        int i;
        char *cdata;
index 48014a254e15fdcf10b31c2ac255d5543083643d..f85f2084324fb9ec9f8189de75f0a6f74f41649d 100644 (file)
@@ -235,6 +235,7 @@ int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg)
                        0, 0, V4L2_SLICED_VPS, 0, 0,    /* 9 */
                        0, 0, 0, 0
                };
+               int is_pal = !(cx25840_get_v4lstd(client) & V4L2_STD_525_60);
                int i;
 
                fmt = arg;
@@ -246,13 +247,25 @@ int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg)
                if ((cx25840_read(client, 0x404) & 0x10) == 0)
                        break;
 
-               for (i = 7; i <= 23; i++) {
-                       u8 v = cx25840_read(client, 0x424 + i - 7);
+               if (is_pal) {
+                       for (i = 7; i <= 23; i++) {
+                               u8 v = cx25840_read(client, 0x424 + i - 7);
+
+                               svbi->service_lines[0][i] = lcr2vbi[v >> 4];
+                               svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
+                               svbi->service_set |=
+                                       svbi->service_lines[0][i] | svbi->service_lines[1][i];
+                       }
+               }
+               else {
+                       for (i = 10; i <= 21; i++) {
+                               u8 v = cx25840_read(client, 0x424 + i - 10);
 
-                       svbi->service_lines[0][i] = lcr2vbi[v >> 4];
-                       svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
-                       svbi->service_set |=
-                                svbi->service_lines[0][i] | svbi->service_lines[1][i];
+                               svbi->service_lines[0][i] = lcr2vbi[v >> 4];
+                               svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
+                               svbi->service_set |=
+                                       svbi->service_lines[0][i] | svbi->service_lines[1][i];
+                       }
                }
                break;
        }
index f0340662e078c9fc931fd6d84e8771ca2b42843f..e4355fdc3b6d179fd959b9ad2481f5ea340786f9 100644 (file)
@@ -262,7 +262,7 @@ static void cx8801_aud_irq(snd_cx88_card_t *chip)
 /*
  * BOARD Specific: Handles IRQ calls
  */
-static irqreturn_t cx8801_irq(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t cx8801_irq(int irq, void *dev_id)
 {
        snd_cx88_card_t *chip = dev_id;
        struct cx88_core *core = chip->core;
index af71d4225c763eefafa18907a9efd4c8c805a133..f764a57c56be53abdca042ad26211cdc80c7ec90 100644 (file)
@@ -1230,6 +1230,7 @@ struct cx88_board cx88_boards[] = {
                        .vmux   = 2,
                        .gpio0  = 0x84bf,
                }},
+               .mpeg           = CX88_MPEG_DVB,
        },
        [CX88_BOARD_NORWOOD_MICRO] = {
                .name           = "Norwood Micro TV Tuner",
@@ -1590,6 +1591,18 @@ struct cx88_subid cx88_subids[] = {
                .subvendor = 0x0070,
                .subdevice = 0x9000,
                .card      = CX88_BOARD_HAUPPAUGE_DVB_T1,
+       },{
+               .subvendor = 0x0070,
+               .subdevice = 0x1400,
+               .card      = CX88_BOARD_HAUPPAUGE_HVR3000,
+       },{
+               .subvendor = 0x0070,
+               .subdevice = 0x1401,
+               .card      = CX88_BOARD_HAUPPAUGE_HVR3000,
+       },{
+               .subvendor = 0x0070,
+               .subdevice = 0x1402,
+               .card      = CX88_BOARD_HAUPPAUGE_HVR3000,
        },
 };
 const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids);
@@ -1633,7 +1646,15 @@ static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data)
        /* Make sure we support the board model */
        switch (tv.model)
        {
+       case 14009: /* WinTV-HVR3000 (Retail, IR, b/panel video, 3.5mm audio in) */
+       case 14019: /* WinTV-HVR3000 (Retail, IR Blaster, b/panel video, 3.5mm audio in) */
+       case 14029: /* WinTV-HVR3000 (Retail, IR, b/panel video, 3.5mm audio in - 880 bridge) */
+       case 14109: /* WinTV-HVR3000 (Retail, IR, b/panel video, 3.5mm audio in - low profile) */
+       case 14129: /* WinTV-HVR3000 (Retail, IR, b/panel video, 3.5mm audio in - 880 bridge - LP) */
+       case 14559: /* WinTV-HVR3000 (OEM, no IR, b/panel video, 3.5mm audio in) */
        case 14569: /* WinTV-HVR3000 (OEM, no IR, no back panel video) */
+       case 14659: /* WinTV-HVR3000 (OEM, no IR, b/panel video, RCA audio in - Low profile) */
+       case 14669: /* WinTV-HVR3000 (OEM, no IR, no b/panel video - Low profile) */
        case 28552: /* WinTV-PVR 'Roslyn' (No IR) */
        case 34519: /* WinTV-PCI-FM */
        case 90002: /* Nova-T-PCI (9002) */
index bd0c8797f26d6289898dcf1de0e5480a4b02c7b6..0ef13e7efa2ee2efc6841913338ed48c2f22fe29 100644 (file)
@@ -315,15 +315,22 @@ static struct cx22702_config hauppauge_novat_config = {
        .demod_address = 0x43,
        .output_mode   = CX22702_SERIAL_OUTPUT,
 };
+
 static struct cx22702_config hauppauge_hvr1100_config = {
        .demod_address = 0x63,
        .output_mode   = CX22702_SERIAL_OUTPUT,
 };
+
 static struct cx22702_config hauppauge_hvr1300_config = {
        .demod_address = 0x63,
        .output_mode   = CX22702_SERIAL_OUTPUT,
 };
 
+static struct cx22702_config hauppauge_hvr3000_config = {
+       .demod_address = 0x63,
+       .output_mode = CX22702_SERIAL_OUTPUT,
+};
+
 static int or51132_set_ts_param(struct dvb_frontend* fe,
                                int is_punctured)
 {
@@ -558,6 +565,16 @@ static int dvb_register(struct cx8802_dev *dev)
                                   &dvb_pll_fmd1216me);
                }
                break;
+       case CX88_BOARD_HAUPPAUGE_HVR3000:
+               dev->dvb.frontend = dvb_attach(cx22702_attach,
+                                              &hauppauge_hvr3000_config,
+                                              &dev->core->i2c_adap);
+               if (dev->dvb.frontend != NULL) {
+                       dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
+                                  &dev->core->i2c_adap,
+                                  &dvb_pll_fmd1216me);
+               }
+               break;
        case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS:
                dev->dvb.frontend = dvb_attach(mt352_attach,
                                               &dvico_fusionhdtv,
index 83ebf7a3c054a9bfa44d384175bdba3d72acae48..ee48995a4ab5e92d350d119dfb4f4aa5eff66394 100644 (file)
@@ -196,6 +196,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
        case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
        case CX88_BOARD_HAUPPAUGE_HVR1100:
        case CX88_BOARD_HAUPPAUGE_HVR1300:
+       case CX88_BOARD_HAUPPAUGE_HVR3000:
                ir_codes = ir_codes_hauppauge_new;
                ir_type = IR_TYPE_RC5;
                ir->sampling = 1;
@@ -419,6 +420,7 @@ void cx88_ir_irq(struct cx88_core *core)
        case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
        case CX88_BOARD_HAUPPAUGE_HVR1100:
        case CX88_BOARD_HAUPPAUGE_HVR1300:
+       case CX88_BOARD_HAUPPAUGE_HVR3000:
                ircode = ir_decode_biphase(ir->samples, ir->scount, 5, 7);
                ir_dprintk("biphase decoded: %x\n", ircode);
                if ((ircode & 0xfffff000) != 0x3000)
index d6d980774c21bbbe20491f9a1d4c18a2488dfb3f..6b23a4e6f66d2447f50d389b8b046298e447ba29 100644 (file)
@@ -376,7 +376,7 @@ static void cx8802_mpeg_irq(struct cx8802_dev *dev)
 
 #define MAX_IRQ_LOOP 10
 
-static irqreturn_t cx8802_irq(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t cx8802_irq(int irq, void *dev_id)
 {
        struct cx8802_dev *dev = dev_id;
        struct cx88_core *core = dev->core;
index cb0c0eea20f956e392ddfac737e87116e1f4b0f6..90e298d074d11f688f825bb9986426569546586a 100644 (file)
@@ -1744,7 +1744,7 @@ static void cx8800_vid_irq(struct cx8800_dev *dev)
        }
 }
 
-static irqreturn_t cx8800_irq(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t cx8800_irq(int irq, void *dev_id)
 {
        struct cx8800_dev *dev = dev_id;
        struct cx88_core *core = dev->core;
index b9ba95f5e02632116b28fe2cf5d4468c36cfd351..b1012e92ee04e4b2e524ab44f1f883ad83b21342 100644 (file)
@@ -166,7 +166,7 @@ static int dabusb_free_buffers (pdabusb_t s)
        return 0;
 }
 /*-------------------------------------------------------------------*/
-static void dabusb_iso_complete (struct urb *purb, struct pt_regs *regs)
+static void dabusb_iso_complete (struct urb *purb)
 {
        pbuff_t b = purb->context;
        pdabusb_t s = b->s;
index 4350cc75b025a0ffcf24252fb1af9d5517dad938..255a47dfb84fcaa76346385ec8f22970a889acc1 100644 (file)
@@ -382,7 +382,7 @@ int em28xx_resolution_set(struct em28xx *dev)
 /******************* isoc transfer handling ****************************/
 
 #ifdef ENABLE_DEBUG_ISOC_FRAMES
-static void em28xx_isoc_dump(struct urb *urb, struct pt_regs *regs)
+static void em28xx_isoc_dump(struct urb *urb)
 {
        int len = 0;
        int ntrans = 0;
@@ -534,7 +534,7 @@ static inline void em28xx_isoc_video_copy(struct em28xx *dev,
  * em28xx_isoIrq()
  * handles the incoming isoc urbs and fills the frames from our inqueue
  */
-static void em28xx_isocIrq(struct urb *urb, struct pt_regs *regs)
+static void em28xx_isocIrq(struct urb *urb)
 {
        struct em28xx *dev = urb->context;
        int i, status;
@@ -545,7 +545,7 @@ static void em28xx_isocIrq(struct urb *urb, struct pt_regs *regs)
                return;
 #ifdef ENABLE_DEBUG_ISOC_FRAMES
        if (isoc_debug>1)
-               em28xx_isoc_dump(urb, regs);
+               em28xx_isoc_dump(urb);
 #endif
 
        if (urb->status == -ENOENT)
index 20df657b70c8f1c63bbef43fbdb2c1ee3c4855e6..2a461dde480c89c0dcf339920861764a709c89f9 100644 (file)
@@ -174,7 +174,7 @@ static void em28xx_config_i2c(struct em28xx *dev)
 
        route.input = INPUT(dev->ctl_input)->vmux;
        route.output = 0;
-       em28xx_i2c_call_clients(dev, VIDIOC_INT_RESET, 0);
+       em28xx_i2c_call_clients(dev, VIDIOC_INT_RESET, NULL);
        em28xx_i2c_call_clients(dev, VIDIOC_INT_S_VIDEO_ROUTING, &route);
        em28xx_i2c_call_clients(dev, VIDIOC_STREAMON, NULL);
 
index 8992b6e62b9f76ee9fa03068756633c7ac67e65f..f786ab11d2cd9b1a48cb0aff6bd70f85c19abd2f 100644 (file)
@@ -398,7 +398,7 @@ int et61x251_i2c_write(struct et61x251_device* cam, u8 address, u8 value)
 
 /*****************************************************************************/
 
-static void et61x251_urb_complete(struct urb *urb, struct pt_regs* regs)
+static void et61x251_urb_complete(struct urb *urb)
 {
        struct et61x251_device* cam = urb->context;
        struct et61x251_frame_t** f;
@@ -973,16 +973,32 @@ static CLASS_DEVICE_ATTR(i2c_val, S_IRUGO | S_IWUSR,
                         et61x251_show_i2c_val, et61x251_store_i2c_val);
 
 
-static void et61x251_create_sysfs(struct et61x251_device* cam)
+static int et61x251_create_sysfs(struct et61x251_device* cam)
 {
        struct video_device *v4ldev = cam->v4ldev;
+       int rc;
 
-       video_device_create_file(v4ldev, &class_device_attr_reg);
-       video_device_create_file(v4ldev, &class_device_attr_val);
+       rc = video_device_create_file(v4ldev, &class_device_attr_reg);
+       if (rc) goto err;
+       rc = video_device_create_file(v4ldev, &class_device_attr_val);
+       if (rc) goto err_reg;
        if (cam->sensor.sysfs_ops) {
-               video_device_create_file(v4ldev, &class_device_attr_i2c_reg);
-               video_device_create_file(v4ldev, &class_device_attr_i2c_val);
+               rc = video_device_create_file(v4ldev, &class_device_attr_i2c_reg);
+               if (rc) goto err_val;
+               rc = video_device_create_file(v4ldev, &class_device_attr_i2c_val);
+               if (rc) goto err_i2c_reg;
        }
+
+       return 0;
+
+err_i2c_reg:
+       video_device_remove_file(v4ldev, &class_device_attr_i2c_reg);
+err_val:
+       video_device_remove_file(v4ldev, &class_device_attr_val);
+err_reg:
+       video_device_remove_file(v4ldev, &class_device_attr_reg);
+err:
+       return rc;
 }
 #endif /* CONFIG_VIDEO_ADV_DEBUG */
 
@@ -2534,7 +2550,9 @@ et61x251_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
        dev_nr = (dev_nr < ET61X251_MAX_DEVICES-1) ? dev_nr+1 : 0;
 
 #ifdef CONFIG_VIDEO_ADV_DEBUG
-       et61x251_create_sysfs(cam);
+       err = et61x251_create_sysfs(cam);
+       if (err)
+               goto fail2;
        DBG(2, "Optional device control through 'sysfs' interface ready");
 #endif
 
@@ -2544,6 +2562,13 @@ et61x251_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
 
        return 0;
 
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+fail2:
+       video_nr[dev_nr] = -1;
+       dev_nr = (dev_nr < ET61X251_MAX_DEVICES-1) ? dev_nr+1 : 0;
+       mutex_unlock(&cam->dev_mutex);
+       video_unregister_device(cam->v4ldev);
+#endif
 fail:
        if (cam) {
                kfree(cam->control_buffer);
index e278753f8f25ad805fff678e32d21673d3bff674..b083338823dfff4559a16d938d588a2550b3e066 100644 (file)
@@ -786,7 +786,7 @@ static void mchip_cont_compression_start(void)
 /* Interrupt handling                                                       */
 /****************************************************************************/
 
-static irqreturn_t meye_irq(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t meye_irq(int irq, void *dev_id)
 {
        u32 v;
        int reqnr;
index 5d8cd283fcd8e747767eb5b4e7e6470be5568322..b4db2cbb5a84246151e0d39ca589e7ceb50f915e 100644 (file)
@@ -3503,7 +3503,7 @@ check_middle:
 }
 
 static void
-ov51x_isoc_irq(struct urb *urb, struct pt_regs *regs)
+ov51x_isoc_irq(struct urb *urb)
 {
        int i;
        struct usb_ov511 *ov;
@@ -5648,17 +5648,49 @@ static ssize_t show_exposure(struct class_device *cd, char *buf)
 }
 static CLASS_DEVICE_ATTR(exposure, S_IRUGO, show_exposure, NULL);
 
-static void ov_create_sysfs(struct video_device *vdev)
+static int ov_create_sysfs(struct video_device *vdev)
 {
-       video_device_create_file(vdev, &class_device_attr_custom_id);
-       video_device_create_file(vdev, &class_device_attr_model);
-       video_device_create_file(vdev, &class_device_attr_bridge);
-       video_device_create_file(vdev, &class_device_attr_sensor);
-       video_device_create_file(vdev, &class_device_attr_brightness);
-       video_device_create_file(vdev, &class_device_attr_saturation);
-       video_device_create_file(vdev, &class_device_attr_contrast);
-       video_device_create_file(vdev, &class_device_attr_hue);
-       video_device_create_file(vdev, &class_device_attr_exposure);
+       int rc;
+
+       rc = video_device_create_file(vdev, &class_device_attr_custom_id);
+       if (rc) goto err;
+       rc = video_device_create_file(vdev, &class_device_attr_model);
+       if (rc) goto err_id;
+       rc = video_device_create_file(vdev, &class_device_attr_bridge);
+       if (rc) goto err_model;
+       rc = video_device_create_file(vdev, &class_device_attr_sensor);
+       if (rc) goto err_bridge;
+       rc = video_device_create_file(vdev, &class_device_attr_brightness);
+       if (rc) goto err_sensor;
+       rc = video_device_create_file(vdev, &class_device_attr_saturation);
+       if (rc) goto err_bright;
+       rc = video_device_create_file(vdev, &class_device_attr_contrast);
+       if (rc) goto err_sat;
+       rc = video_device_create_file(vdev, &class_device_attr_hue);
+       if (rc) goto err_contrast;
+       rc = video_device_create_file(vdev, &class_device_attr_exposure);
+       if (rc) goto err_hue;
+
+       return 0;
+
+err_hue:
+       video_device_remove_file(vdev, &class_device_attr_hue);
+err_contrast:
+       video_device_remove_file(vdev, &class_device_attr_contrast);
+err_sat:
+       video_device_remove_file(vdev, &class_device_attr_saturation);
+err_bright:
+       video_device_remove_file(vdev, &class_device_attr_brightness);
+err_sensor:
+       video_device_remove_file(vdev, &class_device_attr_sensor);
+err_bridge:
+       video_device_remove_file(vdev, &class_device_attr_bridge);
+err_model:
+       video_device_remove_file(vdev, &class_device_attr_model);
+err_id:
+       video_device_remove_file(vdev, &class_device_attr_custom_id);
+err:
+       return rc;
 }
 
 /****************************************************************************
@@ -5817,7 +5849,11 @@ ov51x_probe(struct usb_interface *intf, const struct usb_device_id *id)
             ov->vdev->minor);
 
        usb_set_intfdata(intf, ov);
-       ov_create_sysfs(ov->vdev);
+       if (ov_create_sysfs(ov->vdev)) {
+               err("ov_create_sysfs failed");
+               goto error;
+       }
+
        return 0;
 
 error:
index 3484e36b68016f4d2c58953ed9fa60dc3d4c6e7a..368d6e219fa43b767e2072c1c01a5169ad9f3e6e 100644 (file)
@@ -91,7 +91,7 @@ static void planb_close(struct video_device *);
 static int planb_ioctl(struct video_device *, unsigned int, void *);
 static int planb_init_done(struct video_device *);
 static int planb_mmap(struct video_device *, const char *, unsigned long);
-static void planb_irq(int, void *, struct pt_regs *);
+static void planb_irq(int, void *);
 static void release_planb(void);
 int init_planbs(struct video_init *);
 
@@ -1316,7 +1316,7 @@ cmd_tab_data_end:
        return c1;
 }
 
-static void planb_irq(int irq, void *dev_id, struct pt_regs * regs)
+static void planb_irq(int irq, void *dev_id)
 {
        unsigned int stat, astat;
        struct planb *pb = (struct planb *)dev_id;
index 3d8cd0daf6a9314d1dbc1a37194a57d7a05ac510..f920e0ccacd3d4141dabf501fa278bb9a96247a9 100644 (file)
@@ -2552,7 +2552,7 @@ void pvr2_hdw_v4l_store_minor_number(struct pvr2_hdw *hdw,int v)
 }
 
 
-static void pvr2_ctl_write_complete(struct urb *urb, struct pt_regs *regs)
+static void pvr2_ctl_write_complete(struct urb *urb)
 {
        struct pvr2_hdw *hdw = urb->context;
        hdw->ctl_write_pend_flag = 0;
@@ -2561,7 +2561,7 @@ static void pvr2_ctl_write_complete(struct urb *urb, struct pt_regs *regs)
 }
 
 
-static void pvr2_ctl_read_complete(struct urb *urb, struct pt_regs *regs)
+static void pvr2_ctl_read_complete(struct urb *urb)
 {
        struct pvr2_hdw *hdw = urb->context;
        hdw->ctl_read_pend_flag = 0;
index 1e393762546c174b55c71f967d5c9bdc9f7e65db..70aa63eba0cbdcfa62829e964f7e942313768b11 100644 (file)
@@ -429,7 +429,7 @@ static void pvr2_stream_done(struct pvr2_stream *sp)
        } while (0); mutex_unlock(&sp->mutex);
 }
 
-static void buffer_complete(struct urb *urb, struct pt_regs *regs)
+static void buffer_complete(struct urb *urb)
 {
        struct pvr2_buffer *bp = urb->context;
        struct pvr2_stream *sp;
index 53c4b5790d5c6dd8aa08bf132dee83c611f0ef27..46c1148308843a4d8ed3e0db02d6f20fd8f73c76 100644 (file)
@@ -682,7 +682,7 @@ static int pwc_rcv_short_packet(struct pwc_device *pdev, const struct pwc_frame_
 /* This gets called for the Isochronous pipe (video). This is done in
  * interrupt time, so it has to be fast, not crash, and not stall. Neat.
  */
-static void pwc_isoc_handler(struct urb *urb, struct pt_regs *regs)
+static void pwc_isoc_handler(struct urb *urb)
 {
        struct pwc_device *pdev;
        int i, fst, flen;
@@ -1024,12 +1024,25 @@ static ssize_t show_snapshot_button_status(struct class_device *class_dev, char
 static CLASS_DEVICE_ATTR(button, S_IRUGO | S_IWUSR, show_snapshot_button_status,
                         NULL);
 
-static void pwc_create_sysfs_files(struct video_device *vdev)
+static int pwc_create_sysfs_files(struct video_device *vdev)
 {
        struct pwc_device *pdev = video_get_drvdata(vdev);
-       if (pdev->features & FEATURE_MOTOR_PANTILT)
-               video_device_create_file(vdev, &class_device_attr_pan_tilt);
-       video_device_create_file(vdev, &class_device_attr_button);
+       int rc;
+
+       rc = video_device_create_file(vdev, &class_device_attr_button);
+       if (rc)
+               goto err;
+       if (pdev->features & FEATURE_MOTOR_PANTILT) {
+               rc = video_device_create_file(vdev,&class_device_attr_pan_tilt);
+               if (rc) goto err_button;
+       }
+
+       return 0;
+
+err_button:
+       video_device_remove_file(vdev, &class_device_attr_button);
+err:
+       return rc;
 }
 
 static void pwc_remove_sysfs_files(struct video_device *vdev)
@@ -1408,7 +1421,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
        struct usb_device *udev = interface_to_usbdev(intf);
        struct pwc_device *pdev = NULL;
        int vendor_id, product_id, type_id;
-       int i, hint;
+       int i, hint, rc;
        int features = 0;
        int video_nr = -1; /* default: use next available device */
        char serial_number[30], *name;
@@ -1709,9 +1722,8 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
        i = video_register_device(pdev->vdev, VFL_TYPE_GRABBER, video_nr);
        if (i < 0) {
                PWC_ERROR("Failed to register as video device (%d).\n", i);
-               video_device_release(pdev->vdev); /* Drip... drip... drip... */
-               kfree(pdev); /* Oops, no memory leaks please */
-               return -EIO;
+               rc = i;
+               goto err;
        }
        else {
                PWC_INFO("Registered as /dev/video%d.\n", pdev->vdev->minor & 0x3F);
@@ -1723,13 +1735,24 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
 
        PWC_DEBUG_PROBE("probe() function returning struct at 0x%p.\n", pdev);
        usb_set_intfdata (intf, pdev);
-       pwc_create_sysfs_files(pdev->vdev);
+       rc = pwc_create_sysfs_files(pdev->vdev);
+       if (rc)
+               goto err_unreg;
 
        /* Set the leds off */
        pwc_set_leds(pdev, 0, 0);
        pwc_camera_power(pdev, 0);
 
        return 0;
+
+err_unreg:
+       if (hint < MAX_DEV_HINTS)
+               device_hint[hint].pdev = NULL;
+       video_unregister_device(pdev->vdev);
+err:
+       video_device_release(pdev->vdev); /* Drip... drip... drip... */
+       kfree(pdev); /* Oops, no memory leaks please */
+       return rc;
 }
 
 /* The user janked out the cable... */
index 974179d4d3895b2dd3135b245d1e5158c4a8e213..c5719f7bd1acafbaee6f53c8553363c35f1b5bf2 100644 (file)
@@ -960,6 +960,8 @@ static void saa711x_set_v4lstd(struct i2c_client *client, v4l2_std_id std)
                        reg |= 0x10;
                } else if (std == V4L2_STD_NTSC_M_JP) {
                        reg |= 0x40;
+               } else if (std == V4L2_STD_SECAM) {
+                       reg |= 0x50;
                }
                saa711x_write(client, R_0E_CHROMA_CNTL_1, reg);
        } else {
index a39e0136ce3ba4614b422d05e8febc1fd319c736..4abf5c03a740f14c035d771349bd3ea82159772f 100644 (file)
@@ -212,7 +212,7 @@ static void saa7134_irq_alsa_done(struct saa7134_dev *dev,
  *
  */
 
-static irqreturn_t saa7134_alsa_irq(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t saa7134_alsa_irq(int irq, void *dev_id)
 {
        struct saa7134_dmasound *dmasound = dev_id;
        struct saa7134_dev *dev = dmasound->priv_data;
index 09aa62f61af7bab0ce172f4452750fa4dc4b7944..5c9e63dfbea6ef3227385e5e1652a0e8caf99e15 100644 (file)
@@ -495,7 +495,7 @@ static void print_irqstatus(struct saa7134_dev *dev, int loop,
        printk("\n");
 }
 
-static irqreturn_t saa7134_irq(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t saa7134_irq(int irq, void *dev_id)
 {
        struct saa7134_dev *dev = (struct saa7134_dev*) dev_id;
        unsigned long report,status;
index 2e3ba5f31453656a872fbfa1c9eab65c6dcaa0e9..bfcb860d14cc4605cff0b5828f4ba3fd75a95f02 100644 (file)
@@ -814,7 +814,7 @@ struct file_operations saa7134_mixer_fops = {
 
 /* ------------------------------------------------------------------ */
 
-static irqreturn_t saa7134_oss_irq(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t saa7134_oss_irq(int irq, void *dev_id)
 {
        struct saa7134_dmasound *dmasound = dev_id;
        struct saa7134_dev *dev = dmasound->priv_data;
index 203302f21827e5104e8b7d1b2485afbb369b76c2..830617ea81cc5ca0b6c68fce66fe45be112a1fc8 100644 (file)
@@ -2248,7 +2248,11 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
                t->type = V4L2_TUNER_RADIO;
 
                saa7134_i2c_call_clients(dev, VIDIOC_G_TUNER, t);
-
+               if (dev->input->amux == TV) {
+                       t->signal = 0xf800 - ((saa_readb(0x581) & 0x1f) << 11);
+                       t->rxsubchans = (saa_readb(0x529) & 0x08) ?
+                                       V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO;
+               }
                return 0;
        }
        case VIDIOC_S_TUNER:
index 67987baee77ae8e8c5767598d9c2ef32d248c6c5..7aeec574d7ce349a99a68ebe9272b5bf45e03fb7 100644 (file)
@@ -282,7 +282,7 @@ static void se401_auto_resetlevel(struct usb_se401 *se401)
 }
 
 /* irq handler for snapshot button */
-static void se401_button_irq(struct urb *urb, struct pt_regs *regs)
+static void se401_button_irq(struct urb *urb)
 {
        struct usb_se401 *se401 = urb->context;
        int status;
@@ -318,7 +318,7 @@ exit:
                     __FUNCTION__, status);
 }
 
-static void se401_video_irq(struct urb *urb, struct pt_regs *regs)
+static void se401_video_irq(struct urb *urb)
 {
        struct usb_se401 *se401 = urb->context;
        int length = urb->actual_length;
index 48d138a7c7235c6c1197afa6c9d9d0010cdd191a..a4702d3c2aca4f295faa28dff8ca5c9c37bf49e1 100644 (file)
@@ -518,7 +518,7 @@ sn9c102_find_eof_header(struct sn9c102_device* cam, void* mem, size_t len)
 }
 
 
-static void sn9c102_urb_complete(struct urb *urb, struct pt_regs* regs)
+static void sn9c102_urb_complete(struct urb *urb)
 {
        struct sn9c102_device* cam = urb->context;
        struct sn9c102_frame_t** f;
@@ -1240,23 +1240,53 @@ static CLASS_DEVICE_ATTR(frame_header, S_IRUGO,
                         sn9c102_show_frame_header, NULL);
 
 
-static void sn9c102_create_sysfs(struct sn9c102_device* cam)
+static int sn9c102_create_sysfs(struct sn9c102_device* cam)
 {
        struct video_device *v4ldev = cam->v4ldev;
+       int rc;
+
+       rc = video_device_create_file(v4ldev, &class_device_attr_reg);
+       if (rc) goto err;
+       rc = video_device_create_file(v4ldev, &class_device_attr_val);
+       if (rc) goto err_reg;
+       rc = video_device_create_file(v4ldev, &class_device_attr_frame_header);
+       if (rc) goto err_val;
 
-       video_device_create_file(v4ldev, &class_device_attr_reg);
-       video_device_create_file(v4ldev, &class_device_attr_val);
-       video_device_create_file(v4ldev, &class_device_attr_frame_header);
-       if (cam->bridge == BRIDGE_SN9C101 || cam->bridge == BRIDGE_SN9C102)
-               video_device_create_file(v4ldev, &class_device_attr_green);
-       else if (cam->bridge == BRIDGE_SN9C103) {
-               video_device_create_file(v4ldev, &class_device_attr_blue);
-               video_device_create_file(v4ldev, &class_device_attr_red);
-       }
        if (cam->sensor.sysfs_ops) {
-               video_device_create_file(v4ldev, &class_device_attr_i2c_reg);
-               video_device_create_file(v4ldev, &class_device_attr_i2c_val);
+               rc = video_device_create_file(v4ldev, &class_device_attr_i2c_reg);
+               if (rc) goto err_frhead;
+               rc = video_device_create_file(v4ldev, &class_device_attr_i2c_val);
+               if (rc) goto err_i2c_reg;
+       }
+
+       if (cam->bridge == BRIDGE_SN9C101 || cam->bridge == BRIDGE_SN9C102) {
+               rc = video_device_create_file(v4ldev, &class_device_attr_green);
+               if (rc) goto err_i2c_val;
+       } else if (cam->bridge == BRIDGE_SN9C103) {
+               rc = video_device_create_file(v4ldev, &class_device_attr_blue);
+               if (rc) goto err_i2c_val;
+               rc = video_device_create_file(v4ldev, &class_device_attr_red);
+               if (rc) goto err_blue;
        }
+
+       return 0;
+
+err_blue:
+       video_device_remove_file(v4ldev, &class_device_attr_blue);
+err_i2c_val:
+       if (cam->sensor.sysfs_ops)
+               video_device_remove_file(v4ldev, &class_device_attr_i2c_val);
+err_i2c_reg:
+       if (cam->sensor.sysfs_ops)
+               video_device_remove_file(v4ldev, &class_device_attr_i2c_reg);
+err_frhead:
+       video_device_remove_file(v4ldev, &class_device_attr_frame_header);
+err_val:
+       video_device_remove_file(v4ldev, &class_device_attr_val);
+err_reg:
+       video_device_remove_file(v4ldev, &class_device_attr_reg);
+err:
+       return rc;
 }
 #endif /* CONFIG_VIDEO_ADV_DEBUG */
 
@@ -2809,10 +2839,7 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
                DBG(1, "V4L2 device registration failed");
                if (err == -ENFILE && video_nr[dev_nr] == -1)
                        DBG(1, "Free /dev/videoX node not found");
-               video_nr[dev_nr] = -1;
-               dev_nr = (dev_nr < SN9C102_MAX_DEVICES-1) ? dev_nr+1 : 0;
-               mutex_unlock(&cam->dev_mutex);
-               goto fail;
+               goto fail2;
        }
 
        DBG(2, "V4L2 device registered as /dev/video%d", cam->v4ldev->minor);
@@ -2823,7 +2850,9 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
        dev_nr = (dev_nr < SN9C102_MAX_DEVICES-1) ? dev_nr+1 : 0;
 
 #ifdef CONFIG_VIDEO_ADV_DEBUG
-       sn9c102_create_sysfs(cam);
+       err = sn9c102_create_sysfs(cam);
+       if (err)
+               goto fail3;
        DBG(2, "Optional device control through 'sysfs' interface ready");
 #endif
 
@@ -2833,6 +2862,14 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
 
        return 0;
 
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+fail3:
+       video_unregister_device(cam->v4ldev);
+#endif
+fail2:
+       video_nr[dev_nr] = -1;
+       dev_nr = (dev_nr < SN9C102_MAX_DEVICES-1) ? dev_nr+1 : 0;
+       mutex_unlock(&cam->dev_mutex);
 fail:
        if (cam) {
                kfree(cam->control_buffer);
index 5686547ba76ab49114aa135cca59e50a646791c2..525d81288d55aada3b9308d871e1505a6d3edb11 100644 (file)
@@ -406,7 +406,7 @@ static void send_osd_data(struct saa7146 *saa)
        }
 }
 
-static irqreturn_t saa7146_irq(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t saa7146_irq(int irq, void *dev_id)
 {
        struct saa7146 *saa = dev_id;
        u32 stat, astat;
index 2ba2991a214ff3026858a13929468869d9da2cf4..6d1ef1e2e8efd9dbf8be48763ee7283b3cf42021 100644 (file)
@@ -516,16 +516,45 @@ stv680_file(frames_read, framecount, "%d\n");
 stv680_file(packets_dropped, dropped, "%d\n");
 stv680_file(decoding_errors, error, "%d\n");
 
-static void stv680_create_sysfs_files(struct video_device *vdev)
+static int stv680_create_sysfs_files(struct video_device *vdev)
 {
-       video_device_create_file(vdev, &class_device_attr_model);
-       video_device_create_file(vdev, &class_device_attr_in_use);
-       video_device_create_file(vdev, &class_device_attr_streaming);
-       video_device_create_file(vdev, &class_device_attr_palette);
-       video_device_create_file(vdev, &class_device_attr_frames_total);
-       video_device_create_file(vdev, &class_device_attr_frames_read);
-       video_device_create_file(vdev, &class_device_attr_packets_dropped);
-       video_device_create_file(vdev, &class_device_attr_decoding_errors);
+       int rc;
+
+       rc = video_device_create_file(vdev, &class_device_attr_model);
+       if (rc) goto err;
+       rc = video_device_create_file(vdev, &class_device_attr_in_use);
+       if (rc) goto err_model;
+       rc = video_device_create_file(vdev, &class_device_attr_streaming);
+       if (rc) goto err_inuse;
+       rc = video_device_create_file(vdev, &class_device_attr_palette);
+       if (rc) goto err_stream;
+       rc = video_device_create_file(vdev, &class_device_attr_frames_total);
+       if (rc) goto err_pal;
+       rc = video_device_create_file(vdev, &class_device_attr_frames_read);
+       if (rc) goto err_framtot;
+       rc = video_device_create_file(vdev, &class_device_attr_packets_dropped);
+       if (rc) goto err_framread;
+       rc = video_device_create_file(vdev, &class_device_attr_decoding_errors);
+       if (rc) goto err_dropped;
+
+       return 0;
+
+err_dropped:
+       video_device_remove_file(vdev, &class_device_attr_packets_dropped);
+err_framread:
+       video_device_remove_file(vdev, &class_device_attr_frames_read);
+err_framtot:
+       video_device_remove_file(vdev, &class_device_attr_frames_total);
+err_pal:
+       video_device_remove_file(vdev, &class_device_attr_palette);
+err_stream:
+       video_device_remove_file(vdev, &class_device_attr_streaming);
+err_inuse:
+       video_device_remove_file(vdev, &class_device_attr_in_use);
+err_model:
+       video_device_remove_file(vdev, &class_device_attr_model);
+err:
+       return rc;
 }
 
 static void stv680_remove_sysfs_files(struct video_device *vdev)
@@ -582,7 +611,7 @@ static int stv680_set_pict (struct usb_stv *stv680, struct video_picture *p)
        return 0;
 }
 
-static void stv680_video_irq (struct urb *urb, struct pt_regs *regs)
+static void stv680_video_irq (struct urb *urb)
 {
        struct usb_stv *stv680 = urb->context;
        int length = urb->actual_length;
@@ -1418,9 +1447,13 @@ static int stv680_probe (struct usb_interface *intf, const struct usb_device_id
        PDEBUG (0, "STV(i): registered new video device: video%d", stv680->vdev->minor);
 
        usb_set_intfdata (intf, stv680);
-       stv680_create_sysfs_files(stv680->vdev);
+       retval = stv680_create_sysfs_files(stv680->vdev);
+       if (retval)
+               goto error_unreg;
        return 0;
 
+error_unreg:
+       video_unregister_device(stv680->vdev);
 error_vdev:
        video_device_release(stv680->vdev);
 error:
index 8fff642fad56fa8e2579c2741d96818ea6850d94..781682373b61f3992d36ac9e938a62451cd61608 100644 (file)
@@ -1046,7 +1046,6 @@ static struct tuner_params tuner_samsung_tcpn_2121p30a_params[] = {
                .type   = TUNER_PARAM_TYPE_NTSC,
                .ranges = tuner_samsung_tcpn_2121p30a_ntsc_ranges,
                .count  = ARRAY_SIZE(tuner_samsung_tcpn_2121p30a_ntsc_ranges),
-               .has_tda9887 = 1,
        },
 };
 
index 4eee8be88314104524eafcafce16a263e5400b9b..abe214619092036accc9b50dc262cf6714a0549d 100644 (file)
@@ -387,7 +387,7 @@ static void resubmit_urb(struct uvd *uvd, struct urb *urb)
 }
 
 
-static void konicawc_isoc_irq(struct urb *urb, struct pt_regs *regs)
+static void konicawc_isoc_irq(struct urb *urb)
 {
        struct uvd *uvd = urb->context;
        struct konicawc *cam = (struct konicawc *)uvd->user_data;
index 56e01b6224175c17f7bd5c0d3e13c2efa95a6d4a..9a26b9484aae02f6da917b5fc4bf530fc6056150 100644 (file)
@@ -125,7 +125,7 @@ static void qcm_report_buttonstat(struct qcm *cam)
        }
 }
 
-static void qcm_int_irq(struct urb *urb, struct pt_regs *regs)
+static void qcm_int_irq(struct urb *urb)
 {
        int ret;
        struct uvd *uvd = urb->context;
@@ -606,7 +606,7 @@ static void resubmit_urb(struct uvd *uvd, struct urb *urb)
                err("usb_submit_urb error (%d)", ret);
 }
 
-static void qcm_isoc_irq(struct urb *urb, struct pt_regs *regs)
+static void qcm_isoc_irq(struct urb *urb)
 {
        int len;
        struct uvd *uvd = urb->context;
index 13b37c8c0d5624969776e5607ab1340b13c48244..d8b88024bc2fa4ad93015b70078704e41ab78ffb 100644 (file)
@@ -1680,7 +1680,7 @@ static int usbvideo_CompressIsochronous(struct uvd *uvd, struct urb *urb)
        return totlen;
 }
 
-static void usbvideo_IsocIrq(struct urb *urb, struct pt_regs *regs)
+static void usbvideo_IsocIrq(struct urb *urb)
 {
        int i, ret, len;
        struct uvd *uvd = urb->context;
index 479a0675cf60bf8ddfc7b6a372077be03063b35a..d424a4129d69ba188772282ec9f29a95374218c9 100644 (file)
  */
 
 #define dbgarg(cmd, fmt, arg...) \
-               if (vfd->debug & V4L2_DEBUG_IOCTL_ARG)                  \
+               if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) {                \
                        printk (KERN_DEBUG "%s: ",  vfd->name);         \
                        v4l_printk_ioctl(cmd);                          \
-                       printk (KERN_DEBUG "%s: " fmt, vfd->name, ## arg);
+                       printk (KERN_DEBUG "%s: " fmt, vfd->name, ## arg); \
+               }
 
 #define dbgarg2(fmt, arg...) \
                if (vfd->debug & V4L2_DEBUG_IOCTL_ARG)                  \
@@ -1287,6 +1288,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
                        ret=vfd->vidioc_g_parm(file, fh, p);
                } else {
                        struct v4l2_standard s;
+                       int i;
 
                        if (!vfd->tvnormsize) {
                                printk (KERN_WARNING "%s: no TV norms defined!\n",
@@ -1297,8 +1299,14 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
                        if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
                                return -EINVAL;
 
-                       v4l2_video_std_construct(&s, vfd->tvnorms[vfd->current_norm].id,
-                                                vfd->tvnorms[vfd->current_norm].name);
+                       for (i = 0; i < vfd->tvnormsize; i++)
+                               if (vfd->tvnorms[i].id == vfd->current_norm)
+                                       break;
+                       if (i >= vfd->tvnormsize)
+                               return -EINVAL;
+
+                       v4l2_video_std_construct(&s, vfd->current_norm,
+                                                vfd->tvnorms[i].name);
 
                        memset(p,0,sizeof(*p));
 
index d1e04f7c530bbf9ee66f1e80072fb0263b1b5dab..6b6dff4d236a39e3093e9961de46e380d5eef70d 100644 (file)
@@ -2325,7 +2325,7 @@ static void vino_capture_tasklet(unsigned long channel) {
        }
 }
 
-static irqreturn_t vino_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t vino_interrupt(int irq, void *dev_id)
 {
        u32 ctrl, intr;
        unsigned int fc_a, fc_b;
index e7c01d560b6460f1dd6de8ab19a87ed651556782..3c8dc72dc8e971662b7267d545ee71e8e98a22b9 100644 (file)
@@ -272,7 +272,7 @@ static void gen_line(struct sg_to_addr to_addr[],int inipos,int pages,int wmax,
 
        /* Get first addr pointed to pixel position */
        oldpg=get_addr_pos(pos,pages,to_addr);
-       pg=pfn_to_page(to_addr[oldpg].sg->dma_address >> PAGE_SHIFT);
+       pg=pfn_to_page(sg_dma_address(to_addr[oldpg].sg) >> PAGE_SHIFT);
        basep = kmap_atomic(pg, KM_BOUNCE_READ)+to_addr[oldpg].sg->offset;
 
        /* We will just duplicate the second pixel at the packet */
@@ -287,7 +287,7 @@ static void gen_line(struct sg_to_addr to_addr[],int inipos,int pages,int wmax,
                for (color=0;color<4;color++) {
                        pgpos=get_addr_pos(pos,pages,to_addr);
                        if (pgpos!=oldpg) {
-                               pg=pfn_to_page(to_addr[pgpos].sg->dma_address >> PAGE_SHIFT);
+                               pg=pfn_to_page(sg_dma_address(to_addr[pgpos].sg) >> PAGE_SHIFT);
                                kunmap_atomic(basep, KM_BOUNCE_READ);
                                basep= kmap_atomic(pg, KM_BOUNCE_READ)+to_addr[pgpos].sg->offset;
                                oldpg=pgpos;
@@ -339,8 +339,8 @@ static void gen_line(struct sg_to_addr to_addr[],int inipos,int pages,int wmax,
                                for (color=0;color<4;color++) {
                                        pgpos=get_addr_pos(pos,pages,to_addr);
                                        if (pgpos!=oldpg) {
-                                               pg=pfn_to_page(to_addr[pgpos].
-                                                               sg->dma_address
+                                               pg=pfn_to_page(sg_dma_address(
+                                                               to_addr[pgpos].sg)
                                                                >> PAGE_SHIFT);
                                                kunmap_atomic(basep,
                                                                KM_BOUNCE_READ);
@@ -386,7 +386,7 @@ static void vivi_fillbuff(struct vivi_dev *dev,struct vivi_buffer *buf)
        struct timeval ts;
 
        /* Test if DMA mapping is ready */
-       if (!vb->dma.sglist[0].dma_address)
+       if (!sg_dma_address(&vb->dma.sglist[0]))
                return;
 
        prep_to_addr(to_addr,vb);
@@ -783,7 +783,7 @@ static int vivi_map_sg(void *dev, struct scatterlist *sg, int nents,
        for (i = 0; i < nents; i++ ) {
                BUG_ON(!sg[i].page);
 
-               sg[i].dma_address = page_to_phys(sg[i].page) + sg[i].offset;
+               sg_dma_address(&sg[i]) = page_to_phys(sg[i].page) + sg[i].offset;
        }
 
        return nents;
index 2912326a5aef1c6adace62d91a25bd2b8d930ea1..ddce2fb83424ccf152094da0aeb8aa3ea670d126 100644 (file)
@@ -417,7 +417,7 @@ static int w9968cf_write_fsb(struct w9968cf_device*, u16* data);
 static int w9968cf_write_sb(struct w9968cf_device*, u16 value);
 static int w9968cf_read_sb(struct w9968cf_device*);
 static int w9968cf_upload_quantizationtables(struct w9968cf_device*);
-static void w9968cf_urb_complete(struct urb *urb, struct pt_regs *regs);
+static void w9968cf_urb_complete(struct urb *urb);
 
 /* Low-level I2C (SMBus) I/O */
 static int w9968cf_smbus_start(struct w9968cf_device*);
@@ -781,7 +781,7 @@ static int w9968cf_allocate_memory(struct w9968cf_device* cam)
   If there are no requested frames in the FIFO list, packets are collected into
   a temporary buffer.
   --------------------------------------------------------------------------*/
-static void w9968cf_urb_complete(struct urb *urb, struct pt_regs *regs)
+static void w9968cf_urb_complete(struct urb *urb)
 {
        struct w9968cf_device* cam = (struct w9968cf_device*)urb->context;
        struct w9968cf_frame_t** f;
index 1b2be2d2a3ec50c7e3fa50ba34ed3dc7a7bf2c8e..5b5563424422201acd0841ae2ba581eb52a910f6 100644 (file)
@@ -303,7 +303,7 @@ int zc0301_i2c_write(struct zc0301_device* cam, u16 address, u16 value)
 
 /*****************************************************************************/
 
-static void zc0301_urb_complete(struct urb *urb, struct pt_regs* regs)
+static void zc0301_urb_complete(struct urb *urb)
 {
        struct zc0301_device* cam = urb->context;
        struct zc0301_frame_t** f;
index 3cbac2e8aed393b8f8acfb9e916a479f38330ae2..168e431d7c716e56b5cd924047032901cff31e64 100644 (file)
@@ -1408,15 +1408,14 @@ error_handler (struct zoran *zr,
 
 irqreturn_t
 zoran_irq (int             irq,
-          void           *dev_id,
-          struct pt_regs *regs)
+          void           *dev_id)
 {
        u32 stat, astat;
        int count;
        struct zoran *zr;
        unsigned long flags;
 
-       zr = (struct zoran *) dev_id;
+       zr = dev_id;
        count = 0;
 
        if (zr->testing) {
index f19705cbdb397e591c5781d22ef94fe44532b5bc..37fa86a34083fead91335beb7672cda947952da5 100644 (file)
@@ -64,9 +64,7 @@ extern int wait_grab_pending(struct zoran *zr);
 /* interrupts */
 extern void print_interrupts(struct zoran *zr);
 extern void clear_interrupt_counters(struct zoran *zr);
-extern irqreturn_t zoran_irq(int irq,
-                            void *dev_id,
-                            struct pt_regs *regs);
+extern irqreturn_t zoran_irq(int irq, void *dev_id);
 
 /* JPEG codec access */
 extern void jpeg_start(struct zoran *zr);
index b5ffe53c40d8ee275a66de704bd4f9dcddf2a5ed..0cbf564388a6eb3583210a71413d1ed6592d04a6 100644 (file)
@@ -335,13 +335,13 @@ DEBUG(printk(CARD_DEBUG "turning off\n",CARD));
 }
 
 static
-void zoran_irq(int irq, void *dev_id, struct pt_regs * regs)
+void zoran_irq(int irq, void *dev_id)
 {
        u32 stat,estat;
        int count = 0;
        struct zoran *ztv = dev_id;
 
-       UNUSED(irq); UNUSED(regs);
+       UNUSED(irq);
        for (;;) {
                /* get/clear interrupt status bits */
                stat=zrread(ZORAN_ISR);
index 048b5b8610e3f395d3e7cfcc32cee151eef64446..bb2bf5aa0b62bfa27ffcf4e22bca83e56459b95a 100644 (file)
@@ -6,13 +6,4 @@
 #include <linux/version.h>
 #include <scsi/scsi_device.h>
 
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,6))
-static int inline scsi_device_online(struct scsi_device *sdev)
-{
-       return sdev->online;
-}
-#endif
-
-
-/*}-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 #endif /* _LINUX_COMPAT_H */
index 29d0635cce1d2d314a9f5f9d41277f178199299c..e5c72719debc70496596980d67213ea3dd08770f 100644 (file)
@@ -122,7 +122,7 @@ static DECLARE_WAIT_QUEUE_HEAD(mpt_waitq);
 /*
  *  Forward protos...
  */
-static irqreturn_t mpt_interrupt(int irq, void *bus_id, struct pt_regs *r);
+static irqreturn_t mpt_interrupt(int irq, void *bus_id);
 static int     mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply);
 static int     mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes,
                        u32 *req, int replyBytes, u16 *u16reply, int maxwait,
@@ -351,7 +351,6 @@ mpt_reply(MPT_ADAPTER *ioc, u32 pa)
  *     mpt_interrupt - MPT adapter (IOC) specific interrupt handler.
  *     @irq: irq number (not used)
  *     @bus_id: bus identifier cookie == pointer to MPT_ADAPTER structure
- *     @r: pt_regs pointer (not used)
  *
  *     This routine is registered via the request_irq() kernel API call,
  *     and handles all interrupts generated from a specific MPT adapter
@@ -365,7 +364,7 @@ mpt_reply(MPT_ADAPTER *ioc, u32 pa)
  *     the protocol-specific details of the MPT request completion.
  */
 static irqreturn_t
-mpt_interrupt(int irq, void *bus_id, struct pt_regs *r)
+mpt_interrupt(int irq, void *bus_id)
 {
        MPT_ADAPTER *ioc = bus_id;
        u32 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
index ac06f10c54ec1416c1a9b75fdbde20e23051be22..d96c687aee9373fe7638fa61bb88e335b58b65ea 100644 (file)
@@ -80,18 +80,26 @@ static DEVICE_ATTR(scan, S_IWUSR, NULL, i2o_bus_store_scan);
  *     @dev: device to verify if it is a I2O Bus Adapter device
  *
  *     Because we want all Bus Adapters always return 0.
+ *     Except when we fail.  Then we are sad.
  *
- *     Returns 0.
+ *     Returns 0, except when we fail to excel.
  */
 static int i2o_bus_probe(struct device *dev)
 {
        struct i2o_device *i2o_dev = to_i2o_device(get_device(dev));
+       int rc;
 
-       device_create_file(dev, &dev_attr_scan);
+       rc = device_create_file(dev, &dev_attr_scan);
+       if (rc)
+               goto err_out;
 
        osm_info("device added (TID: %03x)\n", i2o_dev->lct_data.tid);
 
        return 0;
+
+err_out:
+       put_device(dev);
+       return rc;
 };
 
 /**
index 7bd4d85d0b42db6af28def4072cbd11fbadbec86..01a5a702b037e9c12e22fd1ef43ebd211b8f4204 100644 (file)
@@ -127,7 +127,7 @@ int i2o_msg_post_wait_mem(struct i2o_controller *c, struct i2o_message *msg,
        DECLARE_WAIT_QUEUE_HEAD(wq);
        struct i2o_exec_wait *wait;
        static u32 tcntxt = 0x80000000;
-       long flags;
+       unsigned long flags;
        int rc = 0;
 
        wait = i2o_exec_wait_alloc();
@@ -325,13 +325,24 @@ static DEVICE_ATTR(product_id, S_IRUGO, i2o_exec_show_product_id, NULL);
 static int i2o_exec_probe(struct device *dev)
 {
        struct i2o_device *i2o_dev = to_i2o_device(dev);
+       int rc;
 
-       i2o_event_register(i2o_dev, &i2o_exec_driver, 0, 0xffffffff);
+       rc = i2o_event_register(i2o_dev, &i2o_exec_driver, 0, 0xffffffff);
+       if (rc) goto err_out;
 
-       device_create_file(dev, &dev_attr_vendor_id);
-       device_create_file(dev, &dev_attr_product_id);
+       rc = device_create_file(dev, &dev_attr_vendor_id);
+       if (rc) goto err_evtreg;
+       rc = device_create_file(dev, &dev_attr_product_id);
+       if (rc) goto err_vid;
 
        return 0;
+
+err_vid:
+       device_remove_file(dev, &dev_attr_vendor_id);
+err_evtreg:
+       i2o_event_register(to_i2o_device(dev), &i2o_exec_driver, 0, 0);
+err_out:
+       return rc;
 };
 
 /**
index dec41cc8993786f111ee216af84849c1fbc728b0..62f1ac08332c48d86bbfb8604a6813f57100bac4 100644 (file)
@@ -224,12 +224,11 @@ static int __devinit i2o_pci_alloc(struct i2o_controller *c)
  *     i2o_pci_interrupt - Interrupt handler for I2O controller
  *     @irq: interrupt line
  *     @dev_id: pointer to the I2O controller
- *     @r: pointer to registers
  *
  *     Handle an interrupt from a PCI based I2O controller. This turns out
  *     to be rather simple. We keep the controller pointer in the cookie.
  */
-static irqreturn_t i2o_pci_interrupt(int irq, void *dev_id, struct pt_regs *r)
+static irqreturn_t i2o_pci_interrupt(int irq, void *dev_id)
 {
        struct i2o_controller *c = dev_id;
        u32 m;
index 2bf32721eb5359163074fd861887e77860f4eea7..149810a084f5e0a9e5463dd2326f716198251318 100644 (file)
@@ -203,7 +203,7 @@ void ucb1x00_adc_disable(struct ucb1x00 *ucb)
  * SIBCLK to talk to the chip.  We leave the clock running until
  * we have finished processing all interrupts from the chip.
  */
-static irqreturn_t ucb1x00_irq(int irqnr, void *devid, struct pt_regs *regs)
+static irqreturn_t ucb1x00_irq(int irqnr, void *devid)
 {
        struct ucb1x00 *ucb = devid;
        struct ucb1x00_irq *irq;
index 3df0e7a07c46c31be7e6635f09f51f5fd489955e..b6c045dc97b4e1331e426323aa4010daffe67e0f 100644 (file)
@@ -28,6 +28,17 @@ config IBM_ASM
 
          If unsure, say N.
 
+config SGI_IOC4
+       tristate "SGI IOC4 Base IO support"
+       ---help---
+         This option enables basic support for the IOC4 chip on certain
+         SGI IO controller cards (IO9, IO10, and PCI-RT).  This option
+         does not enable any specific functions on such a card, but provides
+         necessary infrastructure for other drivers to utilize.
+
+         If you have an SGI Altix with an IOC4-based card say Y.
+         Otherwise say N.
+
 config TIFM_CORE
        tristate "TI Flash Media interface support (EXPERIMENTAL)"
        depends on EXPERIMENTAL
@@ -57,4 +68,23 @@ config TIFM_7XX1
           To compile this driver as a module, choose M here: the module will
          be called tifm_7xx1.
 
+config MSI_LAPTOP
+        tristate "MSI Laptop Extras"
+        depends on X86
+        depends on ACPI_EC
+        depends on BACKLIGHT_CLASS_DEVICE
+        ---help---
+         This is a driver for laptops built by MSI (MICRO-STAR
+         INTERNATIONAL):
+
+         MSI MegaBook S270 (MS-1013)
+         Cytron/TCM/Medion/Tchibo MD96100/SAM2000
+
+         It adds support for Bluetooth, WLAN and LCD brightness control.
+
+         More information about this driver is available at
+         <http://0pointer.de/lennart/tchibo.html>.
+
+         If you have an MSI S270 laptop, say Y or M here.
+
 endmenu
index d65ece76095a43283de2714a8c7dc0ac9a0f1625..c9e98ab021c5b096658012057a8e58542bbb1eef 100644 (file)
@@ -5,6 +5,8 @@ obj- := misc.o  # Dummy rule to force built-in.o to be made
 
 obj-$(CONFIG_IBM_ASM)          += ibmasm/
 obj-$(CONFIG_HDPU_FEATURES)    += hdpuftrs/
+obj-$(CONFIG_MSI_LAPTOP)     += msi-laptop.o
 obj-$(CONFIG_LKDTM)            += lkdtm.o
 obj-$(CONFIG_TIFM_CORE)        += tifm_core.o
 obj-$(CONFIG_TIFM_7XX1)        += tifm_7xx1.o
+obj-$(CONFIG_SGI_IOC4)         += ioc4.o
index 634d538ccd14eb3c3e062b12316f7b3ef3385132..48d5abebfc30afe48ac879b8f1e4ad8e10910f34 100644 (file)
@@ -196,10 +196,10 @@ extern int ibmasm_send_os_state(struct service_processor *sp, int os_state);
 
 /* low level message processing */
 extern int ibmasm_send_i2o_message(struct service_processor *sp);
-extern irqreturn_t ibmasm_interrupt_handler(int irq, void * dev_id, struct pt_regs *regs);
+extern irqreturn_t ibmasm_interrupt_handler(int irq, void * dev_id);
 
 /* remote console */
-extern void ibmasm_handle_mouse_interrupt(struct service_processor *sp, struct pt_regs *regs);
+extern void ibmasm_handle_mouse_interrupt(struct service_processor *sp);
 extern int ibmasm_init_remote_input_dev(struct service_processor *sp);
 extern void ibmasm_free_remote_input_dev(struct service_processor *sp);
 
index 47949a2c7e94f752e737e4e7b0be00e6aee5ff39..a3c589b7cbfa58590a29c1ae5f5038870d8291de 100644 (file)
@@ -54,7 +54,7 @@ int ibmasm_send_i2o_message(struct service_processor *sp)
        return 0;
 }
 
-irqreturn_t ibmasm_interrupt_handler(int irq, void * dev_id, struct pt_regs *regs)
+irqreturn_t ibmasm_interrupt_handler(int irq, void * dev_id)
 {
        u32     mfa;
        struct service_processor *sp = (struct service_processor *)dev_id;
@@ -67,7 +67,7 @@ irqreturn_t ibmasm_interrupt_handler(int irq, void * dev_id, struct pt_regs *reg
        dbg("respond to interrupt at %s\n", get_timestamp(tsbuf));
 
        if (mouse_interrupt_pending(sp)) {
-               ibmasm_handle_mouse_interrupt(sp, regs);
+               ibmasm_handle_mouse_interrupt(sp);
                clear_mouse_interrupt(sp);
        }
 
index 0f9e3aa34d07ddb2645b6b361bcbd889f9198b74..a40fda6c402c6772b57d0331f6a1f78fbb122e42 100644 (file)
@@ -158,12 +158,10 @@ static void print_input(struct remote_input *input)
        }
 }
 
-static void send_mouse_event(struct input_dev *dev, struct pt_regs *regs,
-               struct remote_input *input)
+static void send_mouse_event(struct input_dev *dev, struct remote_input *input)
 {
        unsigned char buttons = input->mouse_buttons;
 
-       input_regs(dev, regs);
        input_report_abs(dev, ABS_X, input->data.mouse.x);
        input_report_abs(dev, ABS_Y, input->data.mouse.y);
        input_report_key(dev, BTN_LEFT, buttons & REMOTE_BUTTON_LEFT);
@@ -172,7 +170,7 @@ static void send_mouse_event(struct input_dev *dev, struct pt_regs *regs,
        input_sync(dev);
 }
 
-static void send_keyboard_event(struct input_dev *dev, struct pt_regs *regs,
+static void send_keyboard_event(struct input_dev *dev,
                struct remote_input *input)
 {
        unsigned int key;
@@ -182,13 +180,11 @@ static void send_keyboard_event(struct input_dev *dev, struct pt_regs *regs,
                key = xlate_high[code & 0xff];
        else
                key = xlate[code];
-       input_regs(dev, regs);
        input_report_key(dev, key, (input->data.keyboard.key_down) ? 1 : 0);
        input_sync(dev);
 }
 
-void ibmasm_handle_mouse_interrupt(struct service_processor *sp,
-               struct pt_regs *regs)
+void ibmasm_handle_mouse_interrupt(struct service_processor *sp)
 {
        unsigned long reader;
        unsigned long writer;
@@ -203,9 +199,9 @@ void ibmasm_handle_mouse_interrupt(struct service_processor *sp,
 
                print_input(&input);
                if (input.type == INPUT_TYPE_MOUSE) {
-                       send_mouse_event(sp->remote.mouse_dev, regs, &input);
+                       send_mouse_event(sp->remote.mouse_dev, &input);
                } else if (input.type == INPUT_TYPE_KEYBOARD) {
-                       send_keyboard_event(sp->remote.keybd_dev, regs, &input);
+                       send_keyboard_event(sp->remote.keybd_dev, &input);
                } else
                        break;
 
diff --git a/drivers/misc/ioc4.c b/drivers/misc/ioc4.c
new file mode 100644 (file)
index 0000000..1c3c14a
--- /dev/null
@@ -0,0 +1,473 @@
+/*
+ * 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) 2005-2006 Silicon Graphics, Inc.  All Rights Reserved.
+ */
+
+/* This file contains the master driver module for use by SGI IOC4 subdrivers.
+ *
+ * It allocates any resources shared between multiple subdevices, and
+ * provides accessor functions (where needed) and the like for those
+ * resources.  It also provides a mechanism for the subdevice modules
+ * to support loading and unloading.
+ *
+ * Non-shared resources (e.g. external interrupt A_INT_OUT register page
+ * alias, serial port and UART registers) are handled by the subdevice
+ * modules themselves.
+ *
+ * This is all necessary because IOC4 is not implemented as a multi-function
+ * PCI device, but an amalgamation of disparate registers for several
+ * types of device (ATA, serial, external interrupts).  The normal
+ * resource management in the kernel doesn't have quite the right interfaces
+ * to handle this situation (e.g. multiple modules can't claim the same
+ * PCI ID), thus this IOC4 master module.
+ */
+
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/ioc4.h>
+#include <linux/ktime.h>
+#include <linux/mutex.h>
+#include <linux/time.h>
+
+/***************
+ * Definitions *
+ ***************/
+
+/* Tweakable values */
+
+/* PCI bus speed detection/calibration */
+#define IOC4_CALIBRATE_COUNT 63                /* Calibration cycle period */
+#define IOC4_CALIBRATE_CYCLES 256      /* Average over this many cycles */
+#define IOC4_CALIBRATE_DISCARD 2       /* Discard first few cycles */
+#define IOC4_CALIBRATE_LOW_MHZ 25      /* Lower bound on bus speed sanity */
+#define IOC4_CALIBRATE_HIGH_MHZ 75     /* Upper bound on bus speed sanity */
+#define IOC4_CALIBRATE_DEFAULT_MHZ 66  /* Assumed if sanity check fails */
+
+/************************
+ * Submodule management *
+ ************************/
+
+static DEFINE_MUTEX(ioc4_mutex);
+
+static LIST_HEAD(ioc4_devices);
+static LIST_HEAD(ioc4_submodules);
+
+/* Register an IOC4 submodule */
+int
+ioc4_register_submodule(struct ioc4_submodule *is)
+{
+       struct ioc4_driver_data *idd;
+
+       mutex_lock(&ioc4_mutex);
+       list_add(&is->is_list, &ioc4_submodules);
+
+       /* Initialize submodule for each IOC4 */
+       if (!is->is_probe)
+               goto out;
+
+       list_for_each_entry(idd, &ioc4_devices, idd_list) {
+               if (is->is_probe(idd)) {
+                       printk(KERN_WARNING
+                              "%s: IOC4 submodule %s probe failed "
+                              "for pci_dev %s",
+                              __FUNCTION__, module_name(is->is_owner),
+                              pci_name(idd->idd_pdev));
+               }
+       }
+ out:
+       mutex_unlock(&ioc4_mutex);
+       return 0;
+}
+
+/* Unregister an IOC4 submodule */
+void
+ioc4_unregister_submodule(struct ioc4_submodule *is)
+{
+       struct ioc4_driver_data *idd;
+
+       mutex_lock(&ioc4_mutex);
+       list_del(&is->is_list);
+
+       /* Remove submodule for each IOC4 */
+       if (!is->is_remove)
+               goto out;
+
+       list_for_each_entry(idd, &ioc4_devices, idd_list) {
+               if (is->is_remove(idd)) {
+                       printk(KERN_WARNING
+                              "%s: IOC4 submodule %s remove failed "
+                              "for pci_dev %s.\n",
+                              __FUNCTION__, module_name(is->is_owner),
+                              pci_name(idd->idd_pdev));
+               }
+       }
+ out:
+       mutex_unlock(&ioc4_mutex);
+}
+
+/*********************
+ * Device management *
+ *********************/
+
+#define IOC4_CALIBRATE_LOW_LIMIT \
+       (1000*IOC4_EXTINT_COUNT_DIVISOR/IOC4_CALIBRATE_LOW_MHZ)
+#define IOC4_CALIBRATE_HIGH_LIMIT \
+       (1000*IOC4_EXTINT_COUNT_DIVISOR/IOC4_CALIBRATE_HIGH_MHZ)
+#define IOC4_CALIBRATE_DEFAULT \
+       (1000*IOC4_EXTINT_COUNT_DIVISOR/IOC4_CALIBRATE_DEFAULT_MHZ)
+
+#define IOC4_CALIBRATE_END \
+       (IOC4_CALIBRATE_CYCLES + IOC4_CALIBRATE_DISCARD)
+
+#define IOC4_INT_OUT_MODE_TOGGLE 0x7   /* Toggle INT_OUT every COUNT+1 ticks */
+
+/* Determines external interrupt output clock period of the PCI bus an
+ * IOC4 is attached to.  This value can be used to determine the PCI
+ * bus speed.
+ *
+ * IOC4 has a design feature that various internal timers are derived from
+ * the PCI bus clock.  This causes IOC4 device drivers to need to take the
+ * bus speed into account when setting various register values (e.g. INT_OUT
+ * register COUNT field, UART divisors, etc).  Since this information is
+ * needed by several subdrivers, it is determined by the main IOC4 driver,
+ * even though the following code utilizes external interrupt registers
+ * to perform the speed calculation.
+ */
+static void
+ioc4_clock_calibrate(struct ioc4_driver_data *idd)
+{
+       union ioc4_int_out int_out;
+       union ioc4_gpcr gpcr;
+       unsigned int state, last_state = 1;
+       struct timespec start_ts, end_ts;
+       uint64_t start, end, period;
+       unsigned int count = 0;
+
+       /* Enable output */
+       gpcr.raw = 0;
+       gpcr.fields.dir = IOC4_GPCR_DIR_0;
+       gpcr.fields.int_out_en = 1;
+       writel(gpcr.raw, &idd->idd_misc_regs->gpcr_s.raw);
+
+       /* Reset to power-on state */
+       writel(0, &idd->idd_misc_regs->int_out.raw);
+       mmiowb();
+
+       /* Set up square wave */
+       int_out.raw = 0;
+       int_out.fields.count = IOC4_CALIBRATE_COUNT;
+       int_out.fields.mode = IOC4_INT_OUT_MODE_TOGGLE;
+       int_out.fields.diag = 0;
+       writel(int_out.raw, &idd->idd_misc_regs->int_out.raw);
+       mmiowb();
+
+       /* Check square wave period averaged over some number of cycles */
+       do {
+               int_out.raw = readl(&idd->idd_misc_regs->int_out.raw);
+               state = int_out.fields.int_out;
+               if (!last_state && state) {
+                       count++;
+                       if (count == IOC4_CALIBRATE_END) {
+                               ktime_get_ts(&end_ts);
+                               break;
+                       } else if (count == IOC4_CALIBRATE_DISCARD)
+                               ktime_get_ts(&start_ts);
+               }
+               last_state = state;
+       } while (1);
+
+       /* Calculation rearranged to preserve intermediate precision.
+        * Logically:
+        * 1. "end - start" gives us the measurement period over all
+        *    the square wave cycles.
+        * 2. Divide by number of square wave cycles to get the period
+        *    of a square wave cycle.
+        * 3. Divide by 2*(int_out.fields.count+1), which is the formula
+        *    by which the IOC4 generates the square wave, to get the
+        *    period of an IOC4 INT_OUT count.
+        */
+       end = end_ts.tv_sec * NSEC_PER_SEC + end_ts.tv_nsec;
+       start = start_ts.tv_sec * NSEC_PER_SEC + start_ts.tv_nsec;
+       period = (end - start) /
+               (IOC4_CALIBRATE_CYCLES * 2 * (IOC4_CALIBRATE_COUNT + 1));
+
+       /* Bounds check the result. */
+       if (period > IOC4_CALIBRATE_LOW_LIMIT ||
+           period < IOC4_CALIBRATE_HIGH_LIMIT) {
+               printk(KERN_INFO
+                      "IOC4 %s: Clock calibration failed.  Assuming"
+                      "PCI clock is %d ns.\n",
+                      pci_name(idd->idd_pdev),
+                      IOC4_CALIBRATE_DEFAULT / IOC4_EXTINT_COUNT_DIVISOR);
+               period = IOC4_CALIBRATE_DEFAULT;
+       } else {
+               u64 ns = period;
+
+               do_div(ns, IOC4_EXTINT_COUNT_DIVISOR);
+               printk(KERN_DEBUG
+                      "IOC4 %s: PCI clock is %lld ns.\n",
+                      pci_name(idd->idd_pdev), ns);
+       }
+
+       /* Remember results.  We store the extint clock period rather
+        * than the PCI clock period so that greater precision is
+        * retained.  Divide by IOC4_EXTINT_COUNT_DIVISOR to get
+        * PCI clock period.
+        */
+       idd->count_period = period;
+}
+
+/* There are three variants of IOC4 cards: IO9, IO10, and PCI-RT.
+ * Each brings out different combinations of IOC4 signals, thus.
+ * the IOC4 subdrivers need to know to which we're attached.
+ *
+ * We look for the presence of a SCSI (IO9) or SATA (IO10) controller
+ * on the same PCI bus at slot number 3 to differentiate IO9 from IO10.
+ * If neither is present, it's a PCI-RT.
+ */
+static unsigned int
+ioc4_variant(struct ioc4_driver_data *idd)
+{
+       struct pci_dev *pdev = NULL;
+       int found = 0;
+
+       /* IO9: Look for a QLogic ISP 12160 at the same bus and slot 3. */
+       do {
+               pdev = pci_get_device(PCI_VENDOR_ID_QLOGIC,
+                                     PCI_DEVICE_ID_QLOGIC_ISP12160, pdev);
+               if (pdev &&
+                   idd->idd_pdev->bus->number == pdev->bus->number &&
+                   3 == PCI_SLOT(pdev->devfn))
+                       found = 1;
+               pci_dev_put(pdev);
+       } while (pdev && !found);
+       if (NULL != pdev)
+               return IOC4_VARIANT_IO9;
+
+       /* IO10: Look for a Vitesse VSC 7174 at the same bus and slot 3. */
+       pdev = NULL;
+       do {
+               pdev = pci_get_device(PCI_VENDOR_ID_VITESSE,
+                                     PCI_DEVICE_ID_VITESSE_VSC7174, pdev);
+               if (pdev &&
+                   idd->idd_pdev->bus->number == pdev->bus->number &&
+                   3 == PCI_SLOT(pdev->devfn))
+                       found = 1;
+               pci_dev_put(pdev);
+       } while (pdev && !found);
+       if (NULL != pdev)
+               return IOC4_VARIANT_IO10;
+
+       /* PCI-RT: No SCSI/SATA controller will be present */
+       return IOC4_VARIANT_PCI_RT;
+}
+
+/* Adds a new instance of an IOC4 card */
+static int
+ioc4_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
+{
+       struct ioc4_driver_data *idd;
+       struct ioc4_submodule *is;
+       uint32_t pcmd;
+       int ret;
+
+       /* Enable IOC4 and take ownership of it */
+       if ((ret = pci_enable_device(pdev))) {
+               printk(KERN_WARNING
+                      "%s: Failed to enable IOC4 device for pci_dev %s.\n",
+                      __FUNCTION__, pci_name(pdev));
+               goto out;
+       }
+       pci_set_master(pdev);
+
+       /* Set up per-IOC4 data */
+       idd = kmalloc(sizeof(struct ioc4_driver_data), GFP_KERNEL);
+       if (!idd) {
+               printk(KERN_WARNING
+                      "%s: Failed to allocate IOC4 data for pci_dev %s.\n",
+                      __FUNCTION__, pci_name(pdev));
+               ret = -ENODEV;
+               goto out_idd;
+       }
+       idd->idd_pdev = pdev;
+       idd->idd_pci_id = pci_id;
+
+       /* Map IOC4 misc registers.  These are shared between subdevices
+        * so the main IOC4 module manages them.
+        */
+       idd->idd_bar0 = pci_resource_start(idd->idd_pdev, 0);
+       if (!idd->idd_bar0) {
+               printk(KERN_WARNING
+                      "%s: Unable to find IOC4 misc resource "
+                      "for pci_dev %s.\n",
+                      __FUNCTION__, pci_name(idd->idd_pdev));
+               ret = -ENODEV;
+               goto out_pci;
+       }
+       if (!request_region(idd->idd_bar0, sizeof(struct ioc4_misc_regs),
+                           "ioc4_misc")) {
+               printk(KERN_WARNING
+                      "%s: Unable to request IOC4 misc region "
+                      "for pci_dev %s.\n",
+                      __FUNCTION__, pci_name(idd->idd_pdev));
+               ret = -ENODEV;
+               goto out_pci;
+       }
+       idd->idd_misc_regs = ioremap(idd->idd_bar0,
+                                    sizeof(struct ioc4_misc_regs));
+       if (!idd->idd_misc_regs) {
+               printk(KERN_WARNING
+                      "%s: Unable to remap IOC4 misc region "
+                      "for pci_dev %s.\n",
+                      __FUNCTION__, pci_name(idd->idd_pdev));
+               ret = -ENODEV;
+               goto out_misc_region;
+       }
+
+       /* Failsafe portion of per-IOC4 initialization */
+
+       /* Detect card variant */
+       idd->idd_variant = ioc4_variant(idd);
+       printk(KERN_INFO "IOC4 %s: %s card detected.\n", pci_name(pdev),
+              idd->idd_variant == IOC4_VARIANT_IO9 ? "IO9" :
+              idd->idd_variant == IOC4_VARIANT_PCI_RT ? "PCI-RT" :
+              idd->idd_variant == IOC4_VARIANT_IO10 ? "IO10" : "unknown");
+
+       /* Initialize IOC4 */
+       pci_read_config_dword(idd->idd_pdev, PCI_COMMAND, &pcmd);
+       pci_write_config_dword(idd->idd_pdev, PCI_COMMAND,
+                              pcmd | PCI_COMMAND_PARITY | PCI_COMMAND_SERR);
+
+       /* Determine PCI clock */
+       ioc4_clock_calibrate(idd);
+
+       /* Disable/clear all interrupts.  Need to do this here lest
+        * one submodule request the shared IOC4 IRQ, but interrupt
+        * is generated by a different subdevice.
+        */
+       /* Disable */
+       writel(~0, &idd->idd_misc_regs->other_iec.raw);
+       writel(~0, &idd->idd_misc_regs->sio_iec);
+       /* Clear (i.e. acknowledge) */
+       writel(~0, &idd->idd_misc_regs->other_ir.raw);
+       writel(~0, &idd->idd_misc_regs->sio_ir);
+
+       /* Track PCI-device specific data */
+       idd->idd_serial_data = NULL;
+       pci_set_drvdata(idd->idd_pdev, idd);
+
+       mutex_lock(&ioc4_mutex);
+       list_add_tail(&idd->idd_list, &ioc4_devices);
+
+       /* Add this IOC4 to all submodules */
+       list_for_each_entry(is, &ioc4_submodules, is_list) {
+               if (is->is_probe && is->is_probe(idd)) {
+                       printk(KERN_WARNING
+                              "%s: IOC4 submodule 0x%s probe failed "
+                              "for pci_dev %s.\n",
+                              __FUNCTION__, module_name(is->is_owner),
+                              pci_name(idd->idd_pdev));
+               }
+       }
+       mutex_unlock(&ioc4_mutex);
+
+       return 0;
+
+out_misc_region:
+       release_region(idd->idd_bar0, sizeof(struct ioc4_misc_regs));
+out_pci:
+       kfree(idd);
+out_idd:
+       pci_disable_device(pdev);
+out:
+       return ret;
+}
+
+/* Removes a particular instance of an IOC4 card. */
+static void
+ioc4_remove(struct pci_dev *pdev)
+{
+       struct ioc4_submodule *is;
+       struct ioc4_driver_data *idd;
+
+       idd = pci_get_drvdata(pdev);
+
+       /* Remove this IOC4 from all submodules */
+       mutex_lock(&ioc4_mutex);
+       list_for_each_entry(is, &ioc4_submodules, is_list) {
+               if (is->is_remove && is->is_remove(idd)) {
+                       printk(KERN_WARNING
+                              "%s: IOC4 submodule 0x%s remove failed "
+                              "for pci_dev %s.\n",
+                              __FUNCTION__, module_name(is->is_owner),
+                              pci_name(idd->idd_pdev));
+               }
+       }
+       mutex_unlock(&ioc4_mutex);
+
+       /* Release resources */
+       iounmap(idd->idd_misc_regs);
+       if (!idd->idd_bar0) {
+               printk(KERN_WARNING
+                      "%s: Unable to get IOC4 misc mapping for pci_dev %s. "
+                      "Device removal may be incomplete.\n",
+                      __FUNCTION__, pci_name(idd->idd_pdev));
+       }
+       release_region(idd->idd_bar0, sizeof(struct ioc4_misc_regs));
+
+       /* Disable IOC4 and relinquish */
+       pci_disable_device(pdev);
+
+       /* Remove and free driver data */
+       mutex_lock(&ioc4_mutex);
+       list_del(&idd->idd_list);
+       mutex_unlock(&ioc4_mutex);
+       kfree(idd);
+}
+
+static struct pci_device_id ioc4_id_table[] = {
+       {PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_IOC4, PCI_ANY_ID,
+        PCI_ANY_ID, 0x0b4000, 0xFFFFFF},
+       {0}
+};
+
+static struct pci_driver ioc4_driver = {
+       .name = "IOC4",
+       .id_table = ioc4_id_table,
+       .probe = ioc4_probe,
+       .remove = ioc4_remove,
+};
+
+MODULE_DEVICE_TABLE(pci, ioc4_id_table);
+
+/*********************
+ * Module management *
+ *********************/
+
+/* Module load */
+static int __devinit
+ioc4_init(void)
+{
+       return pci_register_driver(&ioc4_driver);
+}
+
+/* Module unload */
+static void __devexit
+ioc4_exit(void)
+{
+       pci_unregister_driver(&ioc4_driver);
+}
+
+module_init(ioc4_init);
+module_exit(ioc4_exit);
+
+MODULE_AUTHOR("Brent Casavant - Silicon Graphics, Inc. <bcasavan@sgi.com>");
+MODULE_DESCRIPTION("PCI driver master module for SGI IOC4 Base-IO Card");
+MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(ioc4_register_submodule);
+EXPORT_SYMBOL(ioc4_unregister_submodule);
index e689ee94ac3da71450c7d03c66feda8457fe14f8..bbdba7b37e11e1c9d1a12f6b316de8b4f5e414ea 100644 (file)
@@ -127,15 +127,14 @@ module_param(cpoint_count, int, 06444);
 MODULE_PARM_DESC(cpoint_count, "Crash Point Count, number of times the \
                                crash point is to be hit to trigger action");
 
-unsigned int jp_do_irq(unsigned int irq, struct pt_regs *regs)
+unsigned int jp_do_irq(unsigned int irq)
 {
        lkdtm_handler();
        jprobe_return();
        return 0;
 }
 
-irqreturn_t jp_handle_irq_event(unsigned int irq, struct pt_regs *regs,
-                       struct irqaction *action)
+irqreturn_t jp_handle_irq_event(unsigned int irq, struct irqaction *action)
 {
        lkdtm_handler();
        jprobe_return();
diff --git a/drivers/misc/msi-laptop.c b/drivers/misc/msi-laptop.c
new file mode 100644 (file)
index 0000000..fdb7153
--- /dev/null
@@ -0,0 +1,395 @@
+/*-*-linux-c-*-*/
+
+/*
+  Copyright (C) 2006 Lennart Poettering <mzxreary (at) 0pointer (dot) de>
+
+  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., 51 Franklin Street, Fifth Floor, Boston, MA
+  02110-1301, USA.
+ */
+
+/*
+ * msi-laptop.c - MSI S270 laptop support. This laptop is sold under
+ * various brands, including "Cytron/TCM/Medion/Tchibo MD96100".
+ *
+ * This driver exports a few files in /sys/devices/platform/msi-laptop-pf/:
+ *
+ *   lcd_level - Screen brightness: contains a single integer in the
+ *   range 0..8. (rw)
+ *
+ *   auto_brightness - Enable automatic brightness control: contains
+ *   either 0 or 1. If set to 1 the hardware adjusts the screen
+ *   brightness automatically when the power cord is
+ *   plugged/unplugged. (rw)
+ *
+ *   wlan - WLAN subsystem enabled: contains either 0 or 1. (ro)
+ *
+ *   bluetooth - Bluetooth subsystem enabled: contains either 0 or 1
+ *   Please note that this file is constantly 0 if no Bluetooth
+ *   hardware is available. (ro)
+ *
+ * In addition to these platform device attributes the driver
+ * registers itself in the Linux backlight control subsystem and is
+ * available to userspace under /sys/class/backlight/msi-laptop-bl/.
+ *
+ * This driver might work on other laptops produced by MSI. If you
+ * want to try it you can pass force=1 as argument to the module which
+ * will force it to load even when the DMI data doesn't identify the
+ * laptop as MSI S270. YMMV.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/acpi.h>
+#include <linux/dmi.h>
+#include <linux/backlight.h>
+#include <linux/platform_device.h>
+#include <linux/autoconf.h>
+
+#define MSI_DRIVER_VERSION "0.5"
+
+#define MSI_LCD_LEVEL_MAX 9
+
+#define MSI_EC_COMMAND_WIRELESS 0x10
+#define MSI_EC_COMMAND_LCD_LEVEL 0x11
+
+static int force;
+module_param(force, bool, 0);
+MODULE_PARM_DESC(force, "Force driver load, ignore DMI data");
+
+static int auto_brightness;
+module_param(auto_brightness, int, 0);
+MODULE_PARM_DESC(auto_brightness, "Enable automatic brightness control (0: disabled; 1: enabled; 2: don't touch)");
+
+/* Hardware access */
+
+static int set_lcd_level(int level)
+{
+       u8 buf[2];
+
+       if (level < 0 || level >= MSI_LCD_LEVEL_MAX)
+               return -EINVAL;
+
+       buf[0] = 0x80;
+       buf[1] = (u8) (level*31);
+
+       return ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, buf, sizeof(buf), NULL, 0);
+}
+
+static int get_lcd_level(void)
+{
+       u8 wdata = 0, rdata;
+       int result;
+
+       result = ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, &wdata, 1, &rdata, 1);
+       if (result < 0)
+               return result;
+
+       return (int) rdata / 31;
+}
+
+static int get_auto_brightness(void)
+{
+       u8 wdata = 4, rdata;
+       int result;
+
+       result = ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, &wdata, 1, &rdata, 1);
+       if (result < 0)
+               return result;
+
+       return !!(rdata & 8);
+}
+
+static int set_auto_brightness(int enable)
+{
+       u8 wdata[2], rdata;
+       int result;
+
+       wdata[0] = 4;
+
+       result = ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, wdata, 1, &rdata, 1);
+       if (result < 0)
+               return result;
+
+       wdata[0] = 0x84;
+       wdata[1] = (rdata & 0xF7) | (enable ? 8 : 0);
+
+       return ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, wdata, 2, NULL, 0);
+}
+
+static int get_wireless_state(int *wlan, int *bluetooth)
+{
+       u8 wdata = 0, rdata;
+       int result;
+
+       result = ec_transaction(MSI_EC_COMMAND_WIRELESS, &wdata, 1, &rdata, 1);
+       if (result < 0)
+               return -1;
+
+       if (wlan)
+               *wlan = !!(rdata & 8);
+
+       if (bluetooth)
+               *bluetooth = !!(rdata & 128);
+
+       return 0;
+}
+
+/* Backlight device stuff */
+
+static int bl_get_brightness(struct backlight_device *b)
+{
+       return get_lcd_level();
+}
+
+
+static int bl_update_status(struct backlight_device *b)
+{
+       return set_lcd_level(b->props->brightness);
+}
+
+static struct backlight_properties msibl_props = {
+       .owner          = THIS_MODULE,
+       .get_brightness = bl_get_brightness,
+       .update_status  = bl_update_status,
+       .max_brightness = MSI_LCD_LEVEL_MAX-1,
+};
+
+static struct backlight_device *msibl_device;
+
+/* Platform device */
+
+static ssize_t show_wlan(struct device *dev,
+       struct device_attribute *attr, char *buf)
+{
+
+       int ret, enabled;
+
+       ret = get_wireless_state(&enabled, NULL);
+       if (ret < 0)
+               return ret;
+
+       return sprintf(buf, "%i\n", enabled);
+}
+
+static ssize_t show_bluetooth(struct device *dev,
+       struct device_attribute *attr, char *buf)
+{
+
+       int ret, enabled;
+
+       ret = get_wireless_state(NULL, &enabled);
+       if (ret < 0)
+               return ret;
+
+       return sprintf(buf, "%i\n", enabled);
+}
+
+static ssize_t show_lcd_level(struct device *dev,
+       struct device_attribute *attr, char *buf)
+{
+
+       int ret;
+
+       ret = get_lcd_level();
+       if (ret < 0)
+               return ret;
+
+       return sprintf(buf, "%i\n", ret);
+}
+
+static ssize_t store_lcd_level(struct device *dev,
+       struct device_attribute *attr, const char *buf, size_t count)
+{
+
+       int level, ret;
+
+       if (sscanf(buf, "%i", &level) != 1 || (level < 0 || level >= MSI_LCD_LEVEL_MAX))
+               return -EINVAL;
+
+       ret = set_lcd_level(level);
+       if (ret < 0)
+               return ret;
+
+       return count;
+}
+
+static ssize_t show_auto_brightness(struct device *dev,
+       struct device_attribute *attr, char *buf)
+{
+
+       int ret;
+
+       ret = get_auto_brightness();
+       if (ret < 0)
+               return ret;
+
+       return sprintf(buf, "%i\n", ret);
+}
+
+static ssize_t store_auto_brightness(struct device *dev,
+       struct device_attribute *attr, const char *buf, size_t count)
+{
+
+       int enable, ret;
+
+       if (sscanf(buf, "%i", &enable) != 1 || (enable != (enable & 1)))
+               return -EINVAL;
+
+       ret = set_auto_brightness(enable);
+       if (ret < 0)
+               return ret;
+
+       return count;
+}
+
+static DEVICE_ATTR(lcd_level, 0644, show_lcd_level, store_lcd_level);
+static DEVICE_ATTR(auto_brightness, 0644, show_auto_brightness, store_auto_brightness);
+static DEVICE_ATTR(bluetooth, 0444, show_bluetooth, NULL);
+static DEVICE_ATTR(wlan, 0444, show_wlan, NULL);
+
+static struct attribute *msipf_attributes[] = {
+       &dev_attr_lcd_level.attr,
+       &dev_attr_auto_brightness.attr,
+       &dev_attr_bluetooth.attr,
+       &dev_attr_wlan.attr,
+       NULL
+};
+
+static struct attribute_group msipf_attribute_group = {
+       .attrs = msipf_attributes
+};
+
+static struct platform_driver msipf_driver = {
+       .driver = {
+               .name = "msi-laptop-pf",
+               .owner = THIS_MODULE,
+       }
+};
+
+static struct platform_device *msipf_device;
+
+/* Initialization */
+
+static struct dmi_system_id __initdata msi_dmi_table[] = {
+       {
+               .ident = "MSI S270",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "MICRO-STAR INT'L CO.,LTD"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "MS-1013"),
+               }
+       },
+       {
+               .ident = "Medion MD96100",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "NOTEBOOK"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "SAM2000"),
+               }
+       },
+       { }
+};
+
+
+static int __init msi_init(void)
+{
+       int ret;
+
+       if (acpi_disabled)
+               return -ENODEV;
+
+       if (!force && !dmi_check_system(msi_dmi_table))
+               return -ENODEV;
+
+       if (auto_brightness < 0 || auto_brightness > 2)
+               return -EINVAL;
+
+       /* Register backlight stuff */
+
+       msibl_device = backlight_device_register("msi-laptop-bl", NULL, &msibl_props);
+       if (IS_ERR(msibl_device))
+               return PTR_ERR(msibl_device);
+
+       ret = platform_driver_register(&msipf_driver);
+       if (ret)
+               goto fail_backlight;
+
+       /* Register platform stuff */
+
+       msipf_device = platform_device_alloc("msi-laptop-pf", -1);
+       if (!msipf_device) {
+               ret = -ENOMEM;
+               goto fail_platform_driver;
+       }
+
+       ret = platform_device_add(msipf_device);
+       if (ret)
+               goto fail_platform_device1;
+
+       ret = sysfs_create_group(&msipf_device->dev.kobj, &msipf_attribute_group);
+       if (ret)
+               goto fail_platform_device2;
+
+       /* Disable automatic brightness control by default because
+        * this module was probably loaded to do brightness control in
+        * software. */
+
+       if (auto_brightness != 2)
+               set_auto_brightness(auto_brightness);
+
+       printk(KERN_INFO "msi-laptop: driver "MSI_DRIVER_VERSION" successfully loaded.\n");
+
+       return 0;
+
+fail_platform_device2:
+
+       platform_device_del(msipf_device);
+
+fail_platform_device1:
+
+       platform_device_put(msipf_device);
+
+fail_platform_driver:
+
+       platform_driver_unregister(&msipf_driver);
+
+fail_backlight:
+
+       backlight_device_unregister(msibl_device);
+
+       return ret;
+}
+
+static void __exit msi_cleanup(void)
+{
+
+       sysfs_remove_group(&msipf_device->dev.kobj, &msipf_attribute_group);
+       platform_device_unregister(msipf_device);
+       platform_driver_unregister(&msipf_driver);
+       backlight_device_unregister(msibl_device);
+
+       /* Enable automatic brightness control again */
+       if (auto_brightness != 2)
+               set_auto_brightness(1);
+
+       printk(KERN_INFO "msi-laptop: driver unloaded.\n");
+}
+
+module_init(msi_init);
+module_exit(msi_cleanup);
+
+MODULE_AUTHOR("Lennart Poettering");
+MODULE_DESCRIPTION("MSI Laptop Support");
+MODULE_VERSION(MSI_DRIVER_VERSION);
+MODULE_LICENSE("GPL");
index a7ed30446185b31f90e959fc05aa888b551d2384..1ba8754e93837e417fb88155aeb0bcd968ca9e79 100644 (file)
@@ -48,7 +48,7 @@ static void tifm_7xx1_remove_media(void *adapter)
                        printk(KERN_INFO DRIVER_NAME
                               ": demand removing card from socket %d\n", cnt);
                        sock = fm->sockets[cnt];
-                       fm->sockets[cnt] = 0;
+                       fm->sockets[cnt] = NULL;
                        fm->remove_mask &= ~(1 << cnt);
 
                        writel(0x0e00, sock->addr + SOCK_CONTROL);
@@ -67,7 +67,7 @@ static void tifm_7xx1_remove_media(void *adapter)
        class_device_put(&fm->cdev);
 }
 
-static irqreturn_t tifm_7xx1_isr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t tifm_7xx1_isr(int irq, void *dev_id)
 {
        struct tifm_adapter *fm = dev_id;
        unsigned int irq_status;
@@ -118,7 +118,7 @@ static irqreturn_t tifm_7xx1_isr(int irq, void *dev_id, struct pt_regs *regs)
        return IRQ_HANDLED;
 }
 
-static tifm_media_id tifm_7xx1_toggle_sock_power(char *sock_addr, int is_x2)
+static tifm_media_id tifm_7xx1_toggle_sock_power(char __iomem *sock_addr, int is_x2)
 {
        unsigned int s_state;
        int cnt;
@@ -163,7 +163,8 @@ static tifm_media_id tifm_7xx1_toggle_sock_power(char *sock_addr, int is_x2)
        return (readl(sock_addr + SOCK_PRESENT_STATE) >> 4) & 7;
 }
 
-inline static char *tifm_7xx1_sock_addr(char *base_addr, unsigned int sock_num)
+inline static char __iomem *
+tifm_7xx1_sock_addr(char __iomem *base_addr, unsigned int sock_num)
 {
        return base_addr + ((sock_num + 1) << 10);
 }
@@ -176,7 +177,7 @@ static void tifm_7xx1_insert_media(void *adapter)
        char *card_name = "xx";
        int cnt, ok_to_register;
        unsigned int insert_mask;
-       struct tifm_dev *new_sock = 0;
+       struct tifm_dev *new_sock = NULL;
 
        if (!class_device_get(&fm->cdev))
                return;
@@ -230,7 +231,7 @@ static void tifm_7xx1_insert_media(void *adapter)
                                if (!ok_to_register ||
                                            device_register(&new_sock->dev)) {
                                        spin_lock_irqsave(&fm->lock, flags);
-                                       fm->sockets[cnt] = 0;
+                                       fm->sockets[cnt] = NULL;
                                        spin_unlock_irqrestore(&fm->lock,
                                                                flags);
                                        tifm_free_device(&new_sock->dev);
@@ -390,7 +391,7 @@ static void tifm_7xx1_remove(struct pci_dev *dev)
 
        tifm_remove_adapter(fm);
 
-       pci_set_drvdata(dev, 0);
+       pci_set_drvdata(dev, NULL);
 
        iounmap(fm->addr);
        pci_intx(dev, 0);
index cca5f85224695aaffd8df9717ca89554ea66ef03..ee326136d03bf409d5604229255a9a9591396792 100644 (file)
@@ -157,7 +157,7 @@ struct tifm_dev *tifm_alloc_device(struct tifm_adapter *fm, unsigned int id)
                dev->wq = create_singlethread_workqueue(dev->wq_name);
                if (!dev->wq) {
                        kfree(dev);
-                       return 0;
+                       return NULL;
                }
                dev->dev.parent = fm->dev;
                dev->dev.bus = &tifm_bus_type;
index cb142a66098cf1d30f520207e295d13c5f7c6bdf..494b23fb0a01930503c35e6e42336f65f06f7234 100644 (file)
@@ -661,7 +661,7 @@ static void at91_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 /*
  * Handle an interrupt
  */
-static irqreturn_t at91_mci_irq(int irq, void *devid, struct pt_regs *regs)
+static irqreturn_t at91_mci_irq(int irq, void *devid)
 {
        struct at91mci_host *host = devid;
        int completed = 0;
@@ -754,7 +754,7 @@ static irqreturn_t at91_mci_irq(int irq, void *devid, struct pt_regs *regs)
        return IRQ_HANDLED;
 }
 
-static irqreturn_t at91_mmc_det_irq(int irq, void *_host, struct pt_regs *regs)
+static irqreturn_t at91_mmc_det_irq(int irq, void *_host)
 {
        struct at91mci_host *host = _host;
        int present = !at91_get_gpio_value(irq);
index 61268da13957fe7210edbc30e4a9af989b5fbd08..53ffcbb14a97cf14da80d8de359da8516f63062a 100644 (file)
@@ -750,7 +750,7 @@ static void au1xmmc_dma_callback(int irq, void *dev_id)
 #define STATUS_DATA_IN  (SD_STATUS_NE)
 #define STATUS_DATA_OUT (SD_STATUS_TH)
 
-static irqreturn_t au1xmmc_irq(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t au1xmmc_irq(int irq, void *dev_id)
 {
 
        u32 status;
index 1b79dd271aae37ce9e9d8c8d59b98683ca4fb543..659d4a822cc5d6bf8852516d428b9394e1eff27a 100644 (file)
@@ -635,7 +635,7 @@ static int imxmci_cpu_driven_data(struct imxmci_host *host, unsigned int *pstat)
        return trans_done;
 }
 
-static void imxmci_dma_irq(int dma, void *devid, struct pt_regs *regs)
+static void imxmci_dma_irq(int dma, void *devid)
 {
        struct imxmci_host *host = devid;
        uint32_t stat = MMC_STATUS;
@@ -646,7 +646,7 @@ static void imxmci_dma_irq(int dma, void *devid, struct pt_regs *regs)
        tasklet_schedule(&host->tasklet);
 }
 
-static irqreturn_t imxmci_irq(int irq, void *devid, struct pt_regs *regs)
+static irqreturn_t imxmci_irq(int irq, void *devid)
 {
        struct imxmci_host *host = devid;
        uint32_t stat = MMC_STATUS;
index c1293f1bda870337e38f03d34848ff6c2fce3a5e..f9027c8db79226250a0e0fced80633be29d16cba 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/kdev_t.h>
 #include <linux/blkdev.h>
 #include <linux/mutex.h>
+#include <linux/scatterlist.h>
 
 #include <linux/mmc/card.h>
 #include <linux/mmc/host.h>
@@ -154,6 +155,71 @@ static int mmc_blk_prep_rq(struct mmc_queue *mq, struct request *req)
        return stat;
 }
 
+static u32 mmc_sd_num_wr_blocks(struct mmc_card *card)
+{
+       int err;
+       u32 blocks;
+
+       struct mmc_request mrq;
+       struct mmc_command cmd;
+       struct mmc_data data;
+       unsigned int timeout_us;
+
+       struct scatterlist sg;
+
+       memset(&cmd, 0, sizeof(struct mmc_command));
+
+       cmd.opcode = MMC_APP_CMD;
+       cmd.arg = card->rca << 16;
+       cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
+
+       err = mmc_wait_for_cmd(card->host, &cmd, 0);
+       if ((err != MMC_ERR_NONE) || !(cmd.resp[0] & R1_APP_CMD))
+               return (u32)-1;
+
+       memset(&cmd, 0, sizeof(struct mmc_command));
+
+       cmd.opcode = SD_APP_SEND_NUM_WR_BLKS;
+       cmd.arg = 0;
+       cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
+
+       memset(&data, 0, sizeof(struct mmc_data));
+
+       data.timeout_ns = card->csd.tacc_ns * 100;
+       data.timeout_clks = card->csd.tacc_clks * 100;
+
+       timeout_us = data.timeout_ns / 1000;
+       timeout_us += data.timeout_clks * 1000 /
+               (card->host->ios.clock / 1000);
+
+       if (timeout_us > 100000) {
+               data.timeout_ns = 100000000;
+               data.timeout_clks = 0;
+       }
+
+       data.blksz = 4;
+       data.blocks = 1;
+       data.flags = MMC_DATA_READ;
+       data.sg = &sg;
+       data.sg_len = 1;
+
+       memset(&mrq, 0, sizeof(struct mmc_request));
+
+       mrq.cmd = &cmd;
+       mrq.data = &data;
+
+       sg_init_one(&sg, &blocks, 4);
+
+       mmc_wait_for_req(card->host, &mrq);
+
+       if (cmd.error != MMC_ERR_NONE || data.error != MMC_ERR_NONE)
+               return (u32)-1;
+
+       blocks = ntohl(blocks);
+
+       return blocks;
+}
+
 static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
 {
        struct mmc_blk_data *md = mq->data;
@@ -184,10 +250,13 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
 
                /*
                 * If the host doesn't support multiple block writes, force
-                * block writes to single block.
+                * block writes to single block. SD cards are excepted from
+                * this rule as they support querying the number of
+                * successfully written sectors.
                 */
                if (rq_data_dir(req) != READ &&
-                   !(card->host->caps & MMC_CAP_MULTIWRITE))
+                   !(card->host->caps & MMC_CAP_MULTIWRITE) &&
+                   !mmc_card_sd(card))
                        brq.data.blocks = 1;
 
                if (brq.data.blocks > 1) {
@@ -276,24 +345,41 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
        return 1;
 
  cmd_err:
-       mmc_card_release_host(card);
-
        ret = 1;
 
-       /*
-        * For writes and where the host claims to support proper
-        * error reporting, we first ok the successful blocks.
+       /*
+        * If this is an SD card and we're writing, we can first
+        * mark the known good sectors as ok.
+        *
+        * If the card is not SD, we can still ok written sectors
+        * if the controller can do proper error reporting.
         *
         * For reads we just fail the entire chunk as that should
         * be safe in all cases.
         */
-       if (rq_data_dir(req) != READ &&
-           (card->host->caps & MMC_CAP_MULTIWRITE)) {
+       if (rq_data_dir(req) != READ && mmc_card_sd(card)) {
+               u32 blocks;
+               unsigned int bytes;
+
+               blocks = mmc_sd_num_wr_blocks(card);
+               if (blocks != (u32)-1) {
+                       if (card->csd.write_partial)
+                               bytes = blocks << md->block_bits;
+                       else
+                               bytes = blocks << 9;
+                       spin_lock_irq(&md->lock);
+                       ret = end_that_request_chunk(req, 1, bytes);
+                       spin_unlock_irq(&md->lock);
+               }
+       } else if (rq_data_dir(req) != READ &&
+                  (card->host->caps & MMC_CAP_MULTIWRITE)) {
                spin_lock_irq(&md->lock);
                ret = end_that_request_chunk(req, 1, brq.data.bytes_xfered);
                spin_unlock_irq(&md->lock);
        }
 
+       mmc_card_release_host(card);
+
        spin_lock_irq(&md->lock);
        while (ret) {
                ret = end_that_request_chunk(req, 0,
index 2b5a0cc9ea56392efc4a82e040ab67fe66ce1617..828503c4ee62b509763a0dd0f722de70bfbad727 100644 (file)
@@ -261,7 +261,7 @@ static int mmci_pio_write(struct mmci_host *host, char *buffer, unsigned int rem
 /*
  * PIO data transfer IRQ handler.
  */
-static irqreturn_t mmci_pio_irq(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t mmci_pio_irq(int irq, void *dev_id)
 {
        struct mmci_host *host = dev_id;
        void __iomem *base = host->base;
@@ -347,7 +347,7 @@ static irqreturn_t mmci_pio_irq(int irq, void *dev_id, struct pt_regs *regs)
 /*
  * Handle completion of command and data transfers.
  */
-static irqreturn_t mmci_irq(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t mmci_irq(int irq, void *dev_id)
 {
        struct mmci_host *host = dev_id;
        u32 status;
index 52c9e52e6b781126ece1830f84e329293365ed1d..762fa28958918fbd21770a574f035a725bb14bd5 100644 (file)
@@ -377,7 +377,7 @@ static inline void mmc_omap_report_irq(u16 status)
                }
 }
 
-static irqreturn_t mmc_omap_irq(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t mmc_omap_irq(int irq, void *dev_id)
 {
        struct mmc_omap_host * host = (struct mmc_omap_host *)dev_id;
        u16 status;
@@ -514,7 +514,7 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id, struct pt_regs *regs)
        return IRQ_HANDLED;
 }
 
-static irqreturn_t mmc_omap_switch_irq(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t mmc_omap_switch_irq(int irq, void *dev_id)
 {
        struct mmc_omap_host *host = (struct mmc_omap_host *) dev_id;
 
index ef350908478c75217ff2474dca8824cdb9cd99e9..a526698b8c91b41b701e0dee517adf5323f79cb3 100644 (file)
@@ -299,7 +299,7 @@ static int pxamci_data_done(struct pxamci_host *host, unsigned int stat)
        return 1;
 }
 
-static irqreturn_t pxamci_irq(int irq, void *devid, struct pt_regs *regs)
+static irqreturn_t pxamci_irq(int irq, void *devid)
 {
        struct pxamci_host *host = devid;
        unsigned int ireg;
@@ -399,13 +399,13 @@ static struct mmc_host_ops pxamci_ops = {
        .set_ios        = pxamci_set_ios,
 };
 
-static void pxamci_dma_irq(int dma, void *devid, struct pt_regs *regs)
+static void pxamci_dma_irq(int dma, void *devid)
 {
        printk(KERN_ERR "DMA%d: IRQ???\n", dma);
        DCSR(dma) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR;
 }
 
-static irqreturn_t pxamci_detect_irq(int irq, void *devid, struct pt_regs *regs)
+static irqreturn_t pxamci_detect_irq(int irq, void *devid)
 {
        struct pxamci_host *host = mmc_priv(devid);
 
index 20711acb01201e67828aa8edaea076c3ab70cf58..9a7d39b7cdbf43ae3b24df6eed03b8e4c511148b 100644 (file)
@@ -985,7 +985,7 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask)
        }
 }
 
-static irqreturn_t sdhci_irq(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t sdhci_irq(int irq, void *dev_id)
 {
        irqreturn_t result;
        struct sdhci_host* host = dev_id;
@@ -1329,7 +1329,7 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot)
        tasklet_init(&host->finish_tasklet,
                sdhci_tasklet_finish, (unsigned long)host);
 
-       setup_timer(&host->timer, sdhci_timeout_timer, (long)host);
+       setup_timer(&host->timer, sdhci_timeout_timer, (unsigned long)host);
 
        ret = request_irq(host->irq, sdhci_irq, IRQF_SHARED,
                host->slot_descr, host);
index 6d23dc08d169efff2cbf0fb759e025d548878c34..2bacff60913dc293e291fc7088004e9c52221d18 100644 (file)
@@ -501,13 +501,13 @@ static void tifm_sd_end_cmd(void *data)
        struct tifm_dev *sock = host->dev;
        struct mmc_host *mmc = tifm_get_drvdata(sock);
        struct mmc_request *mrq;
-       struct mmc_data *r_data = 0;
+       struct mmc_data *r_data = NULL;
        unsigned long flags;
 
        spin_lock_irqsave(&sock->lock, flags);
 
        mrq = host->req;
-       host->req = 0;
+       host->req = NULL;
        host->state = IDLE;
 
        if (!mrq) {
@@ -546,7 +546,7 @@ static void tifm_sd_request_nodma(struct mmc_host *mmc, struct mmc_request *mrq)
        struct tifm_dev *sock = host->dev;
        unsigned long flags;
        struct mmc_data *r_data = mrq->cmd->data;
-       char *t_buffer = 0;
+       char *t_buffer = NULL;
 
        if (r_data) {
                t_buffer = kmap(r_data->sg->page);
@@ -613,13 +613,13 @@ static void tifm_sd_end_cmd_nodma(void *data)
        struct tifm_dev *sock = host->dev;
        struct mmc_host *mmc = tifm_get_drvdata(sock);
        struct mmc_request *mrq;
-       struct mmc_data *r_data = 0;
+       struct mmc_data *r_data = NULL;
        unsigned long flags;
 
        spin_lock_irqsave(&sock->lock, flags);
 
        mrq = host->req;
-       host->req = 0;
+       host->req = NULL;
        host->state = IDLE;
 
        if (!mrq) {
@@ -644,7 +644,7 @@ static void tifm_sd_end_cmd_nodma(void *data)
                        r_data->bytes_xfered += r_data->blksz -
                                readl(sock->addr + SOCK_MMCSD_BLOCK_LEN) + 1;
                }
-               host->buffer = 0;
+               host->buffer = NULL;
                host->buffer_pos = 0;
                host->buffer_size = 0;
        }
@@ -895,7 +895,7 @@ static void tifm_sd_remove(struct tifm_dev *sock)
                sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR);
        writel(0, sock->addr + SOCK_DMA_FIFO_INT_ENABLE_SET);
 
-       tifm_set_drvdata(sock, 0);
+       tifm_set_drvdata(sock, NULL);
        mmc_free_host(mmc);
 }
 
index 88c6f0b129f5eea6c6ca4f99ac4932a594b46894..ced309b37a8f94900a3567b1aa3a826b07f06b2f 100644 (file)
@@ -1256,7 +1256,7 @@ end:
  * Interrupt handling
  */
 
-static irqreturn_t wbsd_irq(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t wbsd_irq(int irq, void *dev_id)
 {
        struct wbsd_host *host = dev_id;
        int isr;
index bc7cc71788bc27be9ba18a778b3ee35426f76427..d1717763f719778512e1229a42336773d00305d1 100644 (file)
@@ -62,7 +62,7 @@ static int physmap_flash_remove(struct platform_device *dev)
        }
 
        if (info->map.virt != NULL)
-               iounmap((void *)info->map.virt);
+               iounmap(info->map.virt);
 
        if (info->res != NULL) {
                release_resource(info->res);
index e0a1d386e58198040250988b3f9b54779128ff36..94924d52a9b96d10121ac34f26d3447702eb0ae7 100644 (file)
@@ -249,7 +249,7 @@ static int __init cs553x_init_one(int cs, int mmio, unsigned long adr)
        goto out;
 
 out_ior:
-       iounmap((void *)this->IO_ADDR_R);
+       iounmap(this->IO_ADDR_R);
 out_mtd:
        kfree(new_mtd);
 out:
index 1b82bccd8c713976926ad5bf2649adfea039165c..11d170afa9c398de778eb643a84ae6db843f700c 100644 (file)
@@ -496,7 +496,6 @@ static int el_start_xmit(struct sk_buff *skb, struct net_device *dev)
  * el_interrupt:
  * @irq: Interrupt number
  * @dev_id: The 3c501 that burped
- * @regs: Register data (surplus to our requirements)
  *
  * Handle the ether interface interrupts. The 3c501 needs a lot more
  * hand holding than most cards. In particular we get a transmit interrupt
@@ -515,7 +514,7 @@ static int el_start_xmit(struct sk_buff *skb, struct net_device *dev)
  * TCP window.
  */
 
-static irqreturn_t el_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t el_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
        struct net_local *lp;
index 39d33247475012a87204ebcd353e66685a40bc56..c56a2c62f7deaf094cf1b7e65dcb6bb8ee719bf8 100644 (file)
@@ -7,7 +7,7 @@ static int  el1_probe1(struct net_device *dev, int ioaddr);
 static int  el_open(struct net_device *dev);
 static void el_timeout(struct net_device *dev);
 static int  el_start_xmit(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t el_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t el_interrupt(int irq, void *dev_id);
 static void el_receive(struct net_device *dev);
 static void el_reset(struct net_device *dev);
 static int  el1_close(struct net_device *dev);
index ab8230a68beaeb092228e131ce9aa278689ec16e..458cb9cbe9157dcda0d458b920e1e6622446bf1f 100644 (file)
@@ -649,7 +649,7 @@ static void receive_packet(struct net_device *dev, int len)
  *
  ******************************************************/
 
-static irqreturn_t elp_interrupt(int irq, void *dev_id, struct pt_regs *reg_ptr)
+static irqreturn_t elp_interrupt(int irq, void *dev_id)
 {
        int len;
        int dlen;
index 8205a535c5b74e89ea2e48da9db9376c88ef5de4..aa43563610ae552df0cc25ea6051d9f1d44faf71 100644 (file)
@@ -286,7 +286,7 @@ static unsigned short init_words[] = {
 static int     el16_probe1(struct net_device *dev, int ioaddr);
 static int     el16_open(struct net_device *dev);
 static int     el16_send_packet(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t el16_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t el16_interrupt(int irq, void *dev_id);
 static void el16_rx(struct net_device *dev);
 static int     el16_close(struct net_device *dev);
 static struct net_device_stats *el16_get_stats(struct net_device *dev);
@@ -543,7 +543,7 @@ static int el16_send_packet (struct sk_buff *skb, struct net_device *dev)
 
 /*     The typical workload of the driver:
        Handle the network interface interrupts. */
-static irqreturn_t el16_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t el16_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
        struct net_local *lp;
index b936373ab2a5f1e16754f7301b2cb0890fb9646d..f791bf026e5191711d46308facecdb0d89b9e009 100644 (file)
@@ -191,7 +191,7 @@ static ushort id_read_eeprom(int index);
 static ushort read_eeprom(int ioaddr, int index);
 static int el3_open(struct net_device *dev);
 static int el3_start_xmit(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t el3_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t el3_interrupt(int irq, void *dev_id);
 static void update_stats(struct net_device *dev);
 static struct net_device_stats *el3_get_stats(struct net_device *dev);
 static int el3_rx(struct net_device *dev);
@@ -910,18 +910,13 @@ el3_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 /* The EL3 interrupt handler. */
 static irqreturn_t
-el3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+el3_interrupt(int irq, void *dev_id)
 {
-       struct net_device *dev = (struct net_device *)dev_id;
+       struct net_device *dev = dev_id;
        struct el3_private *lp;
        int ioaddr, status;
        int i = max_interrupt_work;
 
-       if (dev == NULL) {
-               printk ("el3_interrupt(): irq %d for unknown device.\n", irq);
-               return IRQ_NONE;
-       }
-
        lp = netdev_priv(dev);
        spin_lock(&lp->lock);
 
@@ -1006,7 +1001,7 @@ el3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 static void el3_poll_controller(struct net_device *dev)
 {
        disable_irq(dev->irq);
-       el3_interrupt(dev->irq, dev, NULL);
+       el3_interrupt(dev->irq, dev);
        enable_irq(dev->irq);
 }
 #endif
index 91f2232e6050fbfe2f4e8caff253c3b99ed37b43..c307ce66145cda0c91174bffc3e00d7ae0f7a0a2 100644 (file)
@@ -373,8 +373,7 @@ static int corkscrew_start_xmit(struct sk_buff *skb,
 static int corkscrew_rx(struct net_device *dev);
 static void corkscrew_timeout(struct net_device *dev);
 static int boomerang_rx(struct net_device *dev);
-static irqreturn_t corkscrew_interrupt(int irq, void *dev_id,
-                                   struct pt_regs *regs);
+static irqreturn_t corkscrew_interrupt(int irq, void *dev_id);
 static int corkscrew_close(struct net_device *dev);
 static void update_stats(int addr, struct net_device *dev);
 static struct net_device_stats *corkscrew_get_stats(struct net_device *dev);
@@ -1116,8 +1115,7 @@ static int corkscrew_start_xmit(struct sk_buff *skb,
 /* The interrupt handler does all of the Rx thread work and cleans up
    after the Tx thread. */
 
-static irqreturn_t corkscrew_interrupt(int irq, void *dev_id,
-                                   struct pt_regs *regs)
+static irqreturn_t corkscrew_interrupt(int irq, void *dev_id)
 {
        /* Use the now-standard shared IRQ implementation. */
        struct net_device *dev = dev_id;
index cf8a0bc3bf34c82be6dffcf9f46e0639a91c8f57..91849469b4f49f0118f935b33c4caeb0c1afb683 100644 (file)
@@ -180,7 +180,7 @@ sizeof(nop_cmd) = 8;
        dev->name,__LINE__); \
       elmc_id_reset586(); } } }
 
-static irqreturn_t elmc_interrupt(int irq, void *dev_id, struct pt_regs *reg_ptr);
+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 int elmc_send_packet(struct sk_buff *, struct net_device *);
@@ -900,16 +900,13 @@ static void *alloc_rfa(struct net_device *dev, void *ptr)
  */
 
 static irqreturn_t
-elmc_interrupt(int irq, void *dev_id, struct pt_regs *reg_ptr)
+elmc_interrupt(int irq, void *dev_id)
 {
-       struct net_device *dev = (struct net_device *) dev_id;
+       struct net_device *dev = dev_id;
        unsigned short stat;
        struct priv *p;
 
-       if (dev == NULL) {
-               printk(KERN_ERR "elmc-interrupt: irq %d for unknown device.\n", (int) -(((struct pt_regs *) reg_ptr)->orig_eax + 2));
-               return IRQ_NONE;
-       } else if (!netif_running(dev)) {
+       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
index 625e57dc3b4a91aa7bd95ed8b9e999c5e77cccc5..f4aca5386add1c94238d23205e408ef19e8b12e1 100644 (file)
@@ -217,7 +217,7 @@ static int      mc32_command(struct net_device *dev, u16 cmd, void *data, int le
 static int     mc32_open(struct net_device *dev);
 static void    mc32_timeout(struct net_device *dev);
 static int     mc32_send_packet(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t mc32_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+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);
@@ -1316,7 +1316,7 @@ static void mc32_tx_ring(struct net_device *dev)
  *
  */
 
-static irqreturn_t mc32_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+static irqreturn_t mc32_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
        struct mc32_local *lp;
@@ -1324,11 +1324,6 @@ static irqreturn_t mc32_interrupt(int irq, void *dev_id, struct pt_regs * regs)
        int rx_event = 0;
        int tx_event = 0;
 
-       if (dev == NULL) {
-               printk(KERN_WARNING "%s: irq %d for unknown device.\n", cardname, irq);
-               return IRQ_NONE;
-       }
-
        ioaddr = dev->base_addr;
        lp = netdev_priv(dev);
 
index df42e28cc80f68808164a932c2ab8b8fda764c30..80bdcf8462343434fae03cb3091dade3646854ee 100644 (file)
@@ -717,8 +717,8 @@ static int vortex_start_xmit(struct sk_buff *skb, struct net_device *dev);
 static int boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev);
 static int vortex_rx(struct net_device *dev);
 static int boomerang_rx(struct net_device *dev);
-static irqreturn_t vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-static irqreturn_t boomerang_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t vortex_interrupt(int irq, void *dev_id);
+static irqreturn_t boomerang_interrupt(int irq, void *dev_id);
 static int vortex_close(struct net_device *dev);
 static void dump_tx_ring(struct net_device *dev);
 static void update_stats(void __iomem *ioaddr, struct net_device *dev);
@@ -794,7 +794,7 @@ static void poll_vortex(struct net_device *dev)
        unsigned long flags;
        local_save_flags(flags);
        local_irq_disable();
-       (vp->full_bus_master_rx ? boomerang_interrupt:vortex_interrupt)(dev->irq,dev,NULL);
+       (vp->full_bus_master_rx ? boomerang_interrupt:vortex_interrupt)(dev->irq,dev);
        local_irq_restore(flags);
 }
 #endif
@@ -1849,9 +1849,9 @@ static void vortex_tx_timeout(struct net_device *dev)
                        unsigned long flags;
                        local_irq_save(flags);
                        if (vp->full_bus_master_tx)
-                               boomerang_interrupt(dev->irq, dev, NULL);
+                               boomerang_interrupt(dev->irq, dev);
                        else
-                               vortex_interrupt(dev->irq, dev, NULL);
+                               vortex_interrupt(dev->irq, dev);
                        local_irq_restore(flags);
                }
        }
@@ -2149,7 +2149,7 @@ boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev)
  */
 
 static irqreturn_t
-vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+vortex_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
        struct vortex_private *vp = netdev_priv(dev);
@@ -2254,7 +2254,7 @@ handler_exit:
  */
 
 static irqreturn_t
-boomerang_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+boomerang_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
        struct vortex_private *vp = netdev_priv(dev);
index db7b19a5cd5987983fab53eb1b872d56a2662dc2..7733697f7776e9e689186b58dc467d08a4d6fe6f 100644 (file)
@@ -438,7 +438,7 @@ static int lance_tx (struct net_device *dev)
 }
 
 static irqreturn_t
-lance_interrupt (int irq, void *dev_id, struct pt_regs *regs)
+lance_interrupt (int irq, void *dev_id)
 {
         struct net_device *dev = (struct net_device *)dev_id;
         struct lance_private *lp = netdev_priv(dev);
@@ -674,7 +674,7 @@ void lance_poll(struct net_device *dev)
        WRITERAP(lp, LE_CSR0);
        WRITERDP(lp, LE_C0_STRT);
        spin_unlock (&lp->devlock);
-       lance_interrupt(dev->irq, dev, NULL);
+       lance_interrupt(dev->irq, dev);
 }
 #endif
 
index 5a4990ae3730575bf3d19167e95a727f7616126b..458dd9f830c4d5f79e3ddff8348596009c44e857 100644 (file)
@@ -631,8 +631,7 @@ rx_next:
        return 1;               /* not done */
 }
 
-static irqreturn_t
-cp_interrupt (int irq, void *dev_instance, struct pt_regs *regs)
+static irqreturn_t cp_interrupt (int irq, void *dev_instance)
 {
        struct net_device *dev = dev_instance;
        struct cp_private *cp;
@@ -696,7 +695,7 @@ cp_interrupt (int irq, void *dev_instance, struct pt_regs *regs)
 static void cp_poll_controller(struct net_device *dev)
 {
        disable_irq(dev->irq);
-       cp_interrupt(dev->irq, dev, NULL);
+       cp_interrupt(dev->irq, dev);
        enable_irq(dev->irq);
 }
 #endif
index dbc5c0b1b96c60676b5102812cbc89d50a5b35b2..d02ed51abfccab65e2397cc063e4eb53a169bcee 100644 (file)
@@ -629,8 +629,7 @@ static int rtl8139_poll(struct net_device *dev, int *budget);
 #ifdef CONFIG_NET_POLL_CONTROLLER
 static void rtl8139_poll_controller(struct net_device *dev);
 #endif
-static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance,
-                              struct pt_regs *regs);
+static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance);
 static int rtl8139_close (struct net_device *dev);
 static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd);
 static struct net_device_stats *rtl8139_get_stats (struct net_device *dev);
@@ -2146,8 +2145,7 @@ static int rtl8139_poll(struct net_device *dev, int *budget)
 
 /* The interrupt handler does all of the Rx thread work and cleans up
    after the Tx thread. */
-static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance,
-                              struct pt_regs *regs)
+static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance)
 {
        struct net_device *dev = (struct net_device *) dev_instance;
        struct rtl8139_private *tp = netdev_priv(dev);
@@ -2219,7 +2217,7 @@ static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance,
 static void rtl8139_poll_controller(struct net_device *dev)
 {
        disable_irq(dev->irq);
-       rtl8139_interrupt(dev->irq, dev, NULL);
+       rtl8139_interrupt(dev->irq, dev);
        enable_irq(dev->irq);
 }
 #endif
index c9e4dca9d4108e1b65cf6625e17ce88695e53395..8236f26ffd46b29f9c34b99708779610e4e42333 100644 (file)
@@ -357,7 +357,7 @@ static char init_setup[] =
 
 static int i596_open(struct net_device *dev);
 static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t i596_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t i596_interrupt(int irq, void *dev_id);
 static int i596_close(struct net_device *dev);
 static struct net_device_stats *i596_get_stats(struct net_device *dev);
 static void i596_add_cmd(struct net_device *dev, struct i596_cmd *cmd);
@@ -501,7 +501,7 @@ static void i596_display_data(struct net_device *dev)
 
 
 #if defined(ENABLE_MVME16x_NET) || defined(ENABLE_BVME6000_NET)
-static irqreturn_t i596_error(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t i596_error(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
 #ifdef ENABLE_MVME16x_NET
@@ -1283,7 +1283,7 @@ out:
        return ERR_PTR(err);
 }
 
-static irqreturn_t i596_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t i596_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
        struct i596_private *lp;
@@ -1294,7 +1294,7 @@ static irqreturn_t i596_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 #ifdef ENABLE_BVME6000_NET
        if (MACH_IS_BVME6000) {
                if (*(char *) BVME_LOCAL_IRQ_STAT & BVME_ETHERR) {
-                       i596_error(irq, dev_id, regs);
+                       i596_error(irq, dev_id);
                        return IRQ_HANDLED;
                }
        }
index 9d34056147ad5c4c026b74e58a59ffc99cb1ec62..3d1c599ac3cbeead34d4954181fd69f4abe3d611 100644 (file)
@@ -391,7 +391,6 @@ static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev)
  * ei_interrupt - handle the interrupts from an 8390
  * @irq: interrupt number
  * @dev_id: a pointer to the net_device
- * @regs: unused
  *
  * Handle the ether interface interrupts. We pull packets from
  * the 8390 via the card specific functions and fire them at the networking
@@ -400,21 +399,15 @@ static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev)
  * needed.
  */
 
-irqreturn_t ei_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+irqreturn_t ei_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
        long e8390_base;
        int interrupts, nr_serviced = 0;
        struct ei_device *ei_local;
 
-       if (dev == NULL)
-       {
-               printk ("net_interrupt(): irq %d for unknown device.\n", irq);
-               return IRQ_NONE;
-       }
-
        e8390_base = dev->base_addr;
-       ei_local = (struct ei_device *) netdev_priv(dev);
+       ei_local = netdev_priv(dev);
 
        /*
         *      Protect the irq test too.
@@ -506,7 +499,7 @@ irqreturn_t ei_interrupt(int irq, void *dev_id, struct pt_regs * regs)
 void ei_poll(struct net_device *dev)
 {
        disable_irq_lockdep(dev->irq);
-       ei_interrupt(dev->irq, dev, NULL);
+       ei_interrupt(dev->irq, dev);
        enable_irq_lockdep(dev->irq);
 }
 #endif
index ca4eb0ccf8cfe4f55b0084432db8744c47cd891d..f44f1220b3a557c886e287fb575ece44b5d78657 100644 (file)
@@ -35,7 +35,7 @@ extern void ei_poll(struct net_device *dev);
 extern void NS8390_init(struct net_device *dev, int startp);
 extern int ei_open(struct net_device *dev);
 extern int ei_close(struct net_device *dev);
-extern irqreturn_t ei_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+extern irqreturn_t ei_interrupt(int irq, void *dev_id);
 extern struct net_device *__alloc_ei_netdev(int size);
 static inline struct net_device *alloc_ei_netdev(void)
 {
index ab92cc794c64d85363b98d1bf3aa76585c68ccc8..e2ed24918a589fd7f0d0414597f8cc974a4d48fc 100644 (file)
@@ -2288,7 +2288,7 @@ config UGETH_TX_ON_DEMOND
 
 config UGETH_HAS_GIGA
        bool
-       depends on UCC_GETH && MPC836x
+       depends on UCC_GETH && PPC_MPC836x
 
 config MV643XX_ETH
        tristate "MV-643XX Ethernet support"
index 5f7258fea19d2ba5de2f423979d508d8b2898ca4..d76548e7535078d9715263a08e10f430a120196f 100644 (file)
@@ -425,8 +425,7 @@ static int lance_tx (struct net_device *dev)
        return 0;
 }
 
-static irqreturn_t
-lance_interrupt (int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t lance_interrupt (int irq, void *dev_id)
 {
        struct net_device *dev;
        struct lance_private *lp;
index 71a4f60f7325755f7bacd457b97c3352c7f7254b..33c6645455ae73f684a6cdfe33f8b0a1a6a6a5af 100644 (file)
@@ -2144,7 +2144,7 @@ static inline void ace_tx_int(struct net_device *dev,
 }
 
 
-static irqreturn_t ace_interrupt(int irq, void *dev_id, struct pt_regs *ptregs)
+static irqreturn_t ace_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = (struct net_device *)dev_id;
        struct ace_private *ap = netdev_priv(dev);
index efb14b9f4d90360b33dae401a567d316aa6906c8..8ca8534d70bf33c56adac5130bd284808ab1a938 100644 (file)
@@ -769,7 +769,7 @@ static int ace_init(struct net_device *dev);
 static void ace_load_std_rx_ring(struct ace_private *ap, int nr_bufs);
 static void ace_load_mini_rx_ring(struct ace_private *ap, int nr_bufs);
 static void ace_load_jumbo_rx_ring(struct ace_private *ap, int nr_bufs);
-static irqreturn_t ace_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t ace_interrupt(int irq, void *dev_id);
 static int ace_load_firmware(struct net_device *dev);
 static int ace_open(struct net_device *dev);
 static int ace_start_xmit(struct sk_buff *skb, struct net_device *dev);
index 28855a01ed7b2a5bb627b17f17078b9a4604bac8..ef65e5917c8fcf7014ca97f7b72b796233d9e330 100644 (file)
@@ -1257,7 +1257,7 @@ static int amd8111e_calc_coalesce(struct net_device *dev)
 /*
 This is device interrupt function. It handles transmit, receive,link change and hardware timer interrupts.
 */
-static irqreturn_t amd8111e_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t amd8111e_interrupt(int irq, void *dev_id)
 {
 
        struct net_device * dev = (struct net_device *) dev_id;
@@ -1336,7 +1336,7 @@ static void amd8111e_poll(struct net_device *dev)
        unsigned long flags;
        local_save_flags(flags);
        local_irq_disable();
-       amd8111e_interrupt(0, dev, NULL);
+       amd8111e_interrupt(0, dev);
        local_irq_restore(flags);
 }
 #endif
index 643b08cc740337862ae524e695ccf17a0f6425b7..9164d8cd670e4cb6e6054abb9add4cf3e30c38f7 100644 (file)
@@ -88,7 +88,7 @@ static void apne_block_input(struct net_device *dev, int count,
                                                                struct sk_buff *skb, int ring_offset);
 static void apne_block_output(struct net_device *dev, const int count,
                                                        const unsigned char *buf, const int start_page);
-static irqreturn_t apne_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t apne_interrupt(int irq, void *dev_id);
 
 static int init_pcmcia(void);
 
@@ -543,7 +543,7 @@ apne_block_output(struct net_device *dev, int count,
     return;
 }
 
-static irqreturn_t apne_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t apne_interrupt(int irq, void *dev_id)
 {
     unsigned char pcmcia_intreq;
 
@@ -559,7 +559,7 @@ static irqreturn_t apne_interrupt(int irq, void *dev_id, struct pt_regs *regs)
     if (ei_debug > 3)
         printk("pcmcia intreq = %x\n", pcmcia_intreq);
     pcmcia_disable_irq();                      /* to get rid of the sti() within ei_interrupt */
-    ei_interrupt(irq, dev_id, regs);
+    ei_interrupt(irq, dev_id);
     pcmcia_ack_int(pcmcia_get_intreq());
     pcmcia_enable_irq();
     return IRQ_HANDLED;
index ae7f828344d9effa0d2a60f0254c9db0738f27a0..cc1a27ed197fd93f0b360f0545e40610fb823557 100644 (file)
@@ -188,7 +188,7 @@ static void cops_reset (struct net_device *dev, int sleep);
 static void cops_load (struct net_device *dev);
 static int  cops_nodeid (struct net_device *dev, int nodeid);
 
-static irqreturn_t cops_interrupt (int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t cops_interrupt (int irq, void *dev_id);
 static void cops_poll (unsigned long ltdev);
 static void cops_timeout(struct net_device *dev);
 static void cops_rx (struct net_device *dev);
@@ -721,7 +721,7 @@ static void cops_poll(unsigned long ltdev)
  *      The typical workload of the driver:
  *      Handle the network interface interrupts.
  */
-static irqreturn_t cops_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+static irqreturn_t cops_interrupt(int irq, void *dev_id)
 {
         struct net_device *dev = dev_id;
         struct cops_local *lp;
index d5666c37cb0deb39768ff685c2234284716f8f6b..2ea44ce4981064ed0589918a9b1ded3a45a7d793 100644 (file)
@@ -790,7 +790,7 @@ static int sendup_buffer (struct net_device *dev)
 /* the handler for the board interrupt */
  
 static irqreturn_t
-ltpc_interrupt(int irq, void *dev_id, struct pt_regs *reg_ptr)
+ltpc_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
 
index 5a95005253fa1a104adb1b1321f147751f0c049e..4e91dab1f17f330ee4c5108e22c62e20f17c09d0 100644 (file)
@@ -752,7 +752,7 @@ static void arcnet_timeout(struct net_device *dev)
  * interrupts. Establish which device needs attention, and call the correct
  * chipset interrupt handler.
  */
-irqreturn_t arcnet_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t arcnet_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
        struct arcnet_local *lp;
index 3aef3c10d56ff1c2e3170fdbecd064cd5da17bee..9dfc09b181c1c7f42de6aaf02534bdc90a5cb71b 100644 (file)
@@ -120,7 +120,7 @@ static int ariadne_start_xmit(struct sk_buff *skb, struct net_device *dev);
 static void ariadne_tx_timeout(struct net_device *dev);
 static int ariadne_rx(struct net_device *dev);
 static void ariadne_reset(struct net_device *dev);
-static irqreturn_t ariadne_interrupt(int irq, void *data, struct pt_regs *fp);
+static irqreturn_t ariadne_interrupt(int irq, void *data);
 static int ariadne_close(struct net_device *dev);
 static struct net_device_stats *ariadne_get_stats(struct net_device *dev);
 #ifdef HAVE_MULTICAST
@@ -416,7 +416,7 @@ static inline void ariadne_reset(struct net_device *dev)
 }
 
 
-static irqreturn_t ariadne_interrupt(int irq, void *data, struct pt_regs *fp)
+static irqreturn_t ariadne_interrupt(int irq, void *data)
 {
     struct net_device *dev = (struct net_device *)data;
     volatile struct Am79C960 *lance = (struct Am79C960*)dev->base_addr;
index 09d5c3f26985a804e34b49e9ef6c6b0c84677b51..ddd12d44ff22dab8d7ab7b3ec44e323311af46a7 100644 (file)
@@ -38,7 +38,7 @@
 #include "am79c961a.h"
 
 static irqreturn_t
-am79c961_interrupt (int irq, void *dev_id, struct pt_regs *regs);
+am79c961_interrupt (int irq, void *dev_id);
 
 static unsigned int net_debug = NET_DEBUG;
 
@@ -596,7 +596,7 @@ am79c961_tx(struct net_device *dev, struct dev_priv *priv)
 }
 
 static irqreturn_t
-am79c961_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+am79c961_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = (struct net_device *)dev_id;
        struct dev_priv *priv = netdev_priv(dev);
index 3ecf2cc53a7ca2305f76b96ef754b2acb3505bce..b54b857e357e5318d7656b7b581ad5e1cd827111 100644 (file)
@@ -196,7 +196,7 @@ static void update_linkspeed(struct net_device *dev, int silent)
 /*
  * Handle interrupts from the PHY
  */
-static irqreturn_t at91ether_phy_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t at91ether_phy_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = (struct net_device *) dev_id;
        struct at91_private *lp = (struct at91_private *) dev->priv;
@@ -888,7 +888,7 @@ static void at91ether_rx(struct net_device *dev)
 /*
  * MAC interrupt handler
  */
-static irqreturn_t at91ether_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t at91ether_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = (struct net_device *) dev_id;
        struct at91_private *lp = (struct at91_private *) dev->priv;
index d231efa624d4ab50905da8f9aefb4f437a4a64b2..127561c782fd501d4cb1830489d3ebe61645113a 100644 (file)
@@ -435,7 +435,7 @@ static void ep93xx_tx_complete(struct net_device *dev)
                netif_wake_queue(dev);
 }
 
-static irqreturn_t ep93xx_irq(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t ep93xx_irq(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
        struct ep93xx_priv *ep = netdev_priv(dev);
index 312955d07b282f0b95e33ed631b365d4b40ddf69..f3478a30e7787ea7375db5af7c0c9d2aae8d6bf2 100644 (file)
@@ -68,7 +68,7 @@ static unsigned int net_debug = NET_DEBUG;
 
 static int ether1_open(struct net_device *dev);
 static int ether1_sendpacket(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t ether1_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t ether1_interrupt(int irq, void *dev_id);
 static int ether1_close(struct net_device *dev);
 static struct net_device_stats *ether1_getstats(struct net_device *dev);
 static void ether1_setmulticastlist(struct net_device *dev);
@@ -908,7 +908,7 @@ ether1_recv_done (struct net_device *dev)
 }
 
 static irqreturn_t
-ether1_interrupt (int irq, void *dev_id, struct pt_regs *regs)
+ether1_interrupt (int irq, void *dev_id)
 {
        struct net_device *dev = (struct net_device *)dev_id;
        int status;
index 081074180e62dc2f029146de075dc316dd4f642b..84686c8a5bc271aa706a985770c5e70708995043 100644 (file)
@@ -81,7 +81,7 @@ static int    ether3_rx(struct net_device *dev, unsigned int maxcnt);
 static void    ether3_tx(struct net_device *dev);
 static int     ether3_open (struct net_device *dev);
 static int     ether3_sendpacket (struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t ether3_interrupt (int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t ether3_interrupt (int irq, void *dev_id);
 static int     ether3_close (struct net_device *dev);
 static struct net_device_stats *ether3_getstats (struct net_device *dev);
 static void    ether3_setmulticastlist (struct net_device *dev);
@@ -568,7 +568,7 @@ ether3_sendpacket(struct sk_buff *skb, struct net_device *dev)
 }
 
 static irqreturn_t
-ether3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+ether3_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = (struct net_device *)dev_id;
        unsigned int status, handled = IRQ_NONE;
index 4aeca11f3ee28920ec94c8704dd3f7c6e3f8e578..8620a5b470f55fbd16bbb4156be98622388247db 100644 (file)
@@ -161,7 +161,7 @@ static int at1700_probe1(struct net_device *dev, int ioaddr);
 static int read_eeprom(long ioaddr, int location);
 static int net_open(struct net_device *dev);
 static int     net_send_packet(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t net_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t net_interrupt(int irq, void *dev_id);
 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);
@@ -648,8 +648,7 @@ static int net_send_packet (struct sk_buff *skb, struct net_device *dev)
 
 /* The typical workload of the driver:
    Handle the network interface interrupts. */
-static irqreturn_t
-net_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t net_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
        struct net_local *lp;
index 92b52138acadff67266436e43f5f05e7ca5cae0b..4e3bf6a1f22c8439d93d0dd53867404845c4a05a 100644 (file)
@@ -220,7 +220,7 @@ gsend:
 }
 
 static irqreturn_t
-bionet_intr(int irq, void *data, struct pt_regs *fp) {
+bionet_intr(int irq, void *data) {
        return IRQ_HANDLED;
 }
 
index a1026251b933662b40b69a057d70fe9b157e781d..3b543614928606cae76a4bcfc7a661723c1f6668 100644 (file)
@@ -163,7 +163,7 @@ static int pamsnet_close(struct net_device *dev);
 static struct net_device_stats *net_get_stats(struct net_device *dev);
 static void pamsnet_tick(unsigned long);
 
-static irqreturn_t pamsnet_intr(int irq, void *data, struct pt_regs *fp);
+static irqreturn_t pamsnet_intr(int irq, void *data);
 
 static DEFINE_TIMER(pamsnet_timer, pamsnet_tick, 0, 0);
 
@@ -494,7 +494,6 @@ static irqreturn_t
 pamsnet_intr(irq, data, fp)
        int irq;
        void *data;
-       struct pt_regs *fp;
 {
        return IRQ_HANDLED;
 }
index b6570ca6ada76e1a590772feeda9d7dc0e592a8e..d79489e462499bf1ecd9bf700171747caccd9a2e 100644 (file)
@@ -344,7 +344,7 @@ static unsigned long lance_probe1( struct net_device *dev, struct lance_addr
 static int lance_open( struct net_device *dev );
 static void lance_init_ring( struct net_device *dev );
 static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev );
-static irqreturn_t lance_interrupt( int irq, void *dev_id, struct pt_regs *fp );
+static irqreturn_t lance_interrupt( int irq, void *dev_id );
 static int lance_rx( struct net_device *dev );
 static int lance_close( struct net_device *dev );
 static struct net_device_stats *lance_get_stats( struct net_device *dev );
@@ -866,7 +866,7 @@ static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev )
 
 /* The LANCE interrupt handler. */
 
-static irqreturn_t lance_interrupt( int irq, void *dev_id, struct pt_regs *fp)
+static irqreturn_t lance_interrupt( int irq, void *dev_id )
 {
        struct net_device *dev = dev_id;
        struct lance_private *lp;
index f2c8e0d5497b3b789272954994928bbe5e48bbeb..2d306fcb7f3648bfb1d9b13598384db711d2dfe8 100644 (file)
@@ -203,7 +203,7 @@ static void hardware_init(struct net_device *dev);
 static void write_packet(long ioaddr, int length, unsigned char *packet, int pad, int mode);
 static void trigger_send(long ioaddr, int length);
 static int     atp_send_packet(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t atp_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t atp_interrupt(int irq, void *dev_id);
 static void net_rx(struct net_device *dev);
 static void read_block(long ioaddr, int length, unsigned char *buffer, int data_mode);
 static int net_close(struct net_device *dev);
@@ -596,20 +596,15 @@ static int atp_send_packet(struct sk_buff *skb, struct net_device *dev)
 
 /* The typical workload of the driver:
    Handle the network interface interrupts. */
-static irqreturn_t
-atp_interrupt(int irq, void *dev_instance, struct pt_regs * regs)
+static irqreturn_t atp_interrupt(int irq, void *dev_instance)
 {
-       struct net_device *dev = (struct net_device *)dev_instance;
+       struct net_device *dev = dev_instance;
        struct net_local *lp;
        long ioaddr;
        static int num_tx_since_rx;
        int boguscount = max_interrupt_work;
        int handled = 0;
 
-       if (dev == NULL) {
-               printk(KERN_ERR "ATP_interrupt(): irq %d for unknown device.\n", irq);
-               return IRQ_NONE;
-       }
        ioaddr = dev->base_addr;
        lp = netdev_priv(dev);
 
index ac33b1b9cf4a5ed4b189c62a68197a90c030ad44..4873dc610d22e9f772d6a0242b3c66dc200eeed4 100644 (file)
@@ -89,7 +89,7 @@ static int au1000_open(struct net_device *);
 static int au1000_close(struct net_device *);
 static int au1000_tx(struct sk_buff *, struct net_device *);
 static int au1000_rx(struct net_device *);
-static irqreturn_t au1000_interrupt(int, void *, struct pt_regs *);
+static irqreturn_t au1000_interrupt(int, void *);
 static void au1000_tx_timeout(struct net_device *);
 static void set_rx_mode(struct net_device *);
 static struct net_device_stats *au1000_get_stats(struct net_device *);
@@ -1253,7 +1253,7 @@ static int au1000_rx(struct net_device *dev)
 /*
  * Au1000 interrupt service routine.
  */
-static irqreturn_t au1000_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t au1000_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = (struct net_device *) dev_id;
 
index e891ea2ecc3c0464c4ed008181d528386be98edd..1ec217433b4cdc30fcbebe35b1df22b31d3df1ad 100644 (file)
@@ -896,7 +896,7 @@ static int b44_poll(struct net_device *netdev, int *budget)
        return (done ? 0 : 1);
 }
 
-static irqreturn_t b44_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t b44_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
        struct b44 *bp = netdev_priv(dev);
@@ -1461,7 +1461,7 @@ out:
 static void b44_poll_controller(struct net_device *dev)
 {
        disable_irq(dev->irq);
-       b44_interrupt(dev->irq, dev, NULL);
+       b44_interrupt(dev->irq, dev);
        enable_irq(dev->irq);
 }
 #endif
@@ -1706,14 +1706,15 @@ static void __b44_set_rx_mode(struct net_device *dev)
 
                __b44_set_mac_addr(bp);
 
-               if (dev->flags & IFF_ALLMULTI)
+               if ((dev->flags & IFF_ALLMULTI) ||
+                   (dev->mc_count > B44_MCAST_TABLE_SIZE))
                        val |= RXCONFIG_ALLMULTI;
                else
                        i = __b44_load_mcast(bp, dev);
 
-               for (; i < 64; i++) {
+               for (; i < 64; i++)
                        __b44_cam_write(bp, zero, i);
-               }
+
                bw32(bp, B44_RXCONFIG, val);
                val = br32(bp, B44_CAM_CTRL);
                bw32(bp, B44_CAM_CTRL, val | CAM_CTRL_ENABLE);
@@ -2055,7 +2056,7 @@ static int b44_read_eeprom(struct b44 *bp, u8 *data)
        u16 *ptr = (u16 *) data;
 
        for (i = 0; i < 128; i += 2)
-               ptr[i / 2] = readw(bp->regs + 4096 + i);
+               ptr[i / 2] = cpu_to_le16(readw(bp->regs + 4096 + i));
 
        return 0;
 }
index 4adfe7b77031eff0b17e299edcde6ebd583b8e0c..4528ce9c4e435f9312ff87f62b944bad45cc1073 100644 (file)
@@ -152,9 +152,9 @@ static void bmac_init_chip(struct net_device *dev);
 static void bmac_init_registers(struct net_device *dev);
 static void bmac_enable_and_reset_chip(struct net_device *dev);
 static int bmac_set_address(struct net_device *dev, void *addr);
-static irqreturn_t bmac_misc_intr(int irq, void *dev_id, struct pt_regs *regs);
-static irqreturn_t bmac_txdma_intr(int irq, void *dev_id, struct pt_regs *regs);
-static irqreturn_t bmac_rxdma_intr(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t bmac_misc_intr(int irq, void *dev_id);
+static irqreturn_t bmac_txdma_intr(int irq, void *dev_id);
+static irqreturn_t bmac_rxdma_intr(int irq, void *dev_id);
 static void bmac_set_timeout(struct net_device *dev);
 static void bmac_tx_timeout(unsigned long data);
 static int bmac_output(struct sk_buff *skb, struct net_device *dev);
@@ -688,7 +688,7 @@ static int bmac_transmit_packet(struct sk_buff *skb, struct net_device *dev)
 
 static int rxintcount;
 
-static irqreturn_t bmac_rxdma_intr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t bmac_rxdma_intr(int irq, void *dev_id)
 {
        struct net_device *dev = (struct net_device *) dev_id;
        struct bmac_data *bp = netdev_priv(dev);
@@ -765,7 +765,7 @@ static irqreturn_t bmac_rxdma_intr(int irq, void *dev_id, struct pt_regs *regs)
 
 static int txintcount;
 
-static irqreturn_t bmac_txdma_intr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t bmac_txdma_intr(int irq, void *dev_id)
 {
        struct net_device *dev = (struct net_device *) dev_id;
        struct bmac_data *bp = netdev_priv(dev);
@@ -1082,7 +1082,7 @@ static void bmac_set_multicast(struct net_device *dev)
 
 static int miscintcount;
 
-static irqreturn_t bmac_misc_intr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t bmac_misc_intr(int irq, void *dev_id)
 {
        struct net_device *dev = (struct net_device *) dev_id;
        struct bmac_data *bp = netdev_priv(dev);
@@ -1091,7 +1091,7 @@ static irqreturn_t bmac_misc_intr(int irq, void *dev_id, struct pt_regs *regs)
                XXDEBUG(("bmac_misc_intr\n"));
        }
        /* XXDEBUG(("bmac_misc_intr, status=%#08x\n", status)); */
-       /*     bmac_txdma_intr_inner(irq, dev_id, regs); */
+       /*     bmac_txdma_intr_inner(irq, dev_id); */
        /*   if (status & FrameReceived) bp->stats.rx_dropped++; */
        if (status & RxErrorMask) bp->stats.rx_errors++;
        if (status & RxCRCCntExp) bp->stats.rx_crc_errors++;
index 6b4edb63c4c485faaf029164bc6b32ea99c9a982..01b76d3aa42f85a481c8e20b0aa107c4e2a485ac 100644 (file)
@@ -1888,7 +1888,7 @@ next_rx:
  * is that the MSI interrupt is always serviced.
  */
 static irqreturn_t
-bnx2_msi(int irq, void *dev_instance, struct pt_regs *regs)
+bnx2_msi(int irq, void *dev_instance)
 {
        struct net_device *dev = dev_instance;
        struct bnx2 *bp = netdev_priv(dev);
@@ -1908,7 +1908,7 @@ bnx2_msi(int irq, void *dev_instance, struct pt_regs *regs)
 }
 
 static irqreturn_t
-bnx2_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
+bnx2_interrupt(int irq, void *dev_instance)
 {
        struct net_device *dev = dev_instance;
        struct bnx2 *bp = netdev_priv(dev);
@@ -5554,7 +5554,7 @@ poll_bnx2(struct net_device *dev)
        struct bnx2 *bp = netdev_priv(dev);
 
        disable_irq(bp->pdev->irq);
-       bnx2_interrupt(bp->pdev->irq, dev, NULL);
+       bnx2_interrupt(bp->pdev->irq, dev);
        enable_irq(bp->pdev->irq);
 }
 #endif
index e83bc825f6afc4d5346cbb3d70f999e4b5d44e75..32923162179ef8b45948149972343744144694ec 100644 (file)
@@ -1433,7 +1433,7 @@ void bond_alb_monitor(struct bonding *bond)
                 * write lock to protect from other code that also
                 * sets the promiscuity.
                 */
-               write_lock(&bond->curr_slave_lock);
+               write_lock_bh(&bond->curr_slave_lock);
 
                if (bond_info->primary_is_promisc &&
                    (++bond_info->rlb_promisc_timeout_counter >= RLB_PROMISC_TIMEOUT)) {
@@ -1448,7 +1448,7 @@ void bond_alb_monitor(struct bonding *bond)
                        bond_info->primary_is_promisc = 0;
                }
 
-               write_unlock(&bond->curr_slave_lock);
+               write_unlock_bh(&bond->curr_slave_lock);
 
                if (bond_info->rlb_rebalance) {
                        bond_info->rlb_rebalance = 0;
index 7694365092f8587ca9b560fa68c9550d7599bd35..521c5b71023c60c5ba1199268d1d441bfac03ce1 100644 (file)
@@ -2469,7 +2469,7 @@ static inline void cas_handle_irqN(struct net_device *dev,
                cas_post_rxcs_ringN(dev, cp, ring);
 }
 
-static irqreturn_t cas_interruptN(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t cas_interruptN(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
        struct cas *cp = netdev_priv(dev);
@@ -2522,7 +2522,7 @@ static inline void cas_handle_irq1(struct cas *cp, const u32 status)
 }
 
 /* ring 2 handles a few more events than 3 and 4 */
-static irqreturn_t cas_interrupt1(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t cas_interrupt1(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
        struct cas *cp = netdev_priv(dev);
@@ -2574,7 +2574,7 @@ static inline void cas_handle_irq(struct net_device *dev,
                cas_post_rxcs_ringN(dev, cp, 0);
 }
 
-static irqreturn_t cas_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t cas_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
        struct cas *cp = netdev_priv(dev);
@@ -2689,7 +2689,7 @@ static void cas_netpoll(struct net_device *dev)
        struct cas *cp = netdev_priv(dev);
 
        cas_disable_irq(cp, 0);
-       cas_interrupt(cp->pdev->irq, dev, NULL);
+       cas_interrupt(cp->pdev->irq, dev);
        cas_enable_irq(cp, 0);
 
 #ifdef USE_PCI_INTB
index 27925e487bcfd1a27f4bcaea7719dc751ec03410..5b357d9e88d61b6449c463103f82d6b735be224e 100644 (file)
@@ -108,7 +108,7 @@ struct cpl_tx_pkt_lso {
        u8 iff:4;
 #endif
        u16 vlan;
-       u32 len;
+       __be32 len;
 
        u32 rsvd2;
        u8 rsvd3;
@@ -119,7 +119,7 @@ struct cpl_tx_pkt_lso {
        u8 ip_hdr_words:4;
        u8 tcp_hdr_words:4;
 #endif
-       u16 eth_type_mss;
+       __be16 eth_type_mss;
 };
 
 struct cpl_rx_pkt {
@@ -138,7 +138,7 @@ struct cpl_rx_pkt {
        u8 iff:4;
 #endif
        u16 csum;
-       u16 vlan;
+       __be16 vlan;
        u16 len;
 };
 
index 5f1b067534623906b7a8bb0a2e2b11d4c122fdbe..ad7ff9641a7e4afcaa4aae91dcbb4dcf69ebbe91 100644 (file)
@@ -918,7 +918,7 @@ static void t1_netpoll(struct net_device *dev)
        struct adapter *adapter = dev->priv;
 
        local_irq_save(flags);
-        t1_select_intr_handler(adapter)(adapter->pdev->irq, adapter, NULL);
+        t1_select_intr_handler(adapter)(adapter->pdev->irq, adapter);
        local_irq_restore(flags);
 }
 #endif
index ddd0bdb498f4f4f7dcf1bbd62c614dd21756f6e7..9799c12380fce7126be57d76dbaa2a9682a89186 100644 (file)
@@ -1217,7 +1217,7 @@ static inline int napi_is_scheduled(struct net_device *dev)
 /*
  * NAPI version of the main interrupt handler.
  */
-static irqreturn_t t1_interrupt_napi(int irq, void *data, struct pt_regs *regs)
+static irqreturn_t t1_interrupt_napi(int irq, void *data)
 {
        int handled;
        struct adapter *adapter = data;
@@ -1279,7 +1279,7 @@ static irqreturn_t t1_interrupt_napi(int irq, void *data, struct pt_regs *regs)
  * 5. If we took an interrupt, but no valid respQ descriptors was found we
  *      let the slow_intr_handler run and do error handling.
  */
-static irqreturn_t t1_interrupt(int irq, void *cookie, struct pt_regs *regs)
+static irqreturn_t t1_interrupt(int irq, void *cookie)
 {
        int work_done;
        struct respQ_e *e;
@@ -1312,7 +1312,7 @@ static irqreturn_t t1_interrupt(int irq, void *cookie, struct pt_regs *regs)
        return IRQ_RETVAL(work_done != 0);
 }
 
-intr_handler_t t1_select_intr_handler(adapter_t *adapter)
+irq_handler_t t1_select_intr_handler(adapter_t *adapter)
 {
        return adapter->params.sge.polling ? t1_interrupt_napi : t1_interrupt;
 }
index 6d0d24a6364f75d8dc7908b58d83d6d1672b234e..91af47bab7beac32acd3376431fb70c036aac203 100644 (file)
 #include <linux/interrupt.h>
 #include <asm/byteorder.h>
 
-#ifndef IRQ_RETVAL
-#define IRQ_RETVAL(x)
-typedef void irqreturn_t;
-#endif
-
-typedef irqreturn_t (*intr_handler_t)(int, void *, struct pt_regs *);
-
 struct sge_intr_counts {
        unsigned int respQ_empty;      /* # times respQ empty */
        unsigned int respQ_overflow;   /* # respQ overflow (fatal) */
@@ -88,7 +81,7 @@ struct sge *t1_sge_create(struct adapter *, struct sge_params *);
 int t1_sge_configure(struct sge *, struct sge_params *);
 int t1_sge_set_coalesce_params(struct sge *, struct sge_params *);
 void t1_sge_destroy(struct sge *);
-intr_handler_t t1_select_intr_handler(adapter_t *adapter);
+irq_handler_t t1_select_intr_handler(adapter_t *adapter);
 int t1_start_xmit(struct sk_buff *skb, struct net_device *dev);
 void t1_set_vlan_accel(struct adapter *adapter, int on_off);
 void t1_sge_start(struct sge *);
index f1501b6f247e4e9543f8752de83294a5fddf6aed..966b563e42bb8a81498f8cd1176675256aa0b439 100644 (file)
@@ -403,8 +403,8 @@ static int etrax_ethernet_init(void);
 static int e100_open(struct net_device *dev);
 static int e100_set_mac_address(struct net_device *dev, void *addr);
 static int e100_send_packet(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t e100rxtx_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-static irqreturn_t e100nw_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t e100rxtx_interrupt(int irq, void *dev_id);
+static irqreturn_t e100nw_interrupt(int irq, void *dev_id);
 static void e100_rx(struct net_device *dev);
 static int e100_close(struct net_device *dev);
 static int e100_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
@@ -1197,7 +1197,7 @@ e100_send_packet(struct sk_buff *skb, struct net_device *dev)
  */
 
 static irqreturn_t
-e100rxtx_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+e100rxtx_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = (struct net_device *)dev_id;
        struct net_local *np = (struct net_local *)dev->priv;
@@ -1264,7 +1264,7 @@ e100rxtx_interrupt(int irq, void *dev_id, struct pt_regs * regs)
 }
 
 static irqreturn_t
-e100nw_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+e100nw_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = (struct net_device *)dev_id;
        struct net_local *np = (struct net_local *)dev->priv;
index e4d50f0de930f636bf2166bc49d10c2244e0b136..4ffc9b44a8e13509e0c693e24bced26090a7cda8 100644 (file)
@@ -249,7 +249,7 @@ struct net_local {
 static int cs89x0_probe1(struct net_device *dev, int ioaddr, int modular);
 static int net_open(struct net_device *dev);
 static int net_send_packet(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t net_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+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);
@@ -495,7 +495,7 @@ get_eeprom_cksum(int off, int len, int *buffer)
 static void net_poll_controller(struct net_device *dev)
 {
        disable_irq(dev->irq);
-       net_interrupt(dev->irq, dev, NULL);
+       net_interrupt(dev->irq, dev);
        enable_irq(dev->irq);
 }
 #endif
@@ -1573,7 +1573,7 @@ static int net_send_packet(struct sk_buff *skb, struct net_device *dev)
 /* The typical workload of the driver:
    Handle the network interface interrupts. */
 
-static irqreturn_t net_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+static irqreturn_t net_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
        struct net_local *lp;
index 0b930da5d47d884fc57e3f4067005a5d9cdf8e82..690bb40b353dacedf8a6979998ca4f7cc3b1d39d 100644 (file)
@@ -258,19 +258,13 @@ static int de600_start_xmit(struct sk_buff *skb, struct net_device *dev)
  * Handle the network interface interrupts.
  */
 
-static irqreturn_t de600_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+static irqreturn_t de600_interrupt(int irq, void *dev_id)
 {
        struct net_device       *dev = dev_id;
        u8              irq_status;
        int             retrig = 0;
        int             boguscount = 0;
 
-       /* This might just as well be deleted now, no crummy drivers present :-) */
-       if ((dev == NULL) || (DE600_IRQ != irq)) {
-               printk(KERN_ERR "%s: bogus interrupt %d\n", dev?dev->name:"DE-600", irq);
-               return IRQ_NONE;
-       }
-
        spin_lock(&de600_lock);
 
        select_nic();
index e4073015dcd80a540937616555d306708f4a450c..1288e48ba70411aab8a05ac21d099bb29a530818 100644 (file)
@@ -125,7 +125,7 @@ static struct net_device_stats *get_stats(struct net_device *dev);
 static int     de600_start_xmit(struct sk_buff *skb, struct net_device *dev);
 
 /* Dispatch from interrupts. */
-static irqreturn_t de600_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t de600_interrupt(int irq, void *dev_id);
 static int     de600_tx_intr(struct net_device *dev, int irq_status);
 static void    de600_rx_intr(struct net_device *dev);
 
index a18d4d14b665709326be6d3af85c03dc206bf705..b6ad0cb5055261f539aabc9738be954e4139ce9e 100644 (file)
@@ -221,7 +221,7 @@ static void de620_set_multicast_list(struct net_device *);
 static int     de620_start_xmit(struct sk_buff *, struct net_device *);
 
 /* Dispatch from interrupts. */
-static irqreturn_t de620_interrupt(int, void *, struct pt_regs *);
+static irqreturn_t de620_interrupt(int, void *);
 static int     de620_rx_intr(struct net_device *);
 
 /* Initialization */
@@ -591,7 +591,7 @@ static int de620_start_xmit(struct sk_buff *skb, struct net_device *dev)
  *
  */
 static irqreturn_t
-de620_interrupt(int irq_in, void *dev_id, struct pt_regs *regs)
+de620_interrupt(int irq_in, void *dev_id)
 {
        struct net_device *dev = dev_id;
        byte irq_status;
index bbccd741cdbffb12dc804415e53b88778f1a5933..00e2a8a134d7a2993530e29f97ac86d4458bf924 100644 (file)
@@ -694,19 +694,17 @@ out:
        spin_unlock(&lp->lock);
 }
 
-static irqreturn_t lance_dma_merr_int(const int irq, void *dev_id,
-                                     struct pt_regs *regs)
+static irqreturn_t lance_dma_merr_int(const int irq, void *dev_id)
 {
-       struct net_device *dev = (struct net_device *) dev_id;
+       struct net_device *dev = dev_id;
 
        printk("%s: DMA error\n", dev->name);
        return IRQ_HANDLED;
 }
 
-static irqreturn_t lance_interrupt(const int irq, void *dev_id,
-                                  struct pt_regs *regs)
+static irqreturn_t lance_interrupt(const int irq, void *dev_id)
 {
-       struct net_device *dev = (struct net_device *) dev_id;
+       struct net_device *dev = dev_id;
        struct lance_private *lp = netdev_priv(dev);
        volatile struct lance_regs *ll = lp->ll;
        int csr0;
index ae9680552b82e5ef8edefc215f2177cf2a94dae5..8f514cc0debddac800be967f3f551796de58c1ca 100644 (file)
@@ -248,8 +248,7 @@ static int          dfx_close(struct net_device *dev);
 static void            dfx_int_pr_halt_id(DFX_board_t *bp);
 static void            dfx_int_type_0_process(DFX_board_t *bp);
 static void            dfx_int_common(struct net_device *dev);
-static irqreturn_t     dfx_interrupt(int irq, void *dev_id,
-                                     struct pt_regs *regs);
+static irqreturn_t     dfx_interrupt(int irq, void *dev_id);
 
 static struct          net_device_stats *dfx_ctl_get_stats(struct net_device *dev);
 static void            dfx_ctl_set_multicast_list(struct net_device *dev);
@@ -1693,7 +1692,6 @@ static void dfx_int_common(struct net_device *dev)
  * Arguments:
  *   irq       - interrupt vector
  *   dev_id    - pointer to device information
- *      regs   - pointer to registers structure
  *
  * Functional Description:
  *   This routine calls the interrupt processing routine for this adapter.  It
@@ -1716,7 +1714,7 @@ static void dfx_int_common(struct net_device *dev)
  *   Interrupts are disabled, then reenabled at the adapter.
  */
 
-static irqreturn_t dfx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t dfx_interrupt(int irq, void *dev_id)
 {
        struct net_device       *dev = dev_id;
        DFX_board_t             *bp;    /* private board structure pointer */
index af594664df51290236c45e06b3c470c0edb31345..f87f6e3dc721f42b8aeae87b1af6879b2c5f9c6b 100644 (file)
@@ -518,7 +518,7 @@ struct depca_private {
 */
 static int depca_open(struct net_device *dev);
 static int depca_start_xmit(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t depca_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t depca_interrupt(int irq, void *dev_id);
 static int depca_close(struct net_device *dev);
 static int depca_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
 static void depca_tx_timeout(struct net_device *dev);
@@ -965,7 +965,7 @@ static int depca_start_xmit(struct sk_buff *skb, struct net_device *dev)
 /*
 ** The DEPCA interrupt handler.
 */
-static irqreturn_t depca_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t depca_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
        struct depca_private *lp;
index d0842527b3694782ebdcbde85e21e5ad95f55193..a79520295fd0ec9fcce2330ecc98cc1542cd14b9 100644 (file)
@@ -895,10 +895,10 @@ static int dgrs_ioctl(struct net_device *devN, struct ifreq *ifr, int cmd)
  *     dev, priv will always refer to the 0th device in Multi-NIC mode.
  */
 
-static irqreturn_t dgrs_intr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t dgrs_intr(int irq, void *dev_id)
 {
-       struct net_device       *dev0 = (struct net_device *) dev_id;
-       DGRS_PRIV       *priv0 = (DGRS_PRIV *) dev0->priv;
+       struct net_device       *dev0 = dev_id;
+       DGRS_PRIV       *priv0 = dev0->priv;
        I596_CB         *cbp;
        int             cmd;
        int             i;
index 7e95cf1a4872ab2287c7ca5d6b9d3a5c4137e58b..9d446a0fe0bfcb4ca4207b2557fbfd756964e9f4 100644 (file)
@@ -60,7 +60,7 @@ static void rio_timer (unsigned long data);
 static void rio_tx_timeout (struct net_device *dev);
 static void alloc_list (struct net_device *dev);
 static int start_xmit (struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t rio_interrupt (int irq, void *dev_instance, struct pt_regs *regs);
+static irqreturn_t rio_interrupt (int irq, void *dev_instance);
 static void rio_free_tx (struct net_device *dev, int irq);
 static void tx_error (struct net_device *dev, int tx_status);
 static int receive_packet (struct net_device *dev);
@@ -665,7 +665,7 @@ start_xmit (struct sk_buff *skb, struct net_device *dev)
 }
 
 static irqreturn_t
-rio_interrupt (int irq, void *dev_instance, struct pt_regs *rgs)
+rio_interrupt (int irq, void *dev_instance)
 {
        struct net_device *dev = dev_instance;
        struct netdev_private *np;
index a860ebbbf815f34d3c70e0c4a0d0096d7e56c261..615d2b14efa71bbb5f5ff0de37d97afd74451e4c 100644 (file)
@@ -159,7 +159,7 @@ static void dm9000_init_dm9000(struct net_device *);
 
 static struct net_device_stats *dm9000_get_stats(struct net_device *);
 
-static irqreturn_t dm9000_interrupt(int, void *, struct pt_regs *);
+static irqreturn_t dm9000_interrupt(int, void *);
 
 static int dm9000_phy_read(struct net_device *dev, int phyaddr_unsused, int reg);
 static void dm9000_phy_write(struct net_device *dev, int phyaddr_unused, int reg,
@@ -346,7 +346,7 @@ static void dm9000_timeout(struct net_device *dev)
 static void dm9000_poll_controller(struct net_device *dev)
 {
        disable_irq(dev->irq);
-       dm9000_interrupt(dev->irq,dev,NULL);
+       dm9000_interrupt(dev->irq,dev);
        enable_irq(dev->irq);
 }
 #endif
@@ -804,7 +804,7 @@ dm9000_tx_done(struct net_device *dev, board_info_t * db)
 }
 
 static irqreturn_t
-dm9000_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+dm9000_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
        board_info_t *db;
index 26073c3452130b01aaaa3ce83d20b10f2919c382..a3a08a5dd1853bdf0516f0f5745dbbcdf26f068b 100644 (file)
@@ -1949,7 +1949,7 @@ static int e100_rx_alloc_list(struct nic *nic)
        return 0;
 }
 
-static irqreturn_t e100_intr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t e100_intr(int irq, void *dev_id)
 {
        struct net_device *netdev = dev_id;
        struct nic *nic = netdev_priv(netdev);
@@ -2005,7 +2005,7 @@ static void e100_netpoll(struct net_device *netdev)
        struct nic *nic = netdev_priv(netdev);
 
        e100_disable_irq(nic);
-       e100_intr(nic->pdev->irq, netdev, NULL);
+       e100_intr(nic->pdev->irq, netdev);
        e100_tx_clean(nic);
        e100_enable_irq(nic);
 }
@@ -2039,7 +2039,6 @@ static int e100_change_mtu(struct net_device *netdev, int new_mtu)
        return 0;
 }
 
-#ifdef CONFIG_PM
 static int e100_asf(struct nic *nic)
 {
        /* ASF can be enabled from eeprom */
@@ -2048,7 +2047,6 @@ static int e100_asf(struct nic *nic)
           !(nic->eeprom[eeprom_config_asf] & eeprom_gcl) &&
           ((nic->eeprom[eeprom_smbus_addr] & 0xFF) != 0xFE));
 }
-#endif
 
 static int e100_up(struct nic *nic)
 {
@@ -2715,34 +2713,32 @@ static void __devexit e100_remove(struct pci_dev *pdev)
        }
 }
 
+#ifdef CONFIG_PM
 static int e100_suspend(struct pci_dev *pdev, pm_message_t state)
 {
        struct net_device *netdev = pci_get_drvdata(pdev);
        struct nic *nic = netdev_priv(netdev);
 
-       if (netif_running(netdev))
-               e100_down(nic);
-       e100_hw_reset(nic);
-       netif_device_detach(netdev);
+       netif_poll_disable(nic->netdev);
+       del_timer_sync(&nic->watchdog);
+       netif_carrier_off(nic->netdev);
 
-#ifdef CONFIG_PM
        pci_save_state(pdev);
-       if (nic->flags & (wol_magic | e100_asf(nic)))
-#else
-       if (nic->flags & (wol_magic))
-#endif
-               pci_enable_wake(pdev, pci_choose_state(pdev, state), 1);
-       else
-               /* disable PME */
-               pci_enable_wake(pdev, 0, 0);
+
+       if ((nic->flags & wol_magic) | e100_asf(nic)) {
+               pci_enable_wake(pdev, PCI_D3hot, 1);
+               pci_enable_wake(pdev, PCI_D3cold, 1);
+       } else {
+               pci_enable_wake(pdev, PCI_D3hot, 0);
+               pci_enable_wake(pdev, PCI_D3cold, 0);
+       }
 
        pci_disable_device(pdev);
-       pci_set_power_state(pdev, pci_choose_state(pdev, state));
+       pci_set_power_state(pdev, PCI_D3hot);
 
        return 0;
 }
 
-#ifdef CONFIG_PM
 static int e100_resume(struct pci_dev *pdev)
 {
        struct net_device *netdev = pci_get_drvdata(pdev);
@@ -2764,7 +2760,23 @@ static int e100_resume(struct pci_dev *pdev)
 
 static void e100_shutdown(struct pci_dev *pdev)
 {
-       e100_suspend(pdev, PMSG_SUSPEND);
+       struct net_device *netdev = pci_get_drvdata(pdev);
+       struct nic *nic = netdev_priv(netdev);
+
+       netif_poll_disable(nic->netdev);
+       del_timer_sync(&nic->watchdog);
+       netif_carrier_off(nic->netdev);
+
+       if ((nic->flags & wol_magic) | e100_asf(nic)) {
+               pci_enable_wake(pdev, PCI_D3hot, 1);
+               pci_enable_wake(pdev, PCI_D3cold, 1);
+       } else {
+               pci_enable_wake(pdev, PCI_D3hot, 0);
+               pci_enable_wake(pdev, PCI_D3cold, 0);
+       }
+
+       pci_disable_device(pdev);
+       pci_set_power_state(pdev, PCI_D3hot);
 }
 
 /* ------------------ PCI Error Recovery infrastructure  -------------- */
@@ -2848,9 +2860,9 @@ static struct pci_driver e100_driver = {
        .id_table =     e100_id_table,
        .probe =        e100_probe,
        .remove =       __devexit_p(e100_remove),
+#ifdef CONFIG_PM
        /* Power Management hooks */
        .suspend =      e100_suspend,
-#ifdef CONFIG_PM
        .resume =       e100_resume,
 #endif
        .shutdown =     e100_shutdown,
index 778ede3c02163a1c4655c092e52196bb903316e3..773821e4cf57da5cb0fee7bc00187f08f37eacfe 100644 (file)
@@ -883,8 +883,7 @@ e1000_eeprom_test(struct e1000_adapter *adapter, uint64_t *data)
 
 static irqreturn_t
 e1000_test_intr(int irq,
-               void *data,
-               struct pt_regs *regs)
+               void *data)
 {
        struct net_device *netdev = (struct net_device *) data;
        struct e1000_adapter *adapter = netdev_priv(netdev);
index 7dca38fba6a1809605340915aa7c9d65abeaa206..fa849831d0998ead7db0fbe09f6b20c5398a0018 100644 (file)
@@ -153,7 +153,7 @@ static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev);
 static struct net_device_stats * e1000_get_stats(struct net_device *netdev);
 static int e1000_change_mtu(struct net_device *netdev, int new_mtu);
 static int e1000_set_mac(struct net_device *netdev, void *p);
-static irqreturn_t e1000_intr(int irq, void *data, struct pt_regs *regs);
+static irqreturn_t e1000_intr(int irq, void *data);
 static boolean_t e1000_clean_tx_irq(struct e1000_adapter *adapter,
                                     struct e1000_tx_ring *tx_ring);
 #ifdef CONFIG_E1000_NAPI
@@ -3436,11 +3436,10 @@ e1000_update_stats(struct e1000_adapter *adapter)
  * e1000_intr - Interrupt Handler
  * @irq: interrupt number
  * @data: pointer to a network interface device structure
- * @pt_regs: CPU registers structure
  **/
 
 static irqreturn_t
-e1000_intr(int irq, void *data, struct pt_regs *regs)
+e1000_intr(int irq, void *data)
 {
        struct net_device *netdev = data;
        struct e1000_adapter *adapter = netdev_priv(netdev);
@@ -4862,7 +4861,7 @@ e1000_netpoll(struct net_device *netdev)
        struct e1000_adapter *adapter = netdev_priv(netdev);
 
        disable_irq(adapter->pdev->irq);
-       e1000_intr(adapter->pdev->irq, netdev, NULL);
+       e1000_intr(adapter->pdev->irq, netdev);
        e1000_clean_tx_irq(adapter, adapter->tx_ring);
 #ifndef CONFIG_E1000_NAPI
        adapter->clean_rx(adapter, adapter->rx_ring);
@@ -4915,10 +4914,6 @@ static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
        pci_enable_wake(pdev, PCI_D3hot, 0);
        pci_enable_wake(pdev, PCI_D3cold, 0);
 
-       /* Perform card reset only on one instance of the card */
-       if (PCI_FUNC (pdev->devfn) != 0)
-               return PCI_ERS_RESULT_RECOVERED;
-
        e1000_reset(adapter);
        E1000_WRITE_REG(&adapter->hw, WUS, ~0);
 
index 09ff9b9418f45835d976d3db6167ac5235b3f428..a4eb0dc99ecffe42c92b87a1bacac5c72234caa1 100644 (file)
@@ -311,7 +311,7 @@ struct eepro_local {
 static int     eepro_probe1(struct net_device *dev, int autoprobe);
 static int     eepro_open(struct net_device *dev);
 static int     eepro_send_packet(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t eepro_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t eepro_interrupt(int irq, void *dev_id);
 static void    eepro_rx(struct net_device *dev);
 static void    eepro_transmit_interrupt(struct net_device *dev);
 static int     eepro_close(struct net_device *dev);
@@ -994,16 +994,6 @@ static int eepro_open(struct net_device *dev)
                return -EAGAIN;
        }
 
-#ifdef irq2dev_map
-       if  (((irq2dev_map[dev->irq] != 0)
-               || (irq2dev_map[dev->irq] = dev) == 0) &&
-               (irq2dev_map[dev->irq]!=dev)) {
-               /* printk("%s: IRQ map wrong\n", dev->name); */
-               free_irq(dev->irq, dev);
-               return -EAGAIN;
-       }
-#endif
-
        /* Initialize the 82595. */
 
        eepro_sw2bank2(ioaddr); /* be CAREFUL, BANK 2 now */
@@ -1196,19 +1186,13 @@ static int eepro_send_packet(struct sk_buff *skb, struct net_device *dev)
        Handle the network interface interrupts. */
 
 static irqreturn_t
-eepro_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+eepro_interrupt(int irq, void *dev_id)
 {
-       struct net_device *dev =  (struct net_device *)dev_id;
-                             /* (struct net_device *)(irq2dev_map[irq]);*/
+       struct net_device *dev = dev_id;
        struct eepro_local *lp;
        int ioaddr, status, boguscount = 20;
        int handled = 0;
 
-       if (dev == NULL) {
-                printk (KERN_ERR "eepro_interrupt(): irq %d for unknown device.\\n", irq);
-                return IRQ_NONE;
-        }
-
        lp = netdev_priv(dev);
 
         spin_lock(&lp->lock);
@@ -1288,10 +1272,6 @@ static int eepro_close(struct net_device *dev)
        /* release the interrupt */
        free_irq(dev->irq, dev);
 
-#ifdef irq2dev_map
-       irq2dev_map[dev->irq] = 0;
-#endif
-
        /* Update the statistics here. What statistics? */
 
        return 0;
index 499e93b31f540d119be0c1aae2681bac0fda077c..e28bb1e38f8d84c57376fa1c15ef9f604916024a 100644 (file)
@@ -488,7 +488,7 @@ static int speedo_start_xmit(struct sk_buff *skb, struct net_device *dev);
 static void speedo_refill_rx_buffers(struct net_device *dev, int force);
 static int speedo_rx(struct net_device *dev);
 static void speedo_tx_buffer_gc(struct net_device *dev);
-static irqreturn_t speedo_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
+static irqreturn_t speedo_interrupt(int irq, void *dev_instance);
 static int speedo_close(struct net_device *dev);
 static struct net_device_stats *speedo_get_stats(struct net_device *dev);
 static int speedo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
@@ -606,7 +606,7 @@ static void poll_speedo (struct net_device *dev)
        /* disable_irq is not very nice, but with the funny lockless design
           we have no other choice. */
        disable_irq(dev->irq);
-       speedo_interrupt (dev->irq, dev, NULL);
+       speedo_interrupt (dev->irq, dev);
        enable_irq(dev->irq);
 }
 #endif
@@ -1541,7 +1541,7 @@ static void speedo_tx_buffer_gc(struct net_device *dev)
 
 /* The interrupt handler does all of the Rx thread work and cleans up
    after the Tx thread. */
-static irqreturn_t speedo_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
+static irqreturn_t speedo_interrupt(int irq, void *dev_instance)
 {
        struct net_device *dev = (struct net_device *)dev_instance;
        struct speedo_private *sp;
index 9cb05d99ee1b1c75a2abb0b6318b9c8349dfd1ea..e14be020e5624b2f5f999b1d90a0771cb0004f69 100644 (file)
@@ -249,7 +249,7 @@ static void eexp_timeout(struct net_device *dev);
 static struct net_device_stats *eexp_stats(struct net_device *dev);
 static int eexp_xmit(struct sk_buff *buf, struct net_device *dev);
 
-static irqreturn_t eexp_irq(int irq, void *dev_addr, struct pt_regs *regs);
+static irqreturn_t eexp_irq(int irq, void *dev_addr);
 static void eexp_set_multicast(struct net_device *dev);
 
 /*
@@ -789,20 +789,13 @@ static void eexp_cmd_clear(struct net_device *dev)
        }
 }
 
-static irqreturn_t eexp_irq(int irq, void *dev_info, struct pt_regs *regs)
+static irqreturn_t eexp_irq(int irq, void *dev_info)
 {
        struct net_device *dev = dev_info;
        struct net_local *lp;
        unsigned short ioaddr,status,ack_cmd;
        unsigned short old_read_ptr, old_write_ptr;
 
-       if (dev==NULL)
-       {
-               printk(KERN_WARNING "eexpress: irq %d for unknown device\n",
-                      irq);
-               return IRQ_NONE;
-       }
-
        lp = netdev_priv(dev);
        ioaddr = dev->base_addr;
 
index 23b451a8ae120f528fde09f0d131104645931fd3..b40724fc6b74e713a4bcee6213fe3b567def362d 100644 (file)
@@ -39,7 +39,7 @@
 #include <asm/io.h>
 
 #define DRV_NAME       "ehea"
-#define DRV_VERSION    "EHEA_0028"
+#define DRV_VERSION    "EHEA_0034"
 
 #define EHEA_MSG_DEFAULT (NETIF_MSG_LINK | NETIF_MSG_TIMER \
        | NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR)
@@ -50,6 +50,7 @@
 #define EHEA_MAX_ENTRIES_SQ  32767
 #define EHEA_MIN_ENTRIES_QP  127
 
+#define EHEA_SMALL_QUEUES
 #define EHEA_NUM_TX_QP 1
 
 #ifdef EHEA_SMALL_QUEUES
 #define EHEA_DEF_ENTRIES_RQ2    1023
 #define EHEA_DEF_ENTRIES_RQ3    1023
 #else
-#define EHEA_MAX_CQE_COUNT     32000
-#define EHEA_DEF_ENTRIES_SQ    16000
-#define EHEA_DEF_ENTRIES_RQ1   32080
-#define EHEA_DEF_ENTRIES_RQ2    4020
-#define EHEA_DEF_ENTRIES_RQ3    4020
+#define EHEA_MAX_CQE_COUNT      4080
+#define EHEA_DEF_ENTRIES_SQ     4080
+#define EHEA_DEF_ENTRIES_RQ1    8160
+#define EHEA_DEF_ENTRIES_RQ2    2040
+#define EHEA_DEF_ENTRIES_RQ3    2040
 #endif
 
 #define EHEA_MAX_ENTRIES_EQ 20
index 263d1c5b3f23c65b3d8a8a9597ac39ed0d525eb3..eb7d44de59ff1aa91e9a833c3bab423430a7359d 100644 (file)
@@ -536,16 +536,14 @@ void ehea_send_irq_tasklet(unsigned long data)
                tasklet_hi_schedule(&pr->send_comp_task);
 }
 
-static irqreturn_t ehea_send_irq_handler(int irq, void *param,
-                                        struct pt_regs *regs)
+static irqreturn_t ehea_send_irq_handler(int irq, void *param)
 {
        struct ehea_port_res *pr = param;
        tasklet_hi_schedule(&pr->send_comp_task);
        return IRQ_HANDLED;
 }
 
-static irqreturn_t ehea_recv_irq_handler(int irq, void *param,
-                                        struct pt_regs *regs)
+static irqreturn_t ehea_recv_irq_handler(int irq, void *param)
 {
        struct ehea_port_res *pr = param;
        struct ehea_port *port = pr->port;
@@ -553,8 +551,7 @@ static irqreturn_t ehea_recv_irq_handler(int irq, void *param,
        return IRQ_HANDLED;
 }
 
-static irqreturn_t ehea_qp_aff_irq_handler(int irq, void *param,
-                                          struct pt_regs *regs)
+static irqreturn_t ehea_qp_aff_irq_handler(int irq, void *param)
 {
        struct ehea_port *port = param;
        struct ehea_eqe *eqe;
@@ -769,7 +766,7 @@ static void ehea_parse_eqe(struct ehea_adapter *adapter, u64 eqe)
                if (EHEA_BMASK_GET(NEQE_PORT_UP, eqe)) {
                        if (!netif_carrier_ok(port->netdev)) {
                                ret = ehea_sense_port_attr(
-                                       adapter->port[portnum]);
+                                       port);
                                if (ret) {
                                        ehea_error("failed resensing port "
                                                   "attributes");
@@ -821,7 +818,7 @@ static void ehea_parse_eqe(struct ehea_adapter *adapter, u64 eqe)
                netif_stop_queue(port->netdev);
                break;
        default:
-               ehea_error("unknown event code %x", ec);
+               ehea_error("unknown event code %x, eqe=0x%lX", ec, eqe);
                break;
        }
 }
@@ -850,8 +847,7 @@ static void ehea_neq_tasklet(unsigned long data)
                            adapter->neq->fw_handle, event_mask);
 }
 
-static irqreturn_t ehea_interrupt_neq(int irq, void *param,
-                                     struct pt_regs *regs)
+static irqreturn_t ehea_interrupt_neq(int irq, void *param)
 {
        struct ehea_adapter *adapter = param;
        tasklet_hi_schedule(&adapter->neq_tasklet);
@@ -1845,7 +1841,7 @@ static int ehea_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
        if (netif_msg_tx_queued(port)) {
                ehea_info("post swqe on QP %d", pr->qp->init_attr.qp_nr);
-               ehea_dump(swqe, sizeof(*swqe), "swqe");
+               ehea_dump(swqe, 512, "swqe");
        }
 
        ehea_post_swqe(pr->qp, swqe);
index 4a85aca4c7e90c1890942754d2cd3e43cebb483e..0b51a8cea0775209ee9cc9e8c6c93277a05efbe9 100644 (file)
@@ -44,71 +44,99 @@ static inline u16 get_order_of_qentries(u16 queue_entries)
 #define H_ALL_RES_TYPE_MR        5
 #define H_ALL_RES_TYPE_MW        6
 
-static long ehea_hcall_9arg_9ret(unsigned long opcode,
-                                unsigned long arg1, unsigned long arg2,
-                                unsigned long arg3, unsigned long arg4,
-                                unsigned long arg5, unsigned long arg6,
-                                unsigned long arg7, unsigned long arg8,
-                                unsigned long arg9, unsigned long *out1,
-                                unsigned long *out2,unsigned long *out3,
-                                unsigned long *out4,unsigned long *out5,
-                                unsigned long *out6,unsigned long *out7,
-                                unsigned long *out8,unsigned long *out9)
+static long ehea_plpar_hcall_norets(unsigned long opcode,
+                                   unsigned long arg1,
+                                   unsigned long arg2,
+                                   unsigned long arg3,
+                                   unsigned long arg4,
+                                   unsigned long arg5,
+                                   unsigned long arg6,
+                                   unsigned long arg7)
 {
-       long hret;
+       long ret;
        int i, sleep_msecs;
 
        for (i = 0; i < 5; i++) {
-               hret = plpar_hcall_9arg_9ret(opcode,arg1, arg2, arg3, arg4,
-                                            arg5, arg6, arg7, arg8, arg9, out1,
-                                            out2, out3, out4, out5, out6, out7,
-                                            out8, out9);
-               if (H_IS_LONG_BUSY(hret)) {
-                       sleep_msecs = get_longbusy_msecs(hret);
+               ret = plpar_hcall_norets(opcode, arg1, arg2, arg3, arg4,
+                                        arg5, arg6, arg7);
+
+               if (H_IS_LONG_BUSY(ret)) {
+                       sleep_msecs = get_longbusy_msecs(ret);
                        msleep_interruptible(sleep_msecs);
                        continue;
                }
 
-               if (hret < H_SUCCESS)
-                       ehea_error("op=%lx hret=%lx "
-                                  "i1=%lx i2=%lx i3=%lx i4=%lx i5=%lx i6=%lx "
-                                  "i7=%lx i8=%lx i9=%lx "
-                                  "o1=%lx o2=%lx o3=%lx o4=%lx o5=%lx o6=%lx "
-                                  "o7=%lx o8=%lx o9=%lx",
-                                  opcode, hret, arg1, arg2, arg3, arg4, arg5,
-                                  arg6, arg7, arg8, arg9, *out1, *out2, *out3,
-                                  *out4, *out5, *out6, *out7, *out8, *out9);
-               return hret;
+               if (ret < H_SUCCESS)
+                       ehea_error("opcode=%lx ret=%lx"
+                                  " arg1=%lx arg2=%lx arg3=%lx arg4=%lx"
+                                  " arg5=%lx arg6=%lx arg7=%lx ",
+                                  opcode, ret,
+                                  arg1, arg2, arg3, arg4, arg5,
+                                  arg6, arg7);
+
+               return ret;
        }
+
        return H_BUSY;
 }
 
-u64 ehea_h_query_ehea_qp(const u64 adapter_handle, const u8 qp_category,
-                        const u64 qp_handle, const u64 sel_mask, void *cb_addr)
+static long ehea_plpar_hcall9(unsigned long opcode,
+                             unsigned long *outs, /* array of 9 outputs */
+                             unsigned long arg1,
+                             unsigned long arg2,
+                             unsigned long arg3,
+                             unsigned long arg4,
+                             unsigned long arg5,
+                             unsigned long arg6,
+                             unsigned long arg7,
+                             unsigned long arg8,
+                             unsigned long arg9)
 {
-       u64 dummy;
+       long ret;
+       int i, sleep_msecs;
 
-       if ((((u64)cb_addr) & (PAGE_SIZE - 1)) != 0) {
-               ehea_error("not on pageboundary");
-               return H_PARAMETER;
+       for (i = 0; i < 5; i++) {
+               ret = plpar_hcall9(opcode, outs,
+                                  arg1, arg2, arg3, arg4, arg5,
+                                  arg6, arg7, arg8, arg9);
+
+               if (H_IS_LONG_BUSY(ret)) {
+                       sleep_msecs = get_longbusy_msecs(ret);
+                       msleep_interruptible(sleep_msecs);
+                       continue;
+               }
+
+               if (ret < H_SUCCESS)
+                       ehea_error("opcode=%lx ret=%lx"
+                                  " arg1=%lx arg2=%lx arg3=%lx arg4=%lx"
+                                  " arg5=%lx arg6=%lx arg7=%lx arg8=%lx"
+                                  " arg9=%lx"
+                                  " out1=%lx out2=%lx out3=%lx out4=%lx"
+                                  " out5=%lx out6=%lx out7=%lx out8=%lx"
+                                  " out9=%lx",
+                                  opcode, ret,
+                                  arg1, arg2, arg3, arg4, arg5,
+                                  arg6, arg7, arg8, arg9,
+                                  outs[0], outs[1], outs[2], outs[3],
+                                  outs[4], outs[5], outs[6], outs[7],
+                                  outs[8]);
+
+               return ret;
        }
 
-       return ehea_hcall_9arg_9ret(H_QUERY_HEA_QP,
-                                   adapter_handle,             /* R4 */
-                                   qp_category,                /* R5 */
-                                   qp_handle,                  /* R6 */
-                                   sel_mask,                   /* R7 */
-                                   virt_to_abs(cb_addr),       /* R8 */
-                                   0, 0, 0, 0,                 /* R9-R12 */
-                                   &dummy,                     /* R4 */
-                                   &dummy,                     /* R5 */
-                                   &dummy,                     /* R6 */
-                                   &dummy,                     /* R7 */
-                                   &dummy,                     /* R8 */
-                                   &dummy,                     /* R9 */
-                                   &dummy,                     /* R10 */
-                                   &dummy,                     /* R11 */
-                                   &dummy);                    /* R12 */
+       return H_BUSY;
+}
+
+u64 ehea_h_query_ehea_qp(const u64 adapter_handle, const u8 qp_category,
+                        const u64 qp_handle, const u64 sel_mask, void *cb_addr)
+{
+       return ehea_plpar_hcall_norets(H_QUERY_HEA_QP,
+                                      adapter_handle,          /* R4 */
+                                      qp_category,             /* R5 */
+                                      qp_handle,               /* R6 */
+                                      sel_mask,                /* R7 */
+                                      virt_to_abs(cb_addr),    /* R8 */
+                                      0, 0);
 }
 
 /* input param R5 */
@@ -180,6 +208,7 @@ u64 ehea_h_alloc_resource_qp(const u64 adapter_handle,
                             u64 *qp_handle, struct h_epas *h_epas)
 {
        u64 hret;
+       u64 outs[PLPAR_HCALL9_BUFSIZE];
 
        u64 allocate_controls =
            EHEA_BMASK_SET(H_ALL_RES_QP_EQPO, init_attr->low_lat_rq1 ? 1 : 0)
@@ -219,45 +248,29 @@ u64 ehea_h_alloc_resource_qp(const u64 adapter_handle,
            EHEA_BMASK_SET(H_ALL_RES_QP_TH_RQ2, init_attr->rq2_threshold)
            | EHEA_BMASK_SET(H_ALL_RES_QP_TH_RQ3, init_attr->rq3_threshold);
 
-       u64 r5_out = 0;
-       u64 r6_out = 0;
-       u64 r7_out = 0;
-       u64 r8_out = 0;
-       u64 r9_out = 0;
-       u64 g_la_user_out = 0;
-       u64 r11_out = 0;
-       u64 r12_out = 0;
-
-       hret = ehea_hcall_9arg_9ret(H_ALLOC_HEA_RESOURCE,
-                                   adapter_handle,             /* R4 */
-                                   allocate_controls,          /* R5 */
-                                   init_attr->send_cq_handle,  /* R6 */
-                                   init_attr->recv_cq_handle,  /* R7 */
-                                   init_attr->aff_eq_handle,   /* R8 */
-                                   r9_reg,                     /* R9 */
-                                   max_r10_reg,                /* R10 */
-                                   r11_in,                     /* R11 */
-                                   threshold,                  /* R12 */
-                                   qp_handle,                  /* R4 */
-                                   &r5_out,                    /* R5 */
-                                   &r6_out,                    /* R6 */
-                                   &r7_out,                    /* R7 */
-                                   &r8_out,                    /* R8 */
-                                   &r9_out,                    /* R9 */
-                                   &g_la_user_out,             /* R10 */
-                                   &r11_out,                   /* R11 */
-                                   &r12_out);                  /* R12 */
-
-       init_attr->qp_nr = (u32)r5_out;
+       hret = ehea_plpar_hcall9(H_ALLOC_HEA_RESOURCE,
+                                outs,
+                                adapter_handle,                /* R4 */
+                                allocate_controls,             /* R5 */
+                                init_attr->send_cq_handle,     /* R6 */
+                                init_attr->recv_cq_handle,     /* R7 */
+                                init_attr->aff_eq_handle,      /* R8 */
+                                r9_reg,                        /* R9 */
+                                max_r10_reg,                   /* R10 */
+                                r11_in,                        /* R11 */
+                                threshold);                    /* R12 */
+
+       *qp_handle = outs[0];
+       init_attr->qp_nr = (u32)outs[1];
 
        init_attr->act_nr_send_wqes =
-           (u16)EHEA_BMASK_GET(H_ALL_RES_QP_ACT_SWQE, r6_out);
+           (u16)EHEA_BMASK_GET(H_ALL_RES_QP_ACT_SWQE, outs[2]);
        init_attr->act_nr_rwqes_rq1 =
-           (u16)EHEA_BMASK_GET(H_ALL_RES_QP_ACT_R1WQE, r6_out);
+           (u16)EHEA_BMASK_GET(H_ALL_RES_QP_ACT_R1WQE, outs[2]);
        init_attr->act_nr_rwqes_rq2 =
-           (u16)EHEA_BMASK_GET(H_ALL_RES_QP_ACT_R2WQE, r6_out);
+           (u16)EHEA_BMASK_GET(H_ALL_RES_QP_ACT_R2WQE, outs[2]);
        init_attr->act_nr_rwqes_rq3 =
-           (u16)EHEA_BMASK_GET(H_ALL_RES_QP_ACT_R3WQE, r6_out);
+           (u16)EHEA_BMASK_GET(H_ALL_RES_QP_ACT_R3WQE, outs[2]);
 
        init_attr->act_wqe_size_enc_sq = init_attr->wqe_size_enc_sq;
        init_attr->act_wqe_size_enc_rq1 = init_attr->wqe_size_enc_rq1;
@@ -265,25 +278,25 @@ u64 ehea_h_alloc_resource_qp(const u64 adapter_handle,
        init_attr->act_wqe_size_enc_rq3 = init_attr->wqe_size_enc_rq3;
 
        init_attr->nr_sq_pages =
-           (u32)EHEA_BMASK_GET(H_ALL_RES_QP_SIZE_SQ, r8_out);
+           (u32)EHEA_BMASK_GET(H_ALL_RES_QP_SIZE_SQ, outs[4]);
        init_attr->nr_rq1_pages =
-           (u32)EHEA_BMASK_GET(H_ALL_RES_QP_SIZE_RQ1, r8_out);
+           (u32)EHEA_BMASK_GET(H_ALL_RES_QP_SIZE_RQ1, outs[4]);
        init_attr->nr_rq2_pages =
-           (u32)EHEA_BMASK_GET(H_ALL_RES_QP_SIZE_RQ2, r9_out);
+           (u32)EHEA_BMASK_GET(H_ALL_RES_QP_SIZE_RQ2, outs[5]);
        init_attr->nr_rq3_pages =
-           (u32)EHEA_BMASK_GET(H_ALL_RES_QP_SIZE_RQ3, r9_out);
+           (u32)EHEA_BMASK_GET(H_ALL_RES_QP_SIZE_RQ3, outs[5]);
 
        init_attr->liobn_sq =
-           (u32)EHEA_BMASK_GET(H_ALL_RES_QP_LIOBN_SQ, r11_out);
+           (u32)EHEA_BMASK_GET(H_ALL_RES_QP_LIOBN_SQ, outs[7]);
        init_attr->liobn_rq1 =
-           (u32)EHEA_BMASK_GET(H_ALL_RES_QP_LIOBN_RQ1, r11_out);
+           (u32)EHEA_BMASK_GET(H_ALL_RES_QP_LIOBN_RQ1, outs[7]);
        init_attr->liobn_rq2 =
-           (u32)EHEA_BMASK_GET(H_ALL_RES_QP_LIOBN_RQ2, r12_out);
+           (u32)EHEA_BMASK_GET(H_ALL_RES_QP_LIOBN_RQ2, outs[8]);
        init_attr->liobn_rq3 =
-           (u32)EHEA_BMASK_GET(H_ALL_RES_QP_LIOBN_RQ3, r12_out);
+           (u32)EHEA_BMASK_GET(H_ALL_RES_QP_LIOBN_RQ3, outs[8]);
 
        if (!hret)
-               hcp_epas_ctor(h_epas, g_la_user_out, g_la_user_out);
+               hcp_epas_ctor(h_epas, outs[6], outs[6]);
 
        return hret;
 }
@@ -292,31 +305,24 @@ u64 ehea_h_alloc_resource_cq(const u64 adapter_handle,
                             struct ehea_cq_attr *cq_attr,
                             u64 *cq_handle, struct h_epas *epas)
 {
-       u64 hret, dummy, act_nr_of_cqes_out, act_pages_out;
-       u64 g_la_privileged_out, g_la_user_out;
-
-       hret = ehea_hcall_9arg_9ret(H_ALLOC_HEA_RESOURCE,
-                                   adapter_handle,             /* R4 */
-                                   H_ALL_RES_TYPE_CQ,          /* R5 */
-                                   cq_attr->eq_handle,         /* R6 */
-                                   cq_attr->cq_token,          /* R7 */
-                                   cq_attr->max_nr_of_cqes,    /* R8 */
-                                   0, 0, 0, 0,                 /* R9-R12 */
-                                   cq_handle,                  /* R4 */
-                                   &dummy,                     /* R5 */
-                                   &dummy,                     /* R6 */
-                                   &act_nr_of_cqes_out,        /* R7 */
-                                   &act_pages_out,             /* R8 */
-                                   &g_la_privileged_out,       /* R9 */
-                                   &g_la_user_out,             /* R10 */
-                                   &dummy,                     /* R11 */
-                                   &dummy);                    /* R12 */
-
-       cq_attr->act_nr_of_cqes = act_nr_of_cqes_out;
-       cq_attr->nr_pages = act_pages_out;
+       u64 hret;
+       u64 outs[PLPAR_HCALL9_BUFSIZE];
+
+       hret = ehea_plpar_hcall9(H_ALLOC_HEA_RESOURCE,
+                                outs,
+                                adapter_handle,                /* R4 */
+                                H_ALL_RES_TYPE_CQ,             /* R5 */
+                                cq_attr->eq_handle,            /* R6 */
+                                cq_attr->cq_token,             /* R7 */
+                                cq_attr->max_nr_of_cqes,       /* R8 */
+                                0, 0, 0, 0);                   /* R9-R12 */
+
+       *cq_handle = outs[0];
+       cq_attr->act_nr_of_cqes = outs[3];
+       cq_attr->nr_pages = outs[4];
 
        if (!hret)
-               hcp_epas_ctor(epas, g_la_privileged_out, g_la_user_out);
+               hcp_epas_ctor(epas, outs[5], outs[6]);
 
        return hret;
 }
@@ -361,9 +367,8 @@ u64 ehea_h_alloc_resource_cq(const u64 adapter_handle,
 u64 ehea_h_alloc_resource_eq(const u64 adapter_handle,
                             struct ehea_eq_attr *eq_attr, u64 *eq_handle)
 {
-       u64 hret, dummy, eq_liobn, allocate_controls;
-       u64 ist1_out, ist2_out, ist3_out, ist4_out;
-       u64 act_nr_of_eqes_out, act_pages_out;
+       u64 hret, allocate_controls;
+       u64 outs[PLPAR_HCALL9_BUFSIZE];
 
        /* resource type */
        allocate_controls =
@@ -372,27 +377,20 @@ u64 ehea_h_alloc_resource_eq(const u64 adapter_handle,
            | EHEA_BMASK_SET(H_ALL_RES_EQ_INH_EQE_GEN, !eq_attr->eqe_gen)
            | EHEA_BMASK_SET(H_ALL_RES_EQ_NON_NEQ_ISN, 1);
 
-       hret = ehea_hcall_9arg_9ret(H_ALLOC_HEA_RESOURCE,
-                                   adapter_handle,             /* R4 */
-                                   allocate_controls,          /* R5 */
-                                   eq_attr->max_nr_of_eqes,    /* R6 */
-                                   0, 0, 0, 0, 0, 0,           /* R7-R10 */
-                                   eq_handle,                  /* R4 */
-                                   &dummy,                     /* R5 */
-                                   &eq_liobn,                  /* R6 */
-                                   &act_nr_of_eqes_out,        /* R7 */
-                                   &act_pages_out,             /* R8 */
-                                   &ist1_out,                  /* R9 */
-                                   &ist2_out,                  /* R10 */
-                                   &ist3_out,                  /* R11 */
-                                   &ist4_out);                 /* R12 */
-
-       eq_attr->act_nr_of_eqes = act_nr_of_eqes_out;
-       eq_attr->nr_pages = act_pages_out;
-       eq_attr->ist1 = ist1_out;
-       eq_attr->ist2 = ist2_out;
-       eq_attr->ist3 = ist3_out;
-       eq_attr->ist4 = ist4_out;
+       hret = ehea_plpar_hcall9(H_ALLOC_HEA_RESOURCE,
+                                outs,
+                                adapter_handle,                /* R4 */
+                                allocate_controls,             /* R5 */
+                                eq_attr->max_nr_of_eqes,       /* R6 */
+                                0, 0, 0, 0, 0, 0);             /* R7-R10 */
+
+       *eq_handle = outs[0];
+       eq_attr->act_nr_of_eqes = outs[3];
+       eq_attr->nr_pages = outs[4];
+       eq_attr->ist1 = outs[5];
+       eq_attr->ist2 = outs[6];
+       eq_attr->ist3 = outs[7];
+       eq_attr->ist4 = outs[8];
 
        return hret;
 }
@@ -402,31 +400,22 @@ u64 ehea_h_modify_ehea_qp(const u64 adapter_handle, const u8 cat,
                          void *cb_addr, u64 *inv_attr_id, u64 *proc_mask,
                          u16 *out_swr, u16 *out_rwr)
 {
-       u64 hret, dummy, act_out_swr, act_out_rwr;
-
-       if ((((u64)cb_addr) & (PAGE_SIZE - 1)) != 0) {
-               ehea_error("not on page boundary");
-               return H_PARAMETER;
-       }
-
-       hret = ehea_hcall_9arg_9ret(H_MODIFY_HEA_QP,
-                                   adapter_handle,             /* R4 */
-                                   (u64) cat,                  /* R5 */
-                                   qp_handle,                  /* R6 */
-                                   sel_mask,                   /* R7 */
-                                   virt_to_abs(cb_addr),       /* R8 */
-                                   0, 0, 0, 0,                 /* R9-R12 */
-                                   inv_attr_id,                /* R4 */
-                                   &dummy,                     /* R5 */
-                                   &dummy,                     /* R6 */
-                                   &act_out_swr,               /* R7 */
-                                   &act_out_rwr,               /* R8 */
-                                   proc_mask,                  /* R9 */
-                                   &dummy,                     /* R10 */
-                                   &dummy,                     /* R11 */
-                                   &dummy);                    /* R12 */
-       *out_swr = act_out_swr;
-       *out_rwr = act_out_rwr;
+       u64 hret;
+       u64 outs[PLPAR_HCALL9_BUFSIZE];
+
+       hret = ehea_plpar_hcall9(H_MODIFY_HEA_QP,
+                                outs,
+                                adapter_handle,                /* R4 */
+                                (u64) cat,                     /* R5 */
+                                qp_handle,                     /* R6 */
+                                sel_mask,                      /* R7 */
+                                virt_to_abs(cb_addr),          /* R8 */
+                                0, 0, 0, 0);                   /* R9-R12 */
+
+       *inv_attr_id = outs[0];
+       *out_swr = outs[3];
+       *out_rwr = outs[4];
+       *proc_mask = outs[5];
 
        return hret;
 }
@@ -435,122 +424,81 @@ u64 ehea_h_register_rpage(const u64 adapter_handle, const u8 pagesize,
                          const u8 queue_type, const u64 resource_handle,
                          const u64 log_pageaddr, u64 count)
 {
-       u64 dummy, reg_control;
+       u64  reg_control;
 
        reg_control = EHEA_BMASK_SET(H_REG_RPAGE_PAGE_SIZE, pagesize)
                    | EHEA_BMASK_SET(H_REG_RPAGE_QT, queue_type);
 
-       return ehea_hcall_9arg_9ret(H_REGISTER_HEA_RPAGES,
-                                   adapter_handle,             /* R4 */
-                                   reg_control,                /* R5 */
-                                   resource_handle,            /* R6 */
-                                   log_pageaddr,               /* R7 */
-                                   count,                      /* R8 */
-                                   0, 0, 0, 0,                 /* R9-R12 */
-                                   &dummy,                     /* R4 */
-                                   &dummy,                     /* R5 */
-                                   &dummy,                     /* R6 */
-                                   &dummy,                     /* R7 */
-                                   &dummy,                     /* R8 */
-                                   &dummy,                     /* R9 */
-                                   &dummy,                     /* R10 */
-                                   &dummy,                     /* R11 */
-                                   &dummy);                    /* R12 */
+       return ehea_plpar_hcall_norets(H_REGISTER_HEA_RPAGES,
+                                      adapter_handle,          /* R4 */
+                                      reg_control,             /* R5 */
+                                      resource_handle,         /* R6 */
+                                      log_pageaddr,            /* R7 */
+                                      count,                   /* R8 */
+                                      0, 0);                   /* R9-R10 */
 }
 
 u64 ehea_h_register_smr(const u64 adapter_handle, const u64 orig_mr_handle,
                        const u64 vaddr_in, const u32 access_ctrl, const u32 pd,
                        struct ehea_mr *mr)
 {
-       u64 hret, dummy, lkey_out;
-
-       hret = ehea_hcall_9arg_9ret(H_REGISTER_SMR,
-                                   adapter_handle       ,          /* R4 */
-                                   orig_mr_handle,                 /* R5 */
-                                   vaddr_in,                       /* R6 */
-                                   (((u64)access_ctrl) << 32ULL),  /* R7 */
-                                   pd,                             /* R8 */
-                                   0, 0, 0, 0,                     /* R9-R12 */
-                                   &mr->handle,                    /* R4 */
-                                   &dummy,                         /* R5 */
-                                   &lkey_out,                      /* R6 */
-                                   &dummy,                         /* R7 */
-                                   &dummy,                         /* R8 */
-                                   &dummy,                         /* R9 */
-                                   &dummy,                         /* R10 */
-                                   &dummy,                         /* R11 */
-                                   &dummy);                        /* R12 */
-       mr->lkey = (u32)lkey_out;
+       u64 hret;
+       u64 outs[PLPAR_HCALL9_BUFSIZE];
+
+       hret = ehea_plpar_hcall9(H_REGISTER_SMR,
+                                outs,
+                                adapter_handle       ,          /* R4 */
+                                orig_mr_handle,                 /* R5 */
+                                vaddr_in,                       /* R6 */
+                                (((u64)access_ctrl) << 32ULL),  /* R7 */
+                                pd,                             /* R8 */
+                                0, 0, 0, 0);                    /* R9-R12 */
+
+       mr->handle = outs[0];
+       mr->lkey = (u32)outs[2];
 
        return hret;
 }
 
 u64 ehea_h_disable_and_get_hea(const u64 adapter_handle, const u64 qp_handle)
 {
-       u64 hret, dummy, ladr_next_sq_wqe_out;
-       u64 ladr_next_rq1_wqe_out, ladr_next_rq2_wqe_out, ladr_next_rq3_wqe_out;
-
-       hret = ehea_hcall_9arg_9ret(H_DISABLE_AND_GET_HEA,
-                                   adapter_handle,             /* R4 */
-                                   H_DISABLE_GET_EHEA_WQE_P,   /* R5 */
-                                   qp_handle,                  /* R6 */
-                                   0, 0, 0, 0, 0, 0,           /* R7-R12 */
-                                   &ladr_next_sq_wqe_out,      /* R4 */
-                                   &ladr_next_rq1_wqe_out,     /* R5 */
-                                   &ladr_next_rq2_wqe_out,     /* R6 */
-                                   &ladr_next_rq3_wqe_out,     /* R7 */
-                                   &dummy,                     /* R8 */
-                                   &dummy,                     /* R9 */
-                                   &dummy,                     /* R10 */
-                                   &dummy,                     /* R11 */
-                                   &dummy);                    /* R12 */
-       return hret;
+       u64 outs[PLPAR_HCALL9_BUFSIZE];
+
+       return ehea_plpar_hcall9(H_DISABLE_AND_GET_HEA,
+                                        outs,
+                                adapter_handle,                /* R4 */
+                                H_DISABLE_GET_EHEA_WQE_P,      /* R5 */
+                                qp_handle,                     /* R6 */
+                                0, 0, 0, 0, 0, 0);             /* R7-R12 */
 }
 
 u64 ehea_h_free_resource(const u64 adapter_handle, const u64 res_handle)
 {
-       u64 dummy;
-
-       return ehea_hcall_9arg_9ret(H_FREE_RESOURCE,
-                                   adapter_handle,        /* R4 */
-                                   res_handle,            /* R5 */
-                                   0, 0, 0, 0, 0, 0, 0,   /* R6-R12 */
-                                   &dummy,                /* R4 */
-                                   &dummy,                /* R5 */
-                                   &dummy,                /* R6 */
-                                   &dummy,                /* R7 */
-                                   &dummy,                /* R8 */
-                                   &dummy,                /* R9 */
-                                   &dummy,                /* R10 */
-                                   &dummy,                /* R11 */
-                                   &dummy);               /* R12 */
+       return ehea_plpar_hcall_norets(H_FREE_RESOURCE,
+                                      adapter_handle,     /* R4 */
+                                      res_handle,         /* R5 */
+                                      0, 0, 0, 0, 0);     /* R6-R10 */
 }
 
 u64 ehea_h_alloc_resource_mr(const u64 adapter_handle, const u64 vaddr,
                             const u64 length, const u32 access_ctrl,
                             const u32 pd, u64 *mr_handle, u32 *lkey)
 {
-       u64 hret, dummy, lkey_out;
-
-       hret = ehea_hcall_9arg_9ret(H_ALLOC_HEA_RESOURCE,
-                                   adapter_handle,                /* R4 */
-                                   5,                             /* R5 */
-                                   vaddr,                         /* R6 */
-                                   length,                        /* R7 */
-                                   (((u64) access_ctrl) << 32ULL),/* R8 */
-                                   pd,                            /* R9 */
-                                   0, 0, 0,                       /* R10-R12 */
-                                   mr_handle,                     /* R4 */
-                                   &dummy,                        /* R5 */
-                                   &lkey_out,                     /* R6 */
-                                   &dummy,                        /* R7 */
-                                   &dummy,                        /* R8 */
-                                   &dummy,                        /* R9 */
-                                   &dummy,                        /* R10 */
-                                   &dummy,                        /* R11 */
-                                   &dummy);                       /* R12 */
-       *lkey = (u32) lkey_out;
-
+       u64 hret;
+       u64 outs[PLPAR_HCALL9_BUFSIZE];
+
+       hret = ehea_plpar_hcall9(H_ALLOC_HEA_RESOURCE,
+                                outs,
+                                adapter_handle,                   /* R4 */
+                                5,                                /* R5 */
+                                vaddr,                            /* R6 */
+                                length,                           /* R7 */
+                                (((u64) access_ctrl) << 32ULL),   /* R8 */
+                                pd,                               /* R9 */
+                                0, 0, 0);                         /* R10-R12 */
+
+       *mr_handle = outs[0];
+       *lkey = (u32)outs[2];
        return hret;
 }
 
@@ -570,23 +518,14 @@ u64 ehea_h_register_rpage_mr(const u64 adapter_handle, const u64 mr_handle,
 
 u64 ehea_h_query_ehea(const u64 adapter_handle, void *cb_addr)
 {
-       u64 hret, dummy, cb_logaddr;
+       u64 hret, cb_logaddr;
 
        cb_logaddr = virt_to_abs(cb_addr);
 
-       hret = ehea_hcall_9arg_9ret(H_QUERY_HEA,
-                                   adapter_handle,             /* R4 */
-                                   cb_logaddr,                 /* R5 */
-                                   0, 0, 0, 0, 0, 0, 0,        /* R6-R12 */
-                                   &dummy,                     /* R4 */
-                                   &dummy,                     /* R5 */
-                                   &dummy,                     /* R6 */
-                                   &dummy,                     /* R7 */
-                                   &dummy,                     /* R8 */
-                                   &dummy,                     /* R9 */
-                                   &dummy,                     /* R10 */
-                                   &dummy,                     /* R11 */
-                                   &dummy);                    /* R12 */
+       hret = ehea_plpar_hcall_norets(H_QUERY_HEA,
+                                      adapter_handle,          /* R4 */
+                                      cb_logaddr,              /* R5 */
+                                      0, 0, 0, 0, 0);          /* R6-R10 */
 #ifdef DEBUG
        ehea_dmp(cb_addr, sizeof(struct hcp_query_ehea), "hcp_query_ehea");
 #endif
@@ -597,36 +536,28 @@ u64 ehea_h_query_ehea_port(const u64 adapter_handle, const u16 port_num,
                           const u8 cb_cat, const u64 select_mask,
                           void *cb_addr)
 {
-       u64 port_info, dummy;
+       u64 port_info;
        u64 cb_logaddr = virt_to_abs(cb_addr);
        u64 arr_index = 0;
 
        port_info = EHEA_BMASK_SET(H_MEHEAPORT_CAT, cb_cat)
                  | EHEA_BMASK_SET(H_MEHEAPORT_PN, port_num);
 
-       return ehea_hcall_9arg_9ret(H_QUERY_HEA_PORT,
-                                   adapter_handle,             /* R4 */
-                                   port_info,                  /* R5 */
-                                   select_mask,                /* R6 */
-                                   arr_index,                  /* R7 */
-                                   cb_logaddr,                 /* R8 */
-                                   0, 0, 0, 0,                 /* R9-R12 */
-                                   &dummy,                     /* R4 */
-                                   &dummy,                     /* R5 */
-                                   &dummy,                     /* R6 */
-                                   &dummy,                     /* R7 */
-                                   &dummy,                     /* R8 */
-                                   &dummy,                     /* R9 */
-                                   &dummy,                     /* R10 */
-                                   &dummy,                     /* R11 */
-                                   &dummy);                    /* R12 */
+       return ehea_plpar_hcall_norets(H_QUERY_HEA_PORT,
+                                      adapter_handle,          /* R4 */
+                                      port_info,               /* R5 */
+                                      select_mask,             /* R6 */
+                                      arr_index,               /* R7 */
+                                      cb_logaddr,              /* R8 */
+                                      0, 0);                   /* R9-R10 */
 }
 
 u64 ehea_h_modify_ehea_port(const u64 adapter_handle, const u16 port_num,
                            const u8 cb_cat, const u64 select_mask,
                            void *cb_addr)
 {
-       u64 port_info, dummy, inv_attr_ident, proc_mask;
+       u64 outs[PLPAR_HCALL9_BUFSIZE];
+       u64 port_info;
        u64 arr_index = 0;
        u64 cb_logaddr = virt_to_abs(cb_addr);
 
@@ -635,29 +566,21 @@ u64 ehea_h_modify_ehea_port(const u64 adapter_handle, const u16 port_num,
 #ifdef DEBUG
        ehea_dump(cb_addr, sizeof(struct hcp_ehea_port_cb0), "Before HCALL");
 #endif
-       return ehea_hcall_9arg_9ret(H_MODIFY_HEA_PORT,
-                                   adapter_handle,             /* R4 */
-                                   port_info,                  /* R5 */
-                                   select_mask,                /* R6 */
-                                   arr_index,                  /* R7 */
-                                   cb_logaddr,                 /* R8 */
-                                   0, 0, 0, 0,                 /* R9-R12 */
-                                   &inv_attr_ident,            /* R4 */
-                                   &proc_mask,                 /* R5 */
-                                   &dummy,                     /* R6 */
-                                   &dummy,                     /* R7 */
-                                   &dummy,                     /* R8 */
-                                   &dummy,                     /* R9 */
-                                   &dummy,                     /* R10 */
-                                   &dummy,                     /* R11 */
-                                   &dummy);                    /* R12 */
+       return ehea_plpar_hcall9(H_MODIFY_HEA_PORT,
+                                outs,
+                                adapter_handle,                /* R4 */
+                                port_info,                     /* R5 */
+                                select_mask,                   /* R6 */
+                                arr_index,                     /* R7 */
+                                cb_logaddr,                    /* R8 */
+                                0, 0, 0, 0);                   /* R9-R12 */
 }
 
 u64 ehea_h_reg_dereg_bcmc(const u64 adapter_handle, const u16 port_num,
                          const u8 reg_type, const u64 mc_mac_addr,
                          const u16 vlan_id, const u32 hcall_id)
 {
-       u64 r5_port_num, r6_reg_type, r7_mc_mac_addr, r8_vlan_id, dummy;
+       u64 r5_port_num, r6_reg_type, r7_mc_mac_addr, r8_vlan_id;
        u64 mac_addr = mc_mac_addr >> 16;
 
        r5_port_num = EHEA_BMASK_SET(H_REGBCMC_PN, port_num);
@@ -665,41 +588,21 @@ u64 ehea_h_reg_dereg_bcmc(const u64 adapter_handle, const u16 port_num,
        r7_mc_mac_addr = EHEA_BMASK_SET(H_REGBCMC_MACADDR, mac_addr);
        r8_vlan_id = EHEA_BMASK_SET(H_REGBCMC_VLANID, vlan_id);
 
-       return ehea_hcall_9arg_9ret(hcall_id,
-                                   adapter_handle,             /* R4 */
-                                   r5_port_num,                /* R5 */
-                                   r6_reg_type,                /* R6 */
-                                   r7_mc_mac_addr,             /* R7 */
-                                   r8_vlan_id,                 /* R8 */
-                                   0, 0, 0, 0,                 /* R9-R12 */
-                                   &dummy,                     /* R4 */
-                                   &dummy,                     /* R5 */
-                                   &dummy,                     /* R6 */
-                                   &dummy,                     /* R7 */
-                                   &dummy,                     /* R8 */
-                                   &dummy,                     /* R9 */
-                                   &dummy,                     /* R10 */
-                                   &dummy,                     /* R11 */
-                                   &dummy);                    /* R12 */
+       return ehea_plpar_hcall_norets(hcall_id,
+                                      adapter_handle,          /* R4 */
+                                      r5_port_num,             /* R5 */
+                                      r6_reg_type,             /* R6 */
+                                      r7_mc_mac_addr,          /* R7 */
+                                      r8_vlan_id,              /* R8 */
+                                      0, 0);                   /* R9-R12 */
 }
 
 u64 ehea_h_reset_events(const u64 adapter_handle, const u64 neq_handle,
                        const u64 event_mask)
 {
-       u64 dummy;
-
-       return ehea_hcall_9arg_9ret(H_RESET_EVENTS,
-                                   adapter_handle,             /* R4 */
-                                   neq_handle,                 /* R5 */
-                                   event_mask,                 /* R6 */
-                                   0, 0, 0, 0, 0, 0,           /* R7-R12 */
-                                   &dummy,                     /* R4 */
-                                   &dummy,                     /* R5 */
-                                   &dummy,                     /* R6 */
-                                   &dummy,                     /* R7 */
-                                   &dummy,                     /* R8 */
-                                   &dummy,                     /* R9 */
-                                   &dummy,                     /* R10 */
-                                   &dummy,                     /* R11 */
-                                   &dummy);                    /* R12 */
+       return ehea_plpar_hcall_norets(H_RESET_EVENTS,
+                                      adapter_handle,          /* R4 */
+                                      neq_handle,              /* R5 */
+                                      event_mask,              /* R6 */
+                                      0, 0, 0, 0);             /* R7-R12 */
 }
index ba2565ee0439a59c4d9be426e3edd25fe32886d6..3a6a83d3ee1cea872823419e8642d78c49e3e622 100644 (file)
@@ -297,7 +297,7 @@ static void epic_init_ring(struct net_device *dev);
 static int epic_start_xmit(struct sk_buff *skb, struct net_device *dev);
 static int epic_rx(struct net_device *dev, int budget);
 static int epic_poll(struct net_device *dev, int *budget);
-static irqreturn_t epic_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
+static irqreturn_t epic_interrupt(int irq, void *dev_instance);
 static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
 static const struct ethtool_ops netdev_ethtool_ops;
 static int epic_close(struct net_device *dev);
@@ -1081,7 +1081,7 @@ static void epic_tx(struct net_device *dev, struct epic_private *ep)
 
 /* The interrupt handler does all of the Rx thread work and cleans up
    after the Tx thread. */
-static irqreturn_t epic_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
+static irqreturn_t epic_interrupt(int irq, void *dev_instance)
 {
        struct net_device *dev = dev_instance;
        struct epic_private *ep = dev->priv;
index f16b6a5aaa3433fb2fb05b170a5e91525f17e032..b7b8bc2a6307ef7215df4d4390ff4c53f8fc9934 100644 (file)
@@ -162,9 +162,9 @@ static char *version =
 #include <linux/skbuff.h>
 #include <linux/bitops.h>
 #include <linux/jiffies.h>
+#include <linux/io.h>
 
 #include <asm/system.h>
-#include <asm/io.h>
 #include <asm/dma.h>
 
 
@@ -410,7 +410,7 @@ static int     eth16i_close(struct net_device *dev);
 static int     eth16i_tx(struct sk_buff *skb, struct net_device *dev);
 static void    eth16i_rx(struct net_device *dev);
 static void    eth16i_timeout(struct net_device *dev);
-static irqreturn_t eth16i_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t eth16i_interrupt(int irq, void *dev_id);
 static void    eth16i_reset(struct net_device *dev);
 static void    eth16i_timeout(struct net_device *dev);
 static void    eth16i_skip_packet(struct net_device *dev);
@@ -1226,7 +1226,7 @@ static void eth16i_rx(struct net_device *dev)
        } /* while */
 }
 
-static irqreturn_t eth16i_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t eth16i_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
        struct eth16i_local *lp;
index 75a43f7c70cf9755eb6661f3a4af5f34e367402f..c8c41f0a47d6631c594b12e0dde3ae0f55c6fcf1 100644 (file)
@@ -300,7 +300,7 @@ struct ewrk3_private {
  */
 static int ewrk3_open(struct net_device *dev);
 static int ewrk3_queue_pkt(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t ewrk3_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t ewrk3_interrupt(int irq, void *dev_id);
 static int ewrk3_close(struct net_device *dev);
 static struct net_device_stats *ewrk3_get_stats(struct net_device *dev);
 static void set_multicast_list(struct net_device *dev);
@@ -884,7 +884,7 @@ err_out:
 /*
    ** The EWRK3 interrupt handler.
  */
-static irqreturn_t ewrk3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t ewrk3_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
        struct ewrk3_private *lp;
index 191bd429076aacc9efefdf9f86ba70024fcc540b..38a13f44053035945f018a2c0b037b28ce010153 100644 (file)
@@ -434,7 +434,7 @@ static void reset_timer(unsigned long data);
 static void tx_timeout(struct net_device *dev);
 static void init_ring(struct net_device *dev);
 static int start_tx(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t intr_handler(int irq, void *dev_instance, struct pt_regs *regs);
+static irqreturn_t intr_handler(int irq, void *dev_instance);
 static int netdev_rx(struct net_device *dev);
 static void set_rx_mode(struct net_device *dev);
 static void __set_rx_mode(struct net_device *dev);
@@ -1453,7 +1453,7 @@ static void reset_rx_descriptors(struct net_device *dev)
 
 /* The interrupt handler does all of the Rx thread work and cleans up
    after the Tx thread. */
-static irqreturn_t intr_handler(int irq, void *dev_instance, struct pt_regs *rgs)
+static irqreturn_t intr_handler(int irq, void *dev_instance)
 {
        struct net_device *dev = (struct net_device *) dev_instance;
        struct netdev_private *np = netdev_priv(dev);
index 55d86bc4c104ec101abb2be2be9bad886f11f678..6764281b4531b713c291d0c3e3ce158be8d28ed6 100644 (file)
@@ -229,7 +229,7 @@ struct fec_enet_private {
 static int fec_enet_open(struct net_device *dev);
 static int fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev);
 static void fec_enet_mii(struct net_device *dev);
-static irqreturn_t fec_enet_interrupt(int irq, void * dev_id, struct pt_regs * regs);
+static irqreturn_t fec_enet_interrupt(int irq, void * dev_id);
 static void fec_enet_tx(struct net_device *dev);
 static void fec_enet_rx(struct net_device *dev);
 static int fec_enet_close(struct net_device *dev);
@@ -450,7 +450,7 @@ fec_timeout(struct net_device *dev)
  * This is called from the MPC core interrupt.
  */
 static irqreturn_t
-fec_enet_interrupt(int irq, void * dev_id, struct pt_regs * regs)
+fec_enet_interrupt(int irq, void * dev_id)
 {
        struct  net_device *dev = dev_id;
        volatile fec_t  *fecp;
@@ -1236,7 +1236,7 @@ static void
 mii_link_interrupt(void *dev_id);
 #else
 static irqreturn_t
-mii_link_interrupt(int irq, void * dev_id, struct pt_regs * regs);
+mii_link_interrupt(int irq, void * dev_id);
 #endif
 #endif
 
@@ -1251,7 +1251,7 @@ static void __inline__ fec_request_intrs(struct net_device *dev)
        static const struct idesc {
                char *name;
                unsigned short irq;
-               irqreturn_t (*handler)(int, void *, struct pt_regs *);
+               irq_handler_t handler;
        } *idp, id[] = {
                { "fec(RX)", 86, fec_enet_interrupt },
                { "fec(TX)", 87, fec_enet_interrupt },
@@ -2117,7 +2117,7 @@ static void
 mii_link_interrupt(void *dev_id)
 #else
 static irqreturn_t
-mii_link_interrupt(int irq, void * dev_id, struct pt_regs * regs)
+mii_link_interrupt(int irq, void * dev_id)
 #endif
 {
        struct  net_device *dev = dev_id;
index e17a1449ee105366dcb0caccc703216edd7ee537..8e7a56fadfd2b1e29ba0eed297338a36ec609c44 100644 (file)
@@ -708,7 +708,7 @@ static void fec_enet_tx(struct net_device *dev)
  * This is called from the MPC core interrupt.
  */
 static irqreturn_t
-fec_enet_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+fec_enet_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
        struct fec_enet_private *fep;
@@ -768,7 +768,7 @@ fec_enet_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 
 /* This interrupt occurs when the PHY detects a link change. */
 static irqreturn_t
-fec_mii_link_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+fec_mii_link_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
        struct fec_enet_private *fep;
index eea1d66c530e1e32a5a4468779b8f39588542127..c5ed635bce36dc754416cb2f53827f82e5aabd3f 100644 (file)
@@ -2397,7 +2397,7 @@ static void nv_link_irq(struct net_device *dev)
        dprintk(KERN_DEBUG "%s: link change notification done.\n", dev->name);
 }
 
-static irqreturn_t nv_nic_irq(int foo, void *data, struct pt_regs *regs)
+static irqreturn_t nv_nic_irq(int foo, void *data)
 {
        struct net_device *dev = (struct net_device *) data;
        struct fe_priv *np = netdev_priv(dev);
@@ -2490,13 +2490,14 @@ static irqreturn_t nv_nic_irq(int foo, void *data, struct pt_regs *regs)
        return IRQ_RETVAL(i);
 }
 
-static irqreturn_t nv_nic_irq_tx(int foo, void *data, struct pt_regs *regs)
+static irqreturn_t nv_nic_irq_tx(int foo, void *data)
 {
        struct net_device *dev = (struct net_device *) data;
        struct fe_priv *np = netdev_priv(dev);
        u8 __iomem *base = get_hwbase(dev);
        u32 events;
        int i;
+       unsigned long flags;
 
        dprintk(KERN_DEBUG "%s: nv_nic_irq_tx\n", dev->name);
 
@@ -2508,16 +2509,16 @@ static irqreturn_t nv_nic_irq_tx(int foo, void *data, struct pt_regs *regs)
                if (!(events & np->irqmask))
                        break;
 
-               spin_lock_irq(&np->lock);
+               spin_lock_irqsave(&np->lock, flags);
                nv_tx_done(dev);
-               spin_unlock_irq(&np->lock);
+               spin_unlock_irqrestore(&np->lock, flags);
 
                if (events & (NVREG_IRQ_TX_ERR)) {
                        dprintk(KERN_DEBUG "%s: received irq with events 0x%x. Probably TX fail.\n",
                                                dev->name, events);
                }
                if (i > max_interrupt_work) {
-                       spin_lock_irq(&np->lock);
+                       spin_lock_irqsave(&np->lock, flags);
                        /* disable interrupts on the nic */
                        writel(NVREG_IRQ_TX_ALL, base + NvRegIrqMask);
                        pci_push(base);
@@ -2527,7 +2528,7 @@ static irqreturn_t nv_nic_irq_tx(int foo, void *data, struct pt_regs *regs)
                                mod_timer(&np->nic_poll, jiffies + POLL_WAIT);
                        }
                        printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_tx.\n", dev->name, i);
-                       spin_unlock_irq(&np->lock);
+                       spin_unlock_irqrestore(&np->lock, flags);
                        break;
                }
 
@@ -2576,7 +2577,7 @@ static int nv_napi_poll(struct net_device *dev, int *budget)
 #endif
 
 #ifdef CONFIG_FORCEDETH_NAPI
-static irqreturn_t nv_nic_irq_rx(int foo, void *data, struct pt_regs *regs)
+static irqreturn_t nv_nic_irq_rx(int foo, void *data)
 {
        struct net_device *dev = (struct net_device *) data;
        u8 __iomem *base = get_hwbase(dev);
@@ -2594,13 +2595,14 @@ static irqreturn_t nv_nic_irq_rx(int foo, void *data, struct pt_regs *regs)
        return IRQ_HANDLED;
 }
 #else
-static irqreturn_t nv_nic_irq_rx(int foo, void *data, struct pt_regs *regs)
+static irqreturn_t nv_nic_irq_rx(int foo, void *data)
 {
        struct net_device *dev = (struct net_device *) data;
        struct fe_priv *np = netdev_priv(dev);
        u8 __iomem *base = get_hwbase(dev);
        u32 events;
        int i;
+       unsigned long flags;
 
        dprintk(KERN_DEBUG "%s: nv_nic_irq_rx\n", dev->name);
 
@@ -2614,14 +2616,14 @@ static irqreturn_t nv_nic_irq_rx(int foo, void *data, struct pt_regs *regs)
 
                nv_rx_process(dev, dev->weight);
                if (nv_alloc_rx(dev)) {
-                       spin_lock_irq(&np->lock);
+                       spin_lock_irqsave(&np->lock, flags);
                        if (!np->in_shutdown)
                                mod_timer(&np->oom_kick, jiffies + OOM_REFILL);
-                       spin_unlock_irq(&np->lock);
+                       spin_unlock_irqrestore(&np->lock, flags);
                }
 
                if (i > max_interrupt_work) {
-                       spin_lock_irq(&np->lock);
+                       spin_lock_irqsave(&np->lock, flags);
                        /* disable interrupts on the nic */
                        writel(NVREG_IRQ_RX_ALL, base + NvRegIrqMask);
                        pci_push(base);
@@ -2631,7 +2633,7 @@ static irqreturn_t nv_nic_irq_rx(int foo, void *data, struct pt_regs *regs)
                                mod_timer(&np->nic_poll, jiffies + POLL_WAIT);
                        }
                        printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_rx.\n", dev->name, i);
-                       spin_unlock_irq(&np->lock);
+                       spin_unlock_irqrestore(&np->lock, flags);
                        break;
                }
        }
@@ -2641,13 +2643,14 @@ static irqreturn_t nv_nic_irq_rx(int foo, void *data, struct pt_regs *regs)
 }
 #endif
 
-static irqreturn_t nv_nic_irq_other(int foo, void *data, struct pt_regs *regs)
+static irqreturn_t nv_nic_irq_other(int foo, void *data)
 {
        struct net_device *dev = (struct net_device *) data;
        struct fe_priv *np = netdev_priv(dev);
        u8 __iomem *base = get_hwbase(dev);
        u32 events;
        int i;
+       unsigned long flags;
 
        dprintk(KERN_DEBUG "%s: nv_nic_irq_other\n", dev->name);
 
@@ -2660,14 +2663,14 @@ static irqreturn_t nv_nic_irq_other(int foo, void *data, struct pt_regs *regs)
                        break;
 
                if (events & NVREG_IRQ_LINK) {
-                       spin_lock_irq(&np->lock);
+                       spin_lock_irqsave(&np->lock, flags);
                        nv_link_irq(dev);
-                       spin_unlock_irq(&np->lock);
+                       spin_unlock_irqrestore(&np->lock, flags);
                }
                if (np->need_linktimer && time_after(jiffies, np->link_timeout)) {
-                       spin_lock_irq(&np->lock);
+                       spin_lock_irqsave(&np->lock, flags);
                        nv_linkchange(dev);
-                       spin_unlock_irq(&np->lock);
+                       spin_unlock_irqrestore(&np->lock, flags);
                        np->link_timeout = jiffies + LINK_TIMEOUT;
                }
                if (events & (NVREG_IRQ_UNKNOWN)) {
@@ -2675,7 +2678,7 @@ static irqreturn_t nv_nic_irq_other(int foo, void *data, struct pt_regs *regs)
                                                dev->name, events);
                }
                if (i > max_interrupt_work) {
-                       spin_lock_irq(&np->lock);
+                       spin_lock_irqsave(&np->lock, flags);
                        /* disable interrupts on the nic */
                        writel(NVREG_IRQ_OTHER, base + NvRegIrqMask);
                        pci_push(base);
@@ -2685,7 +2688,7 @@ static irqreturn_t nv_nic_irq_other(int foo, void *data, struct pt_regs *regs)
                                mod_timer(&np->nic_poll, jiffies + POLL_WAIT);
                        }
                        printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_other.\n", dev->name, i);
-                       spin_unlock_irq(&np->lock);
+                       spin_unlock_irqrestore(&np->lock, flags);
                        break;
                }
 
@@ -2695,7 +2698,7 @@ static irqreturn_t nv_nic_irq_other(int foo, void *data, struct pt_regs *regs)
        return IRQ_RETVAL(i);
 }
 
-static irqreturn_t nv_nic_irq_test(int foo, void *data, struct pt_regs *regs)
+static irqreturn_t nv_nic_irq_test(int foo, void *data)
 {
        struct net_device *dev = (struct net_device *) data;
        struct fe_priv *np = netdev_priv(dev);
@@ -2905,22 +2908,22 @@ static void nv_do_nic_poll(unsigned long data)
        pci_push(base);
 
        if (!using_multi_irqs(dev)) {
-               nv_nic_irq(0, dev, NULL);
+               nv_nic_irq(0, dev);
                if (np->msi_flags & NV_MSI_X_ENABLED)
                        enable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
                else
                        enable_irq_lockdep(dev->irq);
        } else {
                if (np->nic_poll_irq & NVREG_IRQ_RX_ALL) {
-                       nv_nic_irq_rx(0, dev, NULL);
+                       nv_nic_irq_rx(0, dev);
                        enable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector);
                }
                if (np->nic_poll_irq & NVREG_IRQ_TX_ALL) {
-                       nv_nic_irq_tx(0, dev, NULL);
+                       nv_nic_irq_tx(0, dev);
                        enable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector);
                }
                if (np->nic_poll_irq & NVREG_IRQ_OTHER) {
-                       nv_nic_irq_other(0, dev, NULL);
+                       nv_nic_irq_other(0, dev);
                        enable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_OTHER].vector);
                }
        }
index d01870619a4aefc7ca9d278b58250da77fa3f809..cb3958704a8727f65351bd87b46d1501f2897d92 100644 (file)
@@ -441,7 +441,7 @@ static void fs_enet_tx(struct net_device *dev)
  * This is called from the MPC core interrupt.
  */
 static irqreturn_t
-fs_enet_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+fs_enet_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
        struct fs_enet_private *fep;
@@ -667,7 +667,7 @@ static int fs_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
 }
 
 static int fs_request_irq(struct net_device *dev, int irq, const char *name,
-               irqreturn_t (*irqf)(int irq, void *dev_id, struct pt_regs *regs))
+               irq_handler_t irqf)
 {
        struct fs_enet_private *fep = netdev_priv(dev);
 
index 280b114e253f98f866b74377a86efc9f6b286e6e..a06d8d1aaceb36c2b917d367df0caa74190ac10e 100644 (file)
@@ -119,9 +119,9 @@ struct sk_buff *gfar_new_skb(struct net_device *dev, struct rxbd8 *bdp);
 static struct net_device_stats *gfar_get_stats(struct net_device *dev);
 static int gfar_set_mac_address(struct net_device *dev);
 static int gfar_change_mtu(struct net_device *dev, int new_mtu);
-static irqreturn_t gfar_error(int irq, void *dev_id, struct pt_regs *regs);
-static irqreturn_t gfar_transmit(int irq, void *dev_id, struct pt_regs *regs);
-static irqreturn_t gfar_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t gfar_error(int irq, void *dev_id);
+static irqreturn_t gfar_transmit(int irq, void *dev_id);
+static irqreturn_t gfar_interrupt(int irq, void *dev_id);
 static void adjust_link(struct net_device *dev);
 static void init_registers(struct net_device *dev);
 static int init_phy(struct net_device *dev);
@@ -1173,7 +1173,7 @@ static void gfar_timeout(struct net_device *dev)
 }
 
 /* Interrupt Handler for Transmit complete */
-static irqreturn_t gfar_transmit(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t gfar_transmit(int irq, void *dev_id)
 {
        struct net_device *dev = (struct net_device *) dev_id;
        struct gfar_private *priv = netdev_priv(dev);
@@ -1305,7 +1305,7 @@ static inline void count_errors(unsigned short status, struct gfar_private *priv
        }
 }
 
-irqreturn_t gfar_receive(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t gfar_receive(int irq, void *dev_id)
 {
        struct net_device *dev = (struct net_device *) dev_id;
        struct gfar_private *priv = netdev_priv(dev);
@@ -1537,7 +1537,7 @@ static int gfar_poll(struct net_device *dev, int *budget)
 #endif
 
 /* The interrupt handler for devices with one interrupt */
-static irqreturn_t gfar_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t gfar_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
        struct gfar_private *priv = netdev_priv(dev);
@@ -1550,11 +1550,11 @@ static irqreturn_t gfar_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 
        /* Check for reception */
        if ((events & IEVENT_RXF0) || (events & IEVENT_RXB0))
-               gfar_receive(irq, dev_id, regs);
+               gfar_receive(irq, dev_id);
 
        /* Check for transmit completion */
        if ((events & IEVENT_TXF) || (events & IEVENT_TXB))
-               gfar_transmit(irq, dev_id, regs);
+               gfar_transmit(irq, dev_id);
 
        /* Update error statistics */
        if (events & IEVENT_TXE) {
@@ -1578,7 +1578,7 @@ static irqreturn_t gfar_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                priv->stats.rx_errors++;
                priv->extra_stats.rx_bsy++;
 
-               gfar_receive(irq, dev_id, regs);
+               gfar_receive(irq, dev_id);
 
 #ifndef CONFIG_GFAR_NAPI
                /* Clear the halt bit in RSTAT */
@@ -1857,7 +1857,7 @@ static void gfar_set_mac_for_addr(struct net_device *dev, int num, u8 *addr)
 }
 
 /* GFAR error interrupt handler */
-static irqreturn_t gfar_error(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t gfar_error(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
        struct gfar_private *priv = netdev_priv(dev);
@@ -1898,7 +1898,7 @@ static irqreturn_t gfar_error(int irq, void *dev_id, struct pt_regs *regs)
                priv->stats.rx_errors++;
                priv->extra_stats.rx_bsy++;
 
-               gfar_receive(irq, dev_id, regs);
+               gfar_receive(irq, dev_id);
 
 #ifndef CONFIG_GFAR_NAPI
                /* Clear the halt bit in RSTAT */
index c35d47c40c390c2e57f3d553edb8426e78aa3b35..9e81a50cf2bea19edd78a989338fd4e935de0d72 100644 (file)
@@ -754,7 +754,7 @@ static inline void gfar_write(volatile unsigned __iomem *addr, u32 val)
        out_be32(addr, val);
 }
 
-extern irqreturn_t gfar_receive(int irq, void *dev_id, struct pt_regs *regs);
+extern irqreturn_t gfar_receive(int irq, void *dev_id);
 extern int startup_gfar(struct net_device *dev);
 extern void stop_gfar(struct net_device *dev);
 extern void gfar_halt(struct net_device *dev);
index 5c89ae78a519cb48c974d6ddc57dc03c39f9c0dd..c3c0d67fc38300fcded063cd448aa99ad2c9e24a 100644 (file)
@@ -556,7 +556,7 @@ static void hamachi_timer(unsigned long data);
 static void hamachi_tx_timeout(struct net_device *dev);
 static void hamachi_init_ring(struct net_device *dev);
 static int hamachi_start_xmit(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t hamachi_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
+static irqreturn_t hamachi_interrupt(int irq, void *dev_instance);
 static int hamachi_rx(struct net_device *dev);
 static inline int hamachi_tx(struct net_device *dev);
 static void hamachi_error(struct net_device *dev, int intr_status);
@@ -1376,7 +1376,7 @@ static int hamachi_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 /* The interrupt handler does all of the Rx thread work and cleans up
    after the Tx thread. */
-static irqreturn_t hamachi_interrupt(int irq, void *dev_instance, struct pt_regs *rgs)
+static irqreturn_t hamachi_interrupt(int irq, void *dev_instance)
 {
        struct net_device *dev = dev_instance;
        struct hamachi_private *hmp = netdev_priv(dev);
index 9220de9f4fe729bf1d7d5fdbf345d71f0120df98..1ed9cccd3c11ea5bdca936de6abbe1c6bc6e4e3d 100644 (file)
@@ -323,7 +323,7 @@ static int eppconfig(struct baycom_state *bc)
 
 /* ---------------------------------------------------------------------- */
 
-static void epp_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static void epp_interrupt(int irq, void *dev_id)
 {
 }
 
index 77411a00d1ee6137d04b56c7c243d5e15260cbfe..5930aeb35015f5ffaa4025cd622f218293141629 100644 (file)
@@ -270,7 +270,7 @@ static __inline__ void par96_rx(struct net_device *dev, struct baycom_state *bc)
 
 /* --------------------------------------------------------------------- */
 
-static void par96_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static void par96_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = (struct net_device *)dev_id;
        struct baycom_state *bc = netdev_priv(dev);
index 55906c7b4bb12e25c877225901a83543dd0ccf12..59214e74b9cf5bcd05ff614bf2a5bb3553afa41a 100644 (file)
@@ -279,7 +279,7 @@ static __inline__ void ser12_rx(struct net_device *dev, struct baycom_state *bc,
 
 /* --------------------------------------------------------------------- */
 
-static irqreturn_t ser12_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t ser12_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = (struct net_device *)dev_id;
        struct baycom_state *bc = netdev_priv(dev);
index de95de8983dae4a46c78013ca2eb5604ff87f318..3bcc57acbe6d9515ec49922fd2a529f27a8b2418 100644 (file)
@@ -373,7 +373,7 @@ static inline void ser12_rx(struct net_device *dev, struct baycom_state *bc)
 
 /* --------------------------------------------------------------------- */
 
-static irqreturn_t ser12_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t ser12_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = (struct net_device *)dev_id;
        struct baycom_state *bc = netdev_priv(dev);
index c9a46b89942af382ec10ac71f7a3710343fd0944..0f8b9afd55b43c2b739713252a4aab37be086f3b 100644 (file)
@@ -249,7 +249,7 @@ static void start_timer(struct scc_priv *priv, int t, int r15);
 static inline unsigned char random(void);
 
 static inline void z8530_isr(struct scc_info *info);
-static irqreturn_t scc_isr(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t scc_isr(int irq, void *dev_id);
 static void rx_isr(struct scc_priv *priv);
 static void special_condition(struct scc_priv *priv, int rc);
 static void rx_bh(void *arg);
@@ -1142,7 +1142,7 @@ static inline void z8530_isr(struct scc_info *info)
 }
 
 
-static irqreturn_t scc_isr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t scc_isr(int irq, void *dev_id)
 {
        struct scc_info *info = dev_id;
 
index df4b68142ac7b6dfdd1e43640ecfd83898f2f318..ec9b6d9b6f05d2465e9bd6c1e6f10d49e1520912 100644 (file)
@@ -200,7 +200,7 @@ static void z8530_init(void);
 
 static void init_channel(struct scc_channel *scc);
 static void scc_key_trx (struct scc_channel *scc, char tx);
-static irqreturn_t scc_isr(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t scc_isr(int irq, void *dev_id);
 static void scc_init_timer(struct scc_channel *scc);
 
 static int scc_net_alloc(const char *name, struct scc_channel *scc);
@@ -626,7 +626,7 @@ static void scc_isr_dispatch(struct scc_channel *scc, int vector)
 
 #define SCC_IRQTIMEOUT 30000
 
-static irqreturn_t scc_isr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t scc_isr(int irq, void *dev_id)
 {
        unsigned char vector;   
        struct scc_channel *scc;
index f98f5777dfbb7807729e20c79651ee8c7291e1bb..3c4455bd466d1984779fe6cc33eb9096eea34170 100644 (file)
@@ -702,7 +702,7 @@ static void yam_tx_byte(struct net_device *dev, struct yam_port *yp)
 * ISR routine
 ************************************************************************************/
 
-static irqreturn_t yam_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t yam_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev;
        struct yam_port *yp;
index ae8ad4f763bff9fa1e5634c7422d6aef1fd87ae3..844c136e9920cc92c98d5abbb60c7a8a7767a14c 100644 (file)
@@ -249,7 +249,7 @@ static void hp100_misc_interrupt(struct net_device *dev);
 static void hp100_update_stats(struct net_device *dev);
 static void hp100_clear_stats(struct hp100_private *lp, int ioaddr);
 static void hp100_set_multicast_list(struct net_device *dev);
-static irqreturn_t hp100_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t hp100_interrupt(int irq, void *dev_id);
 static void hp100_start_interface(struct net_device *dev);
 static void hp100_stop_interface(struct net_device *dev);
 static void hp100_load_eeprom(struct net_device *dev, u_short ioaddr);
@@ -2187,7 +2187,7 @@ static void hp100_set_multicast_list(struct net_device *dev)
  *  hardware interrupt handling
  */
 
-static irqreturn_t hp100_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t hp100_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = (struct net_device *) dev_id;
        struct hp100_private *lp = netdev_priv(dev);
index d52e3bd0130173704df883bf50430bfdf56e4564..ffeafb28f782036dff1255ce92fff70efbae68fb 100644 (file)
@@ -184,7 +184,7 @@ static const char emac_stats_keys[EMAC_ETHTOOL_STATS_COUNT][ETH_GSTRING_LEN] = {
        "tx_errors"
 };
 
-static irqreturn_t emac_irq(int irq, void *dev_instance, struct pt_regs *regs);
+static irqreturn_t emac_irq(int irq, void *dev_instance);
 static void emac_clean_tx_ring(struct ocp_enet_private *dev);
 
 static inline int emac_phy_supports_gige(int phy_mode)
@@ -1515,7 +1515,7 @@ static void emac_rxde(void *param)
 }
 
 /* Hard IRQ */
-static irqreturn_t emac_irq(int irq, void *dev_instance, struct pt_regs *regs)
+static irqreturn_t emac_irq(int irq, void *dev_instance)
 {
        struct ocp_enet_private *dev = dev_instance;
        struct emac_regs __iomem *p = dev->emacp;
index c3645908034db3af5ea0c1235e15a8322242a942..92f970d402df85c86bfd8a01d4f6d363373b8d56 100644 (file)
@@ -179,8 +179,7 @@ void emac_dbg_dump_all(void)
 }
 
 #if defined(CONFIG_MAGIC_SYSRQ)
-static void emac_sysrq_handler(int key, struct pt_regs *pt_regs,
-                              struct tty_struct *tty)
+static void emac_sysrq_handler(int key, struct tty_struct *tty)
 {
        emac_dbg_dump_all();
 }
index af50e7b2e0d7f998bcb9cf5f42d728366bc384e8..6c0f071e405206a6163c020fa9de2bed538fa07f 100644 (file)
@@ -168,7 +168,7 @@ static inline void mal_disable_eob_irq(struct ibm_ocp_mal *mal)
        MAL_DBG2("%d: disable_irq" NL, mal->def->index);
 }
 
-static irqreturn_t mal_serr(int irq, void *dev_instance, struct pt_regs *regs)
+static irqreturn_t mal_serr(int irq, void *dev_instance)
 {
        struct ibm_ocp_mal *mal = dev_instance;
        u32 esr = get_mal_dcrn(mal, MAL_ESR);
@@ -216,7 +216,7 @@ static inline void mal_schedule_poll(struct ibm_ocp_mal *mal)
                MAL_DBG2("%d: already in poll" NL, mal->def->index);
 }
 
-static irqreturn_t mal_txeob(int irq, void *dev_instance, struct pt_regs *regs)
+static irqreturn_t mal_txeob(int irq, void *dev_instance)
 {
        struct ibm_ocp_mal *mal = dev_instance;
        u32 r = get_mal_dcrn(mal, MAL_TXEOBISR);
@@ -226,7 +226,7 @@ static irqreturn_t mal_txeob(int irq, void *dev_instance, struct pt_regs *regs)
        return IRQ_HANDLED;
 }
 
-static irqreturn_t mal_rxeob(int irq, void *dev_instance, struct pt_regs *regs)
+static irqreturn_t mal_rxeob(int irq, void *dev_instance)
 {
        struct ibm_ocp_mal *mal = dev_instance;
        u32 r = get_mal_dcrn(mal, MAL_RXEOBISR);
@@ -236,7 +236,7 @@ static irqreturn_t mal_rxeob(int irq, void *dev_instance, struct pt_regs *regs)
        return IRQ_HANDLED;
 }
 
-static irqreturn_t mal_txde(int irq, void *dev_instance, struct pt_regs *regs)
+static irqreturn_t mal_txde(int irq, void *dev_instance)
 {
        struct ibm_ocp_mal *mal = dev_instance;
        u32 deir = get_mal_dcrn(mal, MAL_TXDEIR);
@@ -252,7 +252,7 @@ static irqreturn_t mal_txde(int irq, void *dev_instance, struct pt_regs *regs)
        return IRQ_HANDLED;
 }
 
-static irqreturn_t mal_rxde(int irq, void *dev_instance, struct pt_regs *regs)
+static irqreturn_t mal_rxde(int irq, void *dev_instance)
 {
        struct ibm_ocp_mal *mal = dev_instance;
        struct list_head *l;
index 2a95d72fa593d9631afc7ccc88d76cf76dbb2498..3f946c811511c0566bc88699b5808c783e7d09a3 100644 (file)
@@ -705,7 +705,7 @@ static void irqtxerr_handler(struct net_device *dev)
 
 /* general interrupt entry */
 
-static irqreturn_t irq_handler(int irq, void *device, struct pt_regs *regs)
+static irqreturn_t irq_handler(int irq, void *device)
 {
        struct net_device *dev = (struct net_device *) device;
        u16 ival;
index 767203d35bc2eb7b3088ccdf69053204518000b1..44c9f993dcc4fbe657b216e3c3a8e7a3276c6d97 100644 (file)
@@ -93,7 +93,7 @@ static void ibmveth_proc_register_driver(void);
 static void ibmveth_proc_unregister_driver(void);
 static void ibmveth_proc_register_adapter(struct ibmveth_adapter *adapter);
 static void ibmveth_proc_unregister_adapter(struct ibmveth_adapter *adapter);
-static irqreturn_t ibmveth_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
+static irqreturn_t ibmveth_interrupt(int irq, void *dev_instance);
 static inline void ibmveth_rxq_harvest_buffer(struct ibmveth_adapter *adapter);
 static struct kobj_type ktype_veth_pool;
 
@@ -212,7 +212,8 @@ static void ibmveth_replenish_buffer_pool(struct ibmveth_adapter *adapter, struc
                        break;
                }
 
-               free_index = pool->consumer_index++ % pool->size;
+               free_index = pool->consumer_index;
+               pool->consumer_index = (pool->consumer_index + 1) % pool->size;
                index = pool->free_map[free_index];
 
                ibmveth_assert(index != IBM_VETH_INVALID_MAP);
@@ -238,7 +239,10 @@ static void ibmveth_replenish_buffer_pool(struct ibmveth_adapter *adapter, struc
                if(lpar_rc != H_SUCCESS) {
                        pool->free_map[free_index] = index;
                        pool->skbuff[index] = NULL;
-                       pool->consumer_index--;
+                       if (pool->consumer_index == 0)
+                               pool->consumer_index = pool->size - 1;
+                       else
+                               pool->consumer_index--;
                        dma_unmap_single(&adapter->vdev->dev,
                                        pool->dma_addr[index], pool->buff_size,
                                        DMA_FROM_DEVICE);
@@ -325,7 +329,10 @@ static void ibmveth_remove_buffer_from_pool(struct ibmveth_adapter *adapter, u64
                         adapter->rx_buff_pool[pool].buff_size,
                         DMA_FROM_DEVICE);
 
-       free_index = adapter->rx_buff_pool[pool].producer_index++ % adapter->rx_buff_pool[pool].size;
+       free_index = adapter->rx_buff_pool[pool].producer_index;
+       adapter->rx_buff_pool[pool].producer_index
+               = (adapter->rx_buff_pool[pool].producer_index + 1)
+               % adapter->rx_buff_pool[pool].size;
        adapter->rx_buff_pool[pool].free_map[free_index] = index;
 
        mb();
@@ -437,6 +444,31 @@ static void ibmveth_cleanup(struct ibmveth_adapter *adapter)
                                                 &adapter->rx_buff_pool[i]);
 }
 
+static int ibmveth_register_logical_lan(struct ibmveth_adapter *adapter,
+        union ibmveth_buf_desc rxq_desc, u64 mac_address)
+{
+       int rc, try_again = 1;
+
+       /* After a kexec the adapter will still be open, so our attempt to
+       * open it will fail. So if we get a failure we free the adapter and
+       * try again, but only once. */
+retry:
+       rc = h_register_logical_lan(adapter->vdev->unit_address,
+                                   adapter->buffer_list_dma, rxq_desc.desc,
+                                   adapter->filter_list_dma, mac_address);
+
+       if (rc != H_SUCCESS && try_again) {
+               do {
+                       rc = h_free_logical_lan(adapter->vdev->unit_address);
+               } while (H_IS_LONG_BUSY(rc) || (rc == H_BUSY));
+
+               try_again = 0;
+               goto retry;
+       }
+
+       return rc;
+}
+
 static int ibmveth_open(struct net_device *netdev)
 {
        struct ibmveth_adapter *adapter = netdev->priv;
@@ -502,12 +534,9 @@ static int ibmveth_open(struct net_device *netdev)
        ibmveth_debug_printk("filter list @ 0x%p\n", adapter->filter_list_addr);
        ibmveth_debug_printk("receive q   @ 0x%p\n", adapter->rx_queue.queue_addr);
 
+       h_vio_signal(adapter->vdev->unit_address, VIO_IRQ_DISABLE);
 
-       lpar_rc = h_register_logical_lan(adapter->vdev->unit_address,
-                                        adapter->buffer_list_dma,
-                                        rxq_desc.desc,
-                                        adapter->filter_list_dma,
-                                        mac_address);
+       lpar_rc = ibmveth_register_logical_lan(adapter, rxq_desc, mac_address);
 
        if(lpar_rc != H_SUCCESS) {
                ibmveth_error_printk("h_register_logical_lan failed with %ld\n", lpar_rc);
@@ -543,7 +572,7 @@ static int ibmveth_open(struct net_device *netdev)
        }
 
        ibmveth_debug_printk("initial replenish cycle\n");
-       ibmveth_interrupt(netdev->irq, netdev, NULL);
+       ibmveth_interrupt(netdev->irq, netdev);
 
        netif_start_queue(netdev);
 
@@ -816,7 +845,7 @@ static int ibmveth_poll(struct net_device *netdev, int *budget)
        return 0;
 }
 
-static irqreturn_t ibmveth_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
+static irqreturn_t ibmveth_interrupt(int irq, void *dev_instance)
 {
        struct net_device *netdev = dev_instance;
        struct ibmveth_adapter *adapter = netdev->priv;
@@ -905,6 +934,14 @@ static int ibmveth_change_mtu(struct net_device *dev, int new_mtu)
        return -EINVAL;
 }
 
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void ibmveth_poll_controller(struct net_device *dev)
+{
+       ibmveth_replenish_task(dev->priv);
+       ibmveth_interrupt(dev->irq, dev);
+}
+#endif
+
 static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_id *id)
 {
        int rc, i;
@@ -977,6 +1014,9 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_
        netdev->ethtool_ops           = &netdev_ethtool_ops;
        netdev->change_mtu         = ibmveth_change_mtu;
        SET_NETDEV_DEV(netdev, &dev->dev);
+#ifdef CONFIG_NET_POLL_CONTROLLER
+       netdev->poll_controller = ibmveth_poll_controller;
+#endif
        netdev->features |= NETIF_F_LLTX;
        spin_lock_init(&adapter->stats_lock);
 
@@ -1132,7 +1172,9 @@ static void ibmveth_proc_register_adapter(struct ibmveth_adapter *adapter)
 {
        struct proc_dir_entry *entry;
        if (ibmveth_proc_dir) {
-               entry = create_proc_entry(adapter->netdev->name, S_IFREG, ibmveth_proc_dir);
+               char u_addr[10];
+               sprintf(u_addr, "%x", adapter->vdev->unit_address);
+               entry = create_proc_entry(u_addr, S_IFREG, ibmveth_proc_dir);
                if (!entry) {
                        ibmveth_error_printk("Cannot create adapter proc entry");
                } else {
@@ -1147,7 +1189,9 @@ static void ibmveth_proc_register_adapter(struct ibmveth_adapter *adapter)
 static void ibmveth_proc_unregister_adapter(struct ibmveth_adapter *adapter)
 {
        if (ibmveth_proc_dir) {
-               remove_proc_entry(adapter->netdev->name, ibmveth_proc_dir);
+               char u_addr[10];
+               sprintf(u_addr, "%x", adapter->vdev->unit_address);
+               remove_proc_entry(u_addr, ibmveth_proc_dir);
        }
 }
 
@@ -1261,7 +1305,7 @@ const char * buf, size_t count)
        }
 
        /* kick the interrupt handler to allocate/deallocate pools */
-       ibmveth_interrupt(netdev->irq, netdev, NULL);
+       ibmveth_interrupt(netdev->irq, netdev);
        return count;
 }
 
index 87650237dc5c05b717cfcc778e621824a7495f28..f56b00ee385e339198e950e060558dcba9418788 100644 (file)
@@ -750,7 +750,7 @@ static void ioc3_error(struct ioc3_private *ip, u32 eisr)
 
 /* The interrupt handler does all of the Rx thread work and cleans up
    after the Tx thread.  */
-static irqreturn_t ioc3_interrupt(int irq, void *_dev, struct pt_regs *regs)
+static irqreturn_t ioc3_interrupt(int irq, void *_dev)
 {
        struct net_device *dev = (struct net_device *)_dev;
        struct ioc3_private *ip = netdev_priv(dev);
@@ -1017,7 +1017,7 @@ static void ioc3_init(struct net_device *dev)
        struct ioc3_private *ip = netdev_priv(dev);
        struct ioc3 *ioc3 = ip->regs;
 
-       del_timer(&ip->ioc3_timer);             /* Kill if running      */
+       del_timer_sync(&ip->ioc3_timer);        /* Kill if running      */
 
        ioc3_w_emcr(EMCR_RST);                  /* Reset                */
        (void) ioc3_r_emcr();                   /* Flush WB             */
@@ -1081,7 +1081,7 @@ static int ioc3_close(struct net_device *dev)
 {
        struct ioc3_private *ip = netdev_priv(dev);
 
-       del_timer(&ip->ioc3_timer);
+       del_timer_sync(&ip->ioc3_timer);
 
        netif_stop_queue(dev);
 
index 68d4c418cb98481924c5f7403d764b67b81053ef..cebf8c374bc57521fa93325fd531e3d127bccf3b 100644 (file)
@@ -660,22 +660,15 @@ static int ali_ircc_read_dongle_id (int i, chipio_t *info)
  *    An interrupt from the chip has arrived. Time to do some work
  *
  */
-static irqreturn_t ali_ircc_interrupt(int irq, void *dev_id,
-                                       struct pt_regs *regs)
+static irqreturn_t ali_ircc_interrupt(int irq, void *dev_id)
 {
-       struct net_device *dev = (struct net_device *) dev_id;
+       struct net_device *dev = dev_id;
        struct ali_ircc_cb *self;
        int ret;
                
        IRDA_DEBUG(2, "%s(), ---------------- Start ----------------\n", __FUNCTION__);
                
-       if (!dev) {
-               IRDA_WARNING("%s: irq %d for unknown device.\n",
-                            ALI_IRCC_DRIVER_NAME, irq);
-               return IRQ_NONE;
-       }       
-       
-       self = (struct ali_ircc_cb *) dev->priv;
+       self = dev->priv;
        
        spin_lock(&self->lock);
        
index 7b2b4135bb237d3a9392fb91d63badc8e8c46862..37914dc5b90ee57063b3f86c42d00eb561c99008 100644 (file)
@@ -51,7 +51,7 @@ static int au1k_irda_start(struct net_device *);
 static int au1k_irda_stop(struct net_device *dev);
 static int au1k_irda_hard_xmit(struct sk_buff *, struct net_device *);
 static int au1k_irda_rx(struct net_device *);
-static void au1k_irda_interrupt(int, void *, struct pt_regs *);
+static void au1k_irda_interrupt(int, void *);
 static void au1k_tx_timeout(struct net_device *);
 static struct net_device_stats *au1k_irda_stats(struct net_device *);
 static int au1k_irda_ioctl(struct net_device *, struct ifreq *, int);
@@ -627,7 +627,7 @@ static int au1k_irda_rx(struct net_device *dev)
 }
 
 
-void au1k_irda_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+void au1k_irda_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = (struct net_device *) dev_id;
 
index 33c07d5275da22b3ff719b6e66d4cb06167172b6..16620bd97fbf71c60738762927fb1a2c4ebd0f25 100644 (file)
@@ -657,12 +657,6 @@ toshoboe_makemttpacket (struct toshoboe_cb *self, void *buf, int mtt)
   return xbofs;
 }
 
-static int toshoboe_invalid_dev(int irq)
-{
-  printk (KERN_WARNING DRIVER_NAME ": irq %d for unknown device.\n", irq);
-  return 1;
-}
-
 #ifdef USE_PROBE
 /***********************************************************************/
 /* Probe code */
@@ -709,14 +703,11 @@ stuff_byte (__u8 byte, __u8 * buf)
 }
 
 static irqreturn_t
-toshoboe_probeinterrupt (int irq, void *dev_id, struct pt_regs *regs)
+toshoboe_probeinterrupt (int irq, void *dev_id)
 {
-  struct toshoboe_cb *self = (struct toshoboe_cb *) dev_id;
+  struct toshoboe_cb *self = dev_id;
   __u8 irqstat;
 
-  if (self == NULL && toshoboe_invalid_dev(irq))
-    return IRQ_NONE;
-
   irqstat = INB (OBOE_ISR);
 
 /* was it us */
@@ -1161,15 +1152,12 @@ dumpbufs(skb->data,skb->len,'>');
 
 /*interrupt handler */
 static irqreturn_t
-toshoboe_interrupt (int irq, void *dev_id, struct pt_regs *regs)
+toshoboe_interrupt (int irq, void *dev_id)
 {
-  struct toshoboe_cb *self = (struct toshoboe_cb *) dev_id;
+  struct toshoboe_cb *self = dev_id;
   __u8 irqstat;
   struct sk_buff *skb = NULL;
 
-  if (self == NULL && toshoboe_invalid_dev(irq))
-    return IRQ_NONE;
-
   irqstat = INB (OBOE_ISR);
 
 /* was it us */
@@ -1357,13 +1345,11 @@ toshoboe_net_open (struct net_device *dev)
 {
   struct toshoboe_cb *self;
   unsigned long flags;
+  int rc;
 
   IRDA_DEBUG (4, "%s()\n", __FUNCTION__);
 
-  IRDA_ASSERT (dev != NULL, return -1; );
-  self = (struct toshoboe_cb *) dev->priv;
-
-  IRDA_ASSERT (self != NULL, return 0; );
+  self = netdev_priv(dev);
 
   if (self->async)
     return -EBUSY;
@@ -1371,11 +1357,10 @@ toshoboe_net_open (struct net_device *dev)
   if (self->stopped)
     return 0;
 
-  if (request_irq (self->io.irq, toshoboe_interrupt,
-                   IRQF_SHARED | IRQF_DISABLED, dev->name, (void *) self))
-    {
-      return -EAGAIN;
-    }
+  rc = request_irq (self->io.irq, toshoboe_interrupt,
+                    IRQF_SHARED | IRQF_DISABLED, dev->name, self);
+  if (rc)
+       return rc;
 
   spin_lock_irqsave(&self->spinlock, flags);
   toshoboe_startchip (self);
index 383cef1f5999fbe93e994ddaad893ea7a113d6f1..14bda765c2fa81a347d8e2da624f2353000b53c9 100644 (file)
@@ -114,9 +114,9 @@ static void irda_usb_change_speed_xbofs(struct irda_usb_cb *self);
 static int irda_usb_hard_xmit(struct sk_buff *skb, struct net_device *dev);
 static int irda_usb_open(struct irda_usb_cb *self);
 static void irda_usb_close(struct irda_usb_cb *self);
-static void speed_bulk_callback(struct urb *urb, struct pt_regs *regs);
-static void write_bulk_callback(struct urb *urb, struct pt_regs *regs);
-static void irda_usb_receive(struct urb *urb, struct pt_regs *regs);
+static void speed_bulk_callback(struct urb *urb);
+static void write_bulk_callback(struct urb *urb);
+static void irda_usb_receive(struct urb *urb);
 static void irda_usb_rx_defer_expired(unsigned long data);
 static int irda_usb_net_open(struct net_device *dev);
 static int irda_usb_net_close(struct net_device *dev);
@@ -343,7 +343,7 @@ static void irda_usb_change_speed_xbofs(struct irda_usb_cb *self)
  * Speed URB callback
  * Now, we can only get called for the speed URB.
  */
-static void speed_bulk_callback(struct urb *urb, struct pt_regs *regs)
+static void speed_bulk_callback(struct urb *urb)
 {
        struct irda_usb_cb *self = urb->context;
        
@@ -562,7 +562,7 @@ drop:
 /*
  * Note : this function will be called only for tx_urb...
  */
-static void write_bulk_callback(struct urb *urb, struct pt_regs *regs)
+static void write_bulk_callback(struct urb *urb)
 {
        unsigned long flags;
        struct sk_buff *skb = urb->context;
@@ -809,7 +809,7 @@ static void irda_usb_submit(struct irda_usb_cb *self, struct sk_buff *skb, struc
  *     Called by the USB subsystem when a frame has been received
  *
  */
-static void irda_usb_receive(struct urb *urb, struct pt_regs *regs)
+static void irda_usb_receive(struct urb *urb)
 {
        struct sk_buff *skb = (struct sk_buff *) urb->context;
        struct irda_usb_cb *self; 
index ba4f3eb988b3999dfac84f8936e0b1e716e535a3..654a68b490ae6011f7810e968c8426e382b69872 100644 (file)
@@ -87,8 +87,7 @@ static struct net_device_stats *irport_net_get_stats(struct net_device *dev);
 static int irport_change_speed_complete(struct irda_task *task);
 static void irport_timeout(struct net_device *dev);
 
-static irqreturn_t irport_interrupt(int irq, void *dev_id,
-                                   struct pt_regs *regs);
+static irqreturn_t irport_interrupt(int irq, void *dev_id);
 static int irport_hard_xmit(struct sk_buff *skb, struct net_device *dev);
 static void irport_change_speed(void *priv, __u32 speed);
 static int irport_net_open(struct net_device *dev);
@@ -761,25 +760,20 @@ static inline void irport_receive(struct irport_cb *self)
 }
 
 /*
- * Function irport_interrupt (irq, dev_id, regs)
+ * Function irport_interrupt (irq, dev_id)
  *
  *    Interrupt handler
  */
-static irqreturn_t irport_interrupt(int irq, void *dev_id,
-                                   struct pt_regs *regs) 
+static irqreturn_t irport_interrupt(int irq, void *dev_id) 
 {
-       struct net_device *dev = (struct net_device *) dev_id;
+       struct net_device *dev = dev_id;
        struct irport_cb *self;
        int boguscount = 0;
        int iobase;
        int iir, lsr;
        int handled = 0;
 
-       if (!dev) {
-               IRDA_WARNING("%s() irq %d for unknown device.\n", __FUNCTION__, irq);
-               return IRQ_NONE;
-       }
-       self = (struct irport_cb *) dev->priv;
+       self = dev->priv;
 
        spin_lock(&self->lock);
 
index fc89c8c3dd7f62e3f4d5116b579615a34ae5ec10..3f46b84c6c85cd96063e812a7be370b9a05ac08d 100644 (file)
@@ -74,7 +74,7 @@ struct irport_cb {
        /* For piggyback drivers */
        void *priv;                
        void (*change_speed)(void *priv, __u32 speed);
-       int (*interrupt)(int irq, void *dev_id, struct pt_regs *regs);
+       irqreturn_t (*interrupt)(int irq, void *dev_id);
 };
 
 #endif /* IRPORT_H */
index 415ba8dc94ceb87c04b075e7656e2c663049aa06..b32c52ed19d76c62b7503a3925b294148a4165fc 100644 (file)
@@ -764,7 +764,7 @@ static struct net_device_stats *mcs_net_get_stats(struct net_device *netdev)
 }
 
 /* Receive callback function.  */
-static void mcs_receive_irq(struct urb *urb, struct pt_regs *regs)
+static void mcs_receive_irq(struct urb *urb)
 {
        __u8 *bytes;
        struct mcs_cb *mcs = urb->context;
@@ -813,7 +813,7 @@ static void mcs_receive_irq(struct urb *urb, struct pt_regs *regs)
 }
 
 /* Transmit callback funtion.  */
-static void mcs_send_irq(struct urb *urb, struct pt_regs *regs)
+static void mcs_send_irq(struct urb *urb)
 {
        struct mcs_cb *mcs = urb->context;
        struct net_device *ndev = mcs->netdev;
index 1a723d725c2abff97a110a68bcf8cb4c4878aadf..b18148cee63862b585ed38032aff5a84893ab53e 100644 (file)
@@ -156,8 +156,8 @@ static int mcs_net_close(struct net_device *netdev);
 static int mcs_net_open(struct net_device *netdev);
 static struct net_device_stats *mcs_net_get_stats(struct net_device *netdev);
 
-static void mcs_receive_irq(struct urb *urb, struct pt_regs *regs);
-static void mcs_send_irq(struct urb *urb, struct pt_regs *regs);
+static void mcs_receive_irq(struct urb *urb);
+static void mcs_send_irq(struct urb *urb);
 static int mcs_hard_xmit(struct sk_buff *skb, struct net_device *netdev);
 
 static int mcs_probe(struct usb_interface *intf,
index 7185a4ee3c1e4bf6070840964c93355bcdcad7c7..29b5ccd29d0bbcca3a7d7e78cf352da4848a9d3a 100644 (file)
@@ -2066,20 +2066,14 @@ static void nsc_ircc_fir_interrupt(struct nsc_ircc_cb *self, int iobase,
  *    An interrupt from the chip has arrived. Time to do some work
  *
  */
-static irqreturn_t nsc_ircc_interrupt(int irq, void *dev_id,
-                               struct pt_regs *regs)
+static irqreturn_t nsc_ircc_interrupt(int irq, void *dev_id)
 {
-       struct net_device *dev = (struct net_device *) dev_id;
+       struct net_device *dev = dev_id;
        struct nsc_ircc_cb *self;
        __u8 bsr, eir;
        int iobase;
 
-       if (!dev) {
-               IRDA_WARNING("%s: irq %d for unknown device.\n",
-                            driver_name, irq);
-               return IRQ_NONE;
-       }
-       self = (struct nsc_ircc_cb *) dev->priv;
+       self = dev->priv;
 
        spin_lock(&self->lock); 
 
index afb19e8d95c8dbcd5b040ac1cbf5623959d0011e..f9a1c88a42831c542d59931b55ce6c74397d60e5 100644 (file)
@@ -199,7 +199,7 @@ static int pxa_irda_set_speed(struct pxa_irda *si, int speed)
 }
 
 /* SIR interrupt service routine. */
-static irqreturn_t pxa_irda_sir_irq(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t pxa_irda_sir_irq(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
        struct pxa_irda *si = netdev_priv(dev);
@@ -281,7 +281,7 @@ static irqreturn_t pxa_irda_sir_irq(int irq, void *dev_id, struct pt_regs *regs)
 }
 
 /* FIR Receive DMA interrupt handler */
-static void pxa_irda_fir_dma_rx_irq(int channel, void *data, struct pt_regs *regs)
+static void pxa_irda_fir_dma_rx_irq(int channel, void *data)
 {
        int dcsr = DCSR(channel);
 
@@ -291,7 +291,7 @@ static void pxa_irda_fir_dma_rx_irq(int channel, void *data, struct pt_regs *reg
 }
 
 /* FIR Transmit DMA interrupt handler */
-static void pxa_irda_fir_dma_tx_irq(int channel, void *data, struct pt_regs *regs)
+static void pxa_irda_fir_dma_tx_irq(int channel, void *data)
 {
        struct net_device *dev = data;
        struct pxa_irda *si = netdev_priv(dev);
@@ -388,7 +388,7 @@ static void pxa_irda_fir_irq_eif(struct pxa_irda *si, struct net_device *dev)
 }
 
 /* FIR interrupt handler */
-static irqreturn_t pxa_irda_fir_irq(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t pxa_irda_fir_irq(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
        struct pxa_irda *si = netdev_priv(dev);
index 8d5a288d7976a249cc97c8a6d7f725191a19d9b2..937372d00398af170db4c3c6371bb2ec6c61fb10 100644 (file)
@@ -579,7 +579,7 @@ static void sa1100_irda_fir_irq(struct net_device *dev)
        sa1100_irda_rx_dma_start(si);
 }
 
-static irqreturn_t sa1100_irda_irq(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t sa1100_irda_irq(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
        if (IS_FIR(((struct sa1100_irda *)dev->priv)))
index 22358ff68c4c7d2fe200a0e5517efb21600a9802..31c623381ea84d7bfb638e36056984f725b2b6d8 100644 (file)
@@ -196,7 +196,7 @@ static void smsc_ircc_dma_xmit(struct smsc_ircc_cb *self, int bofs);
 static void smsc_ircc_dma_xmit_complete(struct smsc_ircc_cb *self);
 static void smsc_ircc_change_speed(struct smsc_ircc_cb *self, u32 speed);
 static void smsc_ircc_set_sir_speed(struct smsc_ircc_cb *self, u32 speed);
-static irqreturn_t smsc_ircc_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t smsc_ircc_interrupt(int irq, void *dev_id);
 static irqreturn_t smsc_ircc_interrupt_sir(struct net_device *dev);
 static void smsc_ircc_sir_start(struct smsc_ircc_cb *self);
 #if SMSC_IRCC2_C_SIR_STOP
@@ -1455,7 +1455,7 @@ static void smsc_ircc_sir_receive(struct smsc_ircc_cb *self)
  *    An interrupt from the chip has arrived. Time to do some work
  *
  */
-static irqreturn_t smsc_ircc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t smsc_ircc_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = (struct net_device *) dev_id;
        struct smsc_ircc_cb *self;
@@ -1520,7 +1520,7 @@ static irqreturn_t smsc_ircc_interrupt(int irq, void *dev_id, struct pt_regs *re
 }
 
 /*
- * Function irport_interrupt_sir (irq, dev_id, regs)
+ * Function irport_interrupt_sir (irq, dev_id)
  *
  *    Interrupt handler for SIR modes
  */
index 12103c93f7efb4622da065c77c9f184bdd76c10f..be8a66e702b010cb10f3b995302954e077d59698 100644 (file)
@@ -804,7 +804,7 @@ static int stir_transmit_thread(void *arg)
  * Wakes up every ms (usb round trip) with wrapped 
  * data.
  */
-static void stir_rcv_irq(struct urb *urb, struct pt_regs *regs)
+static void stir_rcv_irq(struct urb *urb)
 {
        struct stir_cb *stir = urb->context;
        int err;
index d916e1257c471d8df1c14e172f9a25963a2c00b8..c3ed9b3067e5b76fc7c9549c48ab46e11a32ac98 100644 (file)
@@ -93,8 +93,7 @@ static int via_ircc_hard_xmit_fir(struct sk_buff *skb,
                                  struct net_device *dev);
 static void via_hw_init(struct via_ircc_cb *self);
 static void via_ircc_change_speed(struct via_ircc_cb *self, __u32 baud);
-static irqreturn_t via_ircc_interrupt(int irq, void *dev_id,
-                                     struct pt_regs *regs);
+static irqreturn_t via_ircc_interrupt(int irq, void *dev_id);
 static int via_ircc_is_receiving(struct via_ircc_cb *self);
 static int via_ircc_read_dongle_id(int iobase);
 
@@ -1345,13 +1344,12 @@ static int RxTimerHandler(struct via_ircc_cb *self, int iobase)
 
 
 /*
- * Function via_ircc_interrupt (irq, dev_id, regs)
+ * Function via_ircc_interrupt (irq, dev_id)
  *
  *    An interrupt from the chip has arrived. Time to do some work
  *
  */
-static irqreturn_t via_ircc_interrupt(int irq, void *dev_id,
-                                     struct pt_regs *regs)
+static irqreturn_t via_ircc_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = (struct net_device *) dev_id;
        struct via_ircc_cb *self;
index 92d646cc9edcfc2e773332ce71b722b6be46b3c0..18c68193bf14edef5e48ab4ebf6eecb2f250ae33 100644 (file)
@@ -1455,8 +1455,7 @@ static int vlsi_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
 
 /********************************************************/
 
-static irqreturn_t vlsi_interrupt(int irq, void *dev_instance,
-                                       struct pt_regs *regs)
+static irqreturn_t vlsi_interrupt(int irq, void *dev_instance)
 {
        struct net_device *ndev = dev_instance;
        vlsi_irda_dev_t *idev = ndev->priv;
index 7de1afdeec3de2b2cb980fc40345bcb9e06ad16a..4212657fa4f976900f498d813d3cc60363f3815b 100644 (file)
@@ -1111,20 +1111,14 @@ static __u8 w83977af_fir_interrupt(struct w83977af_ir *self, int isr)
  *    An interrupt from the chip has arrived. Time to do some work
  *
  */
-static irqreturn_t w83977af_interrupt(int irq, void *dev_id,
-                                       struct pt_regs *regs)
+static irqreturn_t w83977af_interrupt(int irq, void *dev_id)
 {
-       struct net_device *dev = (struct net_device *) dev_id;
+       struct net_device *dev = dev_id;
        struct w83977af_ir *self;
        __u8 set, icr, isr;
        int iobase;
 
-       if (!dev) {
-               printk(KERN_WARNING "%s: irq %d for unknown device.\n", 
-                       driver_name, irq);
-               return IRQ_NONE;
-       }
-       self = (struct w83977af_ir *) dev->priv;
+       self = dev->priv;
 
        iobase = self->io.fir_base;
 
index 984c31d1b3fb38d633a8e03bc363ddcbbe253454..0343f12d2ffb452bc75f220f14eb2ec360feae92 100644 (file)
@@ -107,7 +107,7 @@ struct net_local {
 static int     netcard_probe1(struct net_device *dev, int ioaddr);
 static int     net_open(struct net_device *dev);
 static int     net_send_packet(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t net_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t net_interrupt(int irq, void *dev_id);
 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);
@@ -504,7 +504,7 @@ void net_tx(struct net_device *dev)
  * The typical workload of the driver:
  * Handle the network interface interrupts.
  */
-static irqreturn_t net_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+static irqreturn_t net_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
        struct net_local *np;
index 41b1d08fd57b02a066686aaa8973b7e75fef6fb5..2284e2ce1692630226e065c0c7c3c0276f194c04 100644 (file)
@@ -586,7 +586,7 @@ static void veth_handle_int(struct veth_lpevent *event)
        };
 }
 
-static void veth_handle_event(struct HvLpEvent *event, struct pt_regs *regs)
+static void veth_handle_event(struct HvLpEvent *event)
 {
        struct veth_lpevent *veth_event = (struct veth_lpevent *)event;
 
index cfde7c2569bb80314d979191fa7afad39f143122..e09f575a3a38bbfdfe1676286a7eaed8d373a4b2 100644 (file)
@@ -93,7 +93,7 @@ static int ixgb_xmit_frame(struct sk_buff *skb, struct net_device *netdev);
 static struct net_device_stats *ixgb_get_stats(struct net_device *netdev);
 static int ixgb_change_mtu(struct net_device *netdev, int new_mtu);
 static int ixgb_set_mac(struct net_device *netdev, void *p);
-static irqreturn_t ixgb_intr(int irq, void *data, struct pt_regs *regs);
+static irqreturn_t ixgb_intr(int irq, void *data);
 static boolean_t ixgb_clean_tx_irq(struct ixgb_adapter *adapter);
 
 #ifdef CONFIG_IXGB_NAPI
@@ -1687,11 +1687,10 @@ ixgb_update_stats(struct ixgb_adapter *adapter)
  * ixgb_intr - Interrupt Handler
  * @irq: interrupt number
  * @data: pointer to a network interface device structure
- * @pt_regs: CPU registers structure
  **/
 
 static irqreturn_t
-ixgb_intr(int irq, void *data, struct pt_regs *regs)
+ixgb_intr(int irq, void *data)
 {
        struct net_device *netdev = data;
        struct ixgb_adapter *adapter = netdev_priv(netdev);
@@ -2213,7 +2212,7 @@ static void ixgb_netpoll(struct net_device *dev)
        struct ixgb_adapter *adapter = netdev_priv(dev);
 
        disable_irq(adapter->pdev->irq);
-       ixgb_intr(adapter->pdev->irq, dev, NULL);
+       ixgb_intr(adapter->pdev->irq, dev);
        enable_irq(adapter->pdev->irq);
 }
 #endif
index 6eeb965b4d72b9214a3edddbfc52f6b8f7f21394..a4eccb11d6771b3199d9d08f6437956e051e8956 100644 (file)
@@ -188,7 +188,7 @@ static void ixpdev_tx_complete(void)
        }
 }
 
-static irqreturn_t ixpdev_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t ixpdev_interrupt(int irq, void *dev_id)
 {
        u32 status;
 
index f349e88e0ddfa35132c6b69f8c8eed812a7a8aa1..6efbd499d7526ebdf5fb3fb8a401a07630f71337 100644 (file)
@@ -301,7 +301,7 @@ static int lance_open(struct net_device *dev);
 static void lance_init_ring(struct net_device *dev, gfp_t mode);
 static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev);
 static int lance_rx(struct net_device *dev);
-static irqreturn_t lance_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t lance_interrupt(int irq, void *dev_id);
 static int lance_close(struct net_device *dev);
 static struct net_device_stats *lance_get_stats(struct net_device *dev);
 static void set_multicast_list(struct net_device *dev);
@@ -1012,19 +1012,13 @@ out:
 }
 
 /* The LANCE interrupt handler. */
-static irqreturn_t
-lance_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+static irqreturn_t lance_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
        struct lance_private *lp;
        int csr0, ioaddr, boguscnt=10;
        int must_restart;
 
-       if (dev == NULL) {
-               printk ("lance_interrupt(): irq %d for unknown device.\n", irq);
-               return IRQ_NONE;
-       }
-
        ioaddr = dev->base_addr;
        lp = dev->priv;
 
index da1eedef0b559a4a7ac71638bccb7b606d421988..f4d815bca643e878a93eb1a9cfb1fe4d091d0923 100644 (file)
@@ -403,7 +403,7 @@ static char init_setup[] =
 
 static int i596_open(struct net_device *dev);
 static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t i596_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t i596_interrupt(int irq, void *dev_id);
 static int i596_close(struct net_device *dev);
 static struct net_device_stats *i596_get_stats(struct net_device *dev);
 static void i596_add_cmd(struct net_device *dev, struct i596_cmd *cmd);
@@ -527,7 +527,7 @@ static void i596_display_data(struct net_device *dev)
 
 
 #if defined(ENABLE_MVME16x_NET) || defined(ENABLE_BVME6000_NET)
-static void i596_error(int irq, void *dev_id, struct pt_regs *regs)
+static void i596_error(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
        volatile unsigned char *pcc2 = (unsigned char *) 0xfff42000;
@@ -1252,12 +1252,12 @@ static int __devinit i82596_probe(struct net_device *dev,
 static void i596_poll_controller(struct net_device *dev)
 {
        disable_irq(dev->irq);
-       i596_interrupt(dev->irq, dev, NULL);
+       i596_interrupt(dev->irq, dev);
        enable_irq(dev->irq);
 }
 #endif
 
-static irqreturn_t i596_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t i596_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
        struct i596_private *lp;
index 4178b4b1d2df544a5b7c20fe90a0c0b02727ddcf..82c10dec1b5ac9d739578aa4d4874573d4ad11c4 100644 (file)
 #include <linux/tcp.h>
 #include <linux/percpu.h>
 
-static DEFINE_PER_CPU(struct net_device_stats, loopback_stats);
+struct pcpu_lstats {
+       unsigned long packets;
+       unsigned long bytes;
+};
+static DEFINE_PER_CPU(struct pcpu_lstats, pcpu_lstats);
 
 #define LOOPBACK_OVERHEAD (128 + MAX_HEADER + 16 + 16)
 
@@ -128,7 +132,7 @@ static void emulate_large_send_offload(struct sk_buff *skb)
  */
 static int loopback_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-       struct net_device_stats *lb_stats;
+       struct pcpu_lstats *lb_stats;
 
        skb_orphan(skb);
 
@@ -149,16 +153,14 @@ static int loopback_xmit(struct sk_buff *skb, struct net_device *dev)
 #endif
        dev->last_rx = jiffies;
 
-       lb_stats = &per_cpu(loopback_stats, get_cpu());
-       lb_stats->rx_bytes += skb->len;
-       lb_stats->tx_bytes = lb_stats->rx_bytes;
-       lb_stats->rx_packets++;
-       lb_stats->tx_packets = lb_stats->rx_packets;
-       put_cpu();
+       /* it's OK to use __get_cpu_var() because BHs are off */
+       lb_stats = &__get_cpu_var(pcpu_lstats);
+       lb_stats->bytes += skb->len;
+       lb_stats->packets++;
 
        netif_rx(skb);
 
-       return(0);
+       return 0;
 }
 
 static struct net_device_stats loopback_stats;
@@ -166,20 +168,21 @@ static struct net_device_stats loopback_stats;
 static struct net_device_stats *get_stats(struct net_device *dev)
 {
        struct net_device_stats *stats = &loopback_stats;
+       unsigned long bytes = 0;
+       unsigned long packets = 0;
        int i;
 
-       memset(stats, 0, sizeof(struct net_device_stats));
-
        for_each_possible_cpu(i) {
-               struct net_device_stats *lb_stats;
+               const struct pcpu_lstats *lb_stats;
 
-               lb_stats = &per_cpu(loopback_stats, i);
-               stats->rx_bytes   += lb_stats->rx_bytes;
-               stats->tx_bytes   += lb_stats->tx_bytes;
-               stats->rx_packets += lb_stats->rx_packets;
-               stats->tx_packets += lb_stats->tx_packets;
+               lb_stats = &per_cpu(pcpu_lstats, i);
+               bytes   += lb_stats->bytes;
+               packets += lb_stats->packets;
        }
-
+       stats->rx_packets = packets;
+       stats->tx_packets = packets;
+       stats->rx_bytes = bytes;
+       stats->tx_bytes = bytes;
        return stats;
 }
 
index 0258aaca9ed353c5fca43a0160de41bbe5f87120..b833016f1825fecf5b5008d4cb626ae15241be46 100644 (file)
@@ -379,7 +379,7 @@ static char init_setup[14] = {
 
 static int i596_open(struct net_device *dev);
 static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t i596_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t i596_interrupt(int irq, void *dev_id);
 static int i596_close(struct net_device *dev);
 static struct net_device_stats *i596_get_stats(struct net_device *dev);
 static void i596_add_cmd(struct net_device *dev, struct i596_cmd *cmd);
@@ -1151,7 +1151,7 @@ i596_handle_CU_completion(struct net_device *dev,
 }
 
 static irqreturn_t
-i596_interrupt (int irq, void *dev_instance, struct pt_regs *regs) {
+i596_interrupt (int irq, void *dev_instance) {
        struct net_device *dev = (struct net_device *) dev_instance;
        struct i596_private *lp;
        unsigned short status, ack_cmd = 0;
index 8472b71641dad3f34b4c65e5d35bad883671ba49..e960138011c0322c1ae32f1ed56408cbda5e5e64 100644 (file)
@@ -129,7 +129,7 @@ extern void reset_chip(struct net_device *dev);
 #endif
 static int net_open(struct net_device *dev);
 static int     net_send_packet(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t net_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t net_interrupt(int irq, void *dev_id);
 static void set_multicast_list(struct net_device *dev);
 static void net_rx(struct net_device *dev);
 static int net_close(struct net_device *dev);
@@ -431,7 +431,7 @@ net_send_packet(struct sk_buff *skb, struct net_device *dev)
 
 /* The typical workload of the driver:
    Handle the network interface interrupts. */
-static irqreturn_t net_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+static irqreturn_t net_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
        struct net_local *lp;
index 27c24eaa2414d26b53e7f6977d8ba659efc2e234..2907cfb12ada0adff1422c9ef70b3651b58f56fc 100644 (file)
@@ -82,9 +82,9 @@ static struct net_device_stats *mace_stats(struct net_device *dev);
 static void mace_set_multicast(struct net_device *dev);
 static void mace_reset(struct net_device *dev);
 static int mace_set_address(struct net_device *dev, void *addr);
-static irqreturn_t mace_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-static irqreturn_t mace_txdma_intr(int irq, void *dev_id, struct pt_regs *regs);
-static irqreturn_t mace_rxdma_intr(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t mace_interrupt(int irq, void *dev_id);
+static irqreturn_t mace_txdma_intr(int irq, void *dev_id);
+static irqreturn_t mace_rxdma_intr(int irq, void *dev_id);
 static void mace_set_timeout(struct net_device *dev);
 static void mace_tx_timeout(unsigned long data);
 static inline void dbdma_reset(volatile struct dbdma_regs __iomem *dma);
@@ -678,7 +678,7 @@ static void mace_handle_misc_intrs(struct mace_data *mp, int intr)
            printk(KERN_DEBUG "mace: jabbering transceiver\n");
 }
 
-static irqreturn_t mace_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t mace_interrupt(int irq, void *dev_id)
 {
     struct net_device *dev = (struct net_device *) dev_id;
     struct mace_data *mp = (struct mace_data *) dev->priv;
@@ -890,12 +890,12 @@ out:
     spin_unlock_irqrestore(&mp->lock, flags);
 }
 
-static irqreturn_t mace_txdma_intr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t mace_txdma_intr(int irq, void *dev_id)
 {
        return IRQ_HANDLED;
 }
 
-static irqreturn_t mace_rxdma_intr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t mace_rxdma_intr(int irq, void *dev_id)
 {
     struct net_device *dev = (struct net_device *) dev_id;
     struct mace_data *mp = (struct mace_data *) dev->priv;
index 696d5513e558252d120b868a7446eb98b5e0932b..464e4a6f3d5f45e3bca9101452f123a1b935a02a 100644 (file)
@@ -77,8 +77,8 @@ static int mace_xmit_start(struct sk_buff *skb, struct net_device *dev);
 static struct net_device_stats *mace_stats(struct net_device *dev);
 static void mace_set_multicast(struct net_device *dev);
 static int mace_set_address(struct net_device *dev, void *addr);
-static irqreturn_t mace_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-static irqreturn_t mace_dma_intr(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t mace_interrupt(int irq, void *dev_id);
+static irqreturn_t mace_dma_intr(int irq, void *dev_id);
 static void mace_tx_timeout(struct net_device *dev);
 
 /* Bit-reverse one byte of an ethernet hardware address. */
@@ -573,7 +573,7 @@ static void mace_recv_interrupt(struct net_device *dev)
  * Process the chip interrupt
  */
 
-static irqreturn_t mace_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t mace_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = (struct net_device *) dev_id;
        struct mace_data *mp = (struct mace_data *) dev->priv;
@@ -645,7 +645,7 @@ static void mace_dma_rx_frame(struct net_device *dev, struct mace_frame *mf)
  * The PSC has passed us a DMA interrupt event.
  */
 
-static irqreturn_t mace_dma_intr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t mace_dma_intr(int irq, void *dev_id)
 {
        struct net_device *dev = (struct net_device *) dev_id;
        struct mace_data *mp = (struct mace_data *) dev->priv;
index 55b1495a70d6d10c8fa4c1997d7bcbd5336a7a15..c1aa60b9a982122c324833572b06fee695674deb 100644 (file)
@@ -92,7 +92,7 @@ struct meth_private {
 };
 
 static void meth_tx_timeout(struct net_device *dev);
-static irqreturn_t meth_interrupt(int irq, void *dev_id, struct pt_regs *pregs);
+static irqreturn_t meth_interrupt(int irq, void *dev_id);
 
 /* global, initialized in ip32-setup.c */
 char o2meth_eaddr[8]={0,0,0,0,0,0,0,0};
@@ -569,7 +569,7 @@ static void meth_error(struct net_device* dev, unsigned status)
 /*
  * The typical interrupt entry point
  */
-static irqreturn_t meth_interrupt(int irq, void *dev_id, struct pt_regs *pregs)
+static irqreturn_t meth_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = (struct net_device *)dev_id;
        struct meth_private *priv = (struct meth_private *) dev->priv;
index 07e58f4a29164c6ea76f6a91c9151cfbb0c9ace9..c9469985bd713b61e4fc6d987aed10ec3bf51d34 100644 (file)
@@ -116,8 +116,7 @@ static inline ssize_t mipsnet_get_fromdev(struct net_device *dev, size_t count)
        return count;
 }
 
-static irqreturn_t
-mipsnet_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t mipsnet_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
 
index 7f8e5ad1b7043d5d05a637601786618181cb0c90..9997081c6daea8458fd1b1fad296733f55885dcd 100644 (file)
@@ -507,8 +507,7 @@ static void mv643xx_eth_update_pscr(struct net_device *dev,
  * Output :    N/A
  */
 
-static irqreturn_t mv643xx_eth_int_handler(int irq, void *dev_id,
-                                               struct pt_regs *regs)
+static irqreturn_t mv643xx_eth_int_handler(int irq, void *dev_id)
 {
        struct net_device *dev = (struct net_device *)dev_id;
        struct mv643xx_private *mp = netdev_priv(dev);
@@ -1252,7 +1251,7 @@ static void mv643xx_netpoll(struct net_device *netdev)
        /* wait for previous write to complete */
        mv_read(MV643XX_ETH_INTERRUPT_MASK_REG(port_num));
 
-       mv643xx_eth_int_handler(netdev->irq, netdev, NULL);
+       mv643xx_eth_int_handler(netdev->irq, netdev);
 
        mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), ETH_INT_UNMASK_ALL);
 }
@@ -2156,7 +2155,7 @@ static void eth_update_mib_counters(struct mv643xx_private *mp)
        for (offset = ETH_MIB_BAD_OCTETS_RECEIVED;
                        offset <= ETH_MIB_FRAMES_1024_TO_MAX_OCTETS;
                        offset += 4)
-               *(u32 *)((char *)p + offset) = read_mib(mp, offset);
+               *(u32 *)((char *)p + offset) += read_mib(mp, offset);
 
        p->good_octets_sent += read_mib(mp, ETH_MIB_GOOD_OCTETS_SENT_LOW);
        p->good_octets_sent +=
@@ -2165,7 +2164,7 @@ static void eth_update_mib_counters(struct mv643xx_private *mp)
        for (offset = ETH_MIB_GOOD_FRAMES_SENT;
                        offset <= ETH_MIB_LATE_COLLISION;
                        offset += 4)
-               *(u32 *)((char *)p + offset) = read_mib(mp, offset);
+               *(u32 *)((char *)p + offset) += read_mib(mp, offset);
 }
 
 /*
index 4330197994dfcdb1476687c208269165ee721060..fdbb0d7213b036ee6fa7ef895a307c9894d0b29e 100644 (file)
@@ -1148,7 +1148,7 @@ static int myri10ge_poll(struct net_device *netdev, int *budget)
        return 1;
 }
 
-static irqreturn_t myri10ge_intr(int irq, void *arg, struct pt_regs *regs)
+static irqreturn_t myri10ge_intr(int irq, void *arg)
 {
        struct myri10ge_priv *mgp = arg;
        struct mcp_irq_data *stats = mgp->fw_stats;
index e21ec9b2c706ceb72e92eff05b3ed9b3a8fcf5f9..ba7b8652c5013813808da694801c9c36c6005451 100644 (file)
@@ -1,8 +1,8 @@
 /* This is the Myrinet MCP code for LANai4.x */
 /* Generated by  cat $MYRI_HOME/lib/lanai/mcp4.dat > myri_code4.h */
 
-static unsigned int lanai4_code_off = 0x0000; /* half-word offset */
-static unsigned char lanai4_code[76256] __initdata = {
+static unsigned int __devinitdata lanai4_code_off = 0x0000; /* half-word offset */
+static unsigned char __devinitdata lanai4_code[76256] = {
 0xF2,0x0E,
 0xFE,0x00, 0xC2,0x90, 0x00,0x00, 0x07,0x88, 0x00,0x08, 0xE0,0x01, 0x01,0x4C, 0x97,0x93,
 0xFF,0xFC, 0xE0,0x00, 0x00,0x14, 0x00,0x00, 0x00,0x01, 0x00,0x00, 0x00,0x00, 0x92,0x93,
@@ -4774,8 +4774,8 @@ static unsigned char lanai4_code[76256] __initdata = {
 
 /* This is the LANai data */
 
-static unsigned int lanai4_data_off = 0x94F0; /* half-word offset */
-static unsigned char lanai4_data[20472] __initdata;
+static unsigned int __devinitdata lanai4_data_off = 0x94F0; /* half-word offset */
+static unsigned char __devinitdata lanai4_data[20472];
 
 
 #ifdef SYMBOL_DEFINES_COMPILED
index a925bc9db4acb4f368d050771a5b598e147c21ab..7747bfd99f916a8b084623ba48e00e40a275c8af 100644 (file)
@@ -168,7 +168,7 @@ static int myri_do_handshake(struct myri_eth *mp)
        return 0;
 }
 
-static int myri_load_lanai(struct myri_eth *mp)
+static int __devinit myri_load_lanai(struct myri_eth *mp)
 {
        struct net_device       *dev = mp->dev;
        struct myri_shmem __iomem *shmem = mp->shmem;
@@ -536,7 +536,7 @@ static void myri_rx(struct myri_eth *mp, struct net_device *dev)
        }
 }
 
-static irqreturn_t myri_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t myri_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev          = (struct net_device *) dev_id;
        struct myri_eth *mp             = (struct myri_eth *) dev->priv;
@@ -891,7 +891,7 @@ static void dump_eeprom(struct myri_eth *mp)
 }
 #endif
 
-static int __init myri_ether_init(struct sbus_dev *sdev)
+static int __devinit myri_ether_init(struct sbus_dev *sdev)
 {
        static int num;
        static unsigned version_printed;
index d7b241f7d7bcd519370ef0211988f788f9f9b9be..ffa0afd2eddcd372c614a6724be4cb3444e85f28 100644 (file)
@@ -623,7 +623,7 @@ static void free_ring(struct net_device *dev);
 static void reinit_ring(struct net_device *dev);
 static void init_registers(struct net_device *dev);
 static int start_tx(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t intr_handler(int irq, void *dev_instance, struct pt_regs *regs);
+static irqreturn_t intr_handler(int irq, void *dev_instance);
 static void netdev_error(struct net_device *dev, int intr_status);
 static int natsemi_poll(struct net_device *dev, int *budget);
 static void netdev_rx(struct net_device *dev, int *work_done, int work_to_do);
@@ -2088,7 +2088,7 @@ static void netdev_tx_done(struct net_device *dev)
 
 /* The interrupt handler doesn't actually handle interrupts itself, it
  * schedules a NAPI poll if there is anything to do. */
-static irqreturn_t intr_handler(int irq, void *dev_instance, struct pt_regs *rgs)
+static irqreturn_t intr_handler(int irq, void *dev_instance)
 {
        struct net_device *dev = dev_instance;
        struct netdev_private *np = netdev_priv(dev);
@@ -2373,7 +2373,7 @@ static struct net_device_stats *get_stats(struct net_device *dev)
 static void natsemi_poll_controller(struct net_device *dev)
 {
        disable_irq(dev->irq);
-       intr_handler(dev->irq, dev, NULL);
+       intr_handler(dev->irq, dev);
        enable_irq(dev->irq);
 }
 #endif
index 30ed9a5a40e06a2cb4cf94dffb92afb873a1bce3..a53644f6a29be81db50ed77549c7945364976a23 100644 (file)
@@ -176,7 +176,7 @@ static void netx_eth_receive(struct net_device *ndev)
 }
 
 static irqreturn_t
-netx_eth_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+netx_eth_interrupt(int irq, void *dev_id)
 {
        struct net_device *ndev = dev_id;
        struct netx_eth_priv *priv = netdev_priv(ndev);
index 383c690eefec4f9f3c9914a67703159c2edcedb1..8be0d030d6f414f05d7bba2de16deff9bac686a7 100644 (file)
@@ -99,7 +99,7 @@ struct ni5010_local {
 static int     ni5010_probe1(struct net_device *dev, int ioaddr);
 static int     ni5010_open(struct net_device *dev);
 static int     ni5010_send_packet(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t ni5010_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t ni5010_interrupt(int irq, void *dev_id);
 static void    ni5010_rx(struct net_device *dev);
 static void    ni5010_timeout(struct net_device *dev);
 static int     ni5010_close(struct net_device *dev);
@@ -468,7 +468,7 @@ static int ni5010_send_packet(struct sk_buff *skb, struct net_device *dev)
  * The typical workload of the driver:
  * Handle the network interface interrupts.
  */
-static irqreturn_t ni5010_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t ni5010_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
        struct ni5010_local *lp;
index e8889235996e6751a7cf1b98b24fe68faa93025f..26e42f6e9fb10323ec9dcb492b6b1af86ebda147 100644 (file)
@@ -195,7 +195,7 @@ sizeof(nop_cmd) = 8;
 #define NI52_ADDR2 0x01
 
 static int     ni52_probe1(struct net_device *dev,int ioaddr);
-static irqreturn_t ni52_interrupt(int irq,void *dev_id,struct pt_regs *reg_ptr);
+static irqreturn_t ni52_interrupt(int irq,void *dev_id);
 static int     ni52_open(struct net_device *dev);
 static int     ni52_close(struct net_device *dev);
 static int     ni52_send_packet(struct sk_buff *,struct net_device *);
@@ -837,7 +837,7 @@ static void *alloc_rfa(struct net_device *dev,void *ptr)
  * Interrupt Handler ...
  */
 
-static irqreturn_t ni52_interrupt(int irq,void *dev_id,struct pt_regs *reg_ptr)
+static irqreturn_t ni52_interrupt(int irq,void *dev_id)
 {
        struct net_device *dev = dev_id;
        unsigned short stat;
index fab3c8593ac19605b4e43b1244bc94f3c27888f0..340ad0d5388aa9ff20fd98f9d526793f8b68611e 100644 (file)
@@ -248,7 +248,7 @@ struct priv
 };
 
 static int  ni65_probe1(struct net_device *dev,int);
-static irqreturn_t ni65_interrupt(int irq, void * dev_id, struct pt_regs *regs);
+static irqreturn_t ni65_interrupt(int irq, void * dev_id);
 static void ni65_recv_intr(struct net_device *dev,int);
 static void ni65_xmit_intr(struct net_device *dev,int);
 static int  ni65_open(struct net_device *dev);
@@ -871,7 +871,7 @@ static int ni65_lance_reinit(struct net_device *dev)
 /*
  * interrupt handler
  */
-static irqreturn_t ni65_interrupt(int irq, void * dev_id, struct pt_regs * regs)
+static irqreturn_t ni65_interrupt(int irq, void * dev_id)
 {
        int csr0 = 0;
        struct net_device *dev = dev_id;
index e10da1aa3d30b5d8ec6a4567fb11bf43129987b8..b0127c71a5b6f5a3fabb1950bcf57cab459124e9 100644 (file)
@@ -1288,7 +1288,7 @@ static void ns83820_mib_isr(struct ns83820 *dev)
 }
 
 static void ns83820_do_isr(struct net_device *ndev, u32 isr);
-static irqreturn_t ns83820_irq(int foo, void *data, struct pt_regs *regs)
+static irqreturn_t ns83820_irq(int foo, void *data)
 {
        struct net_device *ndev = data;
        struct ns83820 *dev = PRIV(ndev);
index 2687e747657d82e23e5a429d5c221e6005e7287b..00ca0fdb837b6aeb6e6318fb5417e6f3320943f6 100644 (file)
@@ -502,8 +502,7 @@ static void netdrv_tx_timeout (struct net_device *dev);
 static void netdrv_init_ring (struct net_device *dev);
 static int netdrv_start_xmit (struct sk_buff *skb,
                               struct net_device *dev);
-static irqreturn_t netdrv_interrupt (int irq, void *dev_instance,
-                              struct pt_regs *regs);
+static irqreturn_t netdrv_interrupt (int irq, void *dev_instance);
 static int netdrv_close (struct net_device *dev);
 static int netdrv_ioctl (struct net_device *dev, struct ifreq *rq, int cmd);
 static struct net_device_stats *netdrv_get_stats (struct net_device *dev);
@@ -1654,8 +1653,7 @@ static void netdrv_weird_interrupt (struct net_device *dev,
 
 /* The interrupt handler does all of the Rx thread work and cleans up
    after the Tx thread. */
-static irqreturn_t netdrv_interrupt (int irq, void *dev_instance,
-                              struct pt_regs *regs)
+static irqreturn_t netdrv_interrupt (int irq, void *dev_instance)
 {
        struct net_device *dev = (struct net_device *) dev_instance;
        struct netdrv_private *tp = dev->priv;
index 2418cdb9d317b79cca7f55700e315a2b479b684e..046009928526c08e07f8c841ce009fc51f2dc81b 100644 (file)
@@ -238,7 +238,7 @@ static void tc574_reset(struct net_device *dev);
 static void media_check(unsigned long arg);
 static int el3_open(struct net_device *dev);
 static int el3_start_xmit(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t el3_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t el3_interrupt(int irq, void *dev_id);
 static void update_stats(struct net_device *dev);
 static struct net_device_stats *el3_get_stats(struct net_device *dev);
 static int el3_rx(struct net_device *dev, int worklimit);
@@ -817,7 +817,7 @@ static int el3_start_xmit(struct sk_buff *skb, struct net_device *dev)
 }
 
 /* The EL3 interrupt handler. */
-static irqreturn_t el3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t el3_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = (struct net_device *) dev_id;
        struct el3_private *lp = netdev_priv(dev);
@@ -927,7 +927,7 @@ static void media_check(unsigned long arg)
        if ((inw(ioaddr + EL3_STATUS) & IntLatch) && (inb(ioaddr + Timer) == 0xff)) {
                if (!lp->fast_poll)
                        printk(KERN_INFO "%s: interrupt(s) dropped!\n", dev->name);
-               el3_interrupt(dev->irq, lp, NULL);
+               el3_interrupt(dev->irq, lp);
                lp->fast_poll = HZ;
        }
        if (lp->fast_poll) {
index a0e2b01c027c55367b51617d7ccae2b51e2a6a6a..231fa2c9ec6c4580b4abd23f45ae3513a9feb291 100644 (file)
@@ -151,7 +151,7 @@ static void media_check(unsigned long arg);
 static int el3_config(struct net_device *dev, struct ifmap *map);
 static int el3_open(struct net_device *dev);
 static int el3_start_xmit(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t el3_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t el3_interrupt(int irq, void *dev_id);
 static void update_stats(struct net_device *dev);
 static struct net_device_stats *el3_get_stats(struct net_device *dev);
 static int el3_rx(struct net_device *dev);
@@ -645,7 +645,7 @@ static int el3_start_xmit(struct sk_buff *skb, struct net_device *dev)
 }
 
 /* The EL3 interrupt handler. */
-static irqreturn_t el3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t el3_interrupt(int irq, void *dev_id)
 {
     struct net_device *dev = (struct net_device *) dev_id;
     struct el3_private *lp = netdev_priv(dev);
@@ -748,7 +748,7 @@ static void media_check(unsigned long arg)
        (inb(ioaddr + EL3_TIMER) == 0xff)) {
        if (!lp->fast_poll)
            printk(KERN_WARNING "%s: interrupt(s) dropped!\n", dev->name);
-       el3_interrupt(dev->irq, lp, NULL);
+       el3_interrupt(dev->irq, lp);
        lp->fast_poll = HZ;
     }
     if (lp->fast_poll) {
index a8891a9000acbdb36dfd09155a0d2f14d90fcdfb..5ddd5742f7794f47c0f129d3c846b99df7089a45 100644 (file)
@@ -92,7 +92,7 @@ static int axnet_open(struct net_device *dev);
 static int axnet_close(struct net_device *dev);
 static int axnet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
 static const struct ethtool_ops netdev_ethtool_ops;
-static irqreturn_t ei_irq_wrapper(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t ei_irq_wrapper(int irq, void *dev_id);
 static void ei_watchdog(u_long arg);
 static void axnet_reset_8390(struct net_device *dev);
 
@@ -112,7 +112,7 @@ static void axdev_setup(struct net_device *dev);
 static void AX88190_init(struct net_device *dev, int startp);
 static int ax_open(struct net_device *dev);
 static int ax_close(struct net_device *dev);
-static irqreturn_t ax_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t ax_interrupt(int irq, void *dev_id);
 
 /*====================================================================*/
 
@@ -599,11 +599,11 @@ static void axnet_reset_8390(struct net_device *dev)
 
 /*====================================================================*/
 
-static irqreturn_t ei_irq_wrapper(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t ei_irq_wrapper(int irq, void *dev_id)
 {
     struct net_device *dev = dev_id;
     PRIV(dev)->stale = 0;
-    return ax_interrupt(irq, dev_id, regs);
+    return ax_interrupt(irq, dev_id);
 }
 
 static void ei_watchdog(u_long arg)
@@ -621,7 +621,7 @@ static void ei_watchdog(u_long arg)
     if (info->stale++ && (inb_p(nic_base + EN0_ISR) & ENISR_ALL)) {
        if (!info->fast_poll)
            printk(KERN_INFO "%s: interrupt(s) dropped!\n", dev->name);
-       ei_irq_wrapper(dev->irq, dev, NULL);
+       ei_irq_wrapper(dev->irq, dev);
        info->fast_poll = HZ;
     }
     if (info->fast_poll) {
@@ -1193,7 +1193,7 @@ static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev)
  * needed.
  */
 
-static irqreturn_t ax_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+static irqreturn_t ax_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
        long e8390_base;
@@ -1201,14 +1201,8 @@ static irqreturn_t ax_interrupt(int irq, void *dev_id, struct pt_regs * regs)
        struct ei_device *ei_local;
        int handled = 0;
 
-       if (dev == NULL) 
-       {
-               printk ("net_interrupt(): irq %d for unknown device.\n", irq);
-               return IRQ_NONE;
-       }
-    
        e8390_base = dev->base_addr;
-       ei_local = (struct ei_device *) netdev_priv(dev);
+       ei_local = netdev_priv(dev);
 
        /*
         *      Protect the irq test too.
index d682f30dea6e0bf96a1d482b702d36b1724b8b25..65f6fdf437255125b6d5f20257e74c7df4b8d5c0 100644 (file)
@@ -97,7 +97,7 @@ static int fjn_config(struct net_device *dev, struct ifmap *map);
 static int fjn_open(struct net_device *dev);
 static int fjn_close(struct net_device *dev);
 static int fjn_start_xmit(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t fjn_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t fjn_interrupt(int irq, void *dev_id);
 static void fjn_rx(struct net_device *dev);
 static void fjn_reset(struct net_device *dev);
 static struct net_device_stats *fjn_get_stats(struct net_device *dev);
@@ -733,7 +733,7 @@ module_exit(exit_fmvj18x_cs);
 
 /*====================================================================*/
 
-static irqreturn_t fjn_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t fjn_interrupt(int irq, void *dev_id)
 {
     struct net_device *dev = dev_id;
     local_info_t *lp = netdev_priv(dev);
index 7d5687e9460767d6310734973720de2490856563..e77110e4c288b15bc40e58168af234bd874ac624 100644 (file)
@@ -426,7 +426,7 @@ static int mace_open(struct net_device *dev);
 static int mace_close(struct net_device *dev);
 static int mace_start_xmit(struct sk_buff *skb, struct net_device *dev);
 static void mace_tx_timeout(struct net_device *dev);
-static irqreturn_t mace_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t mace_interrupt(int irq, void *dev_id);
 static struct net_device_stats *mace_get_stats(struct net_device *dev);
 static int mace_rx(struct net_device *dev, unsigned char RxCnt);
 static void restore_multicast_list(struct net_device *dev);
@@ -1002,7 +1002,7 @@ static int mace_start_xmit(struct sk_buff *skb, struct net_device *dev)
 mace_interrupt
        The interrupt handler.
 ---------------------------------------------------------------------------- */
-static irqreturn_t mace_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t mace_interrupt(int irq, void *dev_id)
 {
   struct net_device *dev = (struct net_device *) dev_id;
   mace_private *lp = netdev_priv(dev);
index a09c22840f63a78e02504fde535c373a720139a8..0c00d182e7fd3677a63c027e6ec878b85f2f7652 100644 (file)
@@ -109,7 +109,7 @@ static int pcnet_open(struct net_device *dev);
 static int pcnet_close(struct net_device *dev);
 static int ei_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
 static const struct ethtool_ops netdev_ethtool_ops;
-static irqreturn_t ei_irq_wrapper(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t ei_irq_wrapper(int irq, void *dev_id);
 static void ei_watchdog(u_long arg);
 static void pcnet_reset_8390(struct net_device *dev);
 static int set_config(struct net_device *dev, struct ifmap *map);
@@ -1071,11 +1071,11 @@ static int set_config(struct net_device *dev, struct ifmap *map)
 
 /*====================================================================*/
 
-static irqreturn_t ei_irq_wrapper(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t ei_irq_wrapper(int irq, void *dev_id)
 {
     struct net_device *dev = dev_id;
     pcnet_dev_t *info;
-    irqreturn_t ret = ei_interrupt(irq, dev_id, regs);
+    irqreturn_t ret = ei_interrupt(irq, dev_id);
 
     if (ret == IRQ_HANDLED) {
            info = PRIV(dev);
@@ -1100,7 +1100,7 @@ static void ei_watchdog(u_long arg)
     if (info->stale++ && (inb_p(nic_base + EN0_ISR) & ENISR_ALL)) {
        if (!info->fast_poll)
            printk(KERN_INFO "%s: interrupt(s) dropped!\n", dev->name);
-       ei_irq_wrapper(dev->irq, dev, NULL);
+       ei_irq_wrapper(dev->irq, dev);
        info->fast_poll = HZ;
     }
     if (info->fast_poll) {
index a2f3a0e2a0050cb55361c7a2c75588857ed760ef..20fcc357620256f9043022f40b2857200a6a5a21 100644 (file)
@@ -287,7 +287,7 @@ static int smc_close(struct net_device *dev);
 static int smc_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
 static void smc_tx_timeout(struct net_device *dev);
 static int smc_start_xmit(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t smc_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t smc_interrupt(int irq, void *dev_id);
 static void smc_rx(struct net_device *dev);
 static struct net_device_stats *smc_get_stats(struct net_device *dev);
 static void set_rx_mode(struct net_device *dev);
@@ -1545,7 +1545,7 @@ static void smc_eph_irq(struct net_device *dev)
 
 /*====================================================================*/
 
-static irqreturn_t smc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t smc_interrupt(int irq, void *dev_id)
 {
     struct net_device *dev = dev_id;
     struct smc_private *smc = netdev_priv(dev);
@@ -1966,7 +1966,7 @@ static void media_check(u_long arg)
     if (smc->watchdog++ && ((i>>8) & i)) {
        if (!smc->fast_poll)
            printk(KERN_INFO "%s: interrupt(s) dropped!\n", dev->name);
-       smc_interrupt(dev->irq, smc, NULL);
+       smc_interrupt(dev->irq, smc);
        smc->fast_poll = HZ;
     }
     if (smc->fast_poll) {
index 62664c01eb45d382b546f3fca1557f9b30e716f3..f3914f58d67f2ca95acc1a99403523c41bc4592d 100644 (file)
@@ -308,7 +308,7 @@ static void xirc2ps_detach(struct pcmcia_device *p_dev);
  * less on other parts of the kernel.
  */
 
-static irqreturn_t xirc2ps_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t xirc2ps_interrupt(int irq, void *dev_id);
 
 /****************
  * A linked list of "instances" of the device.  Each actual
@@ -1121,7 +1121,7 @@ static int xirc2ps_resume(struct pcmcia_device *link)
  * This is the Interrupt service route.
  */
 static irqreturn_t
-xirc2ps_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+xirc2ps_interrupt(int irq, void *dev_id)
 {
     struct net_device *dev = (struct net_device *)dev_id;
     local_info_t *lp = netdev_priv(dev);
index a43e24245b7e379644c4bc56f0bec5ba1cc72ffd..36f9d988278f76771292c45a365a41ddd4ad478e 100644 (file)
@@ -304,7 +304,7 @@ static int pcnet32_open(struct net_device *);
 static int pcnet32_init_ring(struct net_device *);
 static int pcnet32_start_xmit(struct sk_buff *, struct net_device *);
 static void pcnet32_tx_timeout(struct net_device *dev);
-static irqreturn_t pcnet32_interrupt(int, void *, struct pt_regs *);
+static irqreturn_t pcnet32_interrupt(int, void *);
 static int pcnet32_close(struct net_device *);
 static struct net_device_stats *pcnet32_get_stats(struct net_device *);
 static void pcnet32_load_multicast(struct net_device *dev);
@@ -674,7 +674,7 @@ static void pcnet32_purge_rx_ring(struct net_device *dev)
 static void pcnet32_poll_controller(struct net_device *dev)
 {
        disable_irq(dev->irq);
-       pcnet32_interrupt(0, dev, NULL);
+       pcnet32_interrupt(0, dev);
        enable_irq(dev->irq);
 }
 #endif
@@ -2561,7 +2561,7 @@ static int pcnet32_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 /* The PCNET32 interrupt handler. */
 static irqreturn_t
-pcnet32_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+pcnet32_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
        struct pcnet32_private *lp;
@@ -2569,13 +2569,6 @@ pcnet32_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        u16 csr0;
        int boguscnt = max_interrupt_work;
 
-       if (!dev) {
-               if (pcnet32_debug & NETIF_MSG_INTR)
-                       printk(KERN_DEBUG "%s(): irq %d for unknown device\n",
-                              __FUNCTION__, irq);
-               return IRQ_NONE;
-       }
-
        ioaddr = dev->base_addr;
        lp = dev->priv;
 
index f5aad77288f916e776d8362fdbcec38c6ba5f5ff..3af9fcf76c81a2688c4596b00d823482f530b07f 100644 (file)
@@ -480,7 +480,7 @@ void phy_error(struct phy_device *phydev)
  * description: When a PHY interrupt occurs, the handler disables
  * interrupts, and schedules a work task to clear the interrupt.
  */
-static irqreturn_t phy_interrupt(int irq, void *phy_dat, struct pt_regs *regs)
+static irqreturn_t phy_interrupt(int irq, void *phy_dat)
 {
        struct phy_device *phydev = phy_dat;
 
index d4f54e9798cd5550223f6ad9cbbbcef16b11d0ee..71afb274498f5558f1c2f33334441503d43a1a19 100644 (file)
@@ -143,7 +143,7 @@ static void plip_bh(struct net_device *dev);
 static void plip_timer_bh(struct net_device *dev);
 
 /* Interrupt handler */
-static void plip_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static void plip_interrupt(int irq, void *dev_id);
 
 /* Functions for DEV methods */
 static int plip_tx_packet(struct sk_buff *skb, struct net_device *dev);
@@ -385,7 +385,7 @@ plip_timer_bh(struct net_device *dev)
        struct net_local *nl = netdev_priv(dev);
 
        if (!(atomic_read (&nl->kill_timer))) {
-               plip_interrupt (-1, dev, NULL);
+               plip_interrupt (-1, dev);
 
                schedule_delayed_work(&nl->timer, 1);
        }
@@ -902,18 +902,13 @@ plip_error(struct net_device *dev, struct net_local *nl,
 
 /* Handle the parallel port interrupts. */
 static void
-plip_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+plip_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
        struct net_local *nl;
        struct plip_local *rcv;
        unsigned char c0;
 
-       if (dev == NULL) {
-               printk(KERN_DEBUG "plip_interrupt: irq %d for unknown device.\n", irq);
-               return;
-       }
-
        nl = netdev_priv(dev);
        rcv = &nl->rcv_data;
 
index 1574718463495278aca0e262a827d0cec21424a1..ec640f6229ae53e0a3f75ce4984c95365cba55ac 100644 (file)
@@ -1965,7 +1965,7 @@ quit_polling:
        return 1;
 }
 
-static irqreturn_t ql3xxx_isr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t ql3xxx_isr(int irq, void *dev_id)
 {
 
        struct net_device *ndev = dev_id;
index 4c47c5b10ba0f9f9b67352446defa49b235e185f..d132fe7d475e99afe10d73cc02963923c1efadbc 100644 (file)
@@ -214,6 +214,7 @@ static struct pci_device_id rtl8169_pci_tbl[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_REALTEK,     0x8168), 0, 0, RTL_CFG_2 },
        { PCI_DEVICE(PCI_VENDOR_ID_REALTEK,     0x8169), 0, 0, RTL_CFG_0 },
        { PCI_DEVICE(PCI_VENDOR_ID_DLINK,       0x4300), 0, 0, RTL_CFG_0 },
+       { PCI_DEVICE(0x1259,                    0xc107), 0, 0, RTL_CFG_0 },
        { PCI_DEVICE(0x16ec,                    0x0116), 0, 0, RTL_CFG_0 },
        { PCI_VENDOR_ID_LINKSYS,                0x1032,
                PCI_ANY_ID, 0x0024, 0, 0, RTL_CFG_0 },
@@ -473,8 +474,7 @@ MODULE_VERSION(RTL8169_VERSION);
 
 static int rtl8169_open(struct net_device *dev);
 static int rtl8169_start_xmit(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance,
-                             struct pt_regs *regs);
+static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance);
 static int rtl8169_init_ring(struct net_device *dev);
 static void rtl8169_hw_start(struct net_device *dev);
 static int rtl8169_close(struct net_device *dev);
@@ -1392,7 +1392,7 @@ static void rtl8169_netpoll(struct net_device *dev)
        struct pci_dev *pdev = tp->pci_dev;
 
        disable_irq(pdev->irq);
-       rtl8169_interrupt(pdev->irq, dev, NULL);
+       rtl8169_interrupt(pdev->irq, dev);
        enable_irq(pdev->irq);
 }
 #endif
@@ -2592,7 +2592,7 @@ rtl8169_rx_interrupt(struct net_device *dev, struct rtl8169_private *tp,
 
 /* The interrupt handler does all of the Rx thread work and cleans up after the Tx thread. */
 static irqreturn_t
-rtl8169_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
+rtl8169_interrupt(int irq, void *dev_instance)
 {
        struct net_device *dev = (struct net_device *) dev_instance;
        struct rtl8169_private *tp = netdev_priv(dev);
@@ -2701,6 +2701,7 @@ static void rtl8169_down(struct net_device *dev)
        struct rtl8169_private *tp = netdev_priv(dev);
        void __iomem *ioaddr = tp->mmio_addr;
        unsigned int poll_locked = 0;
+       unsigned int intrmask;
 
        rtl8169_delete_timer(dev);
 
@@ -2739,8 +2740,11 @@ core_down:
         * 2) dev->change_mtu
         *    -> rtl8169_poll can not be issued again and re-enable the
         *       interruptions. Let's simply issue the IRQ down sequence again.
+        *
+        * No loop if hotpluged or major error (0xffff).
         */
-       if (RTL_R16(IntrMask))
+       intrmask = RTL_R16(IntrMask);
+       if (intrmask && (intrmask != 0xffff))
                goto core_down;
 
        rtl8169_tx_clear(tp);
index 6108bac8d56a277d50b851e411263d7938fc1184..d81536f90df62e10aefd98e83f597f663e5d925c 100644 (file)
@@ -1053,7 +1053,7 @@ static void rx_int(struct net_device *dev, u32 rxlimit, u32 index)
 }
 
 
-static irqreturn_t rr_interrupt(int irq, void *dev_id, struct pt_regs *ptregs)
+static irqreturn_t rr_interrupt(int irq, void *dev_id)
 {
        struct rr_private *rrpriv;
        struct rr_regs __iomem *regs;
index 99451b523399e1ddedfcec7887e01df7409cb62c..9f3e050c4dc6dc27b82c0290b239bcea6029781a 100644 (file)
@@ -829,7 +829,7 @@ struct rr_private
  */
 static int rr_init(struct net_device *dev);
 static int rr_init1(struct net_device *dev);
-static irqreturn_t rr_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t rr_interrupt(int irq, void *dev_id);
 
 static int rr_open(struct net_device *dev);
 static int rr_start_xmit(struct sk_buff *skb, struct net_device *dev);
index 1bf23e41f5804f8f697b347f895b72920cd719aa..a231ab7d28ddccc288dbd4619df552d3a5020d09 100644 (file)
@@ -4029,8 +4029,7 @@ static int s2io_chk_rx_buffers(nic_t *sp, int rng_n)
        return 0;
 }
 
-static irqreturn_t
-s2io_msi_handle(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t s2io_msi_handle(int irq, void *dev_id)
 {
        struct net_device *dev = (struct net_device *) dev_id;
        nic_t *sp = dev->priv;
@@ -4063,8 +4062,7 @@ s2io_msi_handle(int irq, void *dev_id, struct pt_regs *regs)
        return IRQ_HANDLED;
 }
 
-static irqreturn_t
-s2io_msix_ring_handle(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t s2io_msix_ring_handle(int irq, void *dev_id)
 {
        ring_info_t *ring = (ring_info_t *)dev_id;
        nic_t *sp = ring->nic;
@@ -4078,8 +4076,7 @@ s2io_msix_ring_handle(int irq, void *dev_id, struct pt_regs *regs)
        return IRQ_HANDLED;
 }
 
-static irqreturn_t
-s2io_msix_fifo_handle(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t s2io_msix_fifo_handle(int irq, void *dev_id)
 {
        fifo_info_t *fifo = (fifo_info_t *)dev_id;
        nic_t *sp = fifo->nic;
@@ -4155,7 +4152,6 @@ static void s2io_txpic_intr_handle(nic_t *sp)
  *  s2io_isr - ISR handler of the device .
  *  @irq: the irq of the device.
  *  @dev_id: a void pointer to the dev structure of the NIC.
- *  @pt_regs: pointer to the registers pushed on the stack.
  *  Description:  This function is the ISR handler of the device. It
  *  identifies the reason for the interrupt and calls the relevant
  *  service routines. As a contongency measure, this ISR allocates the
@@ -4165,7 +4161,7 @@ static void s2io_txpic_intr_handle(nic_t *sp)
  *   IRQ_HANDLED: will be returned if IRQ was handled by this routine
  *   IRQ_NONE: will be returned if interrupt is not from our device
  */
-static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t s2io_isr(int irq, void *dev_id)
 {
        struct net_device *dev = (struct net_device *) dev_id;
        nic_t *sp = dev->priv;
index 3afd9126a591032dc6a366a9d0f6f2ba9f4d38ec..12b719f4d00f7d161fe2437f369b168ed8f464fe 100644 (file)
@@ -116,179 +116,179 @@ typedef struct {
 /* The statistics block of Xena */
 typedef struct stat_block {
 /* Tx MAC statistics counters. */
-       u32 tmac_data_octets;
-       u32 tmac_frms;
-       u64 tmac_drop_frms;
-       u32 tmac_bcst_frms;
-       u32 tmac_mcst_frms;
-       u64 tmac_pause_ctrl_frms;
-       u32 tmac_ucst_frms;
-       u32 tmac_ttl_octets;
-       u32 tmac_any_err_frms;
-       u32 tmac_nucst_frms;
-       u64 tmac_ttl_less_fb_octets;
-       u64 tmac_vld_ip_octets;
-       u32 tmac_drop_ip;
-       u32 tmac_vld_ip;
-       u32 tmac_rst_tcp;
-       u32 tmac_icmp;
-       u64 tmac_tcp;
-       u32 reserved_0;
-       u32 tmac_udp;
+       __le32 tmac_data_octets;
+       __le32 tmac_frms;
+       __le64 tmac_drop_frms;
+       __le32 tmac_bcst_frms;
+       __le32 tmac_mcst_frms;
+       __le64 tmac_pause_ctrl_frms;
+       __le32 tmac_ucst_frms;
+       __le32 tmac_ttl_octets;
+       __le32 tmac_any_err_frms;
+       __le32 tmac_nucst_frms;
+       __le64 tmac_ttl_less_fb_octets;
+       __le64 tmac_vld_ip_octets;
+       __le32 tmac_drop_ip;
+       __le32 tmac_vld_ip;
+       __le32 tmac_rst_tcp;
+       __le32 tmac_icmp;
+       __le64 tmac_tcp;
+       __le32 reserved_0;
+       __le32 tmac_udp;
 
 /* Rx MAC Statistics counters. */
-       u32 rmac_data_octets;
-       u32 rmac_vld_frms;
-       u64 rmac_fcs_err_frms;
-       u64 rmac_drop_frms;
-       u32 rmac_vld_bcst_frms;
-       u32 rmac_vld_mcst_frms;
-       u32 rmac_out_rng_len_err_frms;
-       u32 rmac_in_rng_len_err_frms;
-       u64 rmac_long_frms;
-       u64 rmac_pause_ctrl_frms;
-       u64 rmac_unsup_ctrl_frms;
-       u32 rmac_accepted_ucst_frms;
-       u32 rmac_ttl_octets;
-       u32 rmac_discarded_frms;
-       u32 rmac_accepted_nucst_frms;
-       u32 reserved_1;
-       u32 rmac_drop_events;
-       u64 rmac_ttl_less_fb_octets;
-       u64 rmac_ttl_frms;
-       u64 reserved_2;
-       u32 rmac_usized_frms;
-       u32 reserved_3;
-       u32 rmac_frag_frms;
-       u32 rmac_osized_frms;
-       u32 reserved_4;
-       u32 rmac_jabber_frms;
-       u64 rmac_ttl_64_frms;
-       u64 rmac_ttl_65_127_frms;
-       u64 reserved_5;
-       u64 rmac_ttl_128_255_frms;
-       u64 rmac_ttl_256_511_frms;
-       u64 reserved_6;
-       u64 rmac_ttl_512_1023_frms;
-       u64 rmac_ttl_1024_1518_frms;
-       u32 rmac_ip;
-       u32 reserved_7;
-       u64 rmac_ip_octets;
-       u32 rmac_drop_ip;
-       u32 rmac_hdr_err_ip;
-       u32 reserved_8;
-       u32 rmac_icmp;
-       u64 rmac_tcp;
-       u32 rmac_err_drp_udp;
-       u32 rmac_udp;
-       u64 rmac_xgmii_err_sym;
-       u64 rmac_frms_q0;
-       u64 rmac_frms_q1;
-       u64 rmac_frms_q2;
-       u64 rmac_frms_q3;
-       u64 rmac_frms_q4;
-       u64 rmac_frms_q5;
-       u64 rmac_frms_q6;
-       u64 rmac_frms_q7;
-       u16 rmac_full_q3;
-       u16 rmac_full_q2;
-       u16 rmac_full_q1;
-       u16 rmac_full_q0;
-       u16 rmac_full_q7;
-       u16 rmac_full_q6;
-       u16 rmac_full_q5;
-       u16 rmac_full_q4;
-       u32 reserved_9;
-       u32 rmac_pause_cnt;
-       u64 rmac_xgmii_data_err_cnt;
-       u64 rmac_xgmii_ctrl_err_cnt;
-       u32 rmac_err_tcp;
-       u32 rmac_accepted_ip;
+       __le32 rmac_data_octets;
+       __le32 rmac_vld_frms;
+       __le64 rmac_fcs_err_frms;
+       __le64 rmac_drop_frms;
+       __le32 rmac_vld_bcst_frms;
+       __le32 rmac_vld_mcst_frms;
+       __le32 rmac_out_rng_len_err_frms;
+       __le32 rmac_in_rng_len_err_frms;
+       __le64 rmac_long_frms;
+       __le64 rmac_pause_ctrl_frms;
+       __le64 rmac_unsup_ctrl_frms;
+       __le32 rmac_accepted_ucst_frms;
+       __le32 rmac_ttl_octets;
+       __le32 rmac_discarded_frms;
+       __le32 rmac_accepted_nucst_frms;
+       __le32 reserved_1;
+       __le32 rmac_drop_events;
+       __le64 rmac_ttl_less_fb_octets;
+       __le64 rmac_ttl_frms;
+       __le64 reserved_2;
+       __le32 rmac_usized_frms;
+       __le32 reserved_3;
+       __le32 rmac_frag_frms;
+       __le32 rmac_osized_frms;
+       __le32 reserved_4;
+       __le32 rmac_jabber_frms;
+       __le64 rmac_ttl_64_frms;
+       __le64 rmac_ttl_65_127_frms;
+       __le64 reserved_5;
+       __le64 rmac_ttl_128_255_frms;
+       __le64 rmac_ttl_256_511_frms;
+       __le64 reserved_6;
+       __le64 rmac_ttl_512_1023_frms;
+       __le64 rmac_ttl_1024_1518_frms;
+       __le32 rmac_ip;
+       __le32 reserved_7;
+       __le64 rmac_ip_octets;
+       __le32 rmac_drop_ip;
+       __le32 rmac_hdr_err_ip;
+       __le32 reserved_8;
+       __le32 rmac_icmp;
+       __le64 rmac_tcp;
+       __le32 rmac_err_drp_udp;
+       __le32 rmac_udp;
+       __le64 rmac_xgmii_err_sym;
+       __le64 rmac_frms_q0;
+       __le64 rmac_frms_q1;
+       __le64 rmac_frms_q2;
+       __le64 rmac_frms_q3;
+       __le64 rmac_frms_q4;
+       __le64 rmac_frms_q5;
+       __le64 rmac_frms_q6;
+       __le64 rmac_frms_q7;
+       __le16 rmac_full_q3;
+       __le16 rmac_full_q2;
+       __le16 rmac_full_q1;
+       __le16 rmac_full_q0;
+       __le16 rmac_full_q7;
+       __le16 rmac_full_q6;
+       __le16 rmac_full_q5;
+       __le16 rmac_full_q4;
+       __le32 reserved_9;
+       __le32 rmac_pause_cnt;
+       __le64 rmac_xgmii_data_err_cnt;
+       __le64 rmac_xgmii_ctrl_err_cnt;
+       __le32 rmac_err_tcp;
+       __le32 rmac_accepted_ip;
 
 /* PCI/PCI-X Read transaction statistics. */
-       u32 new_rd_req_cnt;
-       u32 rd_req_cnt;
-       u32 rd_rtry_cnt;
-       u32 new_rd_req_rtry_cnt;
+       __le32 new_rd_req_cnt;
+       __le32 rd_req_cnt;
+       __le32 rd_rtry_cnt;
+       __le32 new_rd_req_rtry_cnt;
 
 /* PCI/PCI-X Write/Read transaction statistics. */
-       u32 wr_req_cnt;
-       u32 wr_rtry_rd_ack_cnt;
-       u32 new_wr_req_rtry_cnt;
-       u32 new_wr_req_cnt;
-       u32 wr_disc_cnt;
-       u32 wr_rtry_cnt;
+       __le32 wr_req_cnt;
+       __le32 wr_rtry_rd_ack_cnt;
+       __le32 new_wr_req_rtry_cnt;
+       __le32 new_wr_req_cnt;
+       __le32 wr_disc_cnt;
+       __le32 wr_rtry_cnt;
 
 /*     PCI/PCI-X Write / DMA Transaction statistics. */
-       u32 txp_wr_cnt;
-       u32 rd_rtry_wr_ack_cnt;
-       u32 txd_wr_cnt;
-       u32 txd_rd_cnt;
-       u32 rxd_wr_cnt;
-       u32 rxd_rd_cnt;
-       u32 rxf_wr_cnt;
-       u32 txf_rd_cnt;
+       __le32 txp_wr_cnt;
+       __le32 rd_rtry_wr_ack_cnt;
+       __le32 txd_wr_cnt;
+       __le32 txd_rd_cnt;
+       __le32 rxd_wr_cnt;
+       __le32 rxd_rd_cnt;
+       __le32 rxf_wr_cnt;
+       __le32 txf_rd_cnt;
 
 /* Tx MAC statistics overflow counters. */
-       u32 tmac_data_octets_oflow;
-       u32 tmac_frms_oflow;
-       u32 tmac_bcst_frms_oflow;
-       u32 tmac_mcst_frms_oflow;
-       u32 tmac_ucst_frms_oflow;
-       u32 tmac_ttl_octets_oflow;
-       u32 tmac_any_err_frms_oflow;
-       u32 tmac_nucst_frms_oflow;
-       u64 tmac_vlan_frms;
-       u32 tmac_drop_ip_oflow;
-       u32 tmac_vld_ip_oflow;
-       u32 tmac_rst_tcp_oflow;
-       u32 tmac_icmp_oflow;
-       u32 tpa_unknown_protocol;
-       u32 tmac_udp_oflow;
-       u32 reserved_10;
-       u32 tpa_parse_failure;
+       __le32 tmac_data_octets_oflow;
+       __le32 tmac_frms_oflow;
+       __le32 tmac_bcst_frms_oflow;
+       __le32 tmac_mcst_frms_oflow;
+       __le32 tmac_ucst_frms_oflow;
+       __le32 tmac_ttl_octets_oflow;
+       __le32 tmac_any_err_frms_oflow;
+       __le32 tmac_nucst_frms_oflow;
+       __le64 tmac_vlan_frms;
+       __le32 tmac_drop_ip_oflow;
+       __le32 tmac_vld_ip_oflow;
+       __le32 tmac_rst_tcp_oflow;
+       __le32 tmac_icmp_oflow;
+       __le32 tpa_unknown_protocol;
+       __le32 tmac_udp_oflow;
+       __le32 reserved_10;
+       __le32 tpa_parse_failure;
 
 /* Rx MAC Statistics overflow counters. */
-       u32 rmac_data_octets_oflow;
-       u32 rmac_vld_frms_oflow;
-       u32 rmac_vld_bcst_frms_oflow;
-       u32 rmac_vld_mcst_frms_oflow;
-       u32 rmac_accepted_ucst_frms_oflow;
-       u32 rmac_ttl_octets_oflow;
-       u32 rmac_discarded_frms_oflow;
-       u32 rmac_accepted_nucst_frms_oflow;
-       u32 rmac_usized_frms_oflow;
-       u32 rmac_drop_events_oflow;
-       u32 rmac_frag_frms_oflow;
-       u32 rmac_osized_frms_oflow;
-       u32 rmac_ip_oflow;
-       u32 rmac_jabber_frms_oflow;
-       u32 rmac_icmp_oflow;
-       u32 rmac_drop_ip_oflow;
-       u32 rmac_err_drp_udp_oflow;
-       u32 rmac_udp_oflow;
-       u32 reserved_11;
-       u32 rmac_pause_cnt_oflow;
-       u64 rmac_ttl_1519_4095_frms;
-       u64 rmac_ttl_4096_8191_frms;
-       u64 rmac_ttl_8192_max_frms;
-       u64 rmac_ttl_gt_max_frms;
-       u64 rmac_osized_alt_frms;
-       u64 rmac_jabber_alt_frms;
-       u64 rmac_gt_max_alt_frms;
-       u64 rmac_vlan_frms;
-       u32 rmac_len_discard;
-       u32 rmac_fcs_discard;
-       u32 rmac_pf_discard;
-       u32 rmac_da_discard;
-       u32 rmac_red_discard;
-       u32 rmac_rts_discard;
-       u32 reserved_12;
-       u32 rmac_ingm_full_discard;
-       u32 reserved_13;
-       u32 rmac_accepted_ip_oflow;
-       u32 reserved_14;
-       u32 link_fault_cnt;
+       __le32 rmac_data_octets_oflow;
+       __le32 rmac_vld_frms_oflow;
+       __le32 rmac_vld_bcst_frms_oflow;
+       __le32 rmac_vld_mcst_frms_oflow;
+       __le32 rmac_accepted_ucst_frms_oflow;
+       __le32 rmac_ttl_octets_oflow;
+       __le32 rmac_discarded_frms_oflow;
+       __le32 rmac_accepted_nucst_frms_oflow;
+       __le32 rmac_usized_frms_oflow;
+       __le32 rmac_drop_events_oflow;
+       __le32 rmac_frag_frms_oflow;
+       __le32 rmac_osized_frms_oflow;
+       __le32 rmac_ip_oflow;
+       __le32 rmac_jabber_frms_oflow;
+       __le32 rmac_icmp_oflow;
+       __le32 rmac_drop_ip_oflow;
+       __le32 rmac_err_drp_udp_oflow;
+       __le32 rmac_udp_oflow;
+       __le32 reserved_11;
+       __le32 rmac_pause_cnt_oflow;
+       __le64 rmac_ttl_1519_4095_frms;
+       __le64 rmac_ttl_4096_8191_frms;
+       __le64 rmac_ttl_8192_max_frms;
+       __le64 rmac_ttl_gt_max_frms;
+       __le64 rmac_osized_alt_frms;
+       __le64 rmac_jabber_alt_frms;
+       __le64 rmac_gt_max_alt_frms;
+       __le64 rmac_vlan_frms;
+       __le32 rmac_len_discard;
+       __le32 rmac_fcs_discard;
+       __le32 rmac_pf_discard;
+       __le32 rmac_da_discard;
+       __le32 rmac_red_discard;
+       __le32 rmac_rts_discard;
+       __le32 reserved_12;
+       __le32 rmac_ingm_full_discard;
+       __le32 reserved_13;
+       __le32 rmac_accepted_ip_oflow;
+       __le32 reserved_14;
+       __le32 link_fault_cnt;
        u8  buffer[20];
        swStat_t sw_stat;
        xpakStat_t xpak_stat;
@@ -992,12 +992,12 @@ static void s2io_init_pci(nic_t * sp);
 static int s2io_set_mac_addr(struct net_device *dev, u8 * addr);
 static void s2io_alarm_handle(unsigned long data);
 static int s2io_enable_msi(nic_t *nic);
-static irqreturn_t s2io_msi_handle(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t s2io_msi_handle(int irq, void *dev_id);
 static irqreturn_t
-s2io_msix_ring_handle(int irq, void *dev_id, struct pt_regs *regs);
+s2io_msix_ring_handle(int irq, void *dev_id);
 static irqreturn_t
-s2io_msix_fifo_handle(int irq, void *dev_id, struct pt_regs *regs);
-static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs);
+s2io_msix_fifo_handle(int irq, void *dev_id);
+static irqreturn_t s2io_isr(int irq, void *dev_id);
 static int verify_xena_quiescence(nic_t *sp, u64 val64, int flag);
 static const struct ethtool_ops netdev_ethtool_ops;
 static void s2io_set_link(unsigned long data);
index c479b07be788a129b4bac08abf19a141d8e2f945..b269513cde456290ba637d9aaad354789f5ff9f3 100644 (file)
@@ -745,10 +745,9 @@ static int lan_saa9730_rx(struct net_device *dev)
        return 0;
 }
 
-static irqreturn_t lan_saa9730_interrupt(const int irq, void *dev_id,
-                                 struct pt_regs *regs)
+static irqreturn_t lan_saa9730_interrupt(const int irq, void *dev_id)
 {
-       struct net_device *dev = (struct net_device *) dev_id;
+       struct net_device *dev = dev_id;
        struct lan_saa9730_private *lp = netdev_priv(dev);
 
        if (lan_saa9730_debug > 5)
index a1789ae59278a043efcd73d0d88be4fabbbc0a0f..b9fa4fbb13987fb32beb2b0cfffc463dbfdc4e12 100644 (file)
@@ -84,7 +84,7 @@ extern int sb1000_probe(struct net_device *dev);
 static int sb1000_open(struct net_device *dev);
 static int sb1000_dev_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd);
 static int sb1000_start_xmit(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t sb1000_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t sb1000_interrupt(int irq, void *dev_id);
 static struct net_device_stats *sb1000_stats(struct net_device *dev);
 static int sb1000_close(struct net_device *dev);
 
@@ -1079,24 +1079,18 @@ sb1000_start_xmit(struct sk_buff *skb, struct net_device *dev)
 }
 
 /* SB1000 interrupt handler. */
-static irqreturn_t sb1000_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t sb1000_interrupt(int irq, void *dev_id)
 {
        char *name;
        unsigned char st;
        int ioaddr[2];
-       struct net_device *dev = (struct net_device *) dev_id;
+       struct net_device *dev = dev_id;
        struct sb1000_private *lp = netdev_priv(dev);
 
        const unsigned char Command0[6] = {0x80, 0x2c, 0x00, 0x00, 0x00, 0x00};
        const unsigned char Command1[6] = {0x80, 0x2e, 0x00, 0x00, 0x00, 0x00};
        const int MaxRxErrorCount = 6;
 
-       if (dev == NULL) {
-               printk(KERN_ERR "sb1000_interrupt(): irq %d for unknown device.\n",
-                       irq);
-               return IRQ_NONE;
-       }
-
        ioaddr[0] = dev->base_addr;
        /* mem_start holds the second I/O address */
        ioaddr[1] = dev->mem_start;
index e4c8896b76cb34b475376d448ae7e773af704363..1eae16b72b4b71122c47284d9a3902af2c63485e 100644 (file)
@@ -294,7 +294,7 @@ static void sbmac_channel_stop(struct sbmac_softc *s);
 static sbmac_state_t sbmac_set_channel_state(struct sbmac_softc *,sbmac_state_t);
 static void sbmac_promiscuous_mode(struct sbmac_softc *sc,int onoff);
 static uint64_t sbmac_addr2reg(unsigned char *ptr);
-static irqreturn_t sbmac_intr(int irq,void *dev_instance,struct pt_regs *rgs);
+static irqreturn_t sbmac_intr(int irq,void *dev_instance);
 static int sbmac_start_tx(struct sk_buff *skb, struct net_device *dev);
 static void sbmac_setmulti(struct sbmac_softc *sc);
 static int sbmac_init(struct net_device *dev, int idx);
@@ -2049,7 +2049,7 @@ static int sbmac_set_duplex(struct sbmac_softc *s,sbmac_duplex_t duplex,sbmac_fc
  *  Return value:
  *        nothing
  ********************************************************************* */
-static irqreturn_t sbmac_intr(int irq,void *dev_instance,struct pt_regs *rgs)
+static irqreturn_t sbmac_intr(int irq,void *dev_instance)
 {
        struct net_device *dev = (struct net_device *) dev_instance;
        struct sbmac_softc *sc = netdev_priv(dev);
@@ -2903,7 +2903,7 @@ sbmac_init_module(void)
 
                dev = alloc_etherdev(sizeof(struct sbmac_softc));
                if (!dev)
-                       return -ENOMEM; /* return ENOMEM */
+                       return -ENOMEM;
 
                printk(KERN_DEBUG "sbmac: configuring MAC at %lx\n", port);
 
index 20afdc7f2b976f4c89798123b14d615e34b1fbb4..d9d0a3a3c558b349e7c3d0a6147bb8a06538a743 100644 (file)
@@ -83,7 +83,7 @@ static int seeq8005_probe1(struct net_device *dev, int ioaddr);
 static int seeq8005_open(struct net_device *dev);
 static void seeq8005_timeout(struct net_device *dev);
 static int seeq8005_send_packet(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t seeq8005_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t seeq8005_interrupt(int irq, void *dev_id);
 static void seeq8005_rx(struct net_device *dev);
 static int seeq8005_close(struct net_device *dev);
 static struct net_device_stats *seeq8005_get_stats(struct net_device *dev);
@@ -437,7 +437,7 @@ inline void wait_for_buffer(struct net_device * dev)
 
 /* The typical workload of the driver:
    Handle the network interface interrupts. */
-static irqreturn_t seeq8005_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+static irqreturn_t seeq8005_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
        struct net_local *lp;
index f95a5b0223fb9ff8d3ac43737cdadddc15fb5fcf..a833e7f9757f4b12757f9229e8aa127b9527172d 100644 (file)
@@ -432,7 +432,7 @@ static inline void sgiseeq_tx(struct net_device *dev, struct sgiseeq_private *sp
        }
 }
 
-static irqreturn_t sgiseeq_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t sgiseeq_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = (struct net_device *) dev_id;
        struct sgiseeq_private *sp = netdev_priv(dev);
index e8f26b79bbafa9f4102aefcc97c384bbaf8f9764..aaba458584fbed8e8613a900b4edd8f8f9eb4fd6 100644 (file)
@@ -713,7 +713,7 @@ static void sis190_tx_interrupt(struct net_device *dev,
  * The interrupt handler does all of the Rx thread work and cleans up after
  * the Tx thread.
  */
-static irqreturn_t sis190_interrupt(int irq, void *__dev, struct pt_regs *regs)
+static irqreturn_t sis190_interrupt(int irq, void *__dev)
 {
        struct net_device *dev = __dev;
        struct sis190_private *tp = netdev_priv(dev);
@@ -758,7 +758,7 @@ static void sis190_netpoll(struct net_device *dev)
        struct pci_dev *pdev = tp->pci_dev;
 
        disable_irq(pdev->irq);
-       sis190_interrupt(pdev->irq, dev, NULL);
+       sis190_interrupt(pdev->irq, dev);
        enable_irq(pdev->irq);
 }
 #endif
index 28606e20df1c97954ba13ac6f41ea9fc9e529389..fb2b530516358684939212d47be8a8b0e6b25453 100644 (file)
@@ -218,7 +218,7 @@ static void sis900_init_rx_ring(struct net_device *net_dev);
 static int sis900_start_xmit(struct sk_buff *skb, struct net_device *net_dev);
 static int sis900_rx(struct net_device *net_dev);
 static void sis900_finish_xmit (struct net_device *net_dev);
-static irqreturn_t sis900_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
+static irqreturn_t sis900_interrupt(int irq, void *dev_instance);
 static int sis900_close(struct net_device *net_dev);
 static int mii_ioctl(struct net_device *net_dev, struct ifreq *rq, int cmd);
 static struct net_device_stats *sis900_get_stats(struct net_device *net_dev);
@@ -988,7 +988,7 @@ static u16 sis900_reset_phy(struct net_device *net_dev, int phy_addr)
 static void sis900_poll(struct net_device *dev)
 {
        disable_irq(dev->irq);
-       sis900_interrupt(dev->irq, dev, NULL);
+       sis900_interrupt(dev->irq, dev);
        enable_irq(dev->irq);
 }
 #endif
@@ -1642,7 +1642,7 @@ sis900_start_xmit(struct sk_buff *skb, struct net_device *net_dev)
  *     and cleans up after the Tx thread
  */
 
-static irqreturn_t sis900_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
+static irqreturn_t sis900_interrupt(int irq, void *dev_instance)
 {
        struct net_device *net_dev = dev_instance;
        struct sis900_private *sis_priv = net_dev->priv;
index 99e92627642cb01b0b04692e8736b39b05238dce..d4913c3de2a18fe59066537de9c60245621ad5f3 100644 (file)
@@ -196,8 +196,8 @@ static SK_BOOL      BoardAllocMem(SK_AC *pAC);
 static void    BoardFreeMem(SK_AC *pAC);
 static void    BoardInitMem(SK_AC *pAC);
 static void    SetupRing(SK_AC*, void*, uintptr_t, RXD**, RXD**, RXD**, int*, SK_BOOL);
-static SkIsrRetVar     SkGeIsr(int irq, void *dev_id, struct pt_regs *ptregs);
-static SkIsrRetVar     SkGeIsrOnePort(int irq, void *dev_id, struct pt_regs *ptregs);
+static SkIsrRetVar     SkGeIsr(int irq, void *dev_id);
+static SkIsrRetVar     SkGeIsrOnePort(int irq, void *dev_id);
 static int     SkGeOpen(struct SK_NET_DEVICE *dev);
 static int     SkGeClose(struct SK_NET_DEVICE *dev);
 static int     SkGeXmit(struct sk_buff *skb, struct SK_NET_DEVICE *dev);
@@ -880,7 +880,7 @@ int PortIndex)      /* index of the port for which to re-init */
  * Returns: N/A
  *
  */
-static SkIsrRetVar SkGeIsr(int irq, void *dev_id, struct pt_regs *ptregs)
+static SkIsrRetVar SkGeIsr(int irq, void *dev_id)
 {
 struct SK_NET_DEVICE *dev = (struct SK_NET_DEVICE *)dev_id;
 DEV_NET                *pNet;
@@ -1029,7 +1029,7 @@ SK_U32            IntSrc;         /* interrupts source register contents */
  * Returns: N/A
  *
  */
-static SkIsrRetVar SkGeIsrOnePort(int irq, void *dev_id, struct pt_regs *ptregs)
+static SkIsrRetVar SkGeIsrOnePort(int irq, void *dev_id)
 {
 struct SK_NET_DEVICE *dev = (struct SK_NET_DEVICE *)dev_id;
 DEV_NET                *pNet;
@@ -1140,7 +1140,7 @@ SK_U32            IntSrc;         /* interrupts source register contents */
 static void SkGePollController(struct net_device *dev)
 {
        disable_irq(dev->irq);
-       SkGeIsr(dev->irq, dev, NULL);
+       SkGeIsr(dev->irq, dev);
        enable_irq(dev->irq);
 }
 #endif
index 37b88da1abe5606a9474b9dccf63a32b583294ae..96e06c51b75d36790a989e4ce4f11794836f2af5 100644 (file)
@@ -732,7 +732,7 @@ static u16 irqtx_handler(struct net_device *dev, u16 oldcsr0)
 
 /* general interrupt entry */
 
-static irqreturn_t irq_handler(int irq, void *device, struct pt_regs *regs)
+static irqreturn_t irq_handler(int irq, void *device)
 {
        struct net_device *dev = (struct net_device *) device;
        u16 csr0val;
index 8e4d18440a5695ebe17acd66f1052cf0b6683739..9733a11c61462bbaae5dd3fcf386736dbc397d79 100644 (file)
@@ -101,7 +101,7 @@ static const char * const boot_msg =
 static int skfp_driver_init(struct net_device *dev);
 static int skfp_open(struct net_device *dev);
 static int skfp_close(struct net_device *dev);
-static irqreturn_t skfp_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t skfp_interrupt(int irq, void *dev_id);
 static struct net_device_stats *skfp_ctl_get_stats(struct net_device *dev);
 static void skfp_ctl_set_multicast_list(struct net_device *dev);
 static void skfp_ctl_set_multicast_list_wo_lock(struct net_device *dev);
@@ -593,7 +593,6 @@ static int skfp_close(struct net_device *dev)
  * Arguments:
  *   irq        - interrupt vector
  *   dev_id     - pointer to device information
- *       regs   - pointer to registers structure
  *
  * Functional Description:
  *   This routine calls the interrupt processing routine for this adapter.  It
@@ -615,17 +614,12 @@ static int skfp_close(struct net_device *dev)
  *   Interrupts are disabled, then reenabled at the adapter.
  */
 
-irqreturn_t skfp_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t skfp_interrupt(int irq, void *dev_id)
 {
-       struct net_device *dev = (struct net_device *) dev_id;
+       struct net_device *dev = dev_id;
        struct s_smc *smc;      /* private board structure pointer */
        skfddi_priv *bp;
 
-       if (dev == NULL) {
-               printk("%s: irq %d for unknown device\n", dev->name, irq);
-               return IRQ_NONE;
-       }
-
        smc = netdev_priv(dev);
        bp = &smc->os;
 
index 705e9a8fa30fb454b60759331910193136316bf1..e7e414928f89459dab22c753be80eb7a477590b4 100644 (file)
@@ -43,7 +43,7 @@
 #include "skge.h"
 
 #define DRV_NAME               "skge"
-#define DRV_VERSION            "1.8"
+#define DRV_VERSION            "1.9"
 #define PFX                    DRV_NAME " "
 
 #define DEFAULT_TX_RING_SIZE   128
@@ -197,8 +197,8 @@ static u32 skge_supported_modes(const struct skge_hw *hw)
                else if (hw->chip_id == CHIP_ID_YUKON)
                        supported &= ~SUPPORTED_1000baseT_Half;
        } else
-               supported = SUPPORTED_1000baseT_Full | SUPPORTED_FIBRE
-                       | SUPPORTED_Autoneg;
+               supported = SUPPORTED_1000baseT_Full | SUPPORTED_1000baseT_Half
+                       | SUPPORTED_FIBRE | SUPPORTED_Autoneg;
 
        return supported;
 }
@@ -487,31 +487,37 @@ static void skge_get_pauseparam(struct net_device *dev,
 {
        struct skge_port *skge = netdev_priv(dev);
 
-       ecmd->tx_pause = (skge->flow_control == FLOW_MODE_LOC_SEND)
-               || (skge->flow_control == FLOW_MODE_SYMMETRIC);
-       ecmd->rx_pause = (skge->flow_control == FLOW_MODE_REM_SEND)
-               || (skge->flow_control == FLOW_MODE_SYMMETRIC);
+       ecmd->rx_pause = (skge->flow_control == FLOW_MODE_SYMMETRIC)
+               || (skge->flow_control == FLOW_MODE_SYM_OR_REM);
+       ecmd->tx_pause = ecmd->rx_pause || (skge->flow_control == FLOW_MODE_LOC_SEND);
 
-       ecmd->autoneg = skge->autoneg;
+       ecmd->autoneg = ecmd->rx_pause || ecmd->tx_pause;
 }
 
 static int skge_set_pauseparam(struct net_device *dev,
                               struct ethtool_pauseparam *ecmd)
 {
        struct skge_port *skge = netdev_priv(dev);
+       struct ethtool_pauseparam old;
 
-       skge->autoneg = ecmd->autoneg;
-       if (ecmd->rx_pause && ecmd->tx_pause)
-               skge->flow_control = FLOW_MODE_SYMMETRIC;
-       else if (ecmd->rx_pause && !ecmd->tx_pause)
-               skge->flow_control = FLOW_MODE_REM_SEND;
-       else if (!ecmd->rx_pause && ecmd->tx_pause)
-               skge->flow_control = FLOW_MODE_LOC_SEND;
-       else
-               skge->flow_control = FLOW_MODE_NONE;
+       skge_get_pauseparam(dev, &old);
+
+       if (ecmd->autoneg != old.autoneg)
+               skge->flow_control = ecmd->autoneg ? FLOW_MODE_NONE : FLOW_MODE_SYMMETRIC;
+       else {
+               if (ecmd->rx_pause && ecmd->tx_pause)
+                       skge->flow_control = FLOW_MODE_SYMMETRIC;
+               else if (ecmd->rx_pause && !ecmd->tx_pause)
+                       skge->flow_control = FLOW_MODE_SYM_OR_REM;
+               else if (!ecmd->rx_pause && ecmd->tx_pause)
+                       skge->flow_control = FLOW_MODE_LOC_SEND;
+               else
+                       skge->flow_control = FLOW_MODE_NONE;
+       }
 
        if (netif_running(dev))
                skge_phy_reset(skge);
+
        return 0;
 }
 
@@ -854,6 +860,23 @@ static int skge_rx_fill(struct net_device *dev)
        return 0;
 }
 
+static const char *skge_pause(enum pause_status status)
+{
+       switch(status) {
+       case FLOW_STAT_NONE:
+               return "none";
+       case FLOW_STAT_REM_SEND:
+               return "rx only";
+       case FLOW_STAT_LOC_SEND:
+               return "tx_only";
+       case FLOW_STAT_SYMMETRIC:               /* Both station may send PAUSE */
+               return "both";
+       default:
+               return "indeterminated";
+       }
+}
+
+
 static void skge_link_up(struct skge_port *skge)
 {
        skge_write8(skge->hw, SK_REG(skge->port, LNK_LED_REG),
@@ -862,16 +885,13 @@ static void skge_link_up(struct skge_port *skge)
        netif_carrier_on(skge->netdev);
        netif_wake_queue(skge->netdev);
 
-       if (netif_msg_link(skge))
+       if (netif_msg_link(skge)) {
                printk(KERN_INFO PFX
                       "%s: Link is up at %d Mbps, %s duplex, flow control %s\n",
                       skge->netdev->name, skge->speed,
                       skge->duplex == DUPLEX_FULL ? "full" : "half",
-                      (skge->flow_control == FLOW_MODE_NONE) ? "none" :
-                      (skge->flow_control == FLOW_MODE_LOC_SEND) ? "tx only" :
-                      (skge->flow_control == FLOW_MODE_REM_SEND) ? "rx only" :
-                      (skge->flow_control == FLOW_MODE_SYMMETRIC) ? "tx and rx" :
-                      "unknown");
+                      skge_pause(skge->flow_status));
+       }
 }
 
 static void skge_link_down(struct skge_port *skge)
@@ -884,6 +904,29 @@ static void skge_link_down(struct skge_port *skge)
                printk(KERN_INFO PFX "%s: Link is down.\n", skge->netdev->name);
 }
 
+
+static void xm_link_down(struct skge_hw *hw, int port)
+{
+       struct net_device *dev = hw->dev[port];
+       struct skge_port *skge = netdev_priv(dev);
+       u16 cmd, msk;
+
+       if (hw->phy_type == SK_PHY_XMAC) {
+               msk = xm_read16(hw, port, XM_IMSK);
+               msk |= XM_IS_INP_ASS | XM_IS_LIPA_RC | XM_IS_RX_PAGE | XM_IS_AND;
+               xm_write16(hw, port, XM_IMSK, msk);
+       }
+
+       cmd = xm_read16(hw, port, XM_MMU_CMD);
+       cmd &= ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX);
+       xm_write16(hw, port, XM_MMU_CMD, cmd);
+       /* dummy read to ensure writing */
+       (void) xm_read16(hw, port, XM_MMU_CMD);
+
+       if (netif_carrier_ok(dev))
+               skge_link_down(skge);
+}
+
 static int __xm_phy_read(struct skge_hw *hw, int port, u16 reg, u16 *val)
 {
        int i;
@@ -992,7 +1035,15 @@ static const u16 phy_pause_map[] = {
        [FLOW_MODE_NONE] =      0,
        [FLOW_MODE_LOC_SEND] =  PHY_AN_PAUSE_ASYM,
        [FLOW_MODE_SYMMETRIC] = PHY_AN_PAUSE_CAP,
-       [FLOW_MODE_REM_SEND]  = PHY_AN_PAUSE_CAP | PHY_AN_PAUSE_ASYM,
+       [FLOW_MODE_SYM_OR_REM]  = PHY_AN_PAUSE_CAP | PHY_AN_PAUSE_ASYM,
+};
+
+/* special defines for FIBER (88E1011S only) */
+static const u16 fiber_pause_map[] = {
+       [FLOW_MODE_NONE]        = PHY_X_P_NO_PAUSE,
+       [FLOW_MODE_LOC_SEND]    = PHY_X_P_ASYM_MD,
+       [FLOW_MODE_SYMMETRIC]   = PHY_X_P_SYM_MD,
+       [FLOW_MODE_SYM_OR_REM]  = PHY_X_P_BOTH_MD,
 };
 
 
@@ -1008,14 +1059,7 @@ static void bcom_check_link(struct skge_hw *hw, int port)
        status = xm_phy_read(hw, port, PHY_BCOM_STAT);
 
        if ((status & PHY_ST_LSYNC) == 0) {
-               u16 cmd = xm_read16(hw, port, XM_MMU_CMD);
-               cmd &= ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX);
-               xm_write16(hw, port, XM_MMU_CMD, cmd);
-               /* dummy read to ensure writing */
-               (void) xm_read16(hw, port, XM_MMU_CMD);
-
-               if (netif_carrier_ok(dev))
-                       skge_link_down(skge);
+               xm_link_down(hw, port);
                return;
        }
 
@@ -1048,20 +1092,19 @@ static void bcom_check_link(struct skge_hw *hw, int port)
                        return;
                }
 
-
                /* We are using IEEE 802.3z/D5.0 Table 37-4 */
                switch (aux & PHY_B_AS_PAUSE_MSK) {
                case PHY_B_AS_PAUSE_MSK:
-                       skge->flow_control = FLOW_MODE_SYMMETRIC;
+                       skge->flow_status = FLOW_STAT_SYMMETRIC;
                        break;
                case PHY_B_AS_PRR:
-                       skge->flow_control = FLOW_MODE_REM_SEND;
+                       skge->flow_status = FLOW_STAT_REM_SEND;
                        break;
                case PHY_B_AS_PRT:
-                       skge->flow_control = FLOW_MODE_LOC_SEND;
+                       skge->flow_status = FLOW_STAT_LOC_SEND;
                        break;
                default:
-                       skge->flow_control = FLOW_MODE_NONE;
+                       skge->flow_status = FLOW_STAT_NONE;
                }
                skge->speed = SPEED_1000;
        }
@@ -1191,17 +1234,7 @@ static void xm_phy_init(struct skge_port *skge)
                if (skge->advertising & ADVERTISED_1000baseT_Full)
                        ctrl |= PHY_X_AN_FD;
 
-               switch(skge->flow_control) {
-               case FLOW_MODE_NONE:
-                       ctrl |= PHY_X_P_NO_PAUSE;
-                       break;
-               case FLOW_MODE_LOC_SEND:
-                       ctrl |= PHY_X_P_ASYM_MD;
-                       break;
-               case FLOW_MODE_SYMMETRIC:
-                       ctrl |= PHY_X_P_BOTH_MD;
-                       break;
-               }
+               ctrl |= fiber_pause_map[skge->flow_control];
 
                xm_phy_write(hw, port, PHY_XMAC_AUNE_ADV, ctrl);
 
@@ -1235,14 +1268,7 @@ static void xm_check_link(struct net_device *dev)
        status = xm_phy_read(hw, port, PHY_XMAC_STAT);
 
        if ((status & PHY_ST_LSYNC) == 0) {
-               u16 cmd = xm_read16(hw, port, XM_MMU_CMD);
-               cmd &= ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX);
-               xm_write16(hw, port, XM_MMU_CMD, cmd);
-               /* dummy read to ensure writing */
-               (void) xm_read16(hw, port, XM_MMU_CMD);
-
-               if (netif_carrier_ok(dev))
-                       skge_link_down(skge);
+               xm_link_down(hw, port);
                return;
        }
 
@@ -1276,15 +1302,20 @@ static void xm_check_link(struct net_device *dev)
                }
 
                /* We are using IEEE 802.3z/D5.0 Table 37-4 */
-               if (lpa & PHY_X_P_SYM_MD)
-                       skge->flow_control = FLOW_MODE_SYMMETRIC;
-               else if ((lpa & PHY_X_RS_PAUSE) == PHY_X_P_ASYM_MD)
-                       skge->flow_control = FLOW_MODE_REM_SEND;
-               else if ((lpa & PHY_X_RS_PAUSE) == PHY_X_P_BOTH_MD)
-                       skge->flow_control = FLOW_MODE_LOC_SEND;
+               if ((skge->flow_control == FLOW_MODE_SYMMETRIC ||
+                    skge->flow_control == FLOW_MODE_SYM_OR_REM) &&
+                   (lpa & PHY_X_P_SYM_MD))
+                       skge->flow_status = FLOW_STAT_SYMMETRIC;
+               else if (skge->flow_control == FLOW_MODE_SYM_OR_REM &&
+                        (lpa & PHY_X_RS_PAUSE) == PHY_X_P_ASYM_MD)
+                       /* Enable PAUSE receive, disable PAUSE transmit */
+                       skge->flow_status  = FLOW_STAT_REM_SEND;
+               else if (skge->flow_control == FLOW_MODE_LOC_SEND &&
+                        (lpa & PHY_X_RS_PAUSE) == PHY_X_P_BOTH_MD)
+                       /* Disable PAUSE receive, enable PAUSE transmit */
+                       skge->flow_status = FLOW_STAT_LOC_SEND;
                else
-                       skge->flow_control = FLOW_MODE_NONE;
-
+                       skge->flow_status = FLOW_STAT_NONE;
 
                skge->speed = SPEED_1000;
        }
@@ -1568,6 +1599,10 @@ static void genesis_mac_intr(struct skge_hw *hw, int port)
                printk(KERN_DEBUG PFX "%s: mac interrupt status 0x%x\n",
                       skge->netdev->name, status);
 
+       if (hw->phy_type == SK_PHY_XMAC &&
+           (status & (XM_IS_INP_ASS | XM_IS_LIPA_RC)))
+               xm_link_down(hw, port);
+
        if (status & XM_IS_TXF_UR) {
                xm_write32(hw, port, XM_MODE, XM_MD_FTF);
                ++skge->net_stats.tx_fifo_errors;
@@ -1582,7 +1617,7 @@ static void genesis_link_up(struct skge_port *skge)
 {
        struct skge_hw *hw = skge->hw;
        int port = skge->port;
-       u16 cmd;
+       u16 cmd, msk;
        u32 mode;
 
        cmd = xm_read16(hw, port, XM_MMU_CMD);
@@ -1591,8 +1626,8 @@ static void genesis_link_up(struct skge_port *skge)
         * enabling pause frame reception is required for 1000BT
         * because the XMAC is not reset if the link is going down
         */
-       if (skge->flow_control == FLOW_MODE_NONE ||
-           skge->flow_control == FLOW_MODE_LOC_SEND)
+       if (skge->flow_status == FLOW_STAT_NONE ||
+           skge->flow_status == FLOW_STAT_LOC_SEND)
                /* Disable Pause Frame Reception */
                cmd |= XM_MMU_IGN_PF;
        else
@@ -1602,8 +1637,8 @@ static void genesis_link_up(struct skge_port *skge)
        xm_write16(hw, port, XM_MMU_CMD, cmd);
 
        mode = xm_read32(hw, port, XM_MODE);
-       if (skge->flow_control == FLOW_MODE_SYMMETRIC ||
-           skge->flow_control == FLOW_MODE_LOC_SEND) {
+       if (skge->flow_status== FLOW_STAT_SYMMETRIC ||
+           skge->flow_status == FLOW_STAT_LOC_SEND) {
                /*
                 * Configure Pause Frame Generation
                 * Use internal and external Pause Frame Generation.
@@ -1631,7 +1666,11 @@ static void genesis_link_up(struct skge_port *skge)
        }
 
        xm_write32(hw, port, XM_MODE, mode);
-       xm_write16(hw, port, XM_IMSK, XM_DEF_MSK);
+       msk = XM_DEF_MSK;
+       if (hw->phy_type != SK_PHY_XMAC)
+               msk |= XM_IS_INP_ASS;   /* disable GP0 interrupt bit */
+
+       xm_write16(hw, port, XM_IMSK, msk);
        xm_read16(hw, port, XM_ISRC);
 
        /* get MMU Command Reg. */
@@ -1779,11 +1818,17 @@ static void yukon_init(struct skge_hw *hw, int port)
                                adv |= PHY_M_AN_10_FD;
                        if (skge->advertising & ADVERTISED_10baseT_Half)
                                adv |= PHY_M_AN_10_HD;
-               } else  /* special defines for FIBER (88E1011S only) */
-                       adv |= PHY_M_AN_1000X_AHD | PHY_M_AN_1000X_AFD;
 
-               /* Set Flow-control capabilities */
-               adv |= phy_pause_map[skge->flow_control];
+                       /* Set Flow-control capabilities */
+                       adv |= phy_pause_map[skge->flow_control];
+               } else {
+                       if (skge->advertising & ADVERTISED_1000baseT_Full)
+                               adv |= PHY_M_AN_1000X_AFD;
+                       if (skge->advertising & ADVERTISED_1000baseT_Half)
+                               adv |= PHY_M_AN_1000X_AHD;
+
+                       adv |= fiber_pause_map[skge->flow_control];
+               }
 
                /* Restart Auto-negotiation */
                ctrl |= PHY_CT_ANE | PHY_CT_RE_CFG;
@@ -1917,6 +1962,11 @@ static void yukon_mac_init(struct skge_hw *hw, int port)
        case FLOW_MODE_LOC_SEND:
                /* disable Rx flow-control */
                reg |= GM_GPCR_FC_RX_DIS | GM_GPCR_AU_FCT_DIS;
+               break;
+       case FLOW_MODE_SYMMETRIC:
+       case FLOW_MODE_SYM_OR_REM:
+               /* enable Tx & Rx flow-control */
+               break;
        }
 
        gma_write16(hw, port, GM_GP_CTRL, reg);
@@ -2111,13 +2161,11 @@ static void yukon_link_down(struct skge_port *skge)
        ctrl &= ~(GM_GPCR_RX_ENA | GM_GPCR_TX_ENA);
        gma_write16(hw, port, GM_GP_CTRL, ctrl);
 
-       if (skge->flow_control == FLOW_MODE_REM_SEND) {
+       if (skge->flow_status == FLOW_STAT_REM_SEND) {
+               ctrl = gm_phy_read(hw, port, PHY_MARV_AUNE_ADV);
+               ctrl |= PHY_M_AN_ASP;
                /* restore Asymmetric Pause bit */
-               gm_phy_write(hw, port, PHY_MARV_AUNE_ADV,
-                                 gm_phy_read(hw, port,
-                                                  PHY_MARV_AUNE_ADV)
-                                 | PHY_M_AN_ASP);
-
+               gm_phy_write(hw, port, PHY_MARV_AUNE_ADV, ctrl);
        }
 
        yukon_reset(hw, port);
@@ -2164,19 +2212,19 @@ static void yukon_phy_intr(struct skge_port *skge)
                /* We are using IEEE 802.3z/D5.0 Table 37-4 */
                switch (phystat & PHY_M_PS_PAUSE_MSK) {
                case PHY_M_PS_PAUSE_MSK:
-                       skge->flow_control = FLOW_MODE_SYMMETRIC;
+                       skge->flow_status = FLOW_STAT_SYMMETRIC;
                        break;
                case PHY_M_PS_RX_P_EN:
-                       skge->flow_control = FLOW_MODE_REM_SEND;
+                       skge->flow_status = FLOW_STAT_REM_SEND;
                        break;
                case PHY_M_PS_TX_P_EN:
-                       skge->flow_control = FLOW_MODE_LOC_SEND;
+                       skge->flow_status = FLOW_STAT_LOC_SEND;
                        break;
                default:
-                       skge->flow_control = FLOW_MODE_NONE;
+                       skge->flow_status = FLOW_STAT_NONE;
                }
 
-               if (skge->flow_control == FLOW_MODE_NONE ||
+               if (skge->flow_status == FLOW_STAT_NONE ||
                    (skge->speed < SPEED_1000 && skge->duplex == DUPLEX_HALF))
                        skge_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF);
                else
@@ -3051,7 +3099,7 @@ static void skge_extirq(void *arg)
        spin_unlock_irq(&hw->hw_lock);
 }
 
-static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t skge_intr(int irq, void *dev_id)
 {
        struct skge_hw *hw = dev_id;
        u32 status;
@@ -3125,7 +3173,7 @@ static void skge_netpoll(struct net_device *dev)
        struct skge_port *skge = netdev_priv(dev);
 
        disable_irq(dev->irq);
-       skge_intr(dev->irq, skge->hw, NULL);
+       skge_intr(dev->irq, skge->hw);
        enable_irq(dev->irq);
 }
 #endif
@@ -3399,7 +3447,7 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port,
 
        /* Auto speed and flow control */
        skge->autoneg = AUTONEG_ENABLE;
-       skge->flow_control = FLOW_MODE_SYMMETRIC;
+       skge->flow_control = FLOW_MODE_SYM_OR_REM;
        skge->duplex = -1;
        skge->speed = -1;
        skge->advertising = skge_supported_modes(hw);
index d0b47d46cf9d23701239d7b5c6d5c7d32c477c3d..537c0aaa1db8de7b327572657fea85003548afda 100644 (file)
@@ -2195,7 +2195,8 @@ enum {
        XM_IS_RX_COMP   = 1<<0, /* Bit  0:      Frame Rx Complete */
 };
 
-#define XM_DEF_MSK     (~(XM_IS_RXC_OV | XM_IS_TXC_OV | XM_IS_RXF_OV | XM_IS_TXF_UR))
+#define XM_DEF_MSK     (~(XM_IS_INP_ASS | XM_IS_LIPA_RC | \
+                          XM_IS_RXF_OV | XM_IS_TXF_UR))
 
 
 /*     XM_HW_CFG       16 bit r/w      Hardware Config Register */
@@ -2426,13 +2427,24 @@ struct skge_hw {
        struct mutex         phy_mutex;
 };
 
-enum {
-       FLOW_MODE_NONE          = 0, /* No Flow-Control */
-       FLOW_MODE_LOC_SEND      = 1, /* Local station sends PAUSE */
-       FLOW_MODE_REM_SEND      = 2, /* Symmetric or just remote */
+enum pause_control {
+       FLOW_MODE_NONE          = 1, /* No Flow-Control */
+       FLOW_MODE_LOC_SEND      = 2, /* Local station sends PAUSE */
        FLOW_MODE_SYMMETRIC     = 3, /* Both stations may send PAUSE */
+       FLOW_MODE_SYM_OR_REM    = 4, /* Both stations may send PAUSE or
+                                     * just the remote station may send PAUSE
+                                     */
+};
+
+enum pause_status {
+       FLOW_STAT_INDETERMINATED=0,     /* indeterminated */
+       FLOW_STAT_NONE,                 /* No Flow Control */
+       FLOW_STAT_REM_SEND,             /* Remote Station sends PAUSE */
+       FLOW_STAT_LOC_SEND,             /* Local station sends PAUSE */
+       FLOW_STAT_SYMMETRIC,            /* Both station may send PAUSE */
 };
 
+
 struct skge_port {
        u32                  msg_enable;
        struct skge_hw       *hw;
@@ -2445,9 +2457,10 @@ struct skge_port {
        struct net_device_stats net_stats;
 
        struct work_struct   link_thread;
+       enum pause_control   flow_control;
+       enum pause_status    flow_status;
        u8                   rx_csum;
        u8                   blink_on;
-       u8                   flow_control;
        u8                   wol;
        u8                   autoneg;   /* AUTONEG_ENABLE, AUTONEG_DISABLE */
        u8                   duplex;    /* DUPLEX_HALF, DUPLEX_FULL */
index 396e7df3c61b8573017d829fe298b7f7b1ba1f9d..95efdb5bbbe10da3a1932c3614d09ce85cadda09 100644 (file)
@@ -50,7 +50,7 @@
 #include "sky2.h"
 
 #define DRV_NAME               "sky2"
-#define DRV_VERSION            "1.9"
+#define DRV_VERSION            "1.10"
 #define PFX                    DRV_NAME " "
 
 /*
@@ -96,9 +96,9 @@ static int disable_msi = 0;
 module_param(disable_msi, int, 0);
 MODULE_PARM_DESC(disable_msi, "Disable Message Signaled Interrupt (MSI)");
 
-static int idle_timeout = 100;
+static int idle_timeout = 0;
 module_param(idle_timeout, int, 0);
-MODULE_PARM_DESC(idle_timeout, "Idle timeout workaround for lost interrupts (ms)");
+MODULE_PARM_DESC(idle_timeout, "Watchdog timer for lost interrupts (ms)");
 
 static const struct pci_device_id sky2_id_table[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9000) },
@@ -284,6 +284,31 @@ static void sky2_gmac_reset(struct sky2_hw *hw, unsigned port)
        gma_write16(hw, port, GM_RX_CTRL, reg);
 }
 
+/* flow control to advertise bits */
+static const u16 copper_fc_adv[] = {
+       [FC_NONE]       = 0,
+       [FC_TX]         = PHY_M_AN_ASP,
+       [FC_RX]         = PHY_M_AN_PC,
+       [FC_BOTH]       = PHY_M_AN_PC | PHY_M_AN_ASP,
+};
+
+/* flow control to advertise bits when using 1000BaseX */
+static const u16 fiber_fc_adv[] = {
+       [FC_BOTH] = PHY_M_P_BOTH_MD_X,
+       [FC_TX]   = PHY_M_P_ASYM_MD_X,
+       [FC_RX]   = PHY_M_P_SYM_MD_X,
+       [FC_NONE] = PHY_M_P_NO_PAUSE_X,
+};
+
+/* flow control to GMA disable bits */
+static const u16 gm_fc_disable[] = {
+       [FC_NONE] = GM_GPCR_FC_RX_DIS | GM_GPCR_FC_TX_DIS,
+       [FC_TX]   = GM_GPCR_FC_RX_DIS,
+       [FC_RX]   = GM_GPCR_FC_TX_DIS,
+       [FC_BOTH] = 0,
+};
+
+
 static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
 {
        struct sky2_port *sky2 = netdev_priv(hw->dev[port]);
@@ -356,16 +381,7 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
                gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
        }
 
-       ctrl = gm_phy_read(hw, port, PHY_MARV_CTRL);
-       if (sky2->autoneg == AUTONEG_DISABLE)
-               ctrl &= ~PHY_CT_ANE;
-       else
-               ctrl |= PHY_CT_ANE;
-
-       ctrl |= PHY_CT_RESET;
-       gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl);
-
-       ctrl = 0;
+       ctrl = PHY_CT_RESET;
        ct1000 = 0;
        adv = PHY_AN_CSMA;
        reg = 0;
@@ -384,20 +400,16 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
                                adv |= PHY_M_AN_10_FD;
                        if (sky2->advertising & ADVERTISED_10baseT_Half)
                                adv |= PHY_M_AN_10_HD;
+
+                       adv |= copper_fc_adv[sky2->flow_mode];
                } else {        /* special defines for FIBER (88E1040S only) */
                        if (sky2->advertising & ADVERTISED_1000baseT_Full)
                                adv |= PHY_M_AN_1000X_AFD;
                        if (sky2->advertising & ADVERTISED_1000baseT_Half)
                                adv |= PHY_M_AN_1000X_AHD;
-               }
 
-               /* Set Flow-control capabilities */
-               if (sky2->tx_pause && sky2->rx_pause)
-                       adv |= PHY_AN_PAUSE_CAP;        /* symmetric */
-               else if (sky2->rx_pause && !sky2->tx_pause)
-                       adv |= PHY_AN_PAUSE_ASYM | PHY_AN_PAUSE_CAP;
-               else if (!sky2->rx_pause && sky2->tx_pause)
-                       adv |= PHY_AN_PAUSE_ASYM;       /* local */
+                       adv |= fiber_fc_adv[sky2->flow_mode];
+               }
 
                /* Restart Auto-negotiation */
                ctrl |= PHY_CT_ANE | PHY_CT_RE_CFG;
@@ -422,25 +434,17 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
                if (sky2->duplex == DUPLEX_FULL) {
                        reg |= GM_GPCR_DUP_FULL;
                        ctrl |= PHY_CT_DUP_MD;
-               } else if (sky2->speed != SPEED_1000 && hw->chip_id != CHIP_ID_YUKON_EC_U) {
-                       /* Turn off flow control for 10/100mbps */
-                       sky2->rx_pause = 0;
-                       sky2->tx_pause = 0;
-               }
+               } else if (sky2->speed < SPEED_1000)
+                       sky2->flow_mode = FC_NONE;
 
-               if (!sky2->rx_pause)
-                       reg |= GM_GPCR_FC_RX_DIS;
 
-               if (!sky2->tx_pause)
-                       reg |= GM_GPCR_FC_TX_DIS;
+               reg |= gm_fc_disable[sky2->flow_mode];
 
                /* Forward pause packets to GMAC? */
-               if (sky2->tx_pause || sky2->rx_pause)
+               if (sky2->flow_mode & FC_RX)
                        sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_ON);
                else
                        sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF);
-
-               ctrl |= PHY_CT_RESET;
        }
 
        gma_write16(hw, port, GM_GP_CTRL, reg);
@@ -683,7 +687,7 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port)
        sky2_write16(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_OPER_ON);
 
        if (hw->chip_id == CHIP_ID_YUKON_EC_U) {
-               sky2_write8(hw, SK_REG(port, RX_GMF_LP_THR), 768/8);
+               sky2_write8(hw, SK_REG(port, RX_GMF_LP_THR), 512/8);
                sky2_write8(hw, SK_REG(port, RX_GMF_UP_THR), 1024/8);
                if (hw->dev[port]->mtu > ETH_DATA_LEN) {
                        /* set Tx GMAC FIFO Almost Empty Threshold */
@@ -695,16 +699,10 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port)
 
 }
 
-/* Assign Ram Buffer allocation.
- * start and end are in units of 4k bytes
- * ram registers are in units of 64bit words
- */
-static void sky2_ramset(struct sky2_hw *hw, u16 q, u8 startk, u8 endk)
+/* Assign Ram Buffer allocation in units of 64bit (8 bytes) */
+static void sky2_ramset(struct sky2_hw *hw, u16 q, u32 start, u32 end)
 {
-       u32 start, end;
-
-       start = startk * 4096/8;
-       end = (endk * 4096/8) - 1;
+       pr_debug(PFX "q %d %#x %#x\n", q, start, end);
 
        sky2_write8(hw, RB_ADDR(q, RB_CTRL), RB_RST_CLR);
        sky2_write32(hw, RB_ADDR(q, RB_START), start);
@@ -713,7 +711,7 @@ static void sky2_ramset(struct sky2_hw *hw, u16 q, u8 startk, u8 endk)
        sky2_write32(hw, RB_ADDR(q, RB_RP), start);
 
        if (q == Q_R1 || q == Q_R2) {
-               u32 space = (endk - startk) * 4096/8;
+               u32 space = end - start + 1;
                u32 tp = space - space/4;
 
                /* On receive queue's set the thresholds
@@ -1195,19 +1193,16 @@ static int sky2_up(struct net_device *dev)
 
        sky2_mac_init(hw, port);
 
-       /* Determine available ram buffer space (in 4K blocks).
-        * Note: not sure about the FE setting below yet
-        */
-       if (hw->chip_id == CHIP_ID_YUKON_FE)
-               ramsize = 4;
-       else
-               ramsize = sky2_read8(hw, B2_E_0);
+       /* Determine available ram buffer space in qwords.  */
+       ramsize = sky2_read8(hw, B2_E_0) * 4096/8;
 
-       /* Give transmitter one third (rounded up) */
-       rxspace = ramsize - (ramsize + 2) / 3;
+       if (ramsize > 6*1024/8)
+               rxspace = ramsize - (ramsize + 2) / 3;
+       else
+               rxspace = ramsize / 2;
 
-       sky2_ramset(hw, rxqaddr[port], 0, rxspace);
-       sky2_ramset(hw, txqaddr[port], rxspace, ramsize);
+       sky2_ramset(hw, rxqaddr[port], 0, rxspace-1);
+       sky2_ramset(hw, txqaddr[port], rxspace, ramsize-1);
 
        /* Make sure SyncQ is disabled */
        sky2_write8(hw, RB_ADDR(port == 0 ? Q_XS1 : Q_XS2, RB_CTRL),
@@ -1499,6 +1494,11 @@ static int sky2_down(struct net_device *dev)
        /* Stop more packets from being queued */
        netif_stop_queue(dev);
 
+       /* Disable port IRQ */
+       imask = sky2_read32(hw, B0_IMSK);
+       imask &= ~portirq_msk[port];
+       sky2_write32(hw, B0_IMSK, imask);
+
        sky2_gmac_reset(hw, port);
 
        /* Stop transmitter */
@@ -1549,11 +1549,6 @@ static int sky2_down(struct net_device *dev)
        sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET);
        sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET);
 
-       /* Disable port IRQ */
-       imask = sky2_read32(hw, B0_IMSK);
-       imask &= ~portirq_msk[port];
-       sky2_write32(hw, B0_IMSK, imask);
-
        sky2_phy_power(hw, port, 0);
 
        /* turn off LED's */
@@ -1605,6 +1600,12 @@ static void sky2_link_up(struct sky2_port *sky2)
        struct sky2_hw *hw = sky2->hw;
        unsigned port = sky2->port;
        u16 reg;
+       static const char *fc_name[] = {
+               [FC_NONE]       = "none",
+               [FC_TX]         = "tx",
+               [FC_RX]         = "rx",
+               [FC_BOTH]       = "both",
+       };
 
        /* enable Rx/Tx */
        reg = gma_read16(hw, port, GM_GP_CTRL);
@@ -1648,8 +1649,7 @@ static void sky2_link_up(struct sky2_port *sky2)
                       "%s: Link is up at %d Mbps, %s duplex, flow control %s\n",
                       sky2->netdev->name, sky2->speed,
                       sky2->duplex == DUPLEX_FULL ? "full" : "half",
-                      (sky2->tx_pause && sky2->rx_pause) ? "both" :
-                      sky2->tx_pause ? "tx" : sky2->rx_pause ? "rx" : "none");
+                      fc_name[sky2->flow_status]);
 }
 
 static void sky2_link_down(struct sky2_port *sky2)
@@ -1664,7 +1664,7 @@ static void sky2_link_down(struct sky2_port *sky2)
        reg &= ~(GM_GPCR_RX_ENA | GM_GPCR_TX_ENA);
        gma_write16(hw, port, GM_GP_CTRL, reg);
 
-       if (sky2->rx_pause && !sky2->tx_pause) {
+       if (sky2->flow_status == FC_RX) {
                /* restore Asymmetric Pause bit */
                gm_phy_write(hw, port, PHY_MARV_AUNE_ADV,
                             gm_phy_read(hw, port, PHY_MARV_AUNE_ADV)
@@ -1683,6 +1683,14 @@ static void sky2_link_down(struct sky2_port *sky2)
        sky2_phy_init(hw, port);
 }
 
+static enum flow_control sky2_flow(int rx, int tx)
+{
+       if (rx)
+               return tx ? FC_BOTH : FC_RX;
+       else
+               return tx ? FC_TX : FC_NONE;
+}
+
 static int sky2_autoneg_done(struct sky2_port *sky2, u16 aux)
 {
        struct sky2_hw *hw = sky2->hw;
@@ -1703,39 +1711,20 @@ static int sky2_autoneg_done(struct sky2_port *sky2, u16 aux)
        }
 
        sky2->speed = sky2_phy_speed(hw, aux);
-       if (sky2->speed == SPEED_1000) {
-               u16 ctl2 = gm_phy_read(hw, port, PHY_MARV_1000T_CTRL);
-               u16 lpa2 = gm_phy_read(hw, port, PHY_MARV_1000T_STAT);
-               if (lpa2  & PHY_B_1000S_MSF) {
-                       printk(KERN_ERR PFX "%s: master/slave fault",
-                              sky2->netdev->name);
-                       return -1;
-               }
-
-               if ((ctl2 & PHY_M_1000C_AFD) && (lpa2 & PHY_B_1000S_LP_FD))
-                       sky2->duplex = DUPLEX_FULL;
-               else
-                       sky2->duplex = DUPLEX_HALF;
-       } else {
-               u16 adv = gm_phy_read(hw, port, PHY_MARV_AUNE_ADV);
-               if ((aux & adv) & PHY_AN_FULL)
-                       sky2->duplex = DUPLEX_FULL;
-               else
-                       sky2->duplex = DUPLEX_HALF;
-       }
+       sky2->duplex = (aux & PHY_M_PS_FULL_DUP) ? DUPLEX_FULL : DUPLEX_HALF;
 
        /* Pause bits are offset (9..8) */
        if (hw->chip_id == CHIP_ID_YUKON_XL || hw->chip_id == CHIP_ID_YUKON_EC_U)
                aux >>= 6;
 
-       sky2->rx_pause = (aux & PHY_M_PS_RX_P_EN) != 0;
-       sky2->tx_pause = (aux & PHY_M_PS_TX_P_EN) != 0;
+       sky2->flow_status = sky2_flow(aux & PHY_M_PS_RX_P_EN,
+                                     aux & PHY_M_PS_TX_P_EN);
 
-       if (sky2->duplex == DUPLEX_HALF && sky2->speed != SPEED_1000
+       if (sky2->duplex == DUPLEX_HALF && sky2->speed < SPEED_1000
            && hw->chip_id != CHIP_ID_YUKON_EC_U)
-               sky2->rx_pause = sky2->tx_pause = 0;
+               sky2->flow_status = FC_NONE;
 
-       if (sky2->rx_pause || sky2->tx_pause)
+       if (aux & PHY_M_PS_RX_P_EN)
                sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_ON);
        else
                sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF);
@@ -1750,13 +1739,13 @@ static void sky2_phy_intr(struct sky2_hw *hw, unsigned port)
        struct sky2_port *sky2 = netdev_priv(dev);
        u16 istatus, phystat;
 
+       if (!netif_running(dev))
+               return;
+
        spin_lock(&sky2->phy_lock);
        istatus = gm_phy_read(hw, port, PHY_MARV_INT_STAT);
        phystat = gm_phy_read(hw, port, PHY_MARV_PHY_STAT);
 
-       if (!netif_running(dev))
-               goto out;
-
        if (netif_msg_intr(sky2))
                printk(KERN_INFO PFX "%s: phy interrupt status 0x%x 0x%x\n",
                       sky2->netdev->name, istatus, phystat);
@@ -1907,7 +1896,7 @@ static struct sk_buff *receive_copy(struct sky2_port *sky2,
                pci_dma_sync_single_for_device(sky2->hw->pdev, re->data_addr,
                                               length, PCI_DMA_FROMDEVICE);
                re->skb->ip_summed = CHECKSUM_NONE;
-               __skb_put(skb, length);
+               skb_put(skb, length);
        }
        return skb;
 }
@@ -1970,7 +1959,7 @@ static struct sk_buff *receive_new(struct sky2_port *sky2,
        if (skb_shinfo(skb)->nr_frags)
                skb_put_frags(skb, hdr_space, length);
        else
-               skb_put(skb, hdr_space);
+               skb_put(skb, length);
        return skb;
 }
 
@@ -2016,6 +2005,10 @@ oversize:
 
 error:
        ++sky2->net_stats.rx_errors;
+       if (status & GMR_FS_RX_FF_OV) {
+               sky2->net_stats.rx_fifo_errors++;
+               goto resubmit;
+       }
 
        if (netif_msg_rx_err(sky2) && net_ratelimit())
                printk(KERN_INFO PFX "%s: rx error, status 0x%x length %d\n",
@@ -2027,8 +2020,6 @@ error:
                sky2->net_stats.rx_frame_errors++;
        if (status & GMR_FS_CRC_ERR)
                sky2->net_stats.rx_crc_errors++;
-       if (status & GMR_FS_RX_FF_OV)
-               sky2->net_stats.rx_fifo_errors++;
 
        goto resubmit;
 }
@@ -2220,8 +2211,7 @@ static void sky2_hw_intr(struct sky2_hw *hw)
                /* PCI-Express uncorrectable Error occurred */
                u32 pex_err;
 
-               pex_err = sky2_pci_read32(hw,
-                                         hw->err_cap + PCI_ERR_UNCOR_STATUS);
+               pex_err = sky2_pci_read32(hw, PEX_UNC_ERR_STAT);
 
                if (net_ratelimit())
                        printk(KERN_ERR PFX "%s: pci express error (0x%x)\n",
@@ -2229,20 +2219,15 @@ static void sky2_hw_intr(struct sky2_hw *hw)
 
                /* clear the interrupt */
                sky2_write32(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
-               sky2_pci_write32(hw,
-                                hw->err_cap + PCI_ERR_UNCOR_STATUS,
-                                0xffffffffUL);
+               sky2_pci_write32(hw, PEX_UNC_ERR_STAT,
+                                      0xffffffffUL);
                sky2_write32(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
 
-
-               /* In case of fatal error mask off to keep from getting stuck */
-               if (pex_err & (PCI_ERR_UNC_POISON_TLP | PCI_ERR_UNC_FCP
-                              | PCI_ERR_UNC_DLP)) {
+               if (pex_err & PEX_FATAL_ERRORS) {
                        u32 hwmsk = sky2_read32(hw, B0_HWE_IMSK);
                        hwmsk &= ~Y2_IS_PCI_EXP;
                        sky2_write32(hw, B0_HWE_IMSK, hwmsk);
                }
-
        }
 
        if (status & Y2_HWE_L1_MASK)
@@ -2364,7 +2349,7 @@ static int sky2_poll(struct net_device *dev0, int *budget)
        }
 }
 
-static irqreturn_t sky2_intr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t sky2_intr(int irq, void *dev_id)
 {
        struct sky2_hw *hw = dev_id;
        struct net_device *dev0 = hw->dev[0];
@@ -2423,7 +2408,6 @@ static int sky2_reset(struct sky2_hw *hw)
        u16 status;
        u8 t8;
        int i;
-       u32 msk;
 
        sky2_write8(hw, B0_CTST, CS_RST_CLR);
 
@@ -2464,13 +2448,9 @@ static int sky2_reset(struct sky2_hw *hw)
        sky2_write8(hw, B0_CTST, CS_MRST_CLR);
 
        /* clear any PEX errors */
-       if (pci_find_capability(hw->pdev, PCI_CAP_ID_EXP)) {
-               hw->err_cap = pci_find_ext_capability(hw->pdev, PCI_EXT_CAP_ID_ERR);
-               if (hw->err_cap)
-                       sky2_pci_write32(hw,
-                                        hw->err_cap + PCI_ERR_UNCOR_STATUS,
-                                        0xffffffffUL);
-       }
+       if (pci_find_capability(hw->pdev, PCI_CAP_ID_EXP))
+               sky2_pci_write32(hw, PEX_UNC_ERR_STAT, 0xffffffffUL);
+
 
        hw->pmd_type = sky2_read8(hw, B2_PMD_TYP);
        hw->ports = 1;
@@ -2527,10 +2507,7 @@ static int sky2_reset(struct sky2_hw *hw)
                sky2_write8(hw, RAM_BUFFER(i, B3_RI_RTO_XS2), SK_RI_TO_53);
        }
 
-       msk = Y2_HWE_ALL_MASK;
-       if (!hw->err_cap)
-               msk &= ~Y2_IS_PCI_EXP;
-       sky2_write32(hw, B0_HWE_IMSK, msk);
+       sky2_write32(hw, B0_HWE_IMSK, Y2_HWE_ALL_MASK);
 
        for (i = 0; i < hw->ports; i++)
                sky2_gmac_reset(hw, i);
@@ -2762,7 +2739,7 @@ static int sky2_nway_reset(struct net_device *dev)
 {
        struct sky2_port *sky2 = netdev_priv(dev);
 
-       if (sky2->autoneg != AUTONEG_ENABLE)
+       if (!netif_running(dev) || sky2->autoneg != AUTONEG_ENABLE)
                return -EINVAL;
 
        sky2_phy_reinit(sky2);
@@ -2864,6 +2841,14 @@ static int sky2_set_mac_address(struct net_device *dev, void *p)
        return 0;
 }
 
+static void inline sky2_add_filter(u8 filter[8], const u8 *addr)
+{
+       u32 bit;
+
+       bit = ether_crc(ETH_ALEN, addr) & 63;
+       filter[bit >> 3] |= 1 << (bit & 7);
+}
+
 static void sky2_set_multicast(struct net_device *dev)
 {
        struct sky2_port *sky2 = netdev_priv(dev);
@@ -2872,7 +2857,10 @@ static void sky2_set_multicast(struct net_device *dev)
        struct dev_mc_list *list = dev->mc_list;
        u16 reg;
        u8 filter[8];
+       int rx_pause;
+       static const u8 pause_mc_addr[ETH_ALEN] = { 0x1, 0x80, 0xc2, 0x0, 0x0, 0x1 };
 
+       rx_pause = (sky2->flow_status == FC_RX || sky2->flow_status == FC_BOTH);
        memset(filter, 0, sizeof(filter));
 
        reg = gma_read16(hw, port, GM_RX_CTRL);
@@ -2880,18 +2868,19 @@ static void sky2_set_multicast(struct net_device *dev)
 
        if (dev->flags & IFF_PROMISC)   /* promiscuous */
                reg &= ~(GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA);
-       else if ((dev->flags & IFF_ALLMULTI) || dev->mc_count > 16)     /* all multicast */
+       else if (dev->flags & IFF_ALLMULTI)
                memset(filter, 0xff, sizeof(filter));
-       else if (dev->mc_count == 0)    /* no multicast */
+       else if (dev->mc_count == 0 && !rx_pause)
                reg &= ~GM_RXCR_MCF_ENA;
        else {
                int i;
                reg |= GM_RXCR_MCF_ENA;
 
-               for (i = 0; list && i < dev->mc_count; i++, list = list->next) {
-                       u32 bit = ether_crc(ETH_ALEN, list->dmi_addr) & 0x3f;
-                       filter[bit / 8] |= 1 << (bit % 8);
-               }
+               if (rx_pause)
+                       sky2_add_filter(filter, pause_mc_addr);
+
+               for (i = 0; list && i < dev->mc_count; i++, list = list->next)
+                       sky2_add_filter(filter, list->dmi_addr);
        }
 
        gma_write16(hw, port, GM_MC_ADDR_H1,
@@ -3004,8 +2993,20 @@ static void sky2_get_pauseparam(struct net_device *dev,
 {
        struct sky2_port *sky2 = netdev_priv(dev);
 
-       ecmd->tx_pause = sky2->tx_pause;
-       ecmd->rx_pause = sky2->rx_pause;
+       switch (sky2->flow_mode) {
+       case FC_NONE:
+               ecmd->tx_pause = ecmd->rx_pause = 0;
+               break;
+       case FC_TX:
+               ecmd->tx_pause = 1, ecmd->rx_pause = 0;
+               break;
+       case FC_RX:
+               ecmd->tx_pause = 0, ecmd->rx_pause = 1;
+               break;
+       case FC_BOTH:
+               ecmd->tx_pause = ecmd->rx_pause = 1;
+       }
+
        ecmd->autoneg = sky2->autoneg;
 }
 
@@ -3015,10 +3016,10 @@ static int sky2_set_pauseparam(struct net_device *dev,
        struct sky2_port *sky2 = netdev_priv(dev);
 
        sky2->autoneg = ecmd->autoneg;
-       sky2->tx_pause = ecmd->tx_pause != 0;
-       sky2->rx_pause = ecmd->rx_pause != 0;
+       sky2->flow_mode = sky2_flow(ecmd->rx_pause, ecmd->tx_pause);
 
-       sky2_phy_reinit(sky2);
+       if (netif_running(dev))
+               sky2_phy_reinit(sky2);
 
        return 0;
 }
@@ -3248,8 +3249,8 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
 
        /* Auto speed and flow control */
        sky2->autoneg = AUTONEG_ENABLE;
-       sky2->tx_pause = 1;
-       sky2->rx_pause = 1;
+       sky2->flow_mode = FC_BOTH;
+
        sky2->duplex = -1;
        sky2->speed = -1;
        sky2->advertising = sky2_supported_modes(hw);
@@ -3298,8 +3299,7 @@ static void __devinit sky2_show_addr(struct net_device *dev)
 }
 
 /* Handle software interrupt used during MSI test */
-static irqreturn_t __devinit sky2_test_intr(int irq, void *dev_id,
-                                           struct pt_regs *regs)
+static irqreturn_t __devinit sky2_test_intr(int irq, void *dev_id)
 {
        struct sky2_hw *hw = dev_id;
        u32 status = sky2_read32(hw, B0_Y2_SP_ISRC2);
@@ -3341,9 +3341,8 @@ static int __devinit sky2_test_msi(struct sky2_hw *hw)
 
        if (!hw->msi_detected) {
                /* MSI test failed, go back to INTx mode */
-               printk(KERN_WARNING PFX "%s: No interrupt was generated using MSI, "
-                      "switching to INTx mode. Please report this failure to "
-                      "the PCI maintainer and include system chipset information.\n",
+               printk(KERN_INFO PFX "%s: No interrupt generated using MSI, "
+                      "switching to INTx mode.\n",
                       pci_name(pdev));
 
                err = -EOPNOTSUPP;
@@ -3351,6 +3350,7 @@ static int __devinit sky2_test_msi(struct sky2_hw *hw)
        }
 
        sky2_write32(hw, B0_IMSK, 0);
+       sky2_read32(hw, B0_IMSK);
 
        free_irq(pdev->irq, hw);
 
index f66109a96d95b0b2f13dfeba2c02f13241507a8d..6d2a23f66c9ae1e8ca41879ecc8134a86b56edf2 100644 (file)
@@ -6,15 +6,24 @@
 
 #define ETH_JUMBO_MTU          9000    /* Maximum MTU supported */
 
-/* PCI device specific config registers */
+/* PCI config registers */
 enum {
        PCI_DEV_REG1    = 0x40,
        PCI_DEV_REG2    = 0x44,
+       PCI_DEV_STATUS  = 0x7c,
        PCI_DEV_REG3    = 0x80,
        PCI_DEV_REG4    = 0x84,
        PCI_DEV_REG5    = 0x88,
 };
 
+enum {
+       PEX_DEV_CAP     = 0xe4,
+       PEX_DEV_CTRL    = 0xe8,
+       PEX_DEV_STA     = 0xea,
+       PEX_LNK_STAT    = 0xf2,
+       PEX_UNC_ERR_STAT= 0x104,
+};
+
 /* Yukon-2 */
 enum pci_dev_reg_1 {
        PCI_Y2_PIG_ENA   = 1<<31, /* Enable Plug-in-Go (YUKON-2) */
@@ -63,6 +72,39 @@ enum pci_dev_reg_4 {
                               PCI_STATUS_REC_MASTER_ABORT | \
                               PCI_STATUS_REC_TARGET_ABORT | \
                               PCI_STATUS_PARITY)
+
+enum pex_dev_ctrl {
+       PEX_DC_MAX_RRS_MSK      = 7<<12, /* Bit 14..12: Max. Read Request Size */
+       PEX_DC_EN_NO_SNOOP      = 1<<11,/* Enable No Snoop */
+       PEX_DC_EN_AUX_POW       = 1<<10,/* Enable AUX Power */
+       PEX_DC_EN_PHANTOM       = 1<<9, /* Enable Phantom Functions */
+       PEX_DC_EN_EXT_TAG       = 1<<8, /* Enable Extended Tag Field */
+       PEX_DC_MAX_PLS_MSK      = 7<<5, /* Bit  7.. 5:  Max. Payload Size Mask */
+       PEX_DC_EN_REL_ORD       = 1<<4, /* Enable Relaxed Ordering */
+       PEX_DC_EN_UNS_RQ_RP     = 1<<3, /* Enable Unsupported Request Reporting */
+       PEX_DC_EN_FAT_ER_RP     = 1<<2, /* Enable Fatal Error Reporting */
+       PEX_DC_EN_NFA_ER_RP     = 1<<1, /* Enable Non-Fatal Error Reporting */
+       PEX_DC_EN_COR_ER_RP     = 1<<0, /* Enable Correctable Error Reporting */
+};
+#define  PEX_DC_MAX_RD_RQ_SIZE(x) (((x)<<12) & PEX_DC_MAX_RRS_MSK)
+
+/* PEX_UNC_ERR_STAT     PEX Uncorrectable Errors Status Register (Yukon-2) */
+enum pex_err {
+       PEX_UNSUP_REQ   = 1<<20, /* Unsupported Request Error */
+
+       PEX_MALFOR_TLP  = 1<<18, /* Malformed TLP */
+
+       PEX_UNEXP_COMP  = 1<<16, /* Unexpected Completion */
+
+       PEX_COMP_TO     = 1<<14, /* Completion Timeout */
+       PEX_FLOW_CTRL_P = 1<<13, /* Flow Control Protocol Error */
+       PEX_POIS_TLP    = 1<<12, /* Poisoned TLP */
+
+       PEX_DATA_LINK_P = 1<<4, /* Data Link Protocol Error */
+       PEX_FATAL_ERRORS= (PEX_MALFOR_TLP | PEX_FLOW_CTRL_P | PEX_DATA_LINK_P),
+};
+
+
 enum csr_regs {
        B0_RAP          = 0x0000,
        B0_CTST         = 0x0004,
@@ -1534,7 +1576,7 @@ enum {
 
        GMR_FS_ANY_ERR  = GMR_FS_RX_FF_OV | GMR_FS_CRC_ERR |
                          GMR_FS_FRAGMENT | GMR_FS_LONG_ERR |
-                         GMR_FS_MII_ERR | GMR_FS_BAD_FC |
+                         GMR_FS_MII_ERR | GMR_FS_GOOD_FC | GMR_FS_BAD_FC |
                          GMR_FS_UN_SIZE | GMR_FS_JABBER,
 };
 
@@ -1786,6 +1828,13 @@ struct rx_ring_info {
        dma_addr_t      frag_addr[ETH_JUMBO_MTU >> PAGE_SHIFT];
 };
 
+enum flow_control {
+       FC_NONE = 0,
+       FC_TX   = 1,
+       FC_RX   = 2,
+       FC_BOTH = 3,
+};
+
 struct sky2_port {
        struct sky2_hw       *hw;
        struct net_device    *netdev;
@@ -1818,13 +1867,13 @@ struct sky2_port {
 
        dma_addr_t           rx_le_map;
        dma_addr_t           tx_le_map;
-       u32                  advertising;       /* ADVERTISED_ bits */
+       u16                  advertising;       /* ADVERTISED_ bits */
        u16                  speed;     /* SPEED_1000, SPEED_100, ... */
        u8                   autoneg;   /* AUTONEG_ENABLE, AUTONEG_DISABLE */
        u8                   duplex;    /* DUPLEX_HALF, DUPLEX_FULL */
-       u8                   rx_pause;
-       u8                   tx_pause;
        u8                   rx_csum;
+       enum flow_control    flow_mode;
+       enum flow_control    flow_status;
 
        struct net_device_stats net_stats;
 
@@ -1836,7 +1885,6 @@ struct sky2_hw {
        struct net_device    *dev[2];
 
        int                  pm_cap;
-       int                  err_cap;
        u8                   chip_id;
        u8                   chip_rev;
        u8                   pmd_type;
index 7986514883acb3292425b7758b724f2aa36f63ac..889ef0d7c37499bba55e9f0e311dcf9dc1abdcec 100644 (file)
@@ -127,7 +127,7 @@ MODULE_DEVICE_TABLE(isapnp, ultra_device_ids);
 static void ultra_poll(struct net_device *dev)
 {
        disable_irq(dev->irq);
-       ei_interrupt(dev->irq, dev, NULL);
+       ei_interrupt(dev->irq, dev);
        enable_irq(dev->irq);
 }
 #endif
index a621b17456e576b9f2e05ef90d820dcf3f38676d..2c4343395a4d96bd93057da50c6af294723b8144 100644 (file)
@@ -1074,7 +1074,7 @@ static void smc911x_phy_interrupt(struct net_device *dev)
  * This is the main routine of the driver, to handle the device when
  * it needs some attention.
  */
-static irqreturn_t smc911x_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t smc911x_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
        unsigned long ioaddr = dev->base_addr;
@@ -1251,7 +1251,7 @@ static irqreturn_t smc911x_interrupt(int irq, void *dev_id, struct pt_regs *regs
 
 #ifdef SMC_USE_DMA
 static void
-smc911x_tx_dma_irq(int dma, void *data, struct pt_regs *regs)
+smc911x_tx_dma_irq(int dma, void *data)
 {
        struct net_device *dev = (struct net_device *)data;
        struct smc911x_local *lp = netdev_priv(dev);
@@ -1285,7 +1285,7 @@ smc911x_tx_dma_irq(int dma, void *data, struct pt_regs *regs)
                "%s: TX DMA irq completed\n", dev->name);
 }
 static void
-smc911x_rx_dma_irq(int dma, void *data, struct pt_regs *regs)
+smc911x_rx_dma_irq(int dma, void *data)
 {
        struct net_device *dev = (struct net_device *)data;
        unsigned long ioaddr = dev->base_addr;
index 5506a0d3efe2d3f429a7b8be90943f4a1ac6df43..c0d13d65091333555f118f5c16f386a955b500cf 100644 (file)
@@ -270,7 +270,7 @@ static void smc_set_multicast_list(struct net_device *dev);
 /*
  . Handles the actual interrupt
 */
-static irqreturn_t smc_interrupt(int irq, void *, struct pt_regs *regs);
+static irqreturn_t smc_interrupt(int irq, void *);
 /*
  . This is a separate procedure to handle the receipt of a packet, to
  . leave the interrupt code looking slightly cleaner
@@ -1391,7 +1391,7 @@ static void smc_tx( struct net_device * dev )
  .
  ---------------------------------------------------------------------*/
 
-static irqreturn_t smc_interrupt(int irq, void * dev_id,  struct pt_regs * regs)
+static irqreturn_t smc_interrupt(int irq, void * dev_id)
 {
        struct net_device *dev  = dev_id;
        int ioaddr              = dev->base_addr;
index d7e56438b5d657dccaff0964afda77d5127c9019..95b6478f55c66c8c53f36a9f65180effbc47e33e 100644 (file)
@@ -1284,7 +1284,7 @@ static void smc_eph_interrupt(struct net_device *dev)
  * This is the main routine of the driver, to handle the device when
  * it needs some attention.
  */
-static irqreturn_t smc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t smc_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
        struct smc_local *lp = netdev_priv(dev);
@@ -1400,7 +1400,7 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 static void smc_poll_controller(struct net_device *dev)
 {
        disable_irq(dev->irq);
-       smc_interrupt(dev->irq, dev, NULL);
+       smc_interrupt(dev->irq, dev);
        enable_irq(dev->irq);
 }
 #endif
index fedd1a37bc3e71fa631ea9ebb39b97d1e0cf6e15..a8640169fc77afede8c7f28376ccc8967b214668 100644 (file)
@@ -398,6 +398,42 @@ static inline void LPD7_SMC_outsw (unsigned char* a, int r,
 
 #define SMC_IRQ_FLAGS          (0)
 
+#elif  defined(CONFIG_ARCH_VERSATILE)
+
+#define SMC_CAN_USE_8BIT       1
+#define SMC_CAN_USE_16BIT      1
+#define SMC_CAN_USE_32BIT      1
+#define SMC_NOWAIT             1
+
+#define SMC_inb(a, r)          readb((a) + (r))
+#define SMC_inw(a, r)          readw((a) + (r))
+#define SMC_inl(a, r)          readl((a) + (r))
+#define SMC_outb(v, a, r)      writeb(v, (a) + (r))
+#define SMC_outw(v, a, r)      writew(v, (a) + (r))
+#define SMC_outl(v, a, r)      writel(v, (a) + (r))
+#define SMC_insl(a, r, p, l)   readsl((a) + (r), p, l)
+#define SMC_outsl(a, r, p, l)  writesl((a) + (r), p, l)
+
+#define SMC_IRQ_FLAGS          (0)
+
+#elif  defined(CONFIG_ARCH_VERSATILE)
+
+#define SMC_CAN_USE_8BIT       1
+#define SMC_CAN_USE_16BIT      1
+#define SMC_CAN_USE_32BIT      1
+#define SMC_NOWAIT             1
+
+#define SMC_inb(a, r)          readb((a) + (r))
+#define SMC_inw(a, r)          readw((a) + (r))
+#define SMC_inl(a, r)          readl((a) + (r))
+#define SMC_outb(v, a, r)      writeb(v, (a) + (r))
+#define SMC_outw(v, a, r)      writew(v, (a) + (r))
+#define SMC_outl(v, a, r)      writel(v, (a) + (r))
+#define SMC_insl(a, r, p, l)   readsl((a) + (r), p, l)
+#define SMC_outsl(a, r, p, l)  writesl((a) + (r), p, l)
+
+#define SMC_IRQ_FLAGS          (0)
+
 #else
 
 #define SMC_CAN_USE_8BIT       1
@@ -507,7 +543,7 @@ smc_pxa_dma_insw(void __iomem *ioaddr, u_long physaddr, int reg, int dma,
 #endif
 
 static void
-smc_pxa_dma_irq(int dma, void *dummy, struct pt_regs *regs)
+smc_pxa_dma_irq(int dma, void *dummy)
 {
        DCSR(dma) = 0;
 }
index 870cf6b07389cdd4a886f6c5bd309402605618c6..ed7aa0a5accad039fe5bca8e651bfca0246d5636 100644 (file)
@@ -293,17 +293,12 @@ static int sonic_send_packet(struct sk_buff *skb, struct net_device *dev)
  * The typical workload of the driver:
  * Handle the network interface interrupts.
  */
-static irqreturn_t sonic_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t sonic_interrupt(int irq, void *dev_id)
 {
-       struct net_device *dev = (struct net_device *) dev_id;
+       struct net_device *dev = dev_id;
        struct sonic_local *lp = netdev_priv(dev);
        int status;
 
-       if (dev == NULL) {
-               printk(KERN_ERR "sonic_interrupt: irq %d for unknown device.\n", irq);
-               return IRQ_NONE;
-       }
-
        if (!(status = SONIC_READ(SONIC_ISR) & SONIC_IMR_DEFAULT))
                return IRQ_NONE;
 
index 7f886e8ae28fd32c3f1bc7e32eaad9a49d155d47..7db13e4a7ea55c70c8b31c9cd0c93dbbb6012d1f 100644 (file)
@@ -328,7 +328,7 @@ struct sonic_local {
 
 static int sonic_open(struct net_device *dev);
 static int sonic_send_packet(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t sonic_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t sonic_interrupt(int irq, void *dev_id);
 static void sonic_rx(struct net_device *dev);
 static int sonic_close(struct net_device *dev);
 static struct net_device_stats *sonic_get_stats(struct net_device *dev);
index 1397fc55cf688c345899ea19a4f12271d0662287..418138dd6c687452afe9636bafb87c0658a69712 100644 (file)
@@ -55,12 +55,13 @@ MODULE_AUTHOR("Utz Bacher <utz.bacher@de.ibm.com> and Jens Osterkamp " \
              "<Jens.Osterkamp@de.ibm.com>");
 MODULE_DESCRIPTION("Spider Southbridge Gigabit Ethernet driver");
 MODULE_LICENSE("GPL");
+MODULE_VERSION(VERSION);
 
 static int rx_descriptors = SPIDER_NET_RX_DESCRIPTORS_DEFAULT;
 static int tx_descriptors = SPIDER_NET_TX_DESCRIPTORS_DEFAULT;
 
-module_param(rx_descriptors, int, 0644);
-module_param(tx_descriptors, int, 0644);
+module_param(rx_descriptors, int, 0444);
+module_param(tx_descriptors, int, 0444);
 
 MODULE_PARM_DESC(rx_descriptors, "number of descriptors used " \
                 "in rx chains");
@@ -300,7 +301,7 @@ static int
 spider_net_init_chain(struct spider_net_card *card,
                       struct spider_net_descr_chain *chain,
                       struct spider_net_descr *start_descr,
-                      int direction, int no)
+                      int no)
 {
        int i;
        struct spider_net_descr *descr;
@@ -315,7 +316,7 @@ spider_net_init_chain(struct spider_net_card *card,
 
                buf = pci_map_single(card->pdev, descr,
                                     SPIDER_NET_DESCR_SIZE,
-                                    direction);
+                                    PCI_DMA_BIDIRECTIONAL);
 
                if (pci_dma_mapping_error(buf))
                        goto iommu_error;
@@ -329,11 +330,6 @@ spider_net_init_chain(struct spider_net_card *card,
        (descr-1)->next = start_descr;
        start_descr->prev = descr-1;
 
-       descr = start_descr;
-       if (direction == PCI_DMA_FROMDEVICE)
-               for (i=0; i < no; i++, descr++)
-                       descr->next_descr_addr = descr->next->bus_addr;
-
        spin_lock_init(&chain->lock);
        chain->head = start_descr;
        chain->tail = start_descr;
@@ -346,7 +342,7 @@ iommu_error:
                if (descr->bus_addr)
                        pci_unmap_single(card->pdev, descr->bus_addr,
                                         SPIDER_NET_DESCR_SIZE,
-                                        direction);
+                                        PCI_DMA_BIDIRECTIONAL);
        return -ENOMEM;
 }
 
@@ -362,15 +358,15 @@ spider_net_free_rx_chain_contents(struct spider_net_card *card)
        struct spider_net_descr *descr;
 
        descr = card->rx_chain.head;
-       while (descr->next != card->rx_chain.head) {
+       do {
                if (descr->skb) {
                        dev_kfree_skb(descr->skb);
                        pci_unmap_single(card->pdev, descr->buf_addr,
                                         SPIDER_NET_MAX_FRAME,
-                                        PCI_DMA_FROMDEVICE);
+                                        PCI_DMA_BIDIRECTIONAL);
                }
                descr = descr->next;
-       }
+       } while (descr != card->rx_chain.head);
 }
 
 /**
@@ -645,26 +641,41 @@ static int
 spider_net_prepare_tx_descr(struct spider_net_card *card,
                            struct sk_buff *skb)
 {
-       struct spider_net_descr *descr = card->tx_chain.head;
+       struct spider_net_descr *descr;
        dma_addr_t buf;
+       unsigned long flags;
+       int length;
 
-       buf = pci_map_single(card->pdev, skb->data, skb->len, PCI_DMA_TODEVICE);
+       length = skb->len;
+       if (length < ETH_ZLEN) {
+               if (skb_pad(skb, ETH_ZLEN-length))
+                       return 0;
+               length = ETH_ZLEN;
+       }
+
+       buf = pci_map_single(card->pdev, skb->data, length, PCI_DMA_TODEVICE);
        if (pci_dma_mapping_error(buf)) {
                if (netif_msg_tx_err(card) && net_ratelimit())
                        pr_err("could not iommu-map packet (%p, %i). "
-                                 "Dropping packet\n", skb->data, skb->len);
+                                 "Dropping packet\n", skb->data, length);
                card->spider_stats.tx_iommu_map_error++;
                return -ENOMEM;
        }
 
+       spin_lock_irqsave(&card->tx_chain.lock, flags);
+       descr = card->tx_chain.head;
+       card->tx_chain.head = descr->next;
+
        descr->buf_addr = buf;
-       descr->buf_size = skb->len;
+       descr->buf_size = length;
        descr->next_descr_addr = 0;
        descr->skb = skb;
        descr->data_status = 0;
 
        descr->dmac_cmd_status =
                        SPIDER_NET_DESCR_CARDOWNED | SPIDER_NET_DMAC_NOCS;
+       spin_unlock_irqrestore(&card->tx_chain.lock, flags);
+
        if (skb->protocol == htons(ETH_P_IP))
                switch (skb->nh.iph->protocol) {
                case IPPROTO_TCP:
@@ -675,32 +686,51 @@ spider_net_prepare_tx_descr(struct spider_net_card *card,
                        break;
                }
 
+       /* Chain the bus address, so that the DMA engine finds this descr. */
        descr->prev->next_descr_addr = descr->bus_addr;
 
+       card->netdev->trans_start = jiffies; /* set netdev watchdog timer */
        return 0;
 }
 
-/**
- * spider_net_release_tx_descr - processes a used tx descriptor
- * @card: card structure
- * @descr: descriptor to release
- *
- * releases a used tx descriptor (unmapping, freeing of skb)
- */
-static inline void
-spider_net_release_tx_descr(struct spider_net_card *card)
+static int
+spider_net_set_low_watermark(struct spider_net_card *card)
 {
+       unsigned long flags;
+       int status;
+       int cnt=0;
+       int i;
        struct spider_net_descr *descr = card->tx_chain.tail;
-       struct sk_buff *skb;
 
-       card->tx_chain.tail = card->tx_chain.tail->next;
-       descr->dmac_cmd_status |= SPIDER_NET_DESCR_NOT_IN_USE;
+       /* Measure the length of the queue. Measurement does not
+        * need to be precise -- does not need a lock. */
+       while (descr != card->tx_chain.head) {
+               status = descr->dmac_cmd_status & SPIDER_NET_DESCR_NOT_IN_USE;
+               if (status == SPIDER_NET_DESCR_NOT_IN_USE)
+                       break;
+               descr = descr->next;
+               cnt++;
+       }
 
-       /* unmap the skb */
-       skb = descr->skb;
-       pci_unmap_single(card->pdev, descr->buf_addr, skb->len,
-                       PCI_DMA_TODEVICE);
-       dev_kfree_skb_any(skb);
+       /* If TX queue is short, don't even bother with interrupts */
+       if (cnt < card->num_tx_desc/4)
+               return cnt;
+
+       /* Set low-watermark 3/4th's of the way into the queue. */
+       descr = card->tx_chain.tail;
+       cnt = (cnt*3)/4;
+       for (i=0;i<cnt; i++)
+               descr = descr->next;
+
+       /* Set the new watermark, clear the old watermark */
+       spin_lock_irqsave(&card->tx_chain.lock, flags);
+       descr->dmac_cmd_status |= SPIDER_NET_DESCR_TXDESFLG;
+       if (card->low_watermark && card->low_watermark != descr)
+               card->low_watermark->dmac_cmd_status =
+                    card->low_watermark->dmac_cmd_status & ~SPIDER_NET_DESCR_TXDESFLG;
+       card->low_watermark = descr;
+       spin_unlock_irqrestore(&card->tx_chain.lock, flags);
+       return cnt;
 }
 
 /**
@@ -719,21 +749,29 @@ static int
 spider_net_release_tx_chain(struct spider_net_card *card, int brutal)
 {
        struct spider_net_descr_chain *chain = &card->tx_chain;
+       struct spider_net_descr *descr;
+       struct sk_buff *skb;
+       u32 buf_addr;
+       unsigned long flags;
        int status;
 
-       spider_net_read_reg(card, SPIDER_NET_GDTDMACCNTR);
-
        while (chain->tail != chain->head) {
-               status = spider_net_get_descr_status(chain->tail);
+               spin_lock_irqsave(&chain->lock, flags);
+               descr = chain->tail;
+
+               status = spider_net_get_descr_status(descr);
                switch (status) {
                case SPIDER_NET_DESCR_COMPLETE:
                        card->netdev_stats.tx_packets++;
-                       card->netdev_stats.tx_bytes += chain->tail->skb->len;
+                       card->netdev_stats.tx_bytes += descr->skb->len;
                        break;
 
                case SPIDER_NET_DESCR_CARDOWNED:
-                       if (!brutal)
+                       if (!brutal) {
+                               spin_unlock_irqrestore(&chain->lock, flags);
                                return 1;
+                       }
+
                        /* fallthrough, if we release the descriptors
                         * brutally (then we don't care about
                         * SPIDER_NET_DESCR_CARDOWNED) */
@@ -750,11 +788,25 @@ spider_net_release_tx_chain(struct spider_net_card *card, int brutal)
 
                default:
                        card->netdev_stats.tx_dropped++;
-                       return 1;
+                       if (!brutal) {
+                               spin_unlock_irqrestore(&chain->lock, flags);
+                               return 1;
+                       }
                }
-               spider_net_release_tx_descr(card);
-       }
 
+               chain->tail = descr->next;
+               descr->dmac_cmd_status |= SPIDER_NET_DESCR_NOT_IN_USE;
+               skb = descr->skb;
+               buf_addr = descr->buf_addr;
+               spin_unlock_irqrestore(&chain->lock, flags);
+
+               /* unmap the skb */
+               if (skb) {
+                       int len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len;
+                       pci_unmap_single(card->pdev, buf_addr, len, PCI_DMA_TODEVICE);
+                       dev_kfree_skb(skb);
+               }
+       }
        return 0;
 }
 
@@ -763,8 +815,12 @@ spider_net_release_tx_chain(struct spider_net_card *card, int brutal)
  * @card: card structure
  * @descr: descriptor address to enable TX processing at
  *
- * spider_net_kick_tx_dma writes the current tx chain head as start address
- * of the tx descriptor chain and enables the transmission DMA engine
+ * This routine will start the transmit DMA running if
+ * it is not already running. This routine ned only be
+ * called when queueing a new packet to an empty tx queue.
+ * Writes the current tx chain head as start address
+ * of the tx descriptor chain and enables the transmission
+ * DMA engine.
  */
 static inline void
 spider_net_kick_tx_dma(struct spider_net_card *card)
@@ -804,65 +860,43 @@ out:
 static int
 spider_net_xmit(struct sk_buff *skb, struct net_device *netdev)
 {
+       int cnt;
        struct spider_net_card *card = netdev_priv(netdev);
        struct spider_net_descr_chain *chain = &card->tx_chain;
-       struct spider_net_descr *descr = chain->head;
-       unsigned long flags;
-       int result;
-
-       spin_lock_irqsave(&chain->lock, flags);
 
        spider_net_release_tx_chain(card, 0);
 
-       if (chain->head->next == chain->tail->prev) {
-               card->netdev_stats.tx_dropped++;
-               result = NETDEV_TX_LOCKED;
-               goto out;
-       }
+       if ((chain->head->next == chain->tail->prev) ||
+          (spider_net_prepare_tx_descr(card, skb) != 0)) {
 
-       if (spider_net_get_descr_status(descr) != SPIDER_NET_DESCR_NOT_IN_USE) {
                card->netdev_stats.tx_dropped++;
-               result = NETDEV_TX_LOCKED;
-               goto out;
+               netif_stop_queue(netdev);
+               return NETDEV_TX_BUSY;
        }
 
-       if (spider_net_prepare_tx_descr(card, skb) != 0) {
-               card->netdev_stats.tx_dropped++;
-               result = NETDEV_TX_BUSY;
-               goto out;
-       }
-
-       result = NETDEV_TX_OK;
-
-       spider_net_kick_tx_dma(card);
-       card->tx_chain.head = card->tx_chain.head->next;
-
-out:
-       spin_unlock_irqrestore(&chain->lock, flags);
-       netif_wake_queue(netdev);
-       return result;
+       cnt = spider_net_set_low_watermark(card);
+       if (cnt < 5)
+               spider_net_kick_tx_dma(card);
+       return NETDEV_TX_OK;
 }
 
 /**
  * spider_net_cleanup_tx_ring - cleans up the TX ring
  * @card: card structure
  *
- * spider_net_cleanup_tx_ring is called by the tx_timer (as we don't use
- * interrupts to cleanup our TX ring) and returns sent packets to the stack
- * by freeing them
+ * spider_net_cleanup_tx_ring is called by either the tx_timer
+ * or from the NAPI polling routine.
+ * This routine releases resources associted with transmitted
+ * packets, including updating the queue tail pointer.
  */
 static void
 spider_net_cleanup_tx_ring(struct spider_net_card *card)
 {
-       unsigned long flags;
-
-       spin_lock_irqsave(&card->tx_chain.lock, flags);
-
        if ((spider_net_release_tx_chain(card, 0) != 0) &&
-           (card->netdev->flags & IFF_UP))
+           (card->netdev->flags & IFF_UP)) {
                spider_net_kick_tx_dma(card);
-
-       spin_unlock_irqrestore(&card->tx_chain.lock, flags);
+               netif_wake_queue(card->netdev);
+       }
 }
 
 /**
@@ -1053,6 +1087,7 @@ spider_net_poll(struct net_device *netdev, int *budget)
        int packets_to_do, packets_done = 0;
        int no_more_packets = 0;
 
+       spider_net_cleanup_tx_ring(card);
        packets_to_do = min(*budget, netdev->quota);
 
        while (packets_to_do) {
@@ -1243,12 +1278,15 @@ spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg)
        case SPIDER_NET_PHYINT:
        case SPIDER_NET_GMAC2INT:
        case SPIDER_NET_GMAC1INT:
-       case SPIDER_NET_GIPSINT:
        case SPIDER_NET_GFIFOINT:
        case SPIDER_NET_DMACINT:
        case SPIDER_NET_GSYSINT:
                break; */
 
+       case SPIDER_NET_GIPSINT:
+               show_error = 0;
+               break;
+
        case SPIDER_NET_GPWOPCMPINT:
                /* PHY write operation completed */
                show_error = 0;
@@ -1307,9 +1345,10 @@ spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg)
        case SPIDER_NET_GDTDCEINT:
                /* chain end. If a descriptor should be sent, kick off
                 * tx dma
-               if (card->tx_chain.tail == card->tx_chain.head)
+               if (card->tx_chain.tail != card->tx_chain.head)
                        spider_net_kick_tx_dma(card);
-               show_error = 0; */
+               */
+               show_error = 0;
                break;
 
        /* case SPIDER_NET_G1TMCNTINT: not used. print a message */
@@ -1354,7 +1393,7 @@ spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg)
                if (netif_msg_intr(card))
                        pr_err("got descriptor chain end interrupt, "
                               "restarting DMAC %c.\n",
-                              'D'+i-SPIDER_NET_GDDDCEINT);
+                              'D'-(i-SPIDER_NET_GDDDCEINT)/3);
                spider_net_refill_rx_chain(card);
                spider_net_enable_rxdmac(card);
                show_error = 0;
@@ -1423,8 +1462,9 @@ spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg)
        }
 
        if ((show_error) && (netif_msg_intr(card)))
-               pr_err("Got error interrupt, GHIINT0STS = 0x%08x, "
+               pr_err("Got error interrupt on %s, GHIINT0STS = 0x%08x, "
                       "GHIINT1STS = 0x%08x, GHIINT2STS = 0x%08x\n",
+                      card->netdev->name,
                       status_reg, error_reg1, error_reg2);
 
        /* clear interrupt sources */
@@ -1445,7 +1485,7 @@ spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg)
  * interrupts for this device and makes the stack poll the driver
  */
 static irqreturn_t
-spider_net_interrupt(int irq, void *ptr, struct pt_regs *regs)
+spider_net_interrupt(int irq, void *ptr)
 {
        struct net_device *netdev = ptr;
        struct spider_net_card *card = netdev_priv(netdev);
@@ -1460,6 +1500,8 @@ spider_net_interrupt(int irq, void *ptr, struct pt_regs *regs)
                spider_net_rx_irq_off(card);
                netif_rx_schedule(netdev);
        }
+       if (status_reg & SPIDER_NET_TXINT)
+               netif_rx_schedule(netdev);
 
        if (status_reg & SPIDER_NET_ERRINT )
                spider_net_handle_error_irq(card, status_reg);
@@ -1481,7 +1523,7 @@ static void
 spider_net_poll_controller(struct net_device *netdev)
 {
        disable_irq(netdev->irq);
-       spider_net_interrupt(netdev->irq, netdev, NULL);
+       spider_net_interrupt(netdev->irq, netdev);
        enable_irq(netdev->irq);
 }
 #endif /* CONFIG_NET_POLL_CONTROLLER */
@@ -1599,7 +1641,7 @@ spider_net_enable_card(struct spider_net_card *card)
                             SPIDER_NET_INT2_MASK_VALUE);
 
        spider_net_write_reg(card, SPIDER_NET_GDTDMACCNTR,
-                            SPIDER_NET_GDTDCEIDIS);
+                            SPIDER_NET_GDTBSTA | SPIDER_NET_GDTDCEIDIS);
 }
 
 /**
@@ -1615,17 +1657,26 @@ int
 spider_net_open(struct net_device *netdev)
 {
        struct spider_net_card *card = netdev_priv(netdev);
-       int result;
+       struct spider_net_descr *descr;
+       int i, result;
 
        result = -ENOMEM;
        if (spider_net_init_chain(card, &card->tx_chain, card->descr,
-                       PCI_DMA_TODEVICE, card->tx_desc))
+                                 card->num_tx_desc))
                goto alloc_tx_failed;
+
+       card->low_watermark = NULL;
+
+       /* rx_chain is after tx_chain, so offset is descr + tx_count */
        if (spider_net_init_chain(card, &card->rx_chain,
-                       card->descr + card->rx_desc,
-                       PCI_DMA_FROMDEVICE, card->rx_desc))
+                                 card->descr + card->num_tx_desc,
+                                 card->num_rx_desc))
                goto alloc_rx_failed;
 
+       descr = card->rx_chain.head;
+       for (i=0; i < card->num_rx_desc; i++, descr++)
+               descr->next_descr_addr = descr->next->bus_addr;
+
        /* allocate rx skbs */
        if (spider_net_alloc_rx_skbs(card))
                goto alloc_skbs_failed;
@@ -1878,10 +1929,7 @@ spider_net_stop(struct net_device *netdev)
        spider_net_disable_rxdmac(card);
 
        /* release chains */
-       if (spin_trylock(&card->tx_chain.lock)) {
-               spider_net_release_tx_chain(card, 1);
-               spin_unlock(&card->tx_chain.lock);
-       }
+       spider_net_release_tx_chain(card, 1);
 
        spider_net_free_chain(card, &card->tx_chain);
        spider_net_free_chain(card, &card->rx_chain);
@@ -2012,8 +2060,8 @@ spider_net_setup_netdev(struct spider_net_card *card)
 
        card->options.rx_csum = SPIDER_NET_RX_CSUM_DEFAULT;
 
-       card->tx_desc = tx_descriptors;
-       card->rx_desc = rx_descriptors;
+       card->num_tx_desc = tx_descriptors;
+       card->num_rx_desc = rx_descriptors;
 
        spider_net_setup_netdev_ops(netdev);
 
@@ -2252,6 +2300,8 @@ static struct pci_driver spider_net_driver = {
  */
 static int __init spider_net_init(void)
 {
+       printk(KERN_INFO "Spidernet version %s.\n", VERSION);
+
        if (rx_descriptors < SPIDER_NET_RX_DESCRIPTORS_MIN) {
                rx_descriptors = SPIDER_NET_RX_DESCRIPTORS_MIN;
                pr_info("adjusting rx descriptors to %i.\n", rx_descriptors);
index a59deda2f95e1b9e479850a6b4f3a23fe81314f8..b3b46119b4243f141823efe7358d4d01c8bdb5a0 100644 (file)
@@ -24,6 +24,8 @@
 #ifndef _SPIDER_NET_H
 #define _SPIDER_NET_H
 
+#define VERSION "1.1 A"
+
 #include "sungem_phy.h"
 
 extern int spider_net_stop(struct net_device *netdev);
@@ -47,7 +49,7 @@ extern char spider_net_driver_name[];
 #define SPIDER_NET_TX_DESCRIPTORS_MIN          16
 #define SPIDER_NET_TX_DESCRIPTORS_MAX          512
 
-#define SPIDER_NET_TX_TIMER                    20
+#define SPIDER_NET_TX_TIMER                    (HZ/5)
 
 #define SPIDER_NET_RX_CSUM_DEFAULT             1
 
@@ -189,7 +191,9 @@ extern char spider_net_driver_name[];
 #define SPIDER_NET_MACMODE_VALUE       0x00000001
 #define SPIDER_NET_BURSTLMT_VALUE      0x00000200 /* about 16 us */
 
-/* 1(0)                                        enable r/tx dma
+/* DMAC control register GDMACCNTR
+ *
+ * 1(0)                                enable r/tx dma
  *  0000000                            fixed to 0
  *
  *         000000                      fixed to 0
@@ -198,6 +202,7 @@ extern char spider_net_driver_name[];
  *
  *                 000000              fixed to 0
  *                       00            burst alignment: 128 bytes
+ *                       11            burst alignment: 1024 bytes
  *
  *                         00000       fixed to 0
  *                              0      descr writeback size 32 bytes
@@ -208,10 +213,13 @@ extern char spider_net_driver_name[];
 #define SPIDER_NET_DMA_RX_VALUE                0x80000000
 #define SPIDER_NET_DMA_RX_FEND_VALUE   0x00030003
 /* to set TX_DMA_EN */
-#define SPIDER_NET_TX_DMA_EN           0x80000000
-#define SPIDER_NET_GDTDCEIDIS          0x00000002
-#define SPIDER_NET_DMA_TX_VALUE                SPIDER_NET_TX_DMA_EN | \
-                                       SPIDER_NET_GDTDCEIDIS
+#define SPIDER_NET_TX_DMA_EN           0x80000000
+#define SPIDER_NET_GDTBSTA             0x00000300
+#define SPIDER_NET_GDTDCEIDIS          0x00000002
+#define SPIDER_NET_DMA_TX_VALUE        SPIDER_NET_TX_DMA_EN | \
+                                       SPIDER_NET_GDTBSTA | \
+                                       SPIDER_NET_GDTDCEIDIS
+
 #define SPIDER_NET_DMA_TX_FEND_VALUE   0x00030003
 
 /* SPIDER_NET_UA_DESCR_VALUE is OR'ed with the unicast address */
@@ -320,13 +328,10 @@ enum spider_net_int2_status {
        SPIDER_NET_GRISPDNGINT
 };
 
-#define SPIDER_NET_TXINT       ( (1 << SPIDER_NET_GTTEDINT) | \
-                                 (1 << SPIDER_NET_GDTDCEINT) | \
-                                 (1 << SPIDER_NET_GDTFDCINT) )
+#define SPIDER_NET_TXINT       ( (1 << SPIDER_NET_GDTFDCINT) )
 
-/* we rely on flagged descriptor interrupts*/
-#define SPIDER_NET_RXINT       ( (1 << SPIDER_NET_GDAFDCINT) | \
-                                 (1 << SPIDER_NET_GRMFLLINT) )
+/* We rely on flagged descriptor interrupts */
+#define SPIDER_NET_RXINT       ( (1 << SPIDER_NET_GDAFDCINT) )
 
 #define SPIDER_NET_ERRINT      ( 0xffffffff & \
                                  (~SPIDER_NET_TXINT) & \
@@ -349,6 +354,7 @@ enum spider_net_int2_status {
 #define SPIDER_NET_DESCR_FORCE_END             0x50000000 /* used in rx and tx */
 #define SPIDER_NET_DESCR_CARDOWNED             0xA0000000 /* used in rx and tx */
 #define SPIDER_NET_DESCR_NOT_IN_USE            0xF0000000
+#define SPIDER_NET_DESCR_TXDESFLG              0x00800000
 
 struct spider_net_descr {
        /* as defined by the hardware */
@@ -433,6 +439,7 @@ struct spider_net_card {
 
        struct spider_net_descr_chain tx_chain;
        struct spider_net_descr_chain rx_chain;
+       struct spider_net_descr *low_watermark;
 
        struct net_device_stats netdev_stats;
 
@@ -448,8 +455,8 @@ struct spider_net_card {
 
        /* for ethtool */
        int msg_enable;
-       int rx_desc;
-       int tx_desc;
+       int num_rx_desc;
+       int num_tx_desc;
        struct spider_net_extra_stats spider_stats;
 
        struct spider_net_descr descr[0];
index 589e43658dee35e3ccc0feec526ededf5406d6ef..91b99510291516d172701c2b7e9e9cff6f4f30ce 100644 (file)
@@ -76,7 +76,7 @@ spider_net_ethtool_get_drvinfo(struct net_device *netdev,
        /* clear and fill out info */
        memset(drvinfo, 0, sizeof(struct ethtool_drvinfo));
        strncpy(drvinfo->driver, spider_net_driver_name, 32);
-       strncpy(drvinfo->version, "0.1", 32);
+       strncpy(drvinfo->version, VERSION, 32);
        strcpy(drvinfo->fw_version, "no information");
        strncpy(drvinfo->bus_info, pci_name(card->pdev), 32);
 }
@@ -158,9 +158,9 @@ spider_net_ethtool_get_ringparam(struct net_device *netdev,
        struct spider_net_card *card = netdev->priv;
 
        ering->tx_max_pending = SPIDER_NET_TX_DESCRIPTORS_MAX;
-       ering->tx_pending = card->tx_desc;
+       ering->tx_pending = card->num_tx_desc;
        ering->rx_max_pending = SPIDER_NET_RX_DESCRIPTORS_MAX;
-       ering->rx_pending = card->rx_desc;
+       ering->rx_pending = card->num_rx_desc;
 }
 
 static int spider_net_get_stats_count(struct net_device *netdev)
index 3d617e8f54b563c51bce7b9cf0fe583451c78222..7a0aee6c869d2331162a3b4a17574199ef6f8bd4 100644 (file)
@@ -632,7 +632,7 @@ static void check_duplex(struct net_device *dev);
 static void    tx_timeout(struct net_device *dev);
 static void    init_ring(struct net_device *dev);
 static int     start_tx(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t intr_handler(int irq, void *dev_instance, struct pt_regs *regs);
+static irqreturn_t intr_handler(int irq, void *dev_instance);
 static void    netdev_error(struct net_device *dev, int intr_status);
 static int     __netdev_rx(struct net_device *dev, int *quota);
 static void    refill_rx_ring(struct net_device *dev);
@@ -1307,7 +1307,7 @@ static int start_tx(struct sk_buff *skb, struct net_device *dev)
 
 /* The interrupt handler does all of the Rx thread work and cleans up
    after the Tx thread. */
-static irqreturn_t intr_handler(int irq, void *dev_instance, struct pt_regs *rgs)
+static irqreturn_t intr_handler(int irq, void *dev_instance)
 {
        struct net_device *dev = dev_instance;
        struct netdev_private *np = netdev_priv(dev);
index 0605461bc56d49303f767d718788156106b59535..a3220a96524f0ead88f6a6b0089ec569007627ea 100644 (file)
@@ -122,7 +122,7 @@ sizeof(nop_cmd) = 8;
      DELAY_16(); DELAY_16(); } }
 
 static int     sun3_82586_probe1(struct net_device *dev,int ioaddr);
-static irqreturn_t sun3_82586_interrupt(int irq,void *dev_id,struct pt_regs *reg_ptr);
+static irqreturn_t sun3_82586_interrupt(int irq,void *dev_id);
 static int     sun3_82586_open(struct net_device *dev);
 static int     sun3_82586_close(struct net_device *dev);
 static int     sun3_82586_send_packet(struct sk_buff *,struct net_device *);
@@ -330,7 +330,7 @@ out2:
 out1:
        free_netdev(dev);
 out:
-       iounmap((void *)ioaddr);
+       iounmap((void __iomem *)ioaddr);
        return ERR_PTR(err);
 }
 
@@ -678,7 +678,7 @@ static void *alloc_rfa(struct net_device *dev,void *ptr)
  * Interrupt Handler ...
  */
 
-static irqreturn_t sun3_82586_interrupt(int irq,void *dev_id,struct pt_regs *reg_ptr)
+static irqreturn_t sun3_82586_interrupt(int irq,void *dev_id)
 {
        struct net_device *dev = dev_id;
        unsigned short stat;
index 61a832ce7ccfdc85642cfc0bd1e7f54dd115f1dc..b865db363ba0bf62fde272a2063fe7135dee788c 100644 (file)
@@ -237,7 +237,7 @@ static int lance_probe( struct net_device *dev);
 static int lance_open( struct net_device *dev );
 static void lance_init_ring( struct net_device *dev );
 static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev );
-static irqreturn_t lance_interrupt( int irq, void *dev_id, struct pt_regs *fp );
+static irqreturn_t lance_interrupt( int irq, void *dev_id);
 static int lance_rx( struct net_device *dev );
 static int lance_close( struct net_device *dev );
 static struct net_device_stats *lance_get_stats( struct net_device *dev );
@@ -286,7 +286,7 @@ struct net_device * __init sun3lance_probe(int unit)
 
 out1:
 #ifdef CONFIG_SUN3
-       iounmap((void *)dev->base_addr);
+       iounmap((void __iomem *)dev->base_addr);
 #endif
 out:
        free_netdev(dev);
@@ -326,7 +326,7 @@ static int __init lance_probe( struct net_device *dev)
                ioaddr_probe[1] = tmp2;
 
 #ifdef CONFIG_SUN3
-               iounmap((void *)ioaddr);
+               iounmap((void __iomem *)ioaddr);
 #endif
                return 0;
        }
@@ -642,7 +642,7 @@ static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev )
 
 /* The LANCE interrupt handler. */
 
-static irqreturn_t lance_interrupt( int irq, void *dev_id, struct pt_regs *fp)
+static irqreturn_t lance_interrupt( int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
        struct lance_private *lp = netdev_priv(dev);
@@ -956,7 +956,7 @@ void cleanup_module(void)
 {
        unregister_netdev(sun3lance_dev);
 #ifdef CONFIG_SUN3
-       iounmap((void *)sun3lance_dev->base_addr);
+       iounmap((void __iomem *)sun3lance_dev->base_addr);
 #endif
        free_netdev(sun3lance_dev);
 }
index 9e4be86495a03ef96b9b38d9f09f6d00ff1b3c03..18f88853e1e583efd38b1f8368dd17ecff873489 100644 (file)
@@ -42,7 +42,7 @@
 #define DRV_RELDATE    "11/24/03"
 #define DRV_AUTHOR     "David S. Miller (davem@redhat.com)"
 
-static char version[] __initdata =
+static char version[] =
        DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " " DRV_AUTHOR "\n";
 
 MODULE_VERSION(DRV_VERSION);
@@ -888,7 +888,7 @@ static void bigmac_rx(struct bigmac *bp)
                printk(KERN_NOTICE "%s: Memory squeeze, deferring packet.\n", bp->dev->name);
 }
 
-static irqreturn_t bigmac_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t bigmac_interrupt(int irq, void *dev_id)
 {
        struct bigmac *bp = (struct bigmac *) dev_id;
        u32 qec_status, bmac_status;
index 6b8f4baf87fd309ff33978ebc62876887fa26d7a..41c503d8bac43d39b5591d16a6c2a2e325daf440 100644 (file)
@@ -420,7 +420,7 @@ static void tx_timeout(struct net_device *dev);
 static void init_ring(struct net_device *dev);
 static int  start_tx(struct sk_buff *skb, struct net_device *dev);
 static int reset_tx (struct net_device *dev);
-static irqreturn_t intr_handler(int irq, void *dev_instance, struct pt_regs *regs);
+static irqreturn_t intr_handler(int irq, void *dev_instance);
 static void rx_poll(unsigned long data);
 static void tx_poll(unsigned long data);
 static void refill_rx (struct net_device *dev);
@@ -1102,7 +1102,7 @@ reset_tx (struct net_device *dev)
 
 /* The interrupt handler cleans up after the Tx thread,
    and schedule a Rx thread work */
-static irqreturn_t intr_handler(int irq, void *dev_instance, struct pt_regs *rgs)
+static irqreturn_t intr_handler(int irq, void *dev_instance)
 {
        struct net_device *dev = (struct net_device *)dev_instance;
        struct netdev_private *np = netdev_priv(dev);
index 0975695ae31bf0328e444b221575db4be82f39f2..253e96e7ad20ae0ff860dae8f7ceb6d55cf4d888 100644 (file)
@@ -932,7 +932,7 @@ static int gem_poll(struct net_device *dev, int *budget)
        return 0;
 }
 
-static irqreturn_t gem_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t gem_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
        struct gem *gp = dev->priv;
@@ -975,7 +975,7 @@ static void gem_poll_controller(struct net_device *dev)
        /* gem_interrupt is safe to reentrance so no need
         * to disable_irq here.
         */
-       gem_interrupt(dev->irq, dev, NULL);
+       gem_interrupt(dev->irq, dev);
 }
 #endif
 
index f05eea53623b522b91261ef0bbc9fd27d2bbcf49..9d7cd130c19db7b9946535e856bd6fb6d5773756 100644 (file)
@@ -2093,10 +2093,10 @@ static void happy_meal_rx(struct happy_meal *hp, struct net_device *dev)
        RXD((">"));
 }
 
-static irqreturn_t happy_meal_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t happy_meal_interrupt(int irq, void *dev_id)
 {
-       struct net_device *dev = (struct net_device *) dev_id;
-       struct happy_meal *hp  = dev->priv;
+       struct net_device *dev = dev_id;
+       struct happy_meal *hp  = netdev_priv(dev);
        u32 happy_status       = hme_read32(hp, hp->gregs + GREG_STAT);
 
        HMD(("happy_meal_interrupt: status=%08x ", happy_status));
@@ -2132,7 +2132,7 @@ out:
 }
 
 #ifdef CONFIG_SBUS
-static irqreturn_t quattro_sbus_interrupt(int irq, void *cookie, struct pt_regs *ptregs)
+static irqreturn_t quattro_sbus_interrupt(int irq, void *cookie)
 {
        struct quattro *qp = (struct quattro *) cookie;
        int i;
index feb42db10ee1abd853e43f87964c5f57cbbd413d..5b00d79b557376d6f63b143a8d3effd697b70294 100644 (file)
@@ -820,9 +820,9 @@ out:
        spin_unlock(&lp->lock);
 }
 
-static irqreturn_t lance_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t lance_interrupt(int irq, void *dev_id)
 {
-       struct net_device *dev = (struct net_device *)dev_id;
+       struct net_device *dev = dev_id;
        struct lance_private *lp = netdev_priv(dev);
        int csr0;
 
index 9202a1c369ddc28dd184ae6fff94bdd475b25360..7874eb1ef04381edade7b85f7eb014705c54d2ed 100644 (file)
@@ -466,9 +466,9 @@ static void qe_tx_reclaim(struct sunqe *qep);
  * so we just run through each qe and check to see who is signaling
  * and thus needs to be serviced.
  */
-static irqreturn_t qec_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t qec_interrupt(int irq, void *dev_id)
 {
-       struct sunqec *qecp = (struct sunqec *) dev_id;
+       struct sunqec *qecp = dev_id;
        u32 qec_status;
        int channel = 0;
 
index 60f0265094876ec846dc74846a9889f17f487829..81ed82f0b52073da356b58be80c5b09fd75ab9aa 100644 (file)
@@ -453,7 +453,7 @@ static int __devinit tc35815_probe1(struct pci_dev *pdev, unsigned int base_addr
 static int     tc35815_open(struct net_device *dev);
 static int     tc35815_send_packet(struct sk_buff *skb, struct net_device *dev);
 static void     tc35815_tx_timeout(struct net_device *dev);
-static irqreturn_t tc35815_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t tc35815_interrupt(int irq, void *dev_id);
 static void    tc35815_rx(struct net_device *dev);
 static void    tc35815_txdone(struct net_device *dev);
 static int     tc35815_close(struct net_device *dev);
@@ -1044,7 +1044,7 @@ static void tc35815_fatal_error_interrupt(struct net_device *dev, int status)
  * The typical workload of the driver:
  *   Handle the network interface interrupts.
  */
-static irqreturn_t tc35815_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+static irqreturn_t tc35815_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
        struct tc35815_regs *tr;
index c25ba273b74596b9727d00d695b1083229efdf36..8e398499c0456ab2ea07b2d63acf702aaa2498dd 100644 (file)
@@ -68,8 +68,8 @@
 
 #define DRV_MODULE_NAME                "tg3"
 #define PFX DRV_MODULE_NAME    ": "
-#define DRV_MODULE_VERSION     "3.66"
-#define DRV_MODULE_RELDATE     "September 23, 2006"
+#define DRV_MODULE_VERSION     "3.67"
+#define DRV_MODULE_RELDATE     "October 18, 2006"
 
 #define TG3_DEF_MAC_MODE       0
 #define TG3_DEF_RX_MODE                0
 #define RX_JUMBO_PKT_BUF_SZ    (9046 + tp->rx_offset + 64)
 
 /* minimum number of free TX descriptors required to wake up TX process */
-#define TG3_TX_WAKEUP_THRESH           (TG3_TX_RING_SIZE / 4)
+#define TG3_TX_WAKEUP_THRESH(tp)               ((tp)->tx_pending / 4)
 
 /* number of ETHTOOL_GSTATS u64's */
 #define TG3_NUM_STATS          (sizeof(struct tg3_ethtool_stats)/sizeof(u64))
@@ -3075,10 +3075,10 @@ static void tg3_tx(struct tg3 *tp)
        smp_mb();
 
        if (unlikely(netif_queue_stopped(tp->dev) &&
-                    (tg3_tx_avail(tp) > TG3_TX_WAKEUP_THRESH))) {
+                    (tg3_tx_avail(tp) > TG3_TX_WAKEUP_THRESH(tp)))) {
                netif_tx_lock(tp->dev);
                if (netif_queue_stopped(tp->dev) &&
-                   (tg3_tx_avail(tp) > TG3_TX_WAKEUP_THRESH))
+                   (tg3_tx_avail(tp) > TG3_TX_WAKEUP_THRESH(tp)))
                        netif_wake_queue(tp->dev);
                netif_tx_unlock(tp->dev);
        }
@@ -3481,7 +3481,7 @@ static inline void tg3_full_unlock(struct tg3 *tp)
 /* One-shot MSI handler - Chip automatically disables interrupt
  * after sending MSI so driver doesn't have to do it.
  */
-static irqreturn_t tg3_msi_1shot(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t tg3_msi_1shot(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
        struct tg3 *tp = netdev_priv(dev);
@@ -3499,7 +3499,7 @@ static irqreturn_t tg3_msi_1shot(int irq, void *dev_id, struct pt_regs *regs)
  * flush status block and interrupt mailbox. PCI ordering rules
  * guarantee that MSI will arrive after the status block.
  */
-static irqreturn_t tg3_msi(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t tg3_msi(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
        struct tg3 *tp = netdev_priv(dev);
@@ -3520,7 +3520,7 @@ static irqreturn_t tg3_msi(int irq, void *dev_id, struct pt_regs *regs)
        return IRQ_RETVAL(1);
 }
 
-static irqreturn_t tg3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t tg3_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
        struct tg3 *tp = netdev_priv(dev);
@@ -3563,7 +3563,7 @@ out:
        return IRQ_RETVAL(handled);
 }
 
-static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
        struct tg3 *tp = netdev_priv(dev);
@@ -3606,8 +3606,7 @@ out:
 }
 
 /* ISR for interrupt test */
-static irqreturn_t tg3_test_isr(int irq, void *dev_id,
-               struct pt_regs *regs)
+static irqreturn_t tg3_test_isr(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
        struct tg3 *tp = netdev_priv(dev);
@@ -3651,7 +3650,7 @@ static void tg3_poll_controller(struct net_device *dev)
 {
        struct tg3 *tp = netdev_priv(dev);
 
-       tg3_interrupt(tp->pdev->irq, dev, NULL);
+       tg3_interrupt(tp->pdev->irq, dev);
 }
 #endif
 
@@ -3929,7 +3928,7 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
        tp->tx_prod = entry;
        if (unlikely(tg3_tx_avail(tp) <= (MAX_SKB_FRAGS + 1))) {
                netif_stop_queue(dev);
-               if (tg3_tx_avail(tp) > TG3_TX_WAKEUP_THRESH)
+               if (tg3_tx_avail(tp) > TG3_TX_WAKEUP_THRESH(tp))
                        netif_wake_queue(tp->dev);
        }
 
@@ -4144,7 +4143,7 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev)
        tp->tx_prod = entry;
        if (unlikely(tg3_tx_avail(tp) <= (MAX_SKB_FRAGS + 1))) {
                netif_stop_queue(dev);
-               if (tg3_tx_avail(tp) > TG3_TX_WAKEUP_THRESH)
+               if (tg3_tx_avail(tp) > TG3_TX_WAKEUP_THRESH(tp))
                        netif_wake_queue(tp->dev);
        }
 
@@ -6838,7 +6837,7 @@ restart_timer:
 
 static int tg3_request_irq(struct tg3 *tp)
 {
-       irqreturn_t (*fn)(int, void *, struct pt_regs *);
+       irq_handler_t fn;
        unsigned long flags;
        struct net_device *dev = tp->dev;
 
@@ -8107,7 +8106,10 @@ static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *e
 
        if ((ering->rx_pending > TG3_RX_RING_SIZE - 1) ||
            (ering->rx_jumbo_pending > TG3_RX_JUMBO_RING_SIZE - 1) ||
-           (ering->tx_pending > TG3_TX_RING_SIZE - 1))
+           (ering->tx_pending > TG3_TX_RING_SIZE - 1) ||
+           (ering->tx_pending <= MAX_SKB_FRAGS) ||
+           ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_1_BUG) &&
+            (ering->tx_pending <= (MAX_SKB_FRAGS * 3))))
                return -EINVAL;
 
        if (netif_running(dev)) {
index 8d807bf603a036963a7ffcfd9ac8d2cf1b0bbe3c..e14f5a00f65af221fd8a55d86412b8767ca3bac5 100644 (file)
@@ -289,7 +289,7 @@ static void TLan_Eisa_Cleanup( void );
 static int      TLan_Init( struct net_device * );
 static int     TLan_Open( struct net_device *dev );
 static int     TLan_StartTx( struct sk_buff *, struct net_device *);
-static irqreturn_t TLan_HandleInterrupt( int, void *, struct pt_regs *);
+static irqreturn_t TLan_HandleInterrupt( int, void *);
 static int     TLan_Close( struct net_device *);
 static struct  net_device_stats *TLan_GetStats( struct net_device *);
 static void    TLan_SetMulticastList( struct net_device *);
@@ -824,7 +824,7 @@ static void  __init TLan_EisaProbe (void)
 static void TLan_Poll(struct net_device *dev)
 {
        disable_irq(dev->irq);
-       TLan_HandleInterrupt(dev->irq, dev, NULL);
+       TLan_HandleInterrupt(dev->irq, dev);
        enable_irq(dev->irq);
 }
 #endif
@@ -1151,7 +1151,6 @@ static int TLan_StartTx( struct sk_buff *skb, struct net_device *dev )
         *                      occurred.
         *              dev_id  A pointer to the device assigned to
         *                      this irq line.
-        *              regs    ???
         *
         *      This function handles an interrupt generated by its
         *      assigned TLAN adapter.  The function deactivates
@@ -1162,7 +1161,7 @@ static int TLan_StartTx( struct sk_buff *skb, struct net_device *dev )
         *
         **************************************************************/
 
-static irqreturn_t TLan_HandleInterrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t TLan_HandleInterrupt(int irq, void *dev_id)
 {
        u32             ack;
        struct net_device       *dev;
index 412390ba142ecff7b14ba41f773403bda4ba6575..7580bdeacadcedca4d168293add3e9388ad8470a 100644 (file)
@@ -130,7 +130,7 @@ static int 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, struct pt_regs *regs);
+static irqreturn_t xl_interrupt(int irq, void *dev_id);
 static struct net_device_stats * xl_get_stats(struct net_device *dev);
 static int xl_set_mac_address(struct net_device *dev, void *addr) ; 
 static void xl_arb_cmd(struct net_device *dev);
@@ -1042,7 +1042,7 @@ static void xl_freemem(struct net_device *dev)
        return  ; 
 }
 
-static irqreturn_t xl_interrupt(int irq, void *dev_id, struct pt_regs *regs
+static irqreturn_t xl_interrupt(int irq, void *dev_id) 
 {
        struct net_device *dev = (struct net_device *)dev_id;
        struct xl_private *xl_priv =(struct xl_private *)dev->priv;
index 4470025ff7f85bc86e580aee983b653a3181c2ce..bfe59865b1dd50e5c4dbd4cefe506a31e1495a1a 100644 (file)
@@ -197,7 +197,7 @@ static void         open_sap(unsigned char type, struct net_device *dev);
 static void    tok_set_multicast_list(struct net_device *dev);
 static int     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, struct pt_regs *regs);
+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);
@@ -1166,7 +1166,7 @@ static void dir_open_adapter (struct net_device *dev)
 
 /******************************************************************************/
 
-static irqreturn_t tok_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t tok_interrupt(int irq, void *dev_id)
 {
        unsigned char status;
        /*  unsigned char status_even ; */
@@ -1178,7 +1178,7 @@ static irqreturn_t tok_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 
        dev = dev_id;
 #if TR_VERBOSE
-       DPRINTK("Int from tok_driver, dev : %p irq%d regs=%p\n", dev,irq,regs);
+       DPRINTK("Int from tok_driver, dev : %p irq%d\n", dev,irq);
 #endif
        ti = (struct tok_info *) dev->priv;
        if (ti->sram_phys & 1)
index bfc8c3eae9a1de7123c2dba1f05932e405215c16..e999feb8c0bbe15777955415691a838d6e0978c8 100644 (file)
@@ -206,8 +206,7 @@ static int streamer_open(struct net_device *dev);
 static int 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,
-                              struct pt_regs *regs);
+static irqreturn_t streamer_interrupt(int irq, void *dev_id);
 static struct net_device_stats *streamer_get_stats(struct net_device *dev);
 static int streamer_set_mac_address(struct net_device *dev, void *addr);
 static void streamer_arb_cmd(struct net_device *dev);
@@ -1028,7 +1027,7 @@ static void streamer_rx(struct net_device *dev)
        }                       /* end for all completed rx descriptors */
 }
 
-static irqreturn_t streamer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t streamer_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = (struct net_device *) dev_id;
        struct streamer_private *streamer_priv =
index 666bbaaae82f5fe780f3d3d8571b26c9eaec6aa5..ed274d6909d0b41bb957e6edf2ff678853427177 100644 (file)
@@ -70,7 +70,7 @@ 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, struct pt_regs *regs);
+static irqreturn_t madgemc_interrupt(int irq, void *dev_id);
 
 /*
  * These work around paging, however they don't guarentee you're on the
@@ -417,7 +417,7 @@ getout:
  * exhausted all contiguous interrupts.
  *
  */
-static irqreturn_t madgemc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t madgemc_interrupt(int irq, void *dev_id)
 {
        int pending,reg1;
        struct net_device *dev;
@@ -451,7 +451,7 @@ static irqreturn_t madgemc_interrupt(int irq, void *dev_id, struct pt_regs *regs
                        outb(reg1, dev->base_addr + MC_CONTROL_REG1);
 
                        /* Continue handling as normal */
-                       tms380tr_interrupt(irq, dev_id, regs);
+                       tms380tr_interrupt(irq, dev_id);
 
                        pending = SIFREADW(SIFSTS); /* restart - the SIF way */
 
index 85831484bc40ce9914572d7d3525a103e2bb137b..cd142d0302bc6e98e2da22967774fca203c1e5d9 100644 (file)
@@ -185,7 +185,7 @@ static int 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, struct pt_regs *regs);
+static irqreturn_t olympic_interrupt(int irq, void *dev_id);
 static struct net_device_stats * olympic_get_stats(struct net_device *dev);
 static int olympic_set_mac_address(struct net_device *dev, void *addr) ; 
 static void olympic_arb_cmd(struct net_device *dev);
@@ -925,7 +925,7 @@ static void olympic_freemem(struct net_device *dev)
        return ; 
 }
  
-static irqreturn_t olympic_interrupt(int irq, void *dev_id, struct pt_regs *regs
+static irqreturn_t olympic_interrupt(int irq, void *dev_id) 
 {
        struct net_device *dev= (struct net_device *)dev_id;
        struct olympic_private *olympic_priv=(struct olympic_private *)dev->priv;
index 85a7f797d343de01d19d713e59516f9550c3bff6..46dabdb120716cf2bc2a0422b58e168b555edb99 100644 (file)
@@ -141,7 +141,7 @@ 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, struct pt_regs *regs);
+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,
@@ -1980,7 +1980,7 @@ static int smctr_internal_self_test(struct net_device *dev)
 /*
  * The typical workload of the driver: Handle the network interface interrupts.
  */
-static irqreturn_t smctr_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t smctr_interrupt(int irq, void *dev_id)
 {
         struct net_device *dev = dev_id;
         struct net_local *tp;
@@ -1990,15 +1990,8 @@ static irqreturn_t smctr_interrupt(int irq, void *dev_id, struct pt_regs *regs)
         __u8 isb_type, isb_subtype;
         __u16 isb_index;
 
-        if(dev == NULL)
-        {
-                printk(KERN_CRIT "%s: irq %d for unknown device.\n", dev->name, irq);
-                return IRQ_NONE;
-        }
-
         ioaddr = dev->base_addr;
         tp = netdev_priv(dev);
-        
 
         if(tp->status == NOT_INITIALIZED)
                 return IRQ_NONE;
index c1925590a0e110e431a0434901349f47d27f1384..ea797ca2b9880096f36cb864518de4dc6ad64514 100644 (file)
@@ -744,18 +744,13 @@ static void tms380tr_timer_chk(unsigned long data)
 /*
  * The typical workload of the driver: Handle the network interface interrupts.
  */
-irqreturn_t tms380tr_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+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;
 
-       if(dev == NULL) {
-               printk(KERN_INFO "%s: irq %d for unknown device.\n", dev->name, irq);
-               return IRQ_NONE;
-       }
-
        tp = netdev_priv(dev);
 
        irq_type = SIFREADW(SIFSTS);
index 30452c67bb68517cfba3236458c35d5c1557cfb4..2a16078ac3fdc6ecde5d685cf9e6ea33e396e516 100644 (file)
@@ -16,7 +16,7 @@
 /* module prototypes */
 int tms380tr_open(struct net_device *dev);
 int tms380tr_close(struct net_device *dev);
-irqreturn_t tms380tr_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+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);
index e1b48bd86646b809400d946171b52b7bee2005d4..f6b3a94e97bfe52727fa39c55772a8eac7d73bfc 100644 (file)
@@ -484,7 +484,7 @@ rx_next:
        de->rx_tail = rx_tail;
 }
 
-static irqreturn_t de_interrupt (int irq, void *dev_instance, struct pt_regs *regs)
+static irqreturn_t de_interrupt (int irq, void *dev_instance)
 {
        struct net_device *dev = dev_instance;
        struct de_private *de = dev->priv;
@@ -1730,7 +1730,7 @@ static void __init de21040_get_media_info(struct de_private *de)
 }
 
 /* Note: this routine returns extra data bits for size detection. */
-static unsigned __init tulip_read_eeprom(void __iomem *regs, int location, int addr_len)
+static unsigned __devinit tulip_read_eeprom(void __iomem *regs, int location, int addr_len)
 {
        int i;
        unsigned retval = 0;
@@ -1926,7 +1926,7 @@ bad_srom:
        goto fill_defaults;
 }
 
-static int __init de_init_one (struct pci_dev *pdev,
+static int __devinit de_init_one (struct pci_dev *pdev,
                                  const struct pci_device_id *ent)
 {
        struct net_device *dev;
@@ -2082,7 +2082,7 @@ err_out_free:
        return rc;
 }
 
-static void __exit de_remove_one (struct pci_dev *pdev)
+static void __devexit de_remove_one (struct pci_dev *pdev)
 {
        struct net_device *dev = pci_get_drvdata(pdev);
        struct de_private *de = dev->priv;
@@ -2164,7 +2164,7 @@ static struct pci_driver de_driver = {
        .name           = DRV_NAME,
        .id_table       = de_pci_tbl,
        .probe          = de_init_one,
-       .remove         = __exit_p(de_remove_one),
+       .remove         = __devexit_p(de_remove_one),
 #ifdef CONFIG_PM
        .suspend        = de_suspend,
        .resume         = de_resume,
index fb5fa7d688886afa5b4f9c2fd0f330533db29934..3f4b6408b755ef6a3d2379329c0bffd4e2dbd36b 100644 (file)
@@ -896,7 +896,7 @@ static struct {
 */
 static int     de4x5_open(struct net_device *dev);
 static int     de4x5_queue_pkt(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t de4x5_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t de4x5_interrupt(int irq, void *dev_id);
 static int     de4x5_close(struct net_device *dev);
 static struct  net_device_stats *de4x5_get_stats(struct net_device *dev);
 static void    de4x5_local_stats(struct net_device *dev, char *buf, int pkt_len);
@@ -1538,18 +1538,14 @@ de4x5_queue_pkt(struct sk_buff *skb, struct net_device *dev)
 ** interrupt is asserted and this routine entered.
 */
 static irqreturn_t
-de4x5_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+de4x5_interrupt(int irq, void *dev_id)
 {
-    struct net_device *dev = (struct net_device *)dev_id;
+    struct net_device *dev = dev_id;
     struct de4x5_private *lp;
     s32 imr, omr, sts, limit;
     u_long iobase;
     unsigned int handled = 0;
 
-    if (dev == NULL) {
-       printk ("de4x5_interrupt(): irq %d for unknown device.\n", irq);
-       return IRQ_NONE;
-    }
     lp = netdev_priv(dev);
     spin_lock(&lp->lock);
     iobase = dev->base_addr;
index ccf2c225f084a2cda63517d86827ec3ca2319d7a..4dd8a0bae8605df4e70a60f4ff85a809b530d1cf 100644 (file)
@@ -300,7 +300,7 @@ static struct net_device_stats * dmfe_get_stats(struct DEVICE *);
 static void dmfe_set_filter_mode(struct DEVICE *);
 static const struct ethtool_ops netdev_ethtool_ops;
 static u16 read_srom_word(long ,int);
-static irqreturn_t dmfe_interrupt(int , void *, struct pt_regs *);
+static irqreturn_t dmfe_interrupt(int , void *);
 #ifdef CONFIG_NET_POLL_CONTROLLER
 static void poll_dmfe (struct net_device *dev);
 #endif
@@ -735,7 +735,7 @@ static int dmfe_stop(struct DEVICE *dev)
  *     receive the packet to upper layer, free the transmitted packet
  */
 
-static irqreturn_t dmfe_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t dmfe_interrupt(int irq, void *dev_id)
 {
        struct DEVICE *dev = dev_id;
        struct dmfe_board_info *db = netdev_priv(dev);
@@ -806,7 +806,7 @@ static void poll_dmfe (struct net_device *dev)
        /* disable_irq here is not very nice, but with the lockless
           interrupt handler we have no other choice. */
        disable_irq(dev->irq);
-       dmfe_interrupt (dev->irq, dev, NULL);
+       dmfe_interrupt (dev->irq, dev);
        enable_irq(dev->irq);
 }
 #endif
index 7f8f5d42a7611a6bca1fb39b9ca1b84cb6b29bda..e3488d7b8ede3a57b89453ed74127d3bb52cd203 100644 (file)
@@ -496,7 +496,7 @@ static inline unsigned int phy_interrupt (struct net_device *dev)
 
 /* The interrupt handler does all of the Rx thread work and cleans up
    after the Tx thread. */
-irqreturn_t tulip_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
+irqreturn_t tulip_interrupt(int irq, void *dev_instance)
 {
        struct net_device *dev = (struct net_device *)dev_instance;
        struct tulip_private *tp = netdev_priv(dev);
index 25668ddb1f7ec30bb0d287695b6536e9475343dd..ad107f45c7b1d3f6a5442a259cfda2b6fc49d976 100644 (file)
@@ -424,7 +424,7 @@ int tulip_read_eeprom(struct net_device *dev, int location, int addr_len);
 /* interrupt.c */
 extern unsigned int tulip_max_interrupt_work;
 extern int tulip_rx_copybreak;
-irqreturn_t tulip_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
+irqreturn_t tulip_interrupt(int irq, void *dev_instance);
 int tulip_refill_rx(struct net_device *dev);
 #ifdef CONFIG_TULIP_NAPI
 int tulip_poll(struct net_device *dev, int *budget);
index 831919a81918f6b614b5276e46afbdbc4e8328f5..0aee618f883c34a3550a51b1c231ab75c08162e6 100644 (file)
@@ -1823,7 +1823,7 @@ static void poll_tulip (struct net_device *dev)
        /* disable_irq here is not very nice, but with the lockless
           interrupt handler we have no other choice. */
        disable_irq(dev->irq);
-       tulip_interrupt (dev->irq, dev, NULL);
+       tulip_interrupt (dev->irq, dev);
        enable_irq(dev->irq);
 }
 #endif
index 0b176be51eb30b1d8cf1c9d41a682926be1be206..229158e8e4be4fc43e03ed8f652baaf8d54b8761 100644 (file)
@@ -224,7 +224,7 @@ static struct net_device_stats * uli526x_get_stats(struct net_device *);
 static void uli526x_set_filter_mode(struct net_device *);
 static const struct ethtool_ops netdev_ethtool_ops;
 static u16 read_srom_word(long, int);
-static irqreturn_t uli526x_interrupt(int, void *, struct pt_regs *);
+static irqreturn_t uli526x_interrupt(int, void *);
 static void uli526x_descriptor_init(struct uli526x_board_info *, unsigned long);
 static void allocate_rx_buffer(struct uli526x_board_info *);
 static void update_cr6(u32, unsigned long);
@@ -659,7 +659,7 @@ static int uli526x_stop(struct net_device *dev)
  *     receive the packet to upper layer, free the transmitted packet
  */
 
-static irqreturn_t uli526x_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t uli526x_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
        struct uli526x_board_info *db = netdev_priv(dev);
index 2fca1ee24f5a65b3f823aeae7c51b091ed54ed82..002a05e0722f16bfb37941d15220349f458a9c96 100644 (file)
@@ -332,7 +332,7 @@ static void tx_timeout(struct net_device *dev);
 static int alloc_ringdesc(struct net_device *dev);
 static void free_ringdesc(struct netdev_private *np);
 static int  start_tx(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t intr_handler(int irq, void *dev_instance, struct pt_regs *regs);
+static irqreturn_t intr_handler(int irq, void *dev_instance);
 static void netdev_error(struct net_device *dev, int intr_status);
 static int  netdev_rx(struct net_device *dev);
 static u32 __set_rx_mode(struct net_device *dev);
@@ -1110,7 +1110,7 @@ static void netdev_tx_done(struct net_device *dev)
 
 /* The interrupt handler does all of the Rx thread work and cleans up
    after the Tx thread. */
-static irqreturn_t intr_handler(int irq, void *dev_instance, struct pt_regs *rgs)
+static irqreturn_t intr_handler(int irq, void *dev_instance)
 {
        struct net_device *dev = (struct net_device *)dev_instance;
        struct netdev_private *np = netdev_priv(dev);
index 629eac64528911aef4f85ed42f58688a57729228..61d313049dd04a84d93849a06932b51a794e0564 100644 (file)
@@ -114,7 +114,7 @@ struct xircom_private {
 /* Function prototypes */
 static int xircom_probe(struct pci_dev *pdev, const struct pci_device_id *id);
 static void xircom_remove(struct pci_dev *pdev);
-static irqreturn_t xircom_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
+static irqreturn_t xircom_interrupt(int irq, void *dev_instance);
 static int xircom_start_xmit(struct sk_buff *skb, struct net_device *dev);
 static int xircom_open(struct net_device *dev);
 static int xircom_close(struct net_device *dev);
@@ -334,7 +334,7 @@ static void __devexit xircom_remove(struct pci_dev *pdev)
        leave("xircom_remove");
 }
 
-static irqreturn_t xircom_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
+static irqreturn_t xircom_interrupt(int irq, void *dev_instance)
 {
        struct net_device *dev = (struct net_device *) dev_instance;
        struct xircom_private *card = netdev_priv(dev);
@@ -513,7 +513,7 @@ static struct net_device_stats *xircom_get_stats(struct net_device *dev)
 static void xircom_poll_controller(struct net_device *dev)
 {
        disable_irq(dev->irq);
-       xircom_interrupt(dev->irq, dev, NULL);
+       xircom_interrupt(dev->irq, dev);
        enable_irq(dev->irq);
 }
 #endif
index 312788caa4c6fa792bfaa5174f626624dd5e25dc..a998c5d0ae9c13f3228e0d00f96af2780b936f5c 100644 (file)
@@ -328,7 +328,7 @@ static void xircom_init_ring(struct net_device *dev);
 static int xircom_start_xmit(struct sk_buff *skb, struct net_device *dev);
 static int xircom_rx(struct net_device *dev);
 static void xircom_media_change(struct net_device *dev);
-static irqreturn_t xircom_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
+static irqreturn_t xircom_interrupt(int irq, void *dev_instance);
 static int xircom_close(struct net_device *dev);
 static struct net_device_stats *xircom_get_stats(struct net_device *dev);
 static int xircom_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
@@ -1044,7 +1044,7 @@ static void check_duplex(struct net_device *dev)
 
 /* The interrupt handler does all of the Rx thread work and cleans up
    after the Tx thread. */
-static irqreturn_t xircom_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
+static irqreturn_t xircom_interrupt(int irq, void *dev_instance)
 {
        struct net_device *dev = dev_instance;
        struct xircom_private *tp = netdev_priv(dev);
index d5c32e9caa978fe1c6e8f1e4a6359bd66245b1a8..3bf9e630404f85283a08cca2e0e42cfcabf190f3 100644 (file)
@@ -1826,7 +1826,7 @@ typhoon_poll(struct net_device *dev, int *total_budget)
 }
 
 static irqreturn_t
-typhoon_interrupt(int irq, void *dev_instance, struct pt_regs *rgs)
+typhoon_interrupt(int irq, void *dev_instance)
 {
        struct net_device *dev = (struct net_device *) dev_instance;
        struct typhoon *tp = dev->priv;
index 700ebd7d145751cefd9b08c2592b3cd5b6f84f4d..b37888011067f2711b8b954213a7e86243ac788c 100644 (file)
@@ -2,14 +2,11 @@
  * Copyright (C) Freescale Semicondutor, Inc. 2006. All rights reserved.
  *
  * Author: Shlomi Gridish <gridish@freescale.com>
+ *        Li Yang <leoli@freescale.com>
  *
  * Description:
  * QE UCC Gigabit Ethernet Driver
  *
- * Changelog:
- * Jul 6, 2006 Li Yang <LeoLi@freescale.com>
- * - Rearrange code and style fixes
- *
  * 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
@@ -31,9 +28,9 @@
 #include <linux/dma-mapping.h>
 #include <linux/fsl_devices.h>
 #include <linux/ethtool.h>
-#include <linux/platform_device.h>
 #include <linux/mii.h>
 
+#include <asm/of_device.h>
 #include <asm/uaccess.h>
 #include <asm/irq.h>
 #include <asm/io.h>
@@ -70,7 +67,7 @@
 
 static DEFINE_SPINLOCK(ugeth_lock);
 
-static ucc_geth_info_t ugeth_primary_info = {
+static struct ucc_geth_info ugeth_primary_info = {
        .uf_info = {
                    .bd_mem_part = MEM_PART_SYSTEM,
                    .rtsm = UCC_FAST_SEND_IDLES_BETWEEN_FRAMES,
@@ -163,7 +160,7 @@ static ucc_geth_info_t ugeth_primary_info = {
        .riscRx = QE_RISC_ALLOCATION_RISC1_AND_RISC2,
 };
 
-static ucc_geth_info_t ugeth_info[8];
+static struct ucc_geth_info ugeth_info[8];
 
 #ifdef DEBUG
 static void mem_disp(u8 *addr, int size)
@@ -219,8 +216,8 @@ static struct list_head *dequeue(struct list_head *lh)
        }
 }
 
-static int get_interface_details(enet_interface_e enet_interface,
-                                enet_speed_e *speed,
+static int get_interface_details(enum enet_interface enet_interface,
+                                enum enet_speed *speed,
                                 int *r10m,
                                 int *rmm,
                                 int *rpm,
@@ -283,7 +280,7 @@ static int get_interface_details(enet_interface_e enet_interface,
        return 0;
 }
 
-static struct sk_buff *get_new_skb(ucc_geth_private_t *ugeth, u8 *bd)
+static struct sk_buff *get_new_skb(struct ucc_geth_private *ugeth, u8 *bd)
 {
        struct sk_buff *skb = NULL;
 
@@ -303,21 +300,19 @@ static struct sk_buff *get_new_skb(ucc_geth_private_t *ugeth, u8 *bd)
 
        skb->dev = ugeth->dev;
 
-       BD_BUFFER_SET(bd,
+       out_be32(&((struct qe_bd *)bd)->buf,
                      dma_map_single(NULL,
                                     skb->data,
                                     ugeth->ug_info->uf_info.max_rx_buf_length +
                                     UCC_GETH_RX_DATA_BUF_ALIGNMENT,
                                     DMA_FROM_DEVICE));
 
-       BD_STATUS_AND_LENGTH_SET(bd,
-                                (R_E | R_I |
-                                 (BD_STATUS_AND_LENGTH(bd) & R_W)));
+       out_be32((u32 *)bd, (R_E | R_I | (in_be32((u32 *)bd) & R_W)));
 
        return skb;
 }
 
-static int rx_bd_buffer_set(ucc_geth_private_t *ugeth, u8 rxQ)
+static int rx_bd_buffer_set(struct ucc_geth_private *ugeth, u8 rxQ)
 {
        u8 *bd;
        u32 bd_status;
@@ -328,7 +323,7 @@ static int rx_bd_buffer_set(ucc_geth_private_t *ugeth, u8 rxQ)
        i = 0;
 
        do {
-               bd_status = BD_STATUS_AND_LENGTH(bd);
+               bd_status = in_be32((u32*)bd);
                skb = get_new_skb(ugeth, bd);
 
                if (!skb)       /* If can not allocate data buffer,
@@ -338,19 +333,19 @@ static int rx_bd_buffer_set(ucc_geth_private_t *ugeth, u8 rxQ)
                ugeth->rx_skbuff[rxQ][i] = skb;
 
                /* advance the BD pointer */
-               bd += UCC_GETH_SIZE_OF_BD;
+               bd += sizeof(struct qe_bd);
                i++;
        } while (!(bd_status & R_W));
 
        return 0;
 }
 
-static int fill_init_enet_entries(ucc_geth_private_t *ugeth,
+static int fill_init_enet_entries(struct ucc_geth_private *ugeth,
                                  volatile u32 *p_start,
                                  u8 num_entries,
                                  u32 thread_size,
                                  u32 thread_alignment,
-                                 qe_risc_allocation_e risc,
+                                 enum qe_risc_allocation risc,
                                  int skip_page_for_first_entry)
 {
        u32 init_enet_offset;
@@ -383,10 +378,10 @@ static int fill_init_enet_entries(ucc_geth_private_t *ugeth,
        return 0;
 }
 
-static int return_init_enet_entries(ucc_geth_private_t *ugeth,
+static int return_init_enet_entries(struct ucc_geth_private *ugeth,
                                    volatile u32 *p_start,
                                    u8 num_entries,
-                                   qe_risc_allocation_e risc,
+                                   enum qe_risc_allocation risc,
                                    int skip_page_for_first_entry)
 {
        u32 init_enet_offset;
@@ -416,11 +411,11 @@ static int return_init_enet_entries(ucc_geth_private_t *ugeth,
 }
 
 #ifdef DEBUG
-static int dump_init_enet_entries(ucc_geth_private_t *ugeth,
+static int dump_init_enet_entries(struct ucc_geth_private *ugeth,
                                  volatile u32 *p_start,
                                  u8 num_entries,
                                  u32 thread_size,
-                                 qe_risc_allocation_e risc,
+                                 enum qe_risc_allocation risc,
                                  int skip_page_for_first_entry)
 {
        u32 init_enet_offset;
@@ -456,14 +451,14 @@ static int dump_init_enet_entries(ucc_geth_private_t *ugeth,
 #endif
 
 #ifdef CONFIG_UGETH_FILTERING
-static enet_addr_container_t *get_enet_addr_container(void)
+static struct enet_addr_container *get_enet_addr_container(void)
 {
-       enet_addr_container_t *enet_addr_cont;
+       struct enet_addr_container *enet_addr_cont;
 
        /* allocate memory */
-       enet_addr_cont = kmalloc(sizeof(enet_addr_container_t), GFP_KERNEL);
+       enet_addr_cont = kmalloc(sizeof(struct enet_addr_container), GFP_KERNEL);
        if (!enet_addr_cont) {
-               ugeth_err("%s: No memory for enet_addr_container_t object.",
+               ugeth_err("%s: No memory for enet_addr_container object.",
                          __FUNCTION__);
                return NULL;
        }
@@ -472,45 +467,43 @@ static enet_addr_container_t *get_enet_addr_container(void)
 }
 #endif /* CONFIG_UGETH_FILTERING */
 
-static void put_enet_addr_container(enet_addr_container_t *enet_addr_cont)
+static void put_enet_addr_container(struct enet_addr_container *enet_addr_cont)
 {
        kfree(enet_addr_cont);
 }
 
+static int set_mac_addr(__be16 __iomem *reg, u8 *mac)
+{
+       out_be16(&reg[0], ((u16)mac[5] << 8) | mac[4]);
+       out_be16(&reg[1], ((u16)mac[3] << 8) | mac[2]);
+       out_be16(&reg[2], ((u16)mac[1] << 8) | mac[0]);
+}
+
 #ifdef CONFIG_UGETH_FILTERING
-static int hw_add_addr_in_paddr(ucc_geth_private_t *ugeth,
-                               enet_addr_t *p_enet_addr, u8 paddr_num)
+static int hw_add_addr_in_paddr(struct ucc_geth_private *ugeth,
+                                u8 *p_enet_addr, u8 paddr_num)
 {
-       ucc_geth_82xx_address_filtering_pram_t *p_82xx_addr_filt;
+       struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt;
 
        if (!(paddr_num < NUM_OF_PADDRS)) {
-               ugeth_warn("%s: Illagel paddr_num.", __FUNCTION__);
+               ugeth_warn("%s: Illegal paddr_num.", __FUNCTION__);
                return -EINVAL;
        }
 
        p_82xx_addr_filt =
-           (ucc_geth_82xx_address_filtering_pram_t *) ugeth->p_rx_glbl_pram->
+           (struct ucc_geth_82xx_address_filtering_pram *) ugeth->p_rx_glbl_pram->
            addressfiltering;
 
        /* Ethernet frames are defined in Little Endian mode,    */
        /* therefore to insert the address we reverse the bytes. */
-       out_be16(&p_82xx_addr_filt->paddr[paddr_num].h,
-                (u16) (((u16) (((u16) ((*p_enet_addr)[5])) << 8)) |
-                       (u16) (*p_enet_addr)[4]));
-       out_be16(&p_82xx_addr_filt->paddr[paddr_num].m,
-                (u16) (((u16) (((u16) ((*p_enet_addr)[3])) << 8)) |
-                       (u16) (*p_enet_addr)[2]));
-       out_be16(&p_82xx_addr_filt->paddr[paddr_num].l,
-                (u16) (((u16) (((u16) ((*p_enet_addr)[1])) << 8)) |
-                       (u16) (*p_enet_addr)[0]));
-
+       set_mac_addr(&p_82xx_addr_filt->paddr[paddr_num].h, p_enet_addr);
        return 0;
 }
 #endif /* CONFIG_UGETH_FILTERING */
 
-static int hw_clear_addr_in_paddr(ucc_geth_private_t *ugeth, u8 paddr_num)
+static int hw_clear_addr_in_paddr(struct ucc_geth_private *ugeth, u8 paddr_num)
 {
-       ucc_geth_82xx_address_filtering_pram_t *p_82xx_addr_filt;
+       struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt;
 
        if (!(paddr_num < NUM_OF_PADDRS)) {
                ugeth_warn("%s: Illagel paddr_num.", __FUNCTION__);
@@ -518,7 +511,7 @@ static int hw_clear_addr_in_paddr(ucc_geth_private_t *ugeth, u8 paddr_num)
        }
 
        p_82xx_addr_filt =
-           (ucc_geth_82xx_address_filtering_pram_t *) ugeth->p_rx_glbl_pram->
+           (struct ucc_geth_82xx_address_filtering_pram *) ugeth->p_rx_glbl_pram->
            addressfiltering;
 
        /* Writing address ff.ff.ff.ff.ff.ff disables address
@@ -530,14 +523,14 @@ static int hw_clear_addr_in_paddr(ucc_geth_private_t *ugeth, u8 paddr_num)
        return 0;
 }
 
-static void hw_add_addr_in_hash(ucc_geth_private_t *ugeth,
-                               enet_addr_t *p_enet_addr)
+static void hw_add_addr_in_hash(struct ucc_geth_private *ugeth,
+                                u8 *p_enet_addr)
 {
-       ucc_geth_82xx_address_filtering_pram_t *p_82xx_addr_filt;
+       struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt;
        u32 cecr_subblock;
 
        p_82xx_addr_filt =
-           (ucc_geth_82xx_address_filtering_pram_t *) ugeth->p_rx_glbl_pram->
+           (struct ucc_geth_82xx_address_filtering_pram *) ugeth->p_rx_glbl_pram->
            addressfiltering;
 
        cecr_subblock =
@@ -546,25 +539,18 @@ static void hw_add_addr_in_hash(ucc_geth_private_t *ugeth,
        /* Ethernet frames are defined in Little Endian mode,
        therefor to insert */
        /* the address to the hash (Big Endian mode), we reverse the bytes.*/
-       out_be16(&p_82xx_addr_filt->taddr.h,
-                (u16) (((u16) (((u16) ((*p_enet_addr)[5])) << 8)) |
-                       (u16) (*p_enet_addr)[4]));
-       out_be16(&p_82xx_addr_filt->taddr.m,
-                (u16) (((u16) (((u16) ((*p_enet_addr)[3])) << 8)) |
-                       (u16) (*p_enet_addr)[2]));
-       out_be16(&p_82xx_addr_filt->taddr.l,
-                (u16) (((u16) (((u16) ((*p_enet_addr)[1])) << 8)) |
-                       (u16) (*p_enet_addr)[0]));
+
+       set_mac_addr(&p_82xx_addr_filt->taddr.h, p_enet_addr);
 
        qe_issue_cmd(QE_SET_GROUP_ADDRESS, cecr_subblock,
-                    (u8) QE_CR_PROTOCOL_ETHERNET, 0);
+                    QE_CR_PROTOCOL_ETHERNET, 0);
 }
 
 #ifdef CONFIG_UGETH_MAGIC_PACKET
-static void magic_packet_detection_enable(ucc_geth_private_t *ugeth)
+static void magic_packet_detection_enable(struct ucc_geth_private *ugeth)
 {
-       ucc_fast_private_t *uccf;
-       ucc_geth_t *ug_regs;
+       struct ucc_fast_private *uccf;
+       struct ucc_geth *ug_regs;
        u32 maccfg2, uccm;
 
        uccf = ugeth->uccf;
@@ -581,10 +567,10 @@ static void magic_packet_detection_enable(ucc_geth_private_t *ugeth)
        out_be32(&ug_regs->maccfg2, maccfg2);
 }
 
-static void magic_packet_detection_disable(ucc_geth_private_t *ugeth)
+static void magic_packet_detection_disable(struct ucc_geth_private *ugeth)
 {
-       ucc_fast_private_t *uccf;
-       ucc_geth_t *ug_regs;
+       struct ucc_fast_private *uccf;
+       struct ucc_geth *ug_regs;
        u32 maccfg2, uccm;
 
        uccf = ugeth->uccf;
@@ -602,26 +588,26 @@ static void magic_packet_detection_disable(ucc_geth_private_t *ugeth)
 }
 #endif /* MAGIC_PACKET */
 
-static inline int compare_addr(enet_addr_t *addr1, enet_addr_t *addr2)
+static inline int compare_addr(u8 **addr1, u8 **addr2)
 {
        return memcmp(addr1, addr2, ENET_NUM_OCTETS_PER_ADDRESS);
 }
 
 #ifdef DEBUG
-static void get_statistics(ucc_geth_private_t *ugeth,
-                          ucc_geth_tx_firmware_statistics_t *
+static void get_statistics(struct ucc_geth_private *ugeth,
+                          struct ucc_geth_tx_firmware_statistics *
                           tx_firmware_statistics,
-                          ucc_geth_rx_firmware_statistics_t *
+                          struct ucc_geth_rx_firmware_statistics *
                           rx_firmware_statistics,
-                          ucc_geth_hardware_statistics_t *hardware_statistics)
+                          struct ucc_geth_hardware_statistics *hardware_statistics)
 {
-       ucc_fast_t *uf_regs;
-       ucc_geth_t *ug_regs;
-       ucc_geth_tx_firmware_statistics_pram_t *p_tx_fw_statistics_pram;
-       ucc_geth_rx_firmware_statistics_pram_t *p_rx_fw_statistics_pram;
+       struct ucc_fast *uf_regs;
+       struct ucc_geth *ug_regs;
+       struct ucc_geth_tx_firmware_statistics_pram *p_tx_fw_statistics_pram;
+       struct ucc_geth_rx_firmware_statistics_pram *p_rx_fw_statistics_pram;
 
        ug_regs = ugeth->ug_regs;
-       uf_regs = (ucc_fast_t *) ug_regs;
+       uf_regs = (struct ucc_fast *) ug_regs;
        p_tx_fw_statistics_pram = ugeth->p_tx_fw_statistics_pram;
        p_rx_fw_statistics_pram = ugeth->p_rx_fw_statistics_pram;
 
@@ -727,7 +713,7 @@ static void get_statistics(ucc_geth_private_t *ugeth,
        }
 }
 
-static void dump_bds(ucc_geth_private_t *ugeth)
+static void dump_bds(struct ucc_geth_private *ugeth)
 {
        int i;
        int length;
@@ -736,7 +722,7 @@ static void dump_bds(ucc_geth_private_t *ugeth)
                if (ugeth->p_tx_bd_ring[i]) {
                        length =
                            (ugeth->ug_info->bdRingLenTx[i] *
-                            UCC_GETH_SIZE_OF_BD);
+                            sizeof(struct qe_bd));
                        ugeth_info("TX BDs[%d]", i);
                        mem_disp(ugeth->p_tx_bd_ring[i], length);
                }
@@ -745,14 +731,14 @@ static void dump_bds(ucc_geth_private_t *ugeth)
                if (ugeth->p_rx_bd_ring[i]) {
                        length =
                            (ugeth->ug_info->bdRingLenRx[i] *
-                            UCC_GETH_SIZE_OF_BD);
+                            sizeof(struct qe_bd));
                        ugeth_info("RX BDs[%d]", i);
                        mem_disp(ugeth->p_rx_bd_ring[i], length);
                }
        }
 }
 
-static void dump_regs(ucc_geth_private_t *ugeth)
+static void dump_regs(struct ucc_geth_private *ugeth)
 {
        int i;
 
@@ -893,7 +879,7 @@ static void dump_regs(ucc_geth_private_t *ugeth)
                        ugeth_info("Base address: 0x%08x",
                                   (u32) & ugeth->p_thread_data_tx[i]);
                        mem_disp((u8 *) & ugeth->p_thread_data_tx[i],
-                                sizeof(ucc_geth_thread_data_tx_t));
+                                sizeof(struct ucc_geth_thread_data_tx));
                }
        }
        if (ugeth->p_thread_data_rx) {
@@ -927,7 +913,7 @@ static void dump_regs(ucc_geth_private_t *ugeth)
                        ugeth_info("Base address: 0x%08x",
                                   (u32) & ugeth->p_thread_data_rx[i]);
                        mem_disp((u8 *) & ugeth->p_thread_data_rx[i],
-                                sizeof(ucc_geth_thread_data_rx_t));
+                                sizeof(struct ucc_geth_thread_data_rx));
                }
        }
        if (ugeth->p_exf_glbl_param) {
@@ -1105,7 +1091,7 @@ static void dump_regs(ucc_geth_private_t *ugeth)
                        ugeth_info("Base address: 0x%08x",
                                   (u32) & ugeth->p_send_q_mem_reg->sqqd[i]);
                        mem_disp((u8 *) & ugeth->p_send_q_mem_reg->sqqd[i],
-                                sizeof(ucc_geth_send_queue_qd_t));
+                                sizeof(struct ucc_geth_send_queue_qd));
                }
        }
        if (ugeth->p_scheduler) {
@@ -1187,7 +1173,7 @@ static void dump_regs(ucc_geth_private_t *ugeth)
                                 qe_muram_addr(in_be32
                                               (&ugeth->p_rx_bd_qs_tbl[i].
                                                bdbaseptr)),
-                                sizeof(ucc_geth_rx_prefetched_bds_t));
+                                sizeof(struct ucc_geth_rx_prefetched_bds));
                }
        }
        if (ugeth->p_init_enet_param_shadow) {
@@ -1198,7 +1184,7 @@ static void dump_regs(ucc_geth_private_t *ugeth)
                mem_disp((u8 *) ugeth->p_init_enet_param_shadow,
                         sizeof(*ugeth->p_init_enet_param_shadow));
 
-               size = sizeof(ucc_geth_thread_rx_pram_t);
+               size = sizeof(struct ucc_geth_thread_rx_pram);
                if (ugeth->ug_info->rxExtendedFiltering) {
                        size +=
                            THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING;
@@ -1216,7 +1202,7 @@ static void dump_regs(ucc_geth_private_t *ugeth)
                                       &(ugeth->p_init_enet_param_shadow->
                                         txthread[0]),
                                       ENET_INIT_PARAM_MAX_ENTRIES_TX,
-                                      sizeof(ucc_geth_thread_tx_pram_t),
+                                      sizeof(struct ucc_geth_thread_tx_pram),
                                       ugeth->ug_info->riscTx, 0);
                dump_init_enet_entries(ugeth,
                                       &(ugeth->p_init_enet_param_shadow->
@@ -1578,12 +1564,12 @@ static int init_min_frame_len(u16 min_frame_length,
        return 0;
 }
 
-static int adjust_enet_interface(ucc_geth_private_t *ugeth)
+static int adjust_enet_interface(struct ucc_geth_private *ugeth)
 {
-       ucc_geth_info_t *ug_info;
-       ucc_geth_t *ug_regs;
-       ucc_fast_t *uf_regs;
-       enet_speed_e speed;
+       struct ucc_geth_info *ug_info;
+       struct ucc_geth *ug_regs;
+       struct ucc_fast *uf_regs;
+       enum enet_speed speed;
        int ret_val, rpm = 0, tbi = 0, r10m = 0, rmm =
            0, limited_to_full_duplex = 0;
        u32 upsmr, maccfg2, utbipar, tbiBaseAddress;
@@ -1691,8 +1677,8 @@ static int adjust_enet_interface(ucc_geth_private_t *ugeth)
  */
 static void adjust_link(struct net_device *dev)
 {
-       ucc_geth_private_t *ugeth = netdev_priv(dev);
-       ucc_geth_t *ug_regs;
+       struct ucc_geth_private *ugeth = netdev_priv(dev);
+       struct ucc_geth *ug_regs;
        u32 tempval;
        struct ugeth_mii_info *mii_info = ugeth->mii_info;
 
@@ -1722,7 +1708,7 @@ static void adjust_link(struct net_device *dev)
                if (mii_info->speed != ugeth->oldspeed) {
                        switch (mii_info->speed) {
                        case 1000:
-#ifdef CONFIG_MPC836x
+#ifdef CONFIG_PPC_MPC836x
 /* FIXME: This code is for 100Mbs BUG fixing,
 remove this when it is fixed!!! */
                                if (ugeth->ug_info->enet_interface ==
@@ -1768,7 +1754,7 @@ remove this when it is fixed!!! */
                                break;
                        case 100:
                        case 10:
-#ifdef CONFIG_MPC836x
+#ifdef CONFIG_PPC_MPC836x
 /* FIXME: This code is for 100Mbs BUG fixing,
 remove this lines when it will be fixed!!! */
                                ugeth->ug_info->enet_interface = ENET_100_RGMII;
@@ -1827,9 +1813,9 @@ remove this lines when it will be fixed!!! */
  */
 static int init_phy(struct net_device *dev)
 {
-       ucc_geth_private_t *ugeth = netdev_priv(dev);
+       struct ucc_geth_private *ugeth = netdev_priv(dev);
        struct phy_info *curphy;
-       ucc_mii_mng_t *mii_regs;
+       struct ucc_mii_mng *mii_regs;
        struct ugeth_mii_info *mii_info;
        int err;
 
@@ -1914,17 +1900,17 @@ static int init_phy(struct net_device *dev)
 }
 
 #ifdef CONFIG_UGETH_TX_ON_DEMOND
-static int ugeth_transmit_on_demand(ucc_geth_private_t *ugeth)
+static int ugeth_transmit_on_demand(struct ucc_geth_private *ugeth)
 {
-       ucc_fast_transmit_on_demand(ugeth->uccf);
+       struct ucc_fastransmit_on_demand(ugeth->uccf);
 
        return 0;
 }
 #endif
 
-static int ugeth_graceful_stop_tx(ucc_geth_private_t *ugeth)
+static int ugeth_graceful_stop_tx(struct ucc_geth_private *ugeth)
 {
-       ucc_fast_private_t *uccf;
+       struct ucc_fast_private *uccf;
        u32 cecr_subblock;
        u32 temp;
 
@@ -1940,7 +1926,7 @@ static int ugeth_graceful_stop_tx(ucc_geth_private_t *ugeth)
        cecr_subblock =
            ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.ucc_num);
        qe_issue_cmd(QE_GRACEFUL_STOP_TX, cecr_subblock,
-                    (u8) QE_CR_PROTOCOL_ETHERNET, 0);
+                    QE_CR_PROTOCOL_ETHERNET, 0);
 
        /* Wait for command to complete */
        do {
@@ -1952,9 +1938,9 @@ static int ugeth_graceful_stop_tx(ucc_geth_private_t *ugeth)
        return 0;
 }
 
-static int ugeth_graceful_stop_rx(ucc_geth_private_t * ugeth)
+static int ugeth_graceful_stop_rx(struct ucc_geth_private * ugeth)
 {
-       ucc_fast_private_t *uccf;
+       struct ucc_fast_private *uccf;
        u32 cecr_subblock;
        u8 temp;
 
@@ -1973,7 +1959,7 @@ static int ugeth_graceful_stop_rx(ucc_geth_private_t * ugeth)
                    ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.
                                                ucc_num);
                qe_issue_cmd(QE_GRACEFUL_STOP_RX, cecr_subblock,
-                            (u8) QE_CR_PROTOCOL_ETHERNET, 0);
+                            QE_CR_PROTOCOL_ETHERNET, 0);
 
                temp = ugeth->p_rx_glbl_pram->rxgstpack;
        } while (!(temp & GRACEFUL_STOP_ACKNOWLEDGE_RX));
@@ -1983,41 +1969,40 @@ static int ugeth_graceful_stop_rx(ucc_geth_private_t * ugeth)
        return 0;
 }
 
-static int ugeth_restart_tx(ucc_geth_private_t *ugeth)
+static int ugeth_restart_tx(struct ucc_geth_private *ugeth)
 {
-       ucc_fast_private_t *uccf;
+       struct ucc_fast_private *uccf;
        u32 cecr_subblock;
 
        uccf = ugeth->uccf;
 
        cecr_subblock =
            ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.ucc_num);
-       qe_issue_cmd(QE_RESTART_TX, cecr_subblock, (u8) QE_CR_PROTOCOL_ETHERNET,
-                    0);
+       qe_issue_cmd(QE_RESTART_TX, cecr_subblock, QE_CR_PROTOCOL_ETHERNET, 0);
        uccf->stopped_tx = 0;
 
        return 0;
 }
 
-static int ugeth_restart_rx(ucc_geth_private_t *ugeth)
+static int ugeth_restart_rx(struct ucc_geth_private *ugeth)
 {
-       ucc_fast_private_t *uccf;
+       struct ucc_fast_private *uccf;
        u32 cecr_subblock;
 
        uccf = ugeth->uccf;
 
        cecr_subblock =
            ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.ucc_num);
-       qe_issue_cmd(QE_RESTART_RX, cecr_subblock, (u8) QE_CR_PROTOCOL_ETHERNET,
+       qe_issue_cmd(QE_RESTART_RX, cecr_subblock, QE_CR_PROTOCOL_ETHERNET,
                     0);
        uccf->stopped_rx = 0;
 
        return 0;
 }
 
-static int ugeth_enable(ucc_geth_private_t *ugeth, comm_dir_e mode)
+static int ugeth_enable(struct ucc_geth_private *ugeth, enum comm_dir mode)
 {
-       ucc_fast_private_t *uccf;
+       struct ucc_fast_private *uccf;
        int enabled_tx, enabled_rx;
 
        uccf = ugeth->uccf;
@@ -2044,9 +2029,9 @@ static int ugeth_enable(ucc_geth_private_t *ugeth, comm_dir_e mode)
 
 }
 
-static int ugeth_disable(ucc_geth_private_t * ugeth, comm_dir_e mode)
+static int ugeth_disable(struct ucc_geth_private * ugeth, enum comm_dir mode)
 {
-       ucc_fast_private_t *uccf;
+       struct ucc_fast_private *uccf;
 
        uccf = ugeth->uccf;
 
@@ -2069,7 +2054,7 @@ static int ugeth_disable(ucc_geth_private_t * ugeth, comm_dir_e mode)
        return 0;
 }
 
-static void ugeth_dump_regs(ucc_geth_private_t *ugeth)
+static void ugeth_dump_regs(struct ucc_geth_private *ugeth)
 {
 #ifdef DEBUG
        ucc_fast_dump_regs(ugeth->uccf);
@@ -2079,9 +2064,9 @@ static void ugeth_dump_regs(ucc_geth_private_t *ugeth)
 }
 
 #ifdef CONFIG_UGETH_FILTERING
-static int ugeth_ext_filtering_serialize_tad(ucc_geth_tad_params_t *
+static int ugeth_ext_filtering_serialize_tad(struct ucc_geth_tad_params *
                                             p_UccGethTadParams,
-                                            qe_fltr_tad_t *qe_fltr_tad)
+                                            struct qe_fltr_tad *qe_fltr_tad)
 {
        u16 temp;
 
@@ -2119,11 +2104,11 @@ static int ugeth_ext_filtering_serialize_tad(ucc_geth_tad_params_t *
        return 0;
 }
 
-static enet_addr_container_t
-    *ugeth_82xx_filtering_get_match_addr_in_hash(ucc_geth_private_t *ugeth,
-                                                enet_addr_t *p_enet_addr)
+static struct enet_addr_container_t
+    *ugeth_82xx_filtering_get_match_addr_in_hash(struct ucc_geth_private *ugeth,
+                                                struct enet_addr *p_enet_addr)
 {
-       enet_addr_container_t *enet_addr_cont;
+       struct enet_addr_container *enet_addr_cont;
        struct list_head *p_lh;
        u16 i, num;
        int32_t j;
@@ -2144,7 +2129,7 @@ static enet_addr_container_t
 
        for (i = 0; i < num; i++) {
                enet_addr_cont =
-                   (enet_addr_container_t *)
+                   (struct enet_addr_container *)
                    ENET_ADDR_CONT_ENTRY(dequeue(p_lh));
                for (j = ENET_NUM_OCTETS_PER_ADDRESS - 1; j >= 0; j--) {
                        if ((*p_enet_addr)[j] != (enet_addr_cont->address)[j])
@@ -2157,11 +2142,11 @@ static enet_addr_container_t
        return NULL;
 }
 
-static int ugeth_82xx_filtering_add_addr_in_hash(ucc_geth_private_t *ugeth,
-                                                enet_addr_t *p_enet_addr)
+static int ugeth_82xx_filtering_add_addr_in_hash(struct ucc_geth_private *ugeth,
+                                                struct enet_addr *p_enet_addr)
 {
-       ucc_geth_enet_address_recognition_location_e location;
-       enet_addr_container_t *enet_addr_cont;
+       enum ucc_geth_enet_address_recognition_location location;
+       struct enet_addr_container *enet_addr_cont;
        struct list_head *p_lh;
        u8 i;
        u32 limit;
@@ -2196,18 +2181,17 @@ static int ugeth_82xx_filtering_add_addr_in_hash(ucc_geth_private_t *ugeth,
        enqueue(p_lh, &enet_addr_cont->node);   /* Put it back */
        ++(*p_counter);
 
-       hw_add_addr_in_hash(ugeth, &(enet_addr_cont->address));
-
+       hw_add_addr_in_hash(ugeth, enet_addr_cont->address);
        return 0;
 }
 
-static int ugeth_82xx_filtering_clear_addr_in_hash(ucc_geth_private_t *ugeth,
-                                                  enet_addr_t *p_enet_addr)
+static int ugeth_82xx_filtering_clear_addr_in_hash(struct ucc_geth_private *ugeth,
+                                                  struct enet_addr *p_enet_addr)
 {
-       ucc_geth_82xx_address_filtering_pram_t *p_82xx_addr_filt;
-       enet_addr_container_t *enet_addr_cont;
-       ucc_fast_private_t *uccf;
-       comm_dir_e comm_dir;
+       struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt;
+       struct enet_addr_container *enet_addr_cont;
+       struct ucc_fast_private *uccf;
+       enum comm_dir comm_dir;
        u16 i, num;
        struct list_head *p_lh;
        u32 *addr_h, *addr_l;
@@ -2216,7 +2200,7 @@ static int ugeth_82xx_filtering_clear_addr_in_hash(ucc_geth_private_t *ugeth,
        uccf = ugeth->uccf;
 
        p_82xx_addr_filt =
-           (ucc_geth_82xx_address_filtering_pram_t *) ugeth->p_rx_glbl_pram->
+           (struct ucc_geth_82xx_address_filtering_pram *) ugeth->p_rx_glbl_pram->
            addressfiltering;
 
        if (!
@@ -2256,9 +2240,9 @@ static int ugeth_82xx_filtering_clear_addr_in_hash(ucc_geth_private_t *ugeth,
        num = --(*p_counter);
        for (i = 0; i < num; i++) {
                enet_addr_cont =
-                   (enet_addr_container_t *)
+                   (struct enet_addr_container *)
                    ENET_ADDR_CONT_ENTRY(dequeue(p_lh));
-               hw_add_addr_in_hash(ugeth, &(enet_addr_cont->address));
+               hw_add_addr_in_hash(ugeth, enet_addr_cont->address);
                enqueue(p_lh, &enet_addr_cont->node);   /* Put it back */
        }
 
@@ -2269,14 +2253,14 @@ static int ugeth_82xx_filtering_clear_addr_in_hash(ucc_geth_private_t *ugeth,
 }
 #endif /* CONFIG_UGETH_FILTERING */
 
-static int ugeth_82xx_filtering_clear_all_addr_in_hash(ucc_geth_private_t *
+static int ugeth_82xx_filtering_clear_all_addr_in_hash(struct ucc_geth_private *
                                                       ugeth,
-                                                      enet_addr_type_e
+                                                      enum enet_addr_type
                                                       enet_addr_type)
 {
-       ucc_geth_82xx_address_filtering_pram_t *p_82xx_addr_filt;
-       ucc_fast_private_t *uccf;
-       comm_dir_e comm_dir;
+       struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt;
+       struct ucc_fast_private *uccf;
+       enum comm_dir comm_dir;
        struct list_head *p_lh;
        u16 i, num;
        u32 *addr_h, *addr_l;
@@ -2285,7 +2269,7 @@ static int ugeth_82xx_filtering_clear_all_addr_in_hash(ucc_geth_private_t *
        uccf = ugeth->uccf;
 
        p_82xx_addr_filt =
-           (ucc_geth_82xx_address_filtering_pram_t *) ugeth->p_rx_glbl_pram->
+           (struct ucc_geth_82xx_address_filtering_pram *) ugeth->p_rx_glbl_pram->
            addressfiltering;
 
        if (enet_addr_type == ENET_ADDR_TYPE_GROUP) {
@@ -2331,8 +2315,8 @@ static int ugeth_82xx_filtering_clear_all_addr_in_hash(ucc_geth_private_t *
 }
 
 #ifdef CONFIG_UGETH_FILTERING
-static int ugeth_82xx_filtering_add_addr_in_paddr(ucc_geth_private_t *ugeth,
-                                                 enet_addr_t *p_enet_addr,
+static int ugeth_82xx_filtering_add_addr_in_paddr(struct ucc_geth_private *ugeth,
+                                                 struct enet_addr *p_enet_addr,
                                                  u8 paddr_num)
 {
        int i;
@@ -2352,14 +2336,14 @@ static int ugeth_82xx_filtering_add_addr_in_paddr(ucc_geth_private_t *ugeth,
 }
 #endif /* CONFIG_UGETH_FILTERING */
 
-static int ugeth_82xx_filtering_clear_addr_in_paddr(ucc_geth_private_t *ugeth,
+static int ugeth_82xx_filtering_clear_addr_in_paddr(struct ucc_geth_private *ugeth,
                                                    u8 paddr_num)
 {
        ugeth->indAddrRegUsed[paddr_num] = 0; /* mark this paddr as not used */
        return hw_clear_addr_in_paddr(ugeth, paddr_num);/* clear in hardware */
 }
 
-static void ucc_geth_memclean(ucc_geth_private_t *ugeth)
+static void ucc_geth_memclean(struct ucc_geth_private *ugeth)
 {
        u16 i, j;
        u8 *bd;
@@ -2433,8 +2417,8 @@ static void ucc_geth_memclean(ucc_geth_private_t *ugeth)
                for (j = 0; j < ugeth->ug_info->bdRingLenTx[i]; j++) {
                        if (ugeth->tx_skbuff[i][j]) {
                                dma_unmap_single(NULL,
-                                                BD_BUFFER_ARG(bd),
-                                                (BD_STATUS_AND_LENGTH(bd) &
+                                                ((qe_bd_t *)bd)->buf,
+                                                (in_be32((u32 *)bd) &
                                                  BD_LENGTH_MASK),
                                                 DMA_TO_DEVICE);
                                dev_kfree_skb_any(ugeth->tx_skbuff[i][j]);
@@ -2460,18 +2444,17 @@ static void ucc_geth_memclean(ucc_geth_private_t *ugeth)
                        bd = ugeth->p_rx_bd_ring[i];
                        for (j = 0; j < ugeth->ug_info->bdRingLenRx[i]; j++) {
                                if (ugeth->rx_skbuff[i][j]) {
-                                       dma_unmap_single(NULL, BD_BUFFER(bd),
-                                                ugeth->ug_info->
-                                                uf_info.
-                                                max_rx_buf_length +
-                                                UCC_GETH_RX_DATA_BUF_ALIGNMENT,
-                                                DMA_FROM_DEVICE);
-
-                                       dev_kfree_skb_any(ugeth->
-                                                         rx_skbuff[i][j]);
+                                       dma_unmap_single(NULL,
+                                               ((struct qe_bd *)bd)->buf,
+                                               ugeth->ug_info->
+                                               uf_info.max_rx_buf_length +
+                                               UCC_GETH_RX_DATA_BUF_ALIGNMENT,
+                                               DMA_FROM_DEVICE);
+                                       dev_kfree_skb_any(
+                                               ugeth->rx_skbuff[i][j]);
                                        ugeth->rx_skbuff[i][j] = NULL;
                                }
-                               bd += UCC_GETH_SIZE_OF_BD;
+                               bd += sizeof(struct qe_bd);
                        }
 
                        kfree(ugeth->rx_skbuff[i]);
@@ -2496,11 +2479,11 @@ static void ucc_geth_memclean(ucc_geth_private_t *ugeth)
 
 static void ucc_geth_set_multi(struct net_device *dev)
 {
-       ucc_geth_private_t *ugeth;
+       struct ucc_geth_private *ugeth;
        struct dev_mc_list *dmi;
-       ucc_fast_t *uf_regs;
-       ucc_geth_82xx_address_filtering_pram_t *p_82xx_addr_filt;
-       enet_addr_t tempaddr;
+       struct ucc_fast *uf_regs;
+       struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt;
+       u8 tempaddr[6];
        u8 *mcptr, *tdptr;
        int i, j;
 
@@ -2517,7 +2500,7 @@ static void ucc_geth_set_multi(struct net_device *dev)
                uf_regs->upsmr &= ~UPSMR_PRO;
 
                p_82xx_addr_filt =
-                   (ucc_geth_82xx_address_filtering_pram_t *) ugeth->
+                   (struct ucc_geth_82xx_address_filtering_pram *) ugeth->
                    p_rx_glbl_pram->addressfiltering;
 
                if (dev->flags & IFF_ALLMULTI) {
@@ -2546,23 +2529,22 @@ static void ucc_geth_set_multi(struct net_device *dev)
                                 * copy bytes MSB first from dmi_addr.
                                 */
                                mcptr = (u8 *) dmi->dmi_addr + 5;
-                               tdptr = (u8 *) tempaddr;
+                               tdptr = (u8 *) tempaddr;
                                for (j = 0; j < 6; j++)
                                        *tdptr++ = *mcptr--;
 
                                /* Ask CPM to run CRC and set bit in
                                 * filter mask.
                                 */
-                               hw_add_addr_in_hash(ugeth, &tempaddr);
-
+                               hw_add_addr_in_hash(ugeth, tempaddr);
                        }
                }
        }
 }
 
-static void ucc_geth_stop(ucc_geth_private_t *ugeth)
+static void ucc_geth_stop(struct ucc_geth_private *ugeth)
 {
-       ucc_geth_t *ug_regs = ugeth->ug_regs;
+       struct ucc_geth *ug_regs = ugeth->ug_regs;
        u32 tempval;
 
        ugeth_vdbg("%s: IN", __FUNCTION__);
@@ -2605,15 +2587,15 @@ static void ucc_geth_stop(ucc_geth_private_t *ugeth)
        ucc_geth_memclean(ugeth);
 }
 
-static int ucc_geth_startup(ucc_geth_private_t *ugeth)
+static int ucc_geth_startup(struct ucc_geth_private *ugeth)
 {
-       ucc_geth_82xx_address_filtering_pram_t *p_82xx_addr_filt;
-       ucc_geth_init_pram_t *p_init_enet_pram;
-       ucc_fast_private_t *uccf;
-       ucc_geth_info_t *ug_info;
-       ucc_fast_info_t *uf_info;
-       ucc_fast_t *uf_regs;
-       ucc_geth_t *ug_regs;
+       struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt;
+       struct ucc_geth_init_pram *p_init_enet_pram;
+       struct ucc_fast_private *uccf;
+       struct ucc_geth_info *ug_info;
+       struct ucc_fast_info *uf_info;
+       struct ucc_fast *uf_regs;
+       struct ucc_geth *ug_regs;
        int ret_val = -EINVAL;
        u32 remoder = UCC_GETH_REMODER_INIT;
        u32 init_enet_pram_offset, cecr_subblock, command, maccfg1;
@@ -2788,7 +2770,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
                UCC_GETH_VLAN_OPERATION_NON_TAGGED_NOP);
 
        uf_regs = uccf->uf_regs;
-       ug_regs = (ucc_geth_t *) (uccf->uf_regs);
+       ug_regs = (struct ucc_geth *) (uccf->uf_regs);
        ugeth->ug_regs = ug_regs;
 
        init_default_reg_vals(&uf_regs->upsmr,
@@ -2869,10 +2851,10 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
                /* Allocate in multiple of
                   UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT,
                   according to spec */
-               length = ((ug_info->bdRingLenTx[j] * UCC_GETH_SIZE_OF_BD)
+               length = ((ug_info->bdRingLenTx[j] * sizeof(struct qe_bd))
                          / UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT)
                    * UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT;
-               if ((ug_info->bdRingLenTx[j] * UCC_GETH_SIZE_OF_BD) %
+               if ((ug_info->bdRingLenTx[j] * sizeof(struct qe_bd)) %
                    UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT)
                        length += UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT;
                if (uf_info->bd_mem_part == MEM_PART_SYSTEM) {
@@ -2904,13 +2886,13 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
                }
                /* Zero unused end of bd ring, according to spec */
                memset(ugeth->p_tx_bd_ring[j] +
-                      ug_info->bdRingLenTx[j] * UCC_GETH_SIZE_OF_BD, 0,
-                      length - ug_info->bdRingLenTx[j] * UCC_GETH_SIZE_OF_BD);
+                      ug_info->bdRingLenTx[j] * sizeof(struct qe_bd), 0,
+                      length - ug_info->bdRingLenTx[j] * sizeof(struct qe_bd));
        }
 
        /* Allocate Rx bds */
        for (j = 0; j < ug_info->numQueuesRx; j++) {
-               length = ug_info->bdRingLenRx[j] * UCC_GETH_SIZE_OF_BD;
+               length = ug_info->bdRingLenRx[j] * sizeof(struct qe_bd);
                if (uf_info->bd_mem_part == MEM_PART_SYSTEM) {
                        u32 align = 4;
                        if (UCC_GETH_RX_BD_RING_ALIGNMENT > 4)
@@ -2960,12 +2942,15 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
                ugeth->skb_curtx[j] = ugeth->skb_dirtytx[j] = 0;
                bd = ugeth->confBd[j] = ugeth->txBd[j] = ugeth->p_tx_bd_ring[j];
                for (i = 0; i < ug_info->bdRingLenTx[j]; i++) {
-                       BD_BUFFER_CLEAR(bd);
-                       BD_STATUS_AND_LENGTH_SET(bd, 0);
-                       bd += UCC_GETH_SIZE_OF_BD;
+                       /* clear bd buffer */
+                       out_be32(&((struct qe_bd *)bd)->buf, 0);
+                       /* set bd status and length */
+                       out_be32((u32 *)bd, 0);
+                       bd += sizeof(struct qe_bd);
                }
-               bd -= UCC_GETH_SIZE_OF_BD;
-               BD_STATUS_AND_LENGTH_SET(bd, T_W);/* for last BD set Wrap bit */
+               bd -= sizeof(struct qe_bd);
+               /* set bd status and length */
+               out_be32((u32 *)bd, T_W);       /* for last BD set Wrap bit */
        }
 
        /* Init Rx bds */
@@ -2989,12 +2974,15 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
                ugeth->skb_currx[j] = 0;
                bd = ugeth->rxBd[j] = ugeth->p_rx_bd_ring[j];
                for (i = 0; i < ug_info->bdRingLenRx[j]; i++) {
-                       BD_STATUS_AND_LENGTH_SET(bd, R_I);
-                       BD_BUFFER_CLEAR(bd);
-                       bd += UCC_GETH_SIZE_OF_BD;
+                       /* set bd status and length */
+                       out_be32((u32 *)bd, R_I);
+                       /* clear bd buffer */
+                       out_be32(&((struct qe_bd *)bd)->buf, 0);
+                       bd += sizeof(struct qe_bd);
                }
-               bd -= UCC_GETH_SIZE_OF_BD;
-               BD_STATUS_AND_LENGTH_SET(bd, R_W);/* for last BD set Wrap bit */
+               bd -= sizeof(struct qe_bd);
+               /* set bd status and length */
+               out_be32((u32 *)bd, R_W); /* for last BD set Wrap bit */
        }
 
        /*
@@ -3003,7 +2991,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
        /* Tx global PRAM */
        /* Allocate global tx parameter RAM page */
        ugeth->tx_glbl_pram_offset =
-           qe_muram_alloc(sizeof(ucc_geth_tx_global_pram_t),
+           qe_muram_alloc(sizeof(struct ucc_geth_tx_global_pram),
                           UCC_GETH_TX_GLOBAL_PRAM_ALIGNMENT);
        if (IS_MURAM_ERR(ugeth->tx_glbl_pram_offset)) {
                ugeth_err
@@ -3013,10 +3001,10 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
                return -ENOMEM;
        }
        ugeth->p_tx_glbl_pram =
-           (ucc_geth_tx_global_pram_t *) qe_muram_addr(ugeth->
+           (struct ucc_geth_tx_global_pram *) qe_muram_addr(ugeth->
                                                        tx_glbl_pram_offset);
        /* Zero out p_tx_glbl_pram */
-       memset(ugeth->p_tx_glbl_pram, 0, sizeof(ucc_geth_tx_global_pram_t));
+       memset(ugeth->p_tx_glbl_pram, 0, sizeof(struct ucc_geth_tx_global_pram));
 
        /* Fill global PRAM */
 
@@ -3024,7 +3012,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
        /* Size varies with number of Tx threads */
        ugeth->thread_dat_tx_offset =
            qe_muram_alloc(numThreadsTxNumerical *
-                          sizeof(ucc_geth_thread_data_tx_t) +
+                          sizeof(struct ucc_geth_thread_data_tx) +
                           32 * (numThreadsTxNumerical == 1),
                           UCC_GETH_THREAD_DATA_ALIGNMENT);
        if (IS_MURAM_ERR(ugeth->thread_dat_tx_offset)) {
@@ -3036,7 +3024,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
        }
 
        ugeth->p_thread_data_tx =
-           (ucc_geth_thread_data_tx_t *) qe_muram_addr(ugeth->
+           (struct ucc_geth_thread_data_tx *) qe_muram_addr(ugeth->
                                                        thread_dat_tx_offset);
        out_be32(&ugeth->p_tx_glbl_pram->tqptr, ugeth->thread_dat_tx_offset);
 
@@ -3053,7 +3041,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
        /* Size varies with number of Tx queues */
        ugeth->send_q_mem_reg_offset =
            qe_muram_alloc(ug_info->numQueuesTx *
-                          sizeof(ucc_geth_send_queue_qd_t),
+                          sizeof(struct ucc_geth_send_queue_qd),
                           UCC_GETH_SEND_QUEUE_QUEUE_DESCRIPTOR_ALIGNMENT);
        if (IS_MURAM_ERR(ugeth->send_q_mem_reg_offset)) {
                ugeth_err
@@ -3064,7 +3052,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
        }
 
        ugeth->p_send_q_mem_reg =
-           (ucc_geth_send_queue_mem_region_t *) qe_muram_addr(ugeth->
+           (struct ucc_geth_send_queue_mem_region *) qe_muram_addr(ugeth->
                        send_q_mem_reg_offset);
        out_be32(&ugeth->p_tx_glbl_pram->sqptr, ugeth->send_q_mem_reg_offset);
 
@@ -3073,7 +3061,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
        for (i = 0; i < ug_info->numQueuesTx; i++) {
                endOfRing =
                    ugeth->p_tx_bd_ring[i] + (ug_info->bdRingLenTx[i] -
-                                             1) * UCC_GETH_SIZE_OF_BD;
+                                             1) * sizeof(struct qe_bd);
                if (ugeth->ug_info->uf_info.bd_mem_part == MEM_PART_SYSTEM) {
                        out_be32(&ugeth->p_send_q_mem_reg->sqqd[i].bd_ring_base,
                                 (u32) virt_to_phys(ugeth->p_tx_bd_ring[i]));
@@ -3096,7 +3084,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
        if (ug_info->numQueuesTx > 1) {
        /* scheduler exists only if more than 1 tx queue */
                ugeth->scheduler_offset =
-                   qe_muram_alloc(sizeof(ucc_geth_scheduler_t),
+                   qe_muram_alloc(sizeof(struct ucc_geth_scheduler),
                                   UCC_GETH_SCHEDULER_ALIGNMENT);
                if (IS_MURAM_ERR(ugeth->scheduler_offset)) {
                        ugeth_err
@@ -3107,12 +3095,12 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
                }
 
                ugeth->p_scheduler =
-                   (ucc_geth_scheduler_t *) qe_muram_addr(ugeth->
+                   (struct ucc_geth_scheduler *) qe_muram_addr(ugeth->
                                                           scheduler_offset);
                out_be32(&ugeth->p_tx_glbl_pram->schedulerbasepointer,
                         ugeth->scheduler_offset);
                /* Zero out p_scheduler */
-               memset(ugeth->p_scheduler, 0, sizeof(ucc_geth_scheduler_t));
+               memset(ugeth->p_scheduler, 0, sizeof(struct ucc_geth_scheduler));
 
                /* Set values in scheduler */
                out_be32(&ugeth->p_scheduler->mblinterval,
@@ -3144,7 +3132,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
            statisticsMode & UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_TX) {
                ugeth->tx_fw_statistics_pram_offset =
                    qe_muram_alloc(sizeof
-                                  (ucc_geth_tx_firmware_statistics_pram_t),
+                                  (struct ucc_geth_tx_firmware_statistics_pram),
                                   UCC_GETH_TX_STATISTICS_ALIGNMENT);
                if (IS_MURAM_ERR(ugeth->tx_fw_statistics_pram_offset)) {
                        ugeth_err
@@ -3154,11 +3142,11 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
                        return -ENOMEM;
                }
                ugeth->p_tx_fw_statistics_pram =
-                   (ucc_geth_tx_firmware_statistics_pram_t *)
+                   (struct ucc_geth_tx_firmware_statistics_pram *)
                    qe_muram_addr(ugeth->tx_fw_statistics_pram_offset);
                /* Zero out p_tx_fw_statistics_pram */
                memset(ugeth->p_tx_fw_statistics_pram,
-                      0, sizeof(ucc_geth_tx_firmware_statistics_pram_t));
+                      0, sizeof(struct ucc_geth_tx_firmware_statistics_pram));
        }
 
        /* temoder */
@@ -3183,7 +3171,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
        /* Rx global PRAM */
        /* Allocate global rx parameter RAM page */
        ugeth->rx_glbl_pram_offset =
-           qe_muram_alloc(sizeof(ucc_geth_rx_global_pram_t),
+           qe_muram_alloc(sizeof(struct ucc_geth_rx_global_pram),
                           UCC_GETH_RX_GLOBAL_PRAM_ALIGNMENT);
        if (IS_MURAM_ERR(ugeth->rx_glbl_pram_offset)) {
                ugeth_err
@@ -3193,10 +3181,10 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
                return -ENOMEM;
        }
        ugeth->p_rx_glbl_pram =
-           (ucc_geth_rx_global_pram_t *) qe_muram_addr(ugeth->
+           (struct ucc_geth_rx_global_pram *) qe_muram_addr(ugeth->
                                                        rx_glbl_pram_offset);
        /* Zero out p_rx_glbl_pram */
-       memset(ugeth->p_rx_glbl_pram, 0, sizeof(ucc_geth_rx_global_pram_t));
+       memset(ugeth->p_rx_glbl_pram, 0, sizeof(struct ucc_geth_rx_global_pram));
 
        /* Fill global PRAM */
 
@@ -3204,7 +3192,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
        /* Size varies with number of Rx threads */
        ugeth->thread_dat_rx_offset =
            qe_muram_alloc(numThreadsRxNumerical *
-                          sizeof(ucc_geth_thread_data_rx_t),
+                          sizeof(struct ucc_geth_thread_data_rx),
                           UCC_GETH_THREAD_DATA_ALIGNMENT);
        if (IS_MURAM_ERR(ugeth->thread_dat_rx_offset)) {
                ugeth_err
@@ -3215,7 +3203,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
        }
 
        ugeth->p_thread_data_rx =
-           (ucc_geth_thread_data_rx_t *) qe_muram_addr(ugeth->
+           (struct ucc_geth_thread_data_rx *) qe_muram_addr(ugeth->
                                                        thread_dat_rx_offset);
        out_be32(&ugeth->p_rx_glbl_pram->rqptr, ugeth->thread_dat_rx_offset);
 
@@ -3227,7 +3215,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
            statisticsMode & UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_RX) {
                ugeth->rx_fw_statistics_pram_offset =
                    qe_muram_alloc(sizeof
-                                  (ucc_geth_rx_firmware_statistics_pram_t),
+                                  (struct ucc_geth_rx_firmware_statistics_pram),
                                   UCC_GETH_RX_STATISTICS_ALIGNMENT);
                if (IS_MURAM_ERR(ugeth->rx_fw_statistics_pram_offset)) {
                        ugeth_err
@@ -3237,11 +3225,11 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
                        return -ENOMEM;
                }
                ugeth->p_rx_fw_statistics_pram =
-                   (ucc_geth_rx_firmware_statistics_pram_t *)
+                   (struct ucc_geth_rx_firmware_statistics_pram *)
                    qe_muram_addr(ugeth->rx_fw_statistics_pram_offset);
                /* Zero out p_rx_fw_statistics_pram */
                memset(ugeth->p_rx_fw_statistics_pram, 0,
-                      sizeof(ucc_geth_rx_firmware_statistics_pram_t));
+                      sizeof(struct ucc_geth_rx_firmware_statistics_pram));
        }
 
        /* intCoalescingPtr */
@@ -3249,7 +3237,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
        /* Size varies with number of Rx queues */
        ugeth->rx_irq_coalescing_tbl_offset =
            qe_muram_alloc(ug_info->numQueuesRx *
-                          sizeof(ucc_geth_rx_interrupt_coalescing_entry_t),
+                          sizeof(struct ucc_geth_rx_interrupt_coalescing_entry),
                           UCC_GETH_RX_INTERRUPT_COALESCING_ALIGNMENT);
        if (IS_MURAM_ERR(ugeth->rx_irq_coalescing_tbl_offset)) {
                ugeth_err
@@ -3260,7 +3248,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
        }
 
        ugeth->p_rx_irq_coalescing_tbl =
-           (ucc_geth_rx_interrupt_coalescing_table_t *)
+           (struct ucc_geth_rx_interrupt_coalescing_table *)
            qe_muram_addr(ugeth->rx_irq_coalescing_tbl_offset);
        out_be32(&ugeth->p_rx_glbl_pram->intcoalescingptr,
                 ugeth->rx_irq_coalescing_tbl_offset);
@@ -3300,7 +3288,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
                l3qt = 0;
                for (i = 0; i < 8; i++)
                        l3qt |= (ug_info->l3qt[j + i] << (28 - 4 * i));
-               out_be32(&ugeth->p_rx_glbl_pram->l3qt[j], l3qt);
+               out_be32(&ugeth->p_rx_glbl_pram->l3qt[j/8], l3qt);
        }
 
        /* vlantype */
@@ -3316,8 +3304,8 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
        /* Size varies with number of Rx queues */
        ugeth->rx_bd_qs_tbl_offset =
            qe_muram_alloc(ug_info->numQueuesRx *
-                          (sizeof(ucc_geth_rx_bd_queues_entry_t) +
-                           sizeof(ucc_geth_rx_prefetched_bds_t)),
+                          (sizeof(struct ucc_geth_rx_bd_queues_entry) +
+                           sizeof(struct ucc_geth_rx_prefetched_bds)),
                           UCC_GETH_RX_BD_QUEUES_ALIGNMENT);
        if (IS_MURAM_ERR(ugeth->rx_bd_qs_tbl_offset)) {
                ugeth_err
@@ -3328,14 +3316,14 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
        }
 
        ugeth->p_rx_bd_qs_tbl =
-           (ucc_geth_rx_bd_queues_entry_t *) qe_muram_addr(ugeth->
+           (struct ucc_geth_rx_bd_queues_entry *) qe_muram_addr(ugeth->
                                    rx_bd_qs_tbl_offset);
        out_be32(&ugeth->p_rx_glbl_pram->rbdqptr, ugeth->rx_bd_qs_tbl_offset);
        /* Zero out p_rx_bd_qs_tbl */
        memset(ugeth->p_rx_bd_qs_tbl,
               0,
-              ug_info->numQueuesRx * (sizeof(ucc_geth_rx_bd_queues_entry_t) +
-                                      sizeof(ucc_geth_rx_prefetched_bds_t)));
+              ug_info->numQueuesRx * (sizeof(struct ucc_geth_rx_bd_queues_entry) +
+                                      sizeof(struct ucc_geth_rx_prefetched_bds)));
 
        /* Setup the table */
        /* Assume BD rings are already established */
@@ -3406,7 +3394,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
                /* Allocate memory for extended filtering Mode Global
                Parameters */
                ugeth->exf_glbl_param_offset =
-                   qe_muram_alloc(sizeof(ucc_geth_exf_global_pram_t),
+                   qe_muram_alloc(sizeof(struct ucc_geth_exf_global_pram),
                UCC_GETH_RX_EXTENDED_FILTERING_GLOBAL_PARAMETERS_ALIGNMENT);
                if (IS_MURAM_ERR(ugeth->exf_glbl_param_offset)) {
                        ugeth_err
@@ -3417,7 +3405,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
                }
 
                ugeth->p_exf_glbl_param =
-                   (ucc_geth_exf_global_pram_t *) qe_muram_addr(ugeth->
+                   (struct ucc_geth_exf_global_pram *) qe_muram_addr(ugeth->
                                 exf_glbl_param_offset);
                out_be32(&ugeth->p_rx_glbl_pram->exfGlobalParam,
                         ugeth->exf_glbl_param_offset);
@@ -3439,7 +3427,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
                        INIT_LIST_HEAD(&ugeth->ind_hash_q);
                }
                p_82xx_addr_filt =
-                   (ucc_geth_82xx_address_filtering_pram_t *) ugeth->
+                   (struct ucc_geth_82xx_address_filtering_pram *) ugeth->
                    p_rx_glbl_pram->addressfiltering;
 
                ugeth_82xx_filtering_clear_all_addr_in_hash(ugeth,
@@ -3462,7 +3450,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
         * allocated resources can be released when the channel is freed.
         */
        if (!(ugeth->p_init_enet_param_shadow =
-            (ucc_geth_init_pram_t *) kmalloc(sizeof(ucc_geth_init_pram_t),
+            (struct ucc_geth_init_pram *) kmalloc(sizeof(struct ucc_geth_init_pram),
                                              GFP_KERNEL))) {
                ugeth_err
                    ("%s: Can not allocate memory for"
@@ -3472,7 +3460,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
        }
        /* Zero out *p_init_enet_param_shadow */
        memset((char *)ugeth->p_init_enet_param_shadow,
-              0, sizeof(ucc_geth_init_pram_t));
+              0, sizeof(struct ucc_geth_init_pram));
 
        /* Fill shadow InitEnet command parameter structure */
 
@@ -3506,7 +3494,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
        }
        ugeth->p_init_enet_param_shadow->largestexternallookupkeysize =
            ug_info->largestexternallookupkeysize;
-       size = sizeof(ucc_geth_thread_rx_pram_t);
+       size = sizeof(struct ucc_geth_thread_rx_pram);
        if (ug_info->rxExtendedFiltering) {
                size += THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING;
                if (ug_info->largestexternallookupkeysize ==
@@ -3537,7 +3525,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
             fill_init_enet_entries(ugeth,
                                    &(ugeth->p_init_enet_param_shadow->
                                      txthread[0]), numThreadsTxNumerical,
-                                   sizeof(ucc_geth_thread_tx_pram_t),
+                                   sizeof(struct ucc_geth_thread_tx_pram),
                                    UCC_GETH_THREAD_TX_PRAM_ALIGNMENT,
                                    ug_info->riscTx, 0)) != 0) {
                ugeth_err("%s: Can not fill p_init_enet_param_shadow.",
@@ -3557,7 +3545,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
        }
 
        /* Allocate InitEnet command parameter structure */
-       init_enet_pram_offset = qe_muram_alloc(sizeof(ucc_geth_init_pram_t), 4);
+       init_enet_pram_offset = qe_muram_alloc(sizeof(struct ucc_geth_init_pram), 4);
        if (IS_MURAM_ERR(init_enet_pram_offset)) {
                ugeth_err
                    ("%s: Can not allocate DPRAM memory for p_init_enet_pram.",
@@ -3566,7 +3554,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
                return -ENOMEM;
        }
        p_init_enet_pram =
-           (ucc_geth_init_pram_t *) qe_muram_addr(init_enet_pram_offset);
+           (struct ucc_geth_init_pram *) qe_muram_addr(init_enet_pram_offset);
 
        /* Copy shadow InitEnet command parameter structure into PRAM */
        p_init_enet_pram->resinit1 = ugeth->p_init_enet_param_shadow->resinit1;
@@ -3591,7 +3579,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
        /* Issue QE command */
        cecr_subblock =
            ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.ucc_num);
-       qe_issue_cmd(command, cecr_subblock, (u8) QE_CR_PROTOCOL_ETHERNET,
+       qe_issue_cmd(command, cecr_subblock, QE_CR_PROTOCOL_ETHERNET,
                     init_enet_pram_offset);
 
        /* Free InitEnet command parameter */
@@ -3603,7 +3591,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
 /* returns a net_device_stats structure pointer */
 static struct net_device_stats *ucc_geth_get_stats(struct net_device *dev)
 {
-       ucc_geth_private_t *ugeth = netdev_priv(dev);
+       struct ucc_geth_private *ugeth = netdev_priv(dev);
 
        return &(ugeth->stats);
 }
@@ -3614,7 +3602,7 @@ static struct net_device_stats *ucc_geth_get_stats(struct net_device *dev)
  * starting over will fix the problem. */
 static void ucc_geth_timeout(struct net_device *dev)
 {
-       ucc_geth_private_t *ugeth = netdev_priv(dev);
+       struct ucc_geth_private *ugeth = netdev_priv(dev);
 
        ugeth_vdbg("%s: IN", __FUNCTION__);
 
@@ -3634,7 +3622,7 @@ static void ucc_geth_timeout(struct net_device *dev)
 /* It is pointed to by the dev->hard_start_xmit function pointer */
 static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-       ucc_geth_private_t *ugeth = netdev_priv(dev);
+       struct ucc_geth_private *ugeth = netdev_priv(dev);
        u8 *bd;                 /* BD pointer */
        u32 bd_status;
        u8 txQ = 0;
@@ -3647,7 +3635,7 @@ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
        /* Start from the next BD that should be filled */
        bd = ugeth->txBd[txQ];
-       bd_status = BD_STATUS_AND_LENGTH(bd);
+       bd_status = in_be32((u32 *)bd);
        /* Save the skb pointer so we can free it later */
        ugeth->tx_skbuff[txQ][ugeth->skb_curtx[txQ]] = skb;
 
@@ -3657,20 +3645,21 @@ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev)
             1) & TX_RING_MOD_MASK(ugeth->ug_info->bdRingLenTx[txQ]);
 
        /* set up the buffer descriptor */
-       BD_BUFFER_SET(bd,
+       out_be32(&((struct qe_bd *)bd)->buf,
                      dma_map_single(NULL, skb->data, skb->len, DMA_TO_DEVICE));
 
-       //printk(KERN_DEBUG"skb->data is 0x%x\n",skb->data);
+       /* printk(KERN_DEBUG"skb->data is 0x%x\n",skb->data); */
 
        bd_status = (bd_status & T_W) | T_R | T_I | T_L | skb->len;
 
-       BD_STATUS_AND_LENGTH_SET(bd, bd_status);
+       /* set bd status and length */
+       out_be32((u32 *)bd, bd_status);
 
        dev->trans_start = jiffies;
 
        /* Move to next BD in the ring */
        if (!(bd_status & T_W))
-               ugeth->txBd[txQ] = bd + UCC_GETH_SIZE_OF_BD;
+               ugeth->txBd[txQ] = bd + sizeof(struct qe_bd);
        else
                ugeth->txBd[txQ] = ugeth->p_tx_bd_ring[txQ];
 
@@ -3695,7 +3684,7 @@ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev)
        return 0;
 }
 
-static int ucc_geth_rx(ucc_geth_private_t *ugeth, u8 rxQ, int rx_work_limit)
+static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit)
 {
        struct sk_buff *skb;
        u8 *bd;
@@ -3709,11 +3698,11 @@ static int ucc_geth_rx(ucc_geth_private_t *ugeth, u8 rxQ, int rx_work_limit)
        /* collect received buffers */
        bd = ugeth->rxBd[rxQ];
 
-       bd_status = BD_STATUS_AND_LENGTH(bd);
+       bd_status = in_be32((u32 *)bd);
 
        /* while there are received buffers and BD is full (~R_E) */
        while (!((bd_status & (R_E)) || (--rx_work_limit < 0))) {
-               bdBuffer = (u8 *) BD_BUFFER(bd);
+               bdBuffer = (u8 *) in_be32(&((struct qe_bd *)bd)->buf);
                length = (u16) ((bd_status & BD_LENGTH_MASK) - 4);
                skb = ugeth->rx_skbuff[rxQ][ugeth->skb_currx[rxQ]];
 
@@ -3768,9 +3757,9 @@ static int ucc_geth_rx(ucc_geth_private_t *ugeth, u8 rxQ, int rx_work_limit)
                if (bd_status & R_W)
                        bd = ugeth->p_rx_bd_ring[rxQ];
                else
-                       bd += UCC_GETH_SIZE_OF_BD;
+                       bd += sizeof(struct qe_bd);
 
-               bd_status = BD_STATUS_AND_LENGTH(bd);
+               bd_status = in_be32((u32 *)bd);
        }
 
        ugeth->rxBd[rxQ] = bd;
@@ -3781,12 +3770,12 @@ static int ucc_geth_rx(ucc_geth_private_t *ugeth, u8 rxQ, int rx_work_limit)
 static int ucc_geth_tx(struct net_device *dev, u8 txQ)
 {
        /* Start from the next BD that should be filled */
-       ucc_geth_private_t *ugeth = netdev_priv(dev);
+       struct ucc_geth_private *ugeth = netdev_priv(dev);
        u8 *bd;                 /* BD pointer */
        u32 bd_status;
 
        bd = ugeth->confBd[txQ];
-       bd_status = BD_STATUS_AND_LENGTH(bd);
+       bd_status = in_be32((u32 *)bd);
 
        /* Normal processing. */
        while ((bd_status & T_R) == 0) {
@@ -3813,7 +3802,7 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ)
 
                /* Advance the confirmation BD pointer */
                if (!(bd_status & T_W))
-                       ugeth->confBd[txQ] += UCC_GETH_SIZE_OF_BD;
+                       ugeth->confBd[txQ] += sizeof(struct qe_bd);
                else
                        ugeth->confBd[txQ] = ugeth->p_tx_bd_ring[txQ];
        }
@@ -3823,7 +3812,7 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ)
 #ifdef CONFIG_UGETH_NAPI
 static int ucc_geth_poll(struct net_device *dev, int *budget)
 {
-       ucc_geth_private_t *ugeth = netdev_priv(dev);
+       struct ucc_geth_private *ugeth = netdev_priv(dev);
        int howmany;
        int rx_work_limit = *budget;
        u8 rxQ = 0;
@@ -3844,13 +3833,12 @@ static int ucc_geth_poll(struct net_device *dev, int *budget)
 }
 #endif                         /* CONFIG_UGETH_NAPI */
 
-static irqreturn_t ucc_geth_irq_handler(int irq, void *info,
-                                       struct pt_regs *regs)
+static irqreturn_t ucc_geth_irq_handler(int irq, void *info)
 {
        struct net_device *dev = (struct net_device *)info;
-       ucc_geth_private_t *ugeth = netdev_priv(dev);
-       ucc_fast_private_t *uccf;
-       ucc_geth_info_t *ug_info;
+       struct ucc_geth_private *ugeth = netdev_priv(dev);
+       struct ucc_fast_private *uccf;
+       struct ucc_geth_info *ug_info;
        register u32 ucce = 0;
        register u32 bit_mask = UCCE_RXBF_SINGLE_MASK;
        register u32 tx_mask = UCCE_TXBF_SINGLE_MASK;
@@ -3910,10 +3898,10 @@ static irqreturn_t ucc_geth_irq_handler(int irq, void *info,
        return IRQ_HANDLED;
 }
 
-static irqreturn_t phy_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t phy_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = (struct net_device *)dev_id;
-       ucc_geth_private_t *ugeth = netdev_priv(dev);
+       struct ucc_geth_private *ugeth = netdev_priv(dev);
 
        ugeth_vdbg("%s: IN", __FUNCTION__);
 
@@ -3933,8 +3921,8 @@ static irqreturn_t phy_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 static void ugeth_phy_change(void *data)
 {
        struct net_device *dev = (struct net_device *)data;
-       ucc_geth_private_t *ugeth = netdev_priv(dev);
-       ucc_geth_t *ug_regs;
+       struct ucc_geth_private *ugeth = netdev_priv(dev);
+       struct ucc_geth *ug_regs;
        int result = 0;
 
        ugeth_vdbg("%s: IN", __FUNCTION__);
@@ -3964,7 +3952,7 @@ static void ugeth_phy_change(void *data)
 static void ugeth_phy_timer(unsigned long data)
 {
        struct net_device *dev = (struct net_device *)data;
-       ucc_geth_private_t *ugeth = netdev_priv(dev);
+       struct ucc_geth_private *ugeth = netdev_priv(dev);
 
        schedule_work(&ugeth->tq);
 
@@ -3980,7 +3968,7 @@ static void ugeth_phy_timer(unsigned long data)
 static void ugeth_phy_startup_timer(unsigned long data)
 {
        struct ugeth_mii_info *mii_info = (struct ugeth_mii_info *)data;
-       ucc_geth_private_t *ugeth = netdev_priv(mii_info->dev);
+       struct ucc_geth_private *ugeth = netdev_priv(mii_info->dev);
        static int secondary = UGETH_AN_TIMEOUT;
        int result;
 
@@ -4035,7 +4023,7 @@ static void ugeth_phy_startup_timer(unsigned long data)
 /* Returns 0 for success. */
 static int ucc_geth_open(struct net_device *dev)
 {
-       ucc_geth_private_t *ugeth = netdev_priv(dev);
+       struct ucc_geth_private *ugeth = netdev_priv(dev);
        int err;
 
        ugeth_vdbg("%s: IN", __FUNCTION__);
@@ -4112,7 +4100,7 @@ static int ucc_geth_open(struct net_device *dev)
 /* Stops the kernel queue, and halts the controller */
 static int ucc_geth_close(struct net_device *dev)
 {
-       ucc_geth_private_t *ugeth = netdev_priv(dev);
+       struct ucc_geth_private *ugeth = netdev_priv(dev);
 
        ugeth_vdbg("%s: IN", __FUNCTION__);
 
@@ -4131,30 +4119,53 @@ static int ucc_geth_close(struct net_device *dev)
 
 const struct ethtool_ops ucc_geth_ethtool_ops = { };
 
-static int ucc_geth_probe(struct device *device)
+static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *match)
 {
-       struct platform_device *pdev = to_platform_device(device);
-       struct ucc_geth_platform_data *ugeth_pdata;
+       struct device *device = &ofdev->dev;
+       struct device_node *np = ofdev->node;
        struct net_device *dev = NULL;
        struct ucc_geth_private *ugeth = NULL;
        struct ucc_geth_info *ug_info;
-       int err;
+       struct resource res;
+       struct device_node *phy;
+       int err, ucc_num, phy_interface;
        static int mii_mng_configured = 0;
+       const phandle *ph;
+       const unsigned int *prop;
 
        ugeth_vdbg("%s: IN", __FUNCTION__);
 
-       ugeth_pdata = (struct ucc_geth_platform_data *)pdev->dev.platform_data;
+       prop = get_property(np, "device-id", NULL);
+       ucc_num = *prop - 1;
+       if ((ucc_num < 0) || (ucc_num > 7))
+               return -ENODEV;
+
+       ug_info = &ugeth_info[ucc_num];
+       ug_info->uf_info.ucc_num = ucc_num;
+       prop = get_property(np, "rx-clock", NULL);
+       ug_info->uf_info.rx_clock = *prop;
+       prop = get_property(np, "tx-clock", NULL);
+       ug_info->uf_info.tx_clock = *prop;
+       err = of_address_to_resource(np, 0, &res);
+       if (err)
+               return -EINVAL;
+
+       ug_info->uf_info.regs = res.start;
+       ug_info->uf_info.irq = irq_of_parse_and_map(np, 0);
+
+       ph = get_property(np, "phy-handle", NULL);
+       phy = of_find_node_by_phandle(*ph);
 
-       ug_info = &ugeth_info[pdev->id];
-       ug_info->uf_info.ucc_num = pdev->id;
-       ug_info->uf_info.rx_clock = ugeth_pdata->rx_clock;
-       ug_info->uf_info.tx_clock = ugeth_pdata->tx_clock;
-       ug_info->uf_info.regs = ugeth_pdata->phy_reg_addr;
-       ug_info->uf_info.irq = platform_get_irq(pdev, 0);
-       ug_info->phy_address = ugeth_pdata->phy_id;
-       ug_info->enet_interface = ugeth_pdata->phy_interface;
-       ug_info->board_flags = ugeth_pdata->board_flags;
-       ug_info->phy_interrupt = ugeth_pdata->phy_interrupt;
+       if (phy == NULL)
+               return -ENODEV;
+
+       prop = get_property(phy, "reg", NULL);
+       ug_info->phy_address = *prop;
+       prop = get_property(phy, "interface", NULL);
+       ug_info->enet_interface = *prop;
+       ug_info->phy_interrupt = irq_of_parse_and_map(phy, 0);
+       ug_info->board_flags = (ug_info->phy_interrupt == NO_IRQ)?
+                       0:FSL_UGETH_BRD_HAS_PHY_INTR;
 
        printk(KERN_INFO "ucc_geth: UCC%1d at 0x%8x (irq = %d) \n",
                ug_info->uf_info.ucc_num + 1, ug_info->uf_info.regs,
@@ -4162,12 +4173,44 @@ static int ucc_geth_probe(struct device *device)
 
        if (ug_info == NULL) {
                ugeth_err("%s: [%d] Missing additional data!", __FUNCTION__,
-                         pdev->id);
+                         ucc_num);
                return -ENODEV;
        }
 
+       /* FIXME: Work around for early chip rev.               */
+       /* There's a bug in initial chip rev(s) in the RGMII ac */
+       /* timing.                                              */
+       /* The following compensates by writing to the reserved */
+       /* QE Port Output Hold Registers (CPOH1?).              */
+       prop = get_property(phy, "interface", NULL);
+       phy_interface = *prop;
+       if ((phy_interface == ENET_1000_RGMII) ||
+                       (phy_interface == ENET_100_RGMII) ||
+                       (phy_interface == ENET_10_RGMII)) {
+               struct device_node *soc;
+               phys_addr_t immrbase = -1;
+               u32 *tmp_reg;
+               u32 tmp_val;
+
+               soc = of_find_node_by_type(NULL, "soc");
+               if (soc) {
+                       unsigned int size;
+                       const void *prop = get_property(soc, "reg", &size);
+                       immrbase = of_translate_address(soc, prop);
+                       of_node_put(soc);
+               };
+
+               tmp_reg = (u32 *) ioremap(immrbase + 0x14A8, 0x4);
+               tmp_val = in_be32(tmp_reg);
+               if (ucc_num == 1)
+                       out_be32(tmp_reg, tmp_val | 0x00003000);
+               else if (ucc_num == 2)
+                       out_be32(tmp_reg, tmp_val | 0x0c000000);
+               iounmap(tmp_reg);
+       }
+
        if (!mii_mng_configured) {
-               ucc_set_qe_mux_mii_mng(ug_info->uf_info.ucc_num);
+               ucc_set_qe_mux_mii_mng(ucc_num);
                mii_mng_configured = 1;
        }
 
@@ -4214,13 +4257,14 @@ static int ucc_geth_probe(struct device *device)
 
        ugeth->ug_info = ug_info;
        ugeth->dev = dev;
-       memcpy(dev->dev_addr, ugeth_pdata->mac_addr, 6);
+       memcpy(dev->dev_addr, get_property(np, "mac-address", NULL), 6);
 
        return 0;
 }
 
-static int ucc_geth_remove(struct device *device)
+static int ucc_geth_remove(struct of_device* ofdev)
 {
+       struct device *device = &ofdev->dev;
        struct net_device *dev = dev_get_drvdata(device);
        struct ucc_geth_private *ugeth = netdev_priv(dev);
 
@@ -4231,28 +4275,38 @@ static int ucc_geth_remove(struct device *device)
        return 0;
 }
 
-/* Structure for a device driver */
-static struct device_driver ucc_geth_driver = {
-       .name = DRV_NAME,
-       .bus = &platform_bus_type,
-       .probe = ucc_geth_probe,
-       .remove = ucc_geth_remove,
+static struct of_device_id ucc_geth_match[] = {
+       {
+               .type = "network",
+               .compatible = "ucc_geth",
+       },
+       {},
+};
+
+MODULE_DEVICE_TABLE(of, ucc_geth_match);
+
+static struct of_platform_driver ucc_geth_driver = {
+       .name           = DRV_NAME,
+       .match_table    = ucc_geth_match,
+       .probe          = ucc_geth_probe,
+       .remove         = ucc_geth_remove,
 };
 
 static int __init ucc_geth_init(void)
 {
        int i;
+
        printk(KERN_INFO "ucc_geth: " DRV_DESC "\n");
        for (i = 0; i < 8; i++)
                memcpy(&(ugeth_info[i]), &ugeth_primary_info,
                       sizeof(ugeth_primary_info));
 
-       return driver_register(&ucc_geth_driver);
+       return of_register_driver(&ucc_geth_driver);
 }
 
 static void __exit ucc_geth_exit(void)
 {
-       driver_unregister(&ucc_geth_driver);
+       of_unregister_driver(&ucc_geth_driver);
 }
 
 module_init(ucc_geth_init);
index 005965f5dd9beaa4fb209b50986c3716aad1aede..a66561253593c3a43ac6c6b8727f739c0918b042 100644 (file)
 #define ENET_INIT_PARAM_MAX_ENTRIES_RX  9
 #define ENET_INIT_PARAM_MAX_ENTRIES_TX  8
 
-typedef struct ucc_mii_mng {
+struct ucc_mii_mng {
        u32 miimcfg;            /* MII management configuration reg */
        u32 miimcom;            /* MII management command reg */
        u32 miimadd;            /* MII management address reg */
        u32 miimcon;            /* MII management control reg */
        u32 miimstat;           /* MII management status reg */
        u32 miimind;            /* MII management indication reg */
-} __attribute__ ((packed)) ucc_mii_mng_t;
+} __attribute__ ((packed));
 
-typedef struct ucc_geth {
-       ucc_fast_t uccf;
+struct ucc_geth {
+       struct ucc_fast uccf;
 
        u32 maccfg1;            /* mac configuration reg. 1 */
        u32 maccfg2;            /* mac configuration reg. 2 */
        u32 ipgifg;             /* interframe gap reg.  */
        u32 hafdup;             /* half-duplex reg.  */
        u8 res1[0x10];
-       ucc_mii_mng_t miimng;   /* MII management structure */
+       struct ucc_mii_mng miimng;      /* MII management structure */
        u32 ifctl;              /* interface control reg */
        u32 ifstat;             /* interface statux reg */
        u32 macstnaddr1;        /* mac station address part 1 reg */
@@ -111,7 +111,7 @@ typedef struct ucc_geth {
        u32 scar;               /* Statistics carry register */
        u32 scam;               /* Statistics caryy mask register */
        u8 res5[0x200 - 0x1c4];
-} __attribute__ ((packed)) ucc_geth_t;
+} __attribute__ ((packed));
 
 /* UCC GETH TEMODR Register */
 #define TEMODER_TX_RMON_STATISTICS_ENABLE       0x0100 /* enable Tx statistics
@@ -508,39 +508,39 @@ typedef struct ucc_geth {
 /* UCC GETH UDSR (Data Synchronization Register) */
 #define UDSR_MAGIC                              0x067E
 
-typedef struct ucc_geth_thread_data_tx {
+struct ucc_geth_thread_data_tx {
        u8 res0[104];
-} __attribute__ ((packed)) ucc_geth_thread_data_tx_t;
+} __attribute__ ((packed));
 
-typedef struct ucc_geth_thread_data_rx {
+struct ucc_geth_thread_data_rx {
        u8 res0[40];
-} __attribute__ ((packed)) ucc_geth_thread_data_rx_t;
+} __attribute__ ((packed));
 
 /* Send Queue Queue-Descriptor */
-typedef struct ucc_geth_send_queue_qd {
+struct ucc_geth_send_queue_qd {
        u32 bd_ring_base;       /* pointer to BD ring base address */
        u8 res0[0x8];
        u32 last_bd_completed_address;/* initialize to last entry in BD ring */
        u8 res1[0x30];
-} __attribute__ ((packed)) ucc_geth_send_queue_qd_t;
+} __attribute__ ((packed));
 
-typedef struct ucc_geth_send_queue_mem_region {
-       ucc_geth_send_queue_qd_t sqqd[NUM_TX_QUEUES];
-} __attribute__ ((packed)) ucc_geth_send_queue_mem_region_t;
+struct ucc_geth_send_queue_mem_region {
+       struct ucc_geth_send_queue_qd sqqd[NUM_TX_QUEUES];
+} __attribute__ ((packed));
 
-typedef struct ucc_geth_thread_tx_pram {
+struct ucc_geth_thread_tx_pram {
        u8 res0[64];
-} __attribute__ ((packed)) ucc_geth_thread_tx_pram_t;
+} __attribute__ ((packed));
 
-typedef struct ucc_geth_thread_rx_pram {
+struct ucc_geth_thread_rx_pram {
        u8 res0[128];
-} __attribute__ ((packed)) ucc_geth_thread_rx_pram_t;
+} __attribute__ ((packed));
 
 #define THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING        64
 #define THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING_8      64
 #define THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING_16     96
 
-typedef struct ucc_geth_scheduler {
+struct ucc_geth_scheduler {
        u16 cpucount0;          /* CPU packet counter */
        u16 cpucount1;          /* CPU packet counter */
        u16 cecount0;           /* QE packet counter */
@@ -574,9 +574,9 @@ typedef struct ucc_geth_scheduler {
                                      /**< weight factor for queues   */
        u32 minw;               /* temporary variable handled by QE */
        u8 res1[0x70 - 0x64];
-} __attribute__ ((packed)) ucc_geth_scheduler_t;
+} __attribute__ ((packed));
 
-typedef struct ucc_geth_tx_firmware_statistics_pram {
+struct ucc_geth_tx_firmware_statistics_pram {
        u32 sicoltx;            /* single collision */
        u32 mulcoltx;           /* multiple collision */
        u32 latecoltxfr;        /* late collision */
@@ -596,9 +596,9 @@ typedef struct ucc_geth_tx_firmware_statistics_pram {
                                   and 1518 octets */
        u32 txpktsjumbo;        /* total packets (including bad) between 1024
                                   and MAXLength octets */
-} __attribute__ ((packed)) ucc_geth_tx_firmware_statistics_pram_t;
+} __attribute__ ((packed));
 
-typedef struct ucc_geth_rx_firmware_statistics_pram {
+struct ucc_geth_rx_firmware_statistics_pram {
        u32 frrxfcser;          /* frames with crc error */
        u32 fraligner;          /* frames with alignment error */
        u32 inrangelenrxer;     /* in range length error */
@@ -630,33 +630,33 @@ typedef struct ucc_geth_rx_firmware_statistics_pram {
                                   replaced */
        u32 insertvlan;         /* total frames that had their VLAN tag
                                   inserted */
-} __attribute__ ((packed)) ucc_geth_rx_firmware_statistics_pram_t;
+} __attribute__ ((packed));
 
-typedef struct ucc_geth_rx_interrupt_coalescing_entry {
+struct ucc_geth_rx_interrupt_coalescing_entry {
        u32 interruptcoalescingmaxvalue;        /* interrupt coalescing max
                                                   value */
        u32 interruptcoalescingcounter; /* interrupt coalescing counter,
                                           initialize to
                                           interruptcoalescingmaxvalue */
-} __attribute__ ((packed)) ucc_geth_rx_interrupt_coalescing_entry_t;
+} __attribute__ ((packed));
 
-typedef struct ucc_geth_rx_interrupt_coalescing_table {
-       ucc_geth_rx_interrupt_coalescing_entry_t coalescingentry[NUM_RX_QUEUES];
+struct ucc_geth_rx_interrupt_coalescing_table {
+       struct ucc_geth_rx_interrupt_coalescing_entry coalescingentry[NUM_RX_QUEUES];
                                       /**< interrupt coalescing entry */
-} __attribute__ ((packed)) ucc_geth_rx_interrupt_coalescing_table_t;
+} __attribute__ ((packed));
 
-typedef struct ucc_geth_rx_prefetched_bds {
-       qe_bd_t bd[NUM_BDS_IN_PREFETCHED_BDS];  /* prefetched bd */
-} __attribute__ ((packed)) ucc_geth_rx_prefetched_bds_t;
+struct ucc_geth_rx_prefetched_bds {
+       struct qe_bd bd[NUM_BDS_IN_PREFETCHED_BDS];     /* prefetched bd */
+} __attribute__ ((packed));
 
-typedef struct ucc_geth_rx_bd_queues_entry {
+struct ucc_geth_rx_bd_queues_entry {
        u32 bdbaseptr;          /* BD base pointer */
        u32 bdptr;              /* BD pointer */
        u32 externalbdbaseptr;  /* external BD base pointer */
        u32 externalbdptr;      /* external BD pointer */
-} __attribute__ ((packed)) ucc_geth_rx_bd_queues_entry_t;
+} __attribute__ ((packed));
 
-typedef struct ucc_geth_tx_global_pram {
+struct ucc_geth_tx_global_pram {
        u16 temoder;
        u8 res0[0x38 - 0x02];
        u32 sqptr;              /* a base pointer to send queue memory region */
@@ -670,15 +670,15 @@ typedef struct ucc_geth_tx_global_pram {
        u32 tqptr;              /* a base pointer to the Tx Queues Memory
                                   Region */
        u8 res2[0x80 - 0x74];
-} __attribute__ ((packed)) ucc_geth_tx_global_pram_t;
+} __attribute__ ((packed));
 
 /* structure representing Extended Filtering Global Parameters in PRAM */
-typedef struct ucc_geth_exf_global_pram {
+struct ucc_geth_exf_global_pram {
        u32 l2pcdptr;           /* individual address filter, high */
        u8 res0[0x10 - 0x04];
-} __attribute__ ((packed)) ucc_geth_exf_global_pram_t;
+} __attribute__ ((packed));
 
-typedef struct ucc_geth_rx_global_pram {
+struct ucc_geth_rx_global_pram {
        u32 remoder;            /* ethernet mode reg. */
        u32 rqptr;              /* base pointer to the Rx Queues Memory Region*/
        u32 res0[0x1];
@@ -710,12 +710,12 @@ typedef struct ucc_geth_rx_global_pram {
        u32 exfGlobalParam;     /* base address for extended filtering global
                                   parameters */
        u8 res6[0x100 - 0xC4];  /* Initialize to zero */
-} __attribute__ ((packed)) ucc_geth_rx_global_pram_t;
+} __attribute__ ((packed));
 
 #define GRACEFUL_STOP_ACKNOWLEDGE_RX            0x01
 
 /* structure representing InitEnet command */
-typedef struct ucc_geth_init_pram {
+struct ucc_geth_init_pram {
        u8 resinit1;
        u8 resinit2;
        u8 resinit3;
@@ -729,7 +729,7 @@ typedef struct ucc_geth_init_pram {
        u32 txglobal;           /* tx global */
        u32 txthread[ENET_INIT_PARAM_MAX_ENTRIES_TX];   /* tx threads */
        u8 res3[0x1];
-} __attribute__ ((packed)) ucc_geth_init_pram_t;
+} __attribute__ ((packed));
 
 #define ENET_INIT_PARAM_RGF_SHIFT               (32 - 4)
 #define ENET_INIT_PARAM_TGF_SHIFT               (32 - 8)
@@ -746,27 +746,27 @@ typedef struct ucc_geth_init_pram {
 #define ENET_INIT_PARAM_MAGIC_RES_INIT5         0x0400
 
 /* structure representing 82xx Address Filtering Enet Address in PRAM */
-typedef struct ucc_geth_82xx_enet_address {
+struct ucc_geth_82xx_enet_address {
        u8 res1[0x2];
        u16 h;                  /* address (MSB) */
        u16 m;                  /* address */
        u16 l;                  /* address (LSB) */
-} __attribute__ ((packed)) ucc_geth_82xx_enet_address_t;
+} __attribute__ ((packed));
 
 /* structure representing 82xx Address Filtering PRAM */
-typedef struct ucc_geth_82xx_address_filtering_pram {
+struct ucc_geth_82xx_address_filtering_pram {
        u32 iaddr_h;            /* individual address filter, high */
        u32 iaddr_l;            /* individual address filter, low */
        u32 gaddr_h;            /* group address filter, high */
        u32 gaddr_l;            /* group address filter, low */
-       ucc_geth_82xx_enet_address_t taddr;
-       ucc_geth_82xx_enet_address_t paddr[NUM_OF_PADDRS];
+       struct ucc_geth_82xx_enet_address taddr;
+       struct ucc_geth_82xx_enet_address paddr[NUM_OF_PADDRS];
        u8 res0[0x40 - 0x38];
-} __attribute__ ((packed)) ucc_geth_82xx_address_filtering_pram_t;
+} __attribute__ ((packed));
 
 /* GETH Tx firmware statistics structure, used when calling
    UCC_GETH_GetStatistics. */
-typedef struct ucc_geth_tx_firmware_statistics {
+struct ucc_geth_tx_firmware_statistics {
        u32 sicoltx;            /* single collision */
        u32 mulcoltx;           /* multiple collision */
        u32 latecoltxfr;        /* late collision */
@@ -786,11 +786,11 @@ typedef struct ucc_geth_tx_firmware_statistics {
                                   and 1518 octets */
        u32 txpktsjumbo;        /* total packets (including bad) between 1024
                                   and MAXLength octets */
-} __attribute__ ((packed)) ucc_geth_tx_firmware_statistics_t;
+} __attribute__ ((packed));
 
 /* GETH Rx firmware statistics structure, used when calling
    UCC_GETH_GetStatistics. */
-typedef struct ucc_geth_rx_firmware_statistics {
+struct ucc_geth_rx_firmware_statistics {
        u32 frrxfcser;          /* frames with crc error */
        u32 fraligner;          /* frames with alignment error */
        u32 inrangelenrxer;     /* in range length error */
@@ -822,11 +822,11 @@ typedef struct ucc_geth_rx_firmware_statistics {
                                   replaced */
        u32 insertvlan;         /* total frames that had their VLAN tag
                                   inserted */
-} __attribute__ ((packed)) ucc_geth_rx_firmware_statistics_t;
+} __attribute__ ((packed));
 
 /* GETH hardware statistics structure, used when calling
    UCC_GETH_GetStatistics. */
-typedef struct ucc_geth_hardware_statistics {
+struct ucc_geth_hardware_statistics {
        u32 tx64;               /* Total number of frames (including bad
                                   frames) transmitted that were exactly of the
                                   minimal length (64 for un tagged, 68 for
@@ -871,7 +871,7 @@ typedef struct ucc_geth_hardware_statistics {
        u32 rbca;               /* Total number of frames received succesfully
                                   that had destination address equal to the
                                   broadcast address */
-} __attribute__ ((packed)) ucc_geth_hardware_statistics_t;
+} __attribute__ ((packed));
 
 /* UCC GETH Tx errors returned via TxConf callback */
 #define TX_ERRORS_DEF      0x0200
@@ -1013,21 +1013,21 @@ typedef struct ucc_geth_hardware_statistics {
                                (MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_112)
 
 /* Ethernet speed */
-typedef enum enet_speed {
+enum enet_speed {
        ENET_SPEED_10BT,        /* 10 Base T */
        ENET_SPEED_100BT,       /* 100 Base T */
        ENET_SPEED_1000BT       /* 1000 Base T */
-} enet_speed_e;
+};
 
 /* Ethernet Address Type. */
-typedef enum enet_addr_type {
+enum enet_addr_type {
        ENET_ADDR_TYPE_INDIVIDUAL,
        ENET_ADDR_TYPE_GROUP,
        ENET_ADDR_TYPE_BROADCAST
-} enet_addr_type_e;
+};
 
 /* TBI / MII Set Register */
-typedef enum enet_tbi_mii_reg {
+enum enet_tbi_mii_reg {
        ENET_TBI_MII_CR = 0x00, /* Control (CR ) */
        ENET_TBI_MII_SR = 0x01, /* Status (SR ) */
        ENET_TBI_MII_ANA = 0x04,        /* AN advertisement (ANA ) */
@@ -1040,10 +1040,10 @@ typedef enum enet_tbi_mii_reg {
        ENET_TBI_MII_EXST = 0x0F,       /* Extended status (EXST ) */
        ENET_TBI_MII_JD = 0x10, /* Jitter diagnostics (JD ) */
        ENET_TBI_MII_TBICON = 0x11      /* TBI control (TBICON ) */
-} enet_tbi_mii_reg_e;
+};
 
 /* UCC GETH 82xx Ethernet Address Recognition Location */
-typedef enum ucc_geth_enet_address_recognition_location {
+enum ucc_geth_enet_address_recognition_location {
        UCC_GETH_ENET_ADDRESS_RECOGNITION_LOCATION_STATION_ADDRESS,/* station
                                                                      address */
        UCC_GETH_ENET_ADDRESS_RECOGNITION_LOCATION_PADDR_FIRST, /* additional
@@ -1065,10 +1065,10 @@ typedef enum ucc_geth_enet_address_recognition_location {
        UCC_GETH_ENET_ADDRESS_RECOGNITION_LOCATION_GROUP_HASH,  /* group hash */
        UCC_GETH_ENET_ADDRESS_RECOGNITION_LOCATION_INDIVIDUAL_HASH /* individual
                                                                      hash */
-} ucc_geth_enet_address_recognition_location_e;
+};
 
 /* UCC GETH vlan operation tagged */
-typedef enum ucc_geth_vlan_operation_tagged {
+enum ucc_geth_vlan_operation_tagged {
        UCC_GETH_VLAN_OPERATION_TAGGED_NOP = 0x0,       /* Tagged - nop */
        UCC_GETH_VLAN_OPERATION_TAGGED_REPLACE_VID_PORTION_OF_Q_TAG
                = 0x1,  /* Tagged - replace vid portion of q tag */
@@ -1076,18 +1076,18 @@ typedef enum ucc_geth_vlan_operation_tagged {
                = 0x2,  /* Tagged - if vid0 replace vid with default value  */
        UCC_GETH_VLAN_OPERATION_TAGGED_EXTRACT_Q_TAG_FROM_FRAME
                = 0x3   /* Tagged - extract q tag from frame */
-} ucc_geth_vlan_operation_tagged_e;
+};
 
 /* UCC GETH vlan operation non-tagged */
-typedef enum ucc_geth_vlan_operation_non_tagged {
+enum ucc_geth_vlan_operation_non_tagged {
        UCC_GETH_VLAN_OPERATION_NON_TAGGED_NOP = 0x0,   /* Non tagged - nop */
        UCC_GETH_VLAN_OPERATION_NON_TAGGED_Q_TAG_INSERT = 0x1   /* Non tagged -
                                                                   q tag insert
                                                                 */
-} ucc_geth_vlan_operation_non_tagged_e;
+};
 
 /* UCC GETH Rx Quality of Service Mode */
-typedef enum ucc_geth_qos_mode {
+enum ucc_geth_qos_mode {
        UCC_GETH_QOS_MODE_DEFAULT = 0x0,        /* default queue */
        UCC_GETH_QOS_MODE_QUEUE_NUM_FROM_L2_CRITERIA = 0x1,     /* queue
                                                                   determined
@@ -1097,11 +1097,11 @@ typedef enum ucc_geth_qos_mode {
                                                                   determined
                                                                   by L3
                                                                   criteria */
-} ucc_geth_qos_mode_e;
+};
 
 /* UCC GETH Statistics Gathering Mode - These are bit flags, 'or' them together
    for combined functionality */
-typedef enum ucc_geth_statistics_gathering_mode {
+enum ucc_geth_statistics_gathering_mode {
        UCC_GETH_STATISTICS_GATHERING_MODE_NONE = 0x00000000,   /* No
                                                                   statistics
                                                                   gathering */
@@ -1122,10 +1122,10 @@ typedef enum ucc_geth_statistics_gathering_mode {
                                                                      statistics
                                                                      gathering
                                                                    */
-} ucc_geth_statistics_gathering_mode_e;
+};
 
 /* UCC GETH Pad and CRC Mode - Note, Padding without CRC is not possible */
-typedef enum ucc_geth_maccfg2_pad_and_crc_mode {
+enum ucc_geth_maccfg2_pad_and_crc_mode {
        UCC_GETH_PAD_AND_CRC_MODE_NONE
                = MACCFG2_PAD_AND_CRC_MODE_NONE,        /* Neither Padding
                                                           short frames
@@ -1135,61 +1135,59 @@ typedef enum ucc_geth_maccfg2_pad_and_crc_mode {
                                                           CRC only */
        UCC_GETH_PAD_AND_CRC_MODE_PAD_AND_CRC =
            MACCFG2_PAD_AND_CRC_MODE_PAD_AND_CRC
-} ucc_geth_maccfg2_pad_and_crc_mode_e;
+};
 
 /* UCC GETH upsmr Flow Control Mode */
-typedef enum ucc_geth_flow_control_mode {
+enum ucc_geth_flow_control_mode {
        UPSMR_AUTOMATIC_FLOW_CONTROL_MODE_NONE = 0x00000000,    /* No automatic
                                                                   flow control
                                                                 */
        UPSMR_AUTOMATIC_FLOW_CONTROL_MODE_PAUSE_WHEN_EMERGENCY
                = 0x00004000    /* Send pause frame when RxFIFO reaches its
                                   emergency threshold */
-} ucc_geth_flow_control_mode_e;
+};
 
 /* UCC GETH number of threads */
-typedef enum ucc_geth_num_of_threads {
+enum ucc_geth_num_of_threads {
        UCC_GETH_NUM_OF_THREADS_1 = 0x1,        /* 1 */
        UCC_GETH_NUM_OF_THREADS_2 = 0x2,        /* 2 */
        UCC_GETH_NUM_OF_THREADS_4 = 0x0,        /* 4 */
        UCC_GETH_NUM_OF_THREADS_6 = 0x3,        /* 6 */
        UCC_GETH_NUM_OF_THREADS_8 = 0x4 /* 8 */
-} ucc_geth_num_of_threads_e;
+};
 
 /* UCC GETH number of station addresses */
-typedef enum ucc_geth_num_of_station_addresses {
+enum ucc_geth_num_of_station_addresses {
        UCC_GETH_NUM_OF_STATION_ADDRESSES_1,    /* 1 */
        UCC_GETH_NUM_OF_STATION_ADDRESSES_5     /* 5 */
-} ucc_geth_num_of_station_addresses_e;
-
-typedef u8 enet_addr_t[ENET_NUM_OCTETS_PER_ADDRESS];
+};
 
 /* UCC GETH 82xx Ethernet Address Container */
-typedef struct enet_addr_container {
-       enet_addr_t address;    /* ethernet address */
-       ucc_geth_enet_address_recognition_location_e location;  /* location in
+struct enet_addr_container {
+       u8 address[ENET_NUM_OCTETS_PER_ADDRESS];        /* ethernet address */
+       enum ucc_geth_enet_address_recognition_location location;       /* location in
                                                                   82xx address
                                                                   recognition
                                                                   hardware */
        struct list_head node;
-} enet_addr_container_t;
+};
 
-#define ENET_ADDR_CONT_ENTRY(ptr) list_entry(ptr, enet_addr_container_t, node)
+#define ENET_ADDR_CONT_ENTRY(ptr) list_entry(ptr, struct enet_addr_container, node)
 
 /* UCC GETH Termination Action Descriptor (TAD) structure. */
-typedef struct ucc_geth_tad_params {
+struct ucc_geth_tad_params {
        int rx_non_dynamic_extended_features_mode;
        int reject_frame;
-       ucc_geth_vlan_operation_tagged_e vtag_op;
-       ucc_geth_vlan_operation_non_tagged_e vnontag_op;
-       ucc_geth_qos_mode_e rqos;
+       enum ucc_geth_vlan_operation_tagged vtag_op;
+       enum ucc_geth_vlan_operation_non_tagged vnontag_op;
+       enum ucc_geth_qos_mode rqos;
        u8 vpri;
        u16 vid;
-} ucc_geth_tad_params_t;
+};
 
 /* GETH protocol initialization structure */
-typedef struct ucc_geth_info {
-       ucc_fast_info_t uf_info;
+struct ucc_geth_info {
+       struct ucc_fast_info uf_info;
        u8 numQueuesTx;
        u8 numQueuesRx;
        int ipCheckSumCheck;
@@ -1251,51 +1249,51 @@ typedef struct ucc_geth_info {
        u8 iphoffset[TX_IP_OFFSET_ENTRY_MAX];
        u16 bdRingLenTx[NUM_TX_QUEUES];
        u16 bdRingLenRx[NUM_RX_QUEUES];
-       enet_interface_e enet_interface;
-       ucc_geth_num_of_station_addresses_e numStationAddresses;
-        qe_fltr_largest_external_tbl_lookup_key_size_e
+       enum enet_interface enet_interface;
+       enum ucc_geth_num_of_station_addresses numStationAddresses;
+       enum qe_fltr_largest_external_tbl_lookup_key_size
            largestexternallookupkeysize;
-       ucc_geth_statistics_gathering_mode_e statisticsMode;
-       ucc_geth_vlan_operation_tagged_e vlanOperationTagged;
-       ucc_geth_vlan_operation_non_tagged_e vlanOperationNonTagged;
-       ucc_geth_qos_mode_e rxQoSMode;
-       ucc_geth_flow_control_mode_e aufc;
-       ucc_geth_maccfg2_pad_and_crc_mode_e padAndCrc;
-       ucc_geth_num_of_threads_e numThreadsTx;
-       ucc_geth_num_of_threads_e numThreadsRx;
-       qe_risc_allocation_e riscTx;
-       qe_risc_allocation_e riscRx;
-} ucc_geth_info_t;
+       enum ucc_geth_statistics_gathering_mode statisticsMode;
+       enum ucc_geth_vlan_operation_tagged vlanOperationTagged;
+       enum ucc_geth_vlan_operation_non_tagged vlanOperationNonTagged;
+       enum ucc_geth_qos_mode rxQoSMode;
+       enum ucc_geth_flow_control_mode aufc;
+       enum ucc_geth_maccfg2_pad_and_crc_mode padAndCrc;
+       enum ucc_geth_num_of_threads numThreadsTx;
+       enum ucc_geth_num_of_threads numThreadsRx;
+       enum qe_risc_allocation riscTx;
+       enum qe_risc_allocation riscRx;
+};
 
 /* structure representing UCC GETH */
-typedef struct ucc_geth_private {
-       ucc_geth_info_t *ug_info;
-       ucc_fast_private_t *uccf;
+struct ucc_geth_private {
+       struct ucc_geth_info *ug_info;
+       struct ucc_fast_private *uccf;
        struct net_device *dev;
        struct net_device_stats stats;  /* linux network statistics */
-       ucc_geth_t *ug_regs;
-       ucc_geth_init_pram_t *p_init_enet_param_shadow;
-       ucc_geth_exf_global_pram_t *p_exf_glbl_param;
+       struct ucc_geth *ug_regs;
+       struct ucc_geth_init_pram *p_init_enet_param_shadow;
+       struct ucc_geth_exf_global_pram *p_exf_glbl_param;
        u32 exf_glbl_param_offset;
-       ucc_geth_rx_global_pram_t *p_rx_glbl_pram;
+       struct ucc_geth_rx_global_pram *p_rx_glbl_pram;
        u32 rx_glbl_pram_offset;
-       ucc_geth_tx_global_pram_t *p_tx_glbl_pram;
+       struct ucc_geth_tx_global_pram *p_tx_glbl_pram;
        u32 tx_glbl_pram_offset;
-       ucc_geth_send_queue_mem_region_t *p_send_q_mem_reg;
+       struct ucc_geth_send_queue_mem_region *p_send_q_mem_reg;
        u32 send_q_mem_reg_offset;
-       ucc_geth_thread_data_tx_t *p_thread_data_tx;
+       struct ucc_geth_thread_data_tx *p_thread_data_tx;
        u32 thread_dat_tx_offset;
-       ucc_geth_thread_data_rx_t *p_thread_data_rx;
+       struct ucc_geth_thread_data_rx *p_thread_data_rx;
        u32 thread_dat_rx_offset;
-       ucc_geth_scheduler_t *p_scheduler;
+       struct ucc_geth_scheduler *p_scheduler;
        u32 scheduler_offset;
-       ucc_geth_tx_firmware_statistics_pram_t *p_tx_fw_statistics_pram;
+       struct ucc_geth_tx_firmware_statistics_pram *p_tx_fw_statistics_pram;
        u32 tx_fw_statistics_pram_offset;
-       ucc_geth_rx_firmware_statistics_pram_t *p_rx_fw_statistics_pram;
+       struct ucc_geth_rx_firmware_statistics_pram *p_rx_fw_statistics_pram;
        u32 rx_fw_statistics_pram_offset;
-       ucc_geth_rx_interrupt_coalescing_table_t *p_rx_irq_coalescing_tbl;
+       struct ucc_geth_rx_interrupt_coalescing_table *p_rx_irq_coalescing_tbl;
        u32 rx_irq_coalescing_tbl_offset;
-       ucc_geth_rx_bd_queues_entry_t *p_rx_bd_qs_tbl;
+       struct ucc_geth_rx_bd_queues_entry *p_rx_bd_qs_tbl;
        u32 rx_bd_qs_tbl_offset;
        u8 *p_tx_bd_ring[NUM_TX_QUEUES];
        u32 tx_bd_ring_offset[NUM_TX_QUEUES];
@@ -1308,7 +1306,7 @@ typedef struct ucc_geth_private {
        u16 cpucount[NUM_TX_QUEUES];
        volatile u16 *p_cpucount[NUM_TX_QUEUES];
        int indAddrRegUsed[NUM_OF_PADDRS];
-       enet_addr_t paddr[NUM_OF_PADDRS];
+       u8 paddr[NUM_OF_PADDRS][ENET_NUM_OCTETS_PER_ADDRESS];   /* ethernet address */
        u8 numGroupAddrInHash;
        u8 numIndAddrInHash;
        u8 numIndAddrInReg;
@@ -1334,6 +1332,6 @@ typedef struct ucc_geth_private {
        int oldspeed;
        int oldduplex;
        int oldlink;
-} ucc_geth_private_t;
+};
 
 #endif                         /* __UCC_GETH_H__ */
index 67260eb3188af2d771e1966af647a118b789fa1d..5360ec05eaa331b256f199714caba1df0b2c60e8 100644 (file)
@@ -42,7 +42,6 @@
 
 #include "ucc_geth.h"
 #include "ucc_geth_phy.h"
-#include <platforms/83xx/mpc8360e_pb.h>
 
 #define ugphy_printk(level, format, arg...)  \
         printk(level format "\n", ## arg)
@@ -72,16 +71,14 @@ static int genmii_read_status(struct ugeth_mii_info *mii_info);
 u16 phy_read(struct ugeth_mii_info *mii_info, u16 regnum);
 void phy_write(struct ugeth_mii_info *mii_info, u16 regnum, u16 val);
 
-static u8 *bcsr_regs = NULL;
-
 /* Write value to the PHY for this device to the register at regnum, */
 /* waiting until the write is done before it returns.  All PHY */
 /* configuration has to be done through the TSEC1 MIIM regs */
 void write_phy_reg(struct net_device *dev, int mii_id, int regnum, int value)
 {
-       ucc_geth_private_t *ugeth = netdev_priv(dev);
-       ucc_mii_mng_t *mii_regs;
-       enet_tbi_mii_reg_e mii_reg = (enet_tbi_mii_reg_e) regnum;
+       struct ucc_geth_private *ugeth = netdev_priv(dev);
+       struct ucc_mii_mng *mii_regs;
+       enum enet_tbi_mii_reg mii_reg = (enum enet_tbi_mii_reg) regnum;
        u32 tmp_reg;
 
        ugphy_vdbg("%s: IN", __FUNCTION__);
@@ -116,9 +113,9 @@ void write_phy_reg(struct net_device *dev, int mii_id, int regnum, int value)
 /* configuration has to be done through the TSEC1 MIIM regs */
 int read_phy_reg(struct net_device *dev, int mii_id, int regnum)
 {
-       ucc_geth_private_t *ugeth = netdev_priv(dev);
-       ucc_mii_mng_t *mii_regs;
-       enet_tbi_mii_reg_e mii_reg = (enet_tbi_mii_reg_e) regnum;
+       struct ucc_geth_private *ugeth = netdev_priv(dev);
+       struct ucc_mii_mng *mii_regs;
+       enum enet_tbi_mii_reg mii_reg = (enum enet_tbi_mii_reg) regnum;
        u32 tmp_reg;
        u16 value;
 
@@ -634,11 +631,6 @@ static void dm9161_close(struct ugeth_mii_info *mii_info)
 
 static int dm9161_ack_interrupt(struct ugeth_mii_info *mii_info)
 {
-/* FIXME: This lines are for BUG fixing in the mpc8325.
-Remove this from here when it's fixed */
-       if (bcsr_regs == NULL)
-               bcsr_regs = (u8 *) ioremap(BCSR_PHYS_ADDR, BCSR_SIZE);
-       bcsr_regs[14] |= 0x40;
        ugphy_vdbg("%s: IN", __FUNCTION__);
 
        /* Clear the interrupts by reading the reg */
@@ -650,12 +642,6 @@ Remove this from here when it's fixed */
 
 static int dm9161_config_intr(struct ugeth_mii_info *mii_info)
 {
-/* FIXME: This lines are for BUG fixing in the mpc8325.
-Remove this from here when it's fixed */
-       if (bcsr_regs == NULL) {
-               bcsr_regs = (u8 *) ioremap(BCSR_PHYS_ADDR, BCSR_SIZE);
-               bcsr_regs[14] &= ~0x40;
-       }
        ugphy_vdbg("%s: IN", __FUNCTION__);
 
        if (mii_info->interrupts == MII_INTERRUPT_ENABLED)
index 2f98b8f1bb0ad16c84af7c07ef5b136f9ae1d6c2..f5740783670ff540e553fd0c23cc54a3603ba8a3 100644 (file)
@@ -126,7 +126,7 @@ struct ugeth_mii_info {
        /* And management functions */
        struct phy_info *phyinfo;
 
-       ucc_mii_mng_t *mii_regs;
+       struct ucc_mii_mng *mii_regs;
 
        /* forced speed & duplex (no autoneg)
         * partner speed & duplex & pause (autoneg)
index cbebf1b96e9dd44954f24c031ea140d92ef280b6..ebbda1d8f542539891087086855107a829e6e759 100644 (file)
@@ -404,7 +404,7 @@ static void mdio_write(struct net_device *dev, int phy_id, int location, int val
 static int  rhine_open(struct net_device *dev);
 static void rhine_tx_timeout(struct net_device *dev);
 static int  rhine_start_tx(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t rhine_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
+static irqreturn_t rhine_interrupt(int irq, void *dev_instance);
 static void rhine_tx(struct net_device *dev);
 static int rhine_rx(struct net_device *dev, int limit);
 static void rhine_error(struct net_device *dev, int intr_status);
@@ -569,7 +569,7 @@ static void __devinit rhine_reload_eeprom(long pioaddr, struct net_device *dev)
 static void rhine_poll(struct net_device *dev)
 {
        disable_irq(dev->irq);
-       rhine_interrupt(dev->irq, (void *)dev, NULL);
+       rhine_interrupt(dev->irq, (void *)dev);
        enable_irq(dev->irq);
 }
 #endif
@@ -1290,7 +1290,7 @@ static int rhine_start_tx(struct sk_buff *skb, struct net_device *dev)
 
 /* The interrupt handler does all of the Rx thread work and cleans up
    after the Tx thread. */
-static irqreturn_t rhine_interrupt(int irq, void *dev_instance, struct pt_regs *rgs)
+static irqreturn_t rhine_interrupt(int irq, void *dev_instance)
 {
        struct net_device *dev = dev_instance;
        struct rhine_private *rp = netdev_priv(dev);
index 7d8808ce541f25b6f8615211e3a1f38a54c9c006..74f894795a1b5ed154d8821b1a16ecb44d5124eb 100644 (file)
@@ -236,7 +236,7 @@ static void velocity_print_info(struct velocity_info *vptr);
 static int velocity_open(struct net_device *dev);
 static int velocity_change_mtu(struct net_device *dev, int mtu);
 static int velocity_xmit(struct sk_buff *skb, struct net_device *dev);
-static int velocity_intr(int irq, void *dev_instance, struct pt_regs *regs);
+static int velocity_intr(int irq, void *dev_instance);
 static void velocity_set_multi(struct net_device *dev);
 static struct net_device_stats *velocity_get_stats(struct net_device *dev);
 static int velocity_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
@@ -2036,7 +2036,6 @@ static int velocity_xmit(struct sk_buff *skb, struct net_device *dev)
  *     velocity_intr           -       interrupt callback
  *     @irq: interrupt number
  *     @dev_instance: interrupting device
- *     @pt_regs: CPU register state at interrupt
  *
  *     Called whenever an interrupt is generated by the velocity
  *     adapter IRQ line. We may not be the source of the interrupt
@@ -2044,7 +2043,7 @@ static int velocity_xmit(struct sk_buff *skb, struct net_device *dev)
  *     efficiently as possible.
  */
 
-static int velocity_intr(int irq, void *dev_instance, struct pt_regs *regs)
+static int velocity_intr(int irq, void *dev_instance)
 {
        struct net_device *dev = dev_instance;
        struct velocity_info *vptr = netdev_priv(dev);
index 1f95b4864ea19e381031b379377711642a7996c5..e1bf8b93f9584e624315ce79144db11599ee6bb8 100644 (file)
@@ -345,7 +345,7 @@ static void put_driver_status(struct cosa_data *cosa);
 static void put_driver_status_nolock(struct cosa_data *cosa);
 
 /* Interrupt handling */
-static irqreturn_t cosa_interrupt(int irq, void *cosa, struct pt_regs *regs);
+static irqreturn_t cosa_interrupt(int irq, void *cosa);
 
 /* I/O ops debugging */
 #ifdef DEBUG_IO
@@ -1972,7 +1972,7 @@ out:
        spin_unlock_irqrestore(&cosa->lock, flags);
 }
 
-static irqreturn_t cosa_interrupt(int irq, void *cosa_, struct pt_regs *regs)
+static irqreturn_t cosa_interrupt(int irq, void *cosa_)
 {
        unsigned status;
        int count = 0;
index a5e7ce1bd16af46b3b9425a07ad8136f05c6aae7..6e5f1c89851713f12ce45aaab040f36ca406d93d 100644 (file)
@@ -74,7 +74,7 @@ static int cycx_wan_setup(struct wan_device *wandev, wandev_conf_t *conf);
 static int cycx_wan_shutdown(struct wan_device *wandev);
 
 /* Miscellaneous functions */
-static irqreturn_t cycx_isr(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t cycx_isr(int irq, void *dev_id);
 
 /* Global Data
  * Note: All data must be explicitly initialized!!!
@@ -301,11 +301,11 @@ out:      return ret;
  * o acknowledge Cyclom 2X hardware interrupt.
  * o call protocol-specific interrupt service routine, if any.
  */
-static irqreturn_t cycx_isr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t cycx_isr(int irq, void *dev_id)
 {
-       struct cycx_device *card = (struct cycx_device *)dev_id;
+       struct cycx_device *card = dev_id;
 
-       if (!card || card->wandev.state == WAN_UNCONFIGURED)
+       if (card->wandev.state == WAN_UNCONFIGURED)
                goto out;
 
        if (card->in_isr) {
index af4d4155905bfc70e2aa9c72d84befcb9d624069..25021a7992a9f91bc436417403c40adb374ec13d 100644 (file)
@@ -365,7 +365,7 @@ static int dscc4_init_ring(struct net_device *);
 static void dscc4_release_ring(struct dscc4_dev_priv *);
 static void dscc4_timer(unsigned long);
 static void dscc4_tx_timeout(struct net_device *);
-static irqreturn_t dscc4_irq(int irq, void *dev_id, struct pt_regs *ptregs);
+static irqreturn_t dscc4_irq(int irq, void *dev_id);
 static int dscc4_hdlc_attach(struct net_device *, unsigned short, unsigned short);
 static int dscc4_set_iface(struct dscc4_dev_priv *, struct net_device *);
 #ifdef DSCC4_POLLING
@@ -1476,7 +1476,7 @@ static int dscc4_set_iface(struct dscc4_dev_priv *dpriv, struct net_device *dev)
        return ret;
 }
 
-static irqreturn_t dscc4_irq(int irq, void *token, struct pt_regs *ptregs)
+static irqreturn_t dscc4_irq(int irq, void *token)
 {
        struct dscc4_dev_priv *root = token;
        struct dscc4_pci_priv *priv;
index 564351aafa4166de7a1b087a09339df7ad001eb4..c45d6a83339d187e6c999427a1d42573e6e7f039 100644 (file)
@@ -1498,7 +1498,7 @@ do_bottom_half_rx(struct fst_card_info *card)
  *      Dev_id is our fst_card_info pointer
  */
 static irqreturn_t
-fst_intr(int irq, void *dev_id, struct pt_regs *regs)
+fst_intr(int irq, void *dev_id)
 {
        struct fst_card_info *card;
        struct fst_port_info *port;
index dce2bb317b82bad854f880996c74345d3076a853..8d0a1f2f00e506d55b6166a58507b7cee1002aaa 100644 (file)
@@ -424,7 +424,7 @@ static inline void sca_tx_intr(port_t *port)
 
 
 
-static irqreturn_t sca_intr(int irq, void* dev_id, struct pt_regs *regs)
+static irqreturn_t sca_intr(int irq, void* dev_id)
 {
        card_t *card = dev_id;
        int i;
index 7b5d81deb0281be717b08377e39d4f19fd39e199..2b54f1bc3a0d3bd18d3ee1cd0e47e5483573788b 100644 (file)
@@ -100,7 +100,7 @@ static int lmc_rx (struct net_device *dev);
 static int lmc_open(struct net_device *dev);
 static int lmc_close(struct net_device *dev);
 static struct net_device_stats *lmc_get_stats(struct net_device *dev);
-static irqreturn_t lmc_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
+static irqreturn_t lmc_interrupt(int irq, void *dev_instance);
 static void lmc_initcsrs(lmc_softc_t * const sc, lmc_csrptr_t csr_base, size_t csr_size);
 static void lmc_softreset(lmc_softc_t * const);
 static void lmc_running_reset(struct net_device *dev);
@@ -1273,7 +1273,7 @@ static int lmc_ifdown (struct net_device *dev) /*fold00*/
 /* Interrupt handling routine.  This will take an incoming packet, or clean
  * up after a trasmit.
  */
-static irqreturn_t lmc_interrupt (int irq, void *dev_instance, struct pt_regs *regs) /*fold00*/
+static irqreturn_t lmc_interrupt (int irq, void *dev_instance) /*fold00*/
 {
     struct net_device *dev = (struct net_device *) dev_instance;
     lmc_softc_t *sc;
index 8d9b959bf15bd12eb62db63f8c58af437b91f042..36d1c3ff7078d28c91827e5af3d99644df09c0e0 100644 (file)
@@ -284,7 +284,7 @@ static void rx_dma_buf_pt_init(pc300_t *, int);
 static void rx_dma_buf_init(pc300_t *, int);
 static void tx_dma_buf_check(pc300_t *, int);
 static void rx_dma_buf_check(pc300_t *, int);
-static irqreturn_t cpc_intr(int, void *, struct pt_regs *);
+static irqreturn_t cpc_intr(int, void *);
 static struct net_device_stats *cpc_get_stats(struct net_device *);
 static int clock_rate_calc(uclong, uclong, int *);
 static uclong detect_ram(pc300_t *);
@@ -2363,7 +2363,7 @@ static void falc_intr(pc300_t * card)
        }
 }
 
-static irqreturn_t cpc_intr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t cpc_intr(int irq, void *dev_id)
 {
        pc300_t *card;
        volatile ucchar plx_status;
@@ -2867,7 +2867,6 @@ static int ch_config(pc300dev_t * d)
        uclong clktype = chan->conf.phys_settings.clock_type;
        ucshort encoding = chan->conf.proto_settings.encoding;
        ucshort parity = chan->conf.proto_settings.parity;   
-       int tmc, br;
        ucchar md0, md2;
     
        /* Reset the channel */
@@ -2940,8 +2939,12 @@ static int ch_config(pc300dev_t * d)
                case PC300_RSV:
                case PC300_X21:
                        if (clktype == CLOCK_INT || clktype == CLOCK_TXINT) {
+                               int tmc, br;
+
                                /* Calculate the clkrate parameters */
                                tmc = clock_rate_calc(clkrate, card->hw.clock, &br);
+                               if (tmc < 0)
+                                       return -EIO;
                                cpc_writeb(scabase + M_REG(TMCT, ch), tmc);
                                cpc_writeb(scabase + M_REG(TXS, ch),
                                           (TXS_DTRXC | TXS_IBRG | br));
@@ -3097,14 +3100,16 @@ static int cpc_attach(struct net_device *dev, unsigned short encoding,
        return 0;
 }
 
-static void cpc_opench(pc300dev_t * d)
+static int cpc_opench(pc300dev_t * d)
 {
        pc300ch_t *chan = (pc300ch_t *) d->chan;
        pc300_t *card = (pc300_t *) chan->card;
-       int ch = chan->channel;
+       int ch = chan->channel, rc;
        void __iomem *scabase = card->hw.scabase;
 
-       ch_config(d);
+       rc = ch_config(d);
+       if (rc)
+               return rc;
 
        rx_config(d);
 
@@ -3113,6 +3118,8 @@ static void cpc_opench(pc300dev_t * d)
        /* Assert RTS and DTR */
        cpc_writeb(scabase + M_REG(CTL, ch),
                   cpc_readb(scabase + M_REG(CTL, ch)) & ~(CTL_RTS | CTL_DTR));
+
+       return 0;
 }
 
 static void cpc_closech(pc300dev_t * d)
@@ -3168,9 +3175,16 @@ int cpc_open(struct net_device *dev)
        }
 
        sprintf(ifr.ifr_name, "%s", dev->name);
-       cpc_opench(d);
+       result = cpc_opench(d);
+       if (result)
+               goto err_out;
+
        netif_start_queue(dev);
        return 0;
+
+err_out:
+       hdlc_close(dev);
+       return result;
 }
 
 static int cpc_close(struct net_device *dev)
index fc75bec19029d6372c65a48d0a9cda92cb1a15bb..fc5c0c611ffd4a79f8d1b358fb8b0e8a14ba8713 100644 (file)
@@ -119,7 +119,7 @@ static int  sbni_ioctl( struct net_device *, struct ifreq *, int );
 static struct net_device_stats  *sbni_get_stats( struct net_device * );
 static void  set_multicast_list( struct net_device * );
 
-static irqreturn_t sbni_interrupt( int, void *, struct pt_regs * );
+static irqreturn_t sbni_interrupt( int, void * );
 static void  handle_channel( struct net_device * );
 static int   recv_frame( struct net_device * );
 static void  send_frame( struct net_device * );
@@ -501,7 +501,7 @@ sbni_start_xmit( struct sk_buff  *skb,  struct net_device  *dev )
  */ 
 
 static irqreturn_t
-sbni_interrupt( int  irq,  void  *dev_id,  struct pt_regs  *regs )
+sbni_interrupt( int  irq,  void  *dev_id )
 {
        struct net_device         *dev = (struct net_device *) dev_id;
        struct net_local  *nl  = (struct net_local *) dev->priv;
index 0ba018f8382b53b2806b71c0bf4d19b97f10f45a..6a485f0556f4b70a5815740f80a80cf457c8d8b0 100644 (file)
@@ -867,7 +867,7 @@ static void sdla_receive(struct net_device *dev)
        spin_unlock_irqrestore(&sdla_lock, flags);
 }
 
-static irqreturn_t sdla_isr(int irq, void *dev_id, struct pt_regs * regs)
+static irqreturn_t sdla_isr(int irq, void *dev_id)
 {
        struct net_device     *dev;
        struct frad_local *flp;
@@ -875,13 +875,7 @@ static irqreturn_t sdla_isr(int irq, void *dev_id, struct pt_regs * regs)
 
        dev = dev_id;
 
-       if (dev == NULL)
-       {
-               printk(KERN_WARNING "sdla_isr(): irq %d for unknown device.\n", irq);
-               return IRQ_NONE;
-       }
-
-       flp = dev->priv;
+       flp = netdev_priv(dev);
 
        if (!flp->initialized)
        {
index ec68f7dfd93f7ca26f5a15d3d8f2117b4920b80c..c73601574334c22e97b46b451b33ff133c22bd99 100644 (file)
@@ -244,7 +244,7 @@ static inline void wanxl_rx_intr(card_t *card)
 
 
 
-static irqreturn_t wanxl_intr(int irq, void* dev_id, struct pt_regs *regs)
+static irqreturn_t wanxl_intr(int irq, void* dev_id)
 {
         card_t *card = dev_id;
         int i;
index caa48f12fd0ff3a6e0acc8e870d6ed8d5e7eb192..59ddd21c3958ae3ab9942b8f9272f13a176467b6 100644 (file)
@@ -728,7 +728,7 @@ EXPORT_SYMBOL(z8530_nop);
  *     channel). c->lock for both channels points to dev->lock
  */
 
-irqreturn_t z8530_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t z8530_interrupt(int irq, void *dev_id)
 {
        struct z8530_dev *dev=dev_id;
        u8 intr;
index 77e53208045f41409e8564a97cd0ebf244b8ffe8..158aea7b8eacbe13fbeda252b5010f483659279a 100644 (file)
@@ -396,7 +396,7 @@ struct z8530_dev
 extern u8 z8530_dead_port[];
 extern u8 z8530_hdlc_kilostream_85230[];
 extern u8 z8530_hdlc_kilostream[];
-extern irqreturn_t z8530_interrupt(int, void *, struct pt_regs *);
+extern irqreturn_t z8530_interrupt(int, void *);
 extern void z8530_describe(struct z8530_dev *, char *mapping, unsigned long io);
 extern int z8530_init(struct z8530_dev *);
 extern int z8530_shutdown(struct z8530_dev *);
index 39d09345027cbbc0680d95e7c863d09b7ed02b32..efcdaf1c5f735fd7b5619a2c39ae221b6e0708f4 100644 (file)
@@ -1120,8 +1120,7 @@ static void mpi_receive_802_3(struct airo_info *ai);
 static void mpi_receive_802_11(struct airo_info *ai);
 static int waitbusy (struct airo_info *ai);
 
-static irqreturn_t airo_interrupt( int irq, void* dev_id, struct pt_regs
-                           *regs);
+static irqreturn_t airo_interrupt( int irq, void* dev_id);
 static int airo_thread(void *data);
 static void timer_func( struct net_device *dev );
 static int airo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
@@ -2898,6 +2897,8 @@ static struct net_device *_init_airo_card( unsigned short irq, int port,
                goto err_out_map;
        }
        ai->wifidev = init_wifidev(ai, dev);
+       if (!ai->wifidev)
+               goto err_out_reg;
 
        set_bit(FLAG_REGISTERED,&ai->flags);
        airo_print_info(dev->name, "MAC enabled %x:%x:%x:%x:%x:%x",
@@ -2909,11 +2910,18 @@ static struct net_device *_init_airo_card( unsigned short irq, int port,
                for( i = 0; i < MAX_FIDS; i++ )
                        ai->fids[i] = transmit_allocate(ai,AIRO_DEF_MTU,i>=MAX_FIDS/2);
 
-       setup_proc_entry( dev, dev->priv ); /* XXX check for failure */
+       if (setup_proc_entry(dev, dev->priv) < 0)
+               goto err_out_wifi;
+
        netif_start_queue(dev);
        SET_MODULE_OWNER(dev);
        return dev;
 
+err_out_wifi:
+       unregister_netdev(ai->wifidev);
+       free_netdev(ai->wifidev);
+err_out_reg:
+       unregister_netdev(dev);
 err_out_map:
        if (test_bit(FLAG_MPI,&ai->flags) && pci) {
                pci_free_consistent(pci, PCI_SHARED_LEN, ai->shared, ai->shared_dma);
@@ -3090,7 +3098,8 @@ static int airo_thread(void *data) {
                                                set_bit(JOB_AUTOWEP, &ai->jobs);
                                                break;
                                        }
-                                       if (!kthread_should_stop()) {
+                                       if (!kthread_should_stop() &&
+                                           !freezing(current)) {
                                                unsigned long wake_at;
                                                if (!ai->expires || !ai->scan_timeout) {
                                                        wake_at = max(ai->expires,
@@ -3102,7 +3111,8 @@ static int airo_thread(void *data) {
                                                schedule_timeout(wake_at - jiffies);
                                                continue;
                                        }
-                               } else if (!kthread_should_stop()) {
+                               } else if (!kthread_should_stop() &&
+                                          !freezing(current)) {
                                        schedule();
                                        continue;
                                }
@@ -3151,7 +3161,7 @@ static int airo_thread(void *data) {
        return 0;
 }
 
-static irqreturn_t airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs) {
+static irqreturn_t airo_interrupt ( int irq, void* dev_id) {
        struct net_device *dev = (struct net_device *)dev_id;
        u16 status;
        u16 fid;
@@ -4496,91 +4506,128 @@ static int setup_proc_entry( struct net_device *dev,
        apriv->proc_entry = create_proc_entry(apriv->proc_name,
                                              S_IFDIR|airo_perm,
                                              airo_entry);
-        apriv->proc_entry->uid = proc_uid;
-        apriv->proc_entry->gid = proc_gid;
-        apriv->proc_entry->owner = THIS_MODULE;
+       if (!apriv->proc_entry)
+               goto fail;
+       apriv->proc_entry->uid = proc_uid;
+       apriv->proc_entry->gid = proc_gid;
+       apriv->proc_entry->owner = THIS_MODULE;
 
        /* Setup the StatsDelta */
        entry = create_proc_entry("StatsDelta",
                                  S_IFREG | (S_IRUGO&proc_perm),
                                  apriv->proc_entry);
-        entry->uid = proc_uid;
-        entry->gid = proc_gid;
+       if (!entry)
+               goto fail_stats_delta;
+       entry->uid = proc_uid;
+       entry->gid = proc_gid;
        entry->data = dev;
-        entry->owner = THIS_MODULE;
+       entry->owner = THIS_MODULE;
        SETPROC_OPS(entry, proc_statsdelta_ops);
 
        /* Setup the Stats */
        entry = create_proc_entry("Stats",
                                  S_IFREG | (S_IRUGO&proc_perm),
                                  apriv->proc_entry);
-        entry->uid = proc_uid;
-        entry->gid = proc_gid;
+       if (!entry)
+               goto fail_stats;
+       entry->uid = proc_uid;
+       entry->gid = proc_gid;
        entry->data = dev;
-        entry->owner = THIS_MODULE;
+       entry->owner = THIS_MODULE;
        SETPROC_OPS(entry, proc_stats_ops);
 
        /* Setup the Status */
        entry = create_proc_entry("Status",
                                  S_IFREG | (S_IRUGO&proc_perm),
                                  apriv->proc_entry);
-        entry->uid = proc_uid;
-        entry->gid = proc_gid;
+       if (!entry)
+               goto fail_status;
+       entry->uid = proc_uid;
+       entry->gid = proc_gid;
        entry->data = dev;
-        entry->owner = THIS_MODULE;
+       entry->owner = THIS_MODULE;
        SETPROC_OPS(entry, proc_status_ops);
 
        /* Setup the Config */
        entry = create_proc_entry("Config",
                                  S_IFREG | proc_perm,
                                  apriv->proc_entry);
-        entry->uid = proc_uid;
-        entry->gid = proc_gid;
+       if (!entry)
+               goto fail_config;
+       entry->uid = proc_uid;
+       entry->gid = proc_gid;
        entry->data = dev;
-        entry->owner = THIS_MODULE;
+       entry->owner = THIS_MODULE;
        SETPROC_OPS(entry, proc_config_ops);
 
        /* Setup the SSID */
        entry = create_proc_entry("SSID",
                                  S_IFREG | proc_perm,
                                  apriv->proc_entry);
-        entry->uid = proc_uid;
-        entry->gid = proc_gid;
+       if (!entry)
+               goto fail_ssid;
+       entry->uid = proc_uid;
+       entry->gid = proc_gid;
        entry->data = dev;
-        entry->owner = THIS_MODULE;
+       entry->owner = THIS_MODULE;
        SETPROC_OPS(entry, proc_SSID_ops);
 
        /* Setup the APList */
        entry = create_proc_entry("APList",
                                  S_IFREG | proc_perm,
                                  apriv->proc_entry);
-        entry->uid = proc_uid;
-        entry->gid = proc_gid;
+       if (!entry)
+               goto fail_aplist;
+       entry->uid = proc_uid;
+       entry->gid = proc_gid;
        entry->data = dev;
-        entry->owner = THIS_MODULE;
+       entry->owner = THIS_MODULE;
        SETPROC_OPS(entry, proc_APList_ops);
 
        /* Setup the BSSList */
        entry = create_proc_entry("BSSList",
                                  S_IFREG | proc_perm,
                                  apriv->proc_entry);
+       if (!entry)
+               goto fail_bsslist;
        entry->uid = proc_uid;
        entry->gid = proc_gid;
        entry->data = dev;
-        entry->owner = THIS_MODULE;
+       entry->owner = THIS_MODULE;
        SETPROC_OPS(entry, proc_BSSList_ops);
 
        /* Setup the WepKey */
        entry = create_proc_entry("WepKey",
                                  S_IFREG | proc_perm,
                                  apriv->proc_entry);
-        entry->uid = proc_uid;
-        entry->gid = proc_gid;
+       if (!entry)
+               goto fail_wepkey;
+       entry->uid = proc_uid;
+       entry->gid = proc_gid;
        entry->data = dev;
-        entry->owner = THIS_MODULE;
+       entry->owner = THIS_MODULE;
        SETPROC_OPS(entry, proc_wepkey_ops);
 
        return 0;
+
+fail_wepkey:
+       remove_proc_entry("BSSList", apriv->proc_entry);
+fail_bsslist:
+       remove_proc_entry("APList", apriv->proc_entry);
+fail_aplist:
+       remove_proc_entry("SSID", apriv->proc_entry);
+fail_ssid:
+       remove_proc_entry("Config", apriv->proc_entry);
+fail_config:
+       remove_proc_entry("Status", apriv->proc_entry);
+fail_status:
+       remove_proc_entry("Stats", apriv->proc_entry);
+fail_stats:
+       remove_proc_entry("StatsDelta", apriv->proc_entry);
+fail_stats_delta:
+       remove_proc_entry(apriv->proc_name, airo_entry);
+fail:
+       return -ENOMEM;
 }
 
 static int takedown_proc_entry( struct net_device *dev,
@@ -5925,7 +5972,6 @@ static int airo_get_essid(struct net_device *dev,
 
        /* Get the current SSID */
        memcpy(extra, status_rid.SSID, status_rid.SSIDlen);
-       extra[status_rid.SSIDlen] = '\0';
        /* If none, we may want to get the one that was set */
 
        /* Push it out ! */
index bb6bea4f32331fa026a037107ca57082dfe44cac..4688e56b69c715a722f1fb00553143aa20ae2c12 100644 (file)
@@ -78,7 +78,7 @@ static int arlans_found;
 
 static  int    arlan_open(struct net_device *dev);
 static  int    arlan_tx(struct sk_buff *skb, struct net_device *dev);
-static  irqreturn_t arlan_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static  irqreturn_t arlan_interrupt(int irq, void *dev_id);
 static  int    arlan_close(struct net_device *dev);
 static  struct net_device_stats *
                arlan_statistics                (struct net_device *dev);
@@ -1651,7 +1651,7 @@ end_int_process:
        return;
 }
 
-static irqreturn_t arlan_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t arlan_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
        struct arlan_private *priv = netdev_priv(dev);
index 0fc267d626dc0c68630b28e4953415a671eb672a..0c07b8b7250d604b8ffd453b947020c9aec3ae46 100644 (file)
@@ -1145,7 +1145,7 @@ next:
        }
 }
 
-static irqreturn_t service_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t service_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = (struct net_device *) dev_id;
        struct atmel_private *priv = netdev_priv(dev);
@@ -1678,11 +1678,9 @@ static int atmel_get_essid(struct net_device *dev,
        /* Get the current SSID */
        if (priv->new_SSID_size != 0) {
                memcpy(extra, priv->new_SSID, priv->new_SSID_size);
-               extra[priv->new_SSID_size] = '\0';
                dwrq->length = priv->new_SSID_size;
        } else {
                memcpy(extra, priv->SSID, priv->SSID_size);
-               extra[priv->SSID_size] = '\0';
                dwrq->length = priv->SSID_size;
        }
 
index 76e3aed4b4711893a4cd96fc8ef6a06af20fc35d..978ed099e2852e45fa20c08a3bebf2011b927a0e 100644 (file)
@@ -705,11 +705,30 @@ int bcm43xx_dma_init(struct bcm43xx_private *bcm)
        struct bcm43xx_dmaring *ring;
        int err = -ENOMEM;
        int dma64 = 0;
-       u32 sbtmstatehi;
+       u64 mask = bcm43xx_get_supported_dma_mask(bcm);
+       int nobits;
 
-       sbtmstatehi = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATEHIGH);
-       if (sbtmstatehi & BCM43xx_SBTMSTATEHIGH_DMA64BIT)
+       if (mask == DMA_64BIT_MASK) {
                dma64 = 1;
+               nobits = 64;
+       } else if (mask == DMA_32BIT_MASK)
+               nobits = 32;
+       else
+               nobits = 30;
+       err = pci_set_dma_mask(bcm->pci_dev, mask);
+       err |= pci_set_consistent_dma_mask(bcm->pci_dev, mask);
+       if (err) {
+#ifdef CONFIG_BCM43XX_PIO
+               printk(KERN_WARNING PFX "DMA not supported on this device."
+                                       " Falling back to PIO.\n");
+               bcm->__using_pio = 1;
+               return -ENOSYS;
+#else
+               printk(KERN_ERR PFX "FATAL: DMA not supported and PIO not configured. "
+                                   "Please recompile the driver with PIO support.\n");
+               return -ENODEV;
+#endif /* CONFIG_BCM43XX_PIO */
+       }
 
        /* setup TX DMA channels. */
        ring = bcm43xx_setup_dmaring(bcm, 0, 1, dma64);
@@ -755,8 +774,7 @@ int bcm43xx_dma_init(struct bcm43xx_private *bcm)
                dma->rx_ring3 = ring;
        }
 
-       dprintk(KERN_INFO PFX "%s DMA initialized\n",
-                       dma64 ? "64-bit" : "32-bit");
+       dprintk(KERN_INFO PFX "%d-bit DMA initialized\n", nobits);
        err = 0;
 out:
        return err;
index e04bcaddd1d004d1b514a39bf047f11a963e1bbf..ea16078cfe98bd95169e626b203a77194a935ace 100644 (file)
@@ -314,6 +314,23 @@ int bcm43xx_dma_tx(struct bcm43xx_private *bcm,
                   struct ieee80211_txb *txb);
 void bcm43xx_dma_rx(struct bcm43xx_dmaring *ring);
 
+/* Helper function that returns the dma mask for this device. */
+static inline
+u64 bcm43xx_get_supported_dma_mask(struct bcm43xx_private *bcm)
+{
+       int dma64 = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATEHIGH) &
+                                  BCM43xx_SBTMSTATEHIGH_DMA64BIT;
+       u16 mmio_base = bcm43xx_dmacontroller_base(dma64, 0);
+       u32 mask = BCM43xx_DMA32_TXADDREXT_MASK;
+
+       if (dma64)
+               return DMA_64BIT_MASK;
+       bcm43xx_write32(bcm, mmio_base + BCM43xx_DMA32_TXCTL, mask);
+       if (bcm43xx_read32(bcm, mmio_base + BCM43xx_DMA32_TXCTL) & mask)
+               return DMA_32BIT_MASK;
+       return DMA_30BIT_MASK;
+}
+
 #else /* CONFIG_BCM43XX_DMA */
 
 
index c3f90c8563d915ee4175afe6ca8cd6a4a41627fb..2ddbec6bf15b878449e1e15b0d06e3e18d36dbbc 100644 (file)
@@ -242,7 +242,7 @@ void bcm43xx_leds_update(struct bcm43xx_private *bcm, int activity)
                        //TODO
                        break;
                case BCM43xx_LED_ASSOC:
-                       if (bcm->softmac->associated)
+                       if (bcm->softmac->associnfo.associated)
                                turn_on = 1;
                        break;
 #ifdef CONFIG_BCM43XX_DEBUG
index eb65db7393ba56dc47d6dcc4c565cbab13042078..a94c6d8826f874e7c4606fa6884491da897a45cf 100644 (file)
@@ -1834,7 +1834,7 @@ static void bcm43xx_interrupt_ack(struct bcm43xx_private *bcm, u32 reason)
 }
 
 /* Interrupt handler top-half */
-static irqreturn_t bcm43xx_interrupt_handler(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t bcm43xx_interrupt_handler(int irq, void *dev_id)
 {
        irqreturn_t ret = IRQ_HANDLED;
        struct bcm43xx_private *bcm = dev_id;
@@ -2925,10 +2925,13 @@ static int bcm43xx_wireless_core_init(struct bcm43xx_private *bcm,
                bcm43xx_write16(bcm, 0x043C, 0x000C);
 
        if (active_wlcore) {
-               if (bcm43xx_using_pio(bcm))
+               if (bcm43xx_using_pio(bcm)) {
                        err = bcm43xx_pio_init(bcm);
-               else
+               } else {
                        err = bcm43xx_dma_init(bcm);
+                       if (err == -ENOSYS)
+                               err = bcm43xx_pio_init(bcm);
+               }
                if (err)
                        goto err_chip_cleanup;
        }
@@ -3164,12 +3167,12 @@ static void bcm43xx_periodic_work_handler(void *d)
        u32 savedirqs = 0;
        int badness;
 
+       mutex_lock(&bcm->mutex);
        badness = estimate_periodic_work_badness(bcm->periodic_state);
        if (badness > BADNESS_LIMIT) {
                /* Periodic work will take a long time, so we want it to
                 * be preemtible.
                 */
-               mutex_lock(&bcm->mutex);
                netif_tx_disable(bcm->net_dev);
                spin_lock_irqsave(&bcm->irq_lock, flags);
                bcm43xx_mac_suspend(bcm);
@@ -3182,7 +3185,6 @@ static void bcm43xx_periodic_work_handler(void *d)
                /* Periodic work should take short time, so we want low
                 * locking overhead.
                 */
-               mutex_lock(&bcm->mutex);
                spin_lock_irqsave(&bcm->irq_lock, flags);
        }
 
@@ -3963,7 +3965,7 @@ static void bcm43xx_net_poll_controller(struct net_device *net_dev)
 
        local_irq_save(flags);
        if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)
-               bcm43xx_interrupt_handler(bcm->irq, bcm, NULL);
+               bcm43xx_interrupt_handler(bcm->irq, bcm);
        local_irq_restore(flags);
 }
 #endif /* CONFIG_NET_POLL_CONTROLLER */
@@ -3993,8 +3995,6 @@ static int bcm43xx_init_private(struct bcm43xx_private *bcm,
                                struct net_device *net_dev,
                                struct pci_dev *pci_dev)
 {
-       int err;
-
        bcm43xx_set_status(bcm, BCM43xx_STAT_UNINIT);
        bcm->ieee = netdev_priv(net_dev);
        bcm->softmac = ieee80211_priv(net_dev);
@@ -4012,22 +4012,8 @@ static int bcm43xx_init_private(struct bcm43xx_private *bcm,
                     (void (*)(unsigned long))bcm43xx_interrupt_tasklet,
                     (unsigned long)bcm);
        tasklet_disable_nosync(&bcm->isr_tasklet);
-       if (modparam_pio) {
+       if (modparam_pio)
                bcm->__using_pio = 1;
-       } else {
-               err = pci_set_dma_mask(pci_dev, DMA_30BIT_MASK);
-               err |= pci_set_consistent_dma_mask(pci_dev, DMA_30BIT_MASK);
-               if (err) {
-#ifdef CONFIG_BCM43XX_PIO
-                       printk(KERN_WARNING PFX "DMA not supported. Falling back to PIO.\n");
-                       bcm->__using_pio = 1;
-#else
-                       printk(KERN_ERR PFX "FATAL: DMA not supported and PIO not configured. "
-                                           "Recompile the driver with PIO support, please.\n");
-                       return -ENODEV;
-#endif /* CONFIG_BCM43XX_PIO */
-               }
-       }
        bcm->rts_threshold = BCM43xx_DEFAULT_RTS_THRESHOLD;
 
        /* default to sw encryption for now */
@@ -4208,7 +4194,11 @@ static int bcm43xx_resume(struct pci_dev *pdev)
        dprintk(KERN_INFO PFX "Resuming...\n");
 
        pci_set_power_state(pdev, 0);
-       pci_enable_device(pdev);
+       err = pci_enable_device(pdev);
+       if (err) {
+               printk(KERN_ERR PFX "Failure with pci_enable_device!\n");
+               return err;
+       }
        pci_restore_state(pdev);
 
        bcm43xx_chipset_attach(bcm);
index 9b7b15cf656153b20d99633019b1885a1b87513c..d27016f8c736bb77def6401028716808d870bdaa 100644 (file)
@@ -847,7 +847,7 @@ static struct iw_statistics *bcm43xx_get_wireless_stats(struct net_device *net_d
        unsigned long flags;
 
        wstats = &bcm->stats.wstats;
-       if (!mac->associated) {
+       if (!mac->associnfo.associated) {
                wstats->miss.beacon = 0;
 //             bcm->ieee->ieee_stats.tx_retry_limit_exceeded = 0; // FIXME: should this be cleared here?
                wstats->discard.retries = 0;
index d500012fdc7a5446aef8315c5dc7172ee4b2eb8e..ed00ebb6e7f4bd255d1a1fe8bf05a6f7a5574d6e 100644 (file)
@@ -2622,7 +2622,7 @@ static void prism2_check_magic(local_info_t *local)
 
 
 /* Called only from hardware IRQ */
-static irqreturn_t prism2_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t prism2_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = (struct net_device *) dev_id;
        struct hostap_interface *iface;
index 599e2fe76188534cedd9973f7ebfd0fb1fb03e6a..4e4eaa2a99ca4da6220a2239785f823b50a2825b 100644 (file)
@@ -3255,7 +3255,7 @@ static void ipw2100_irq_tasklet(struct ipw2100_priv *priv)
        IPW_DEBUG_ISR("exit\n");
 }
 
-static irqreturn_t ipw2100_interrupt(int irq, void *data, struct pt_regs *regs)
+static irqreturn_t ipw2100_interrupt(int irq, void *data)
 {
        struct ipw2100_priv *priv = data;
        u32 inta, inta_mask;
index 5685d7ba55bb83c7758f3d8362dbc84a3797c89d..1f742814a01c295dff243a964fa9c64485b582b2 100644 (file)
@@ -10467,7 +10467,7 @@ static const struct ethtool_ops ipw_ethtool_ops = {
        .set_eeprom = ipw_ethtool_set_eeprom,
 };
 
-static irqreturn_t ipw_isr(int irq, void *data, struct pt_regs *regs)
+static irqreturn_t ipw_isr(int irq, void *data)
 {
        struct ipw_priv *priv = data;
        u32 inta, inta_mask;
index 36b5e004305ee4455000ad832222d4246ca467ff..6714e0dfa8d6ebadd95490477ddb259999a73b2e 100644 (file)
@@ -207,7 +207,7 @@ static int netwave_start_xmit( struct sk_buff *skb, struct net_device *dev);
 static int netwave_rx( struct net_device *dev);
 
 /* Interrupt routines */
-static irqreturn_t netwave_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t netwave_interrupt(int irq, void *dev_id);
 static void netwave_watchdog(struct net_device *);
 
 /* Statistics */
@@ -1072,7 +1072,7 @@ static int netwave_start_xmit(struct sk_buff *skb, struct net_device *dev) {
 } /* netwave_start_xmit */
 
 /*
- * Function netwave_interrupt (irq, dev_id, regs)
+ * Function netwave_interrupt (irq, dev_id)
  *
  *    This function is the interrupt handler for the Netwave card. This
  *    routine will be called whenever: 
@@ -1081,7 +1081,7 @@ static int netwave_start_xmit(struct sk_buff *skb, struct net_device *dev) {
  *          ready to transmit another packet.
  *       3. A command has completed execution.
  */
-static irqreturn_t netwave_interrupt(int irq, void* dev_id, struct pt_regs *regs)
+static irqreturn_t netwave_interrupt(int irq, void* dev_id)
 {
     kio_addr_t iobase;
     u_char __iomem *ramBase;
index 9e19a963febc8b081839a9d9ca9216beb2942a6f..336cabac13b392a584259f2a045bc7e673275be1 100644 (file)
@@ -1952,9 +1952,9 @@ static void __orinoco_ev_wterr(struct net_device *dev, hermes_t *hw)
               dev->name);
 }
 
-irqreturn_t orinoco_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t orinoco_interrupt(int irq, void *dev_id)
 {
-       struct net_device *dev = (struct net_device *)dev_id;
+       struct net_device *dev = dev_id;
        struct orinoco_private *priv = netdev_priv(dev);
        hermes_t *hw = &priv->hw;
        int count = MAX_IRQLOOPS_PER_IRQ;
@@ -2457,6 +2457,7 @@ void free_orinocodev(struct net_device *dev)
 /* Wireless extensions                                              */
 /********************************************************************/
 
+/* Return : < 0 -> error code ; >= 0 -> length */
 static int orinoco_hw_get_essid(struct orinoco_private *priv, int *active,
                                char buf[IW_ESSID_MAX_SIZE+1])
 {
@@ -2501,9 +2502,9 @@ static int orinoco_hw_get_essid(struct orinoco_private *priv, int *active,
        len = le16_to_cpu(essidbuf.len);
        BUG_ON(len > IW_ESSID_MAX_SIZE);
 
-       memset(buf, 0, IW_ESSID_MAX_SIZE+1);
+       memset(buf, 0, IW_ESSID_MAX_SIZE);
        memcpy(buf, p, len);
-       buf[len] = '\0';
+       err = len;
 
  fail_unlock:
        orinoco_unlock(priv, &flags);
@@ -3027,17 +3028,18 @@ static int orinoco_ioctl_getessid(struct net_device *dev,
 
        if (netif_running(dev)) {
                err = orinoco_hw_get_essid(priv, &active, essidbuf);
-               if (err)
+               if (err < 0)
                        return err;
+               erq->length = err;
        } else {
                if (orinoco_lock(priv, &flags) != 0)
                        return -EBUSY;
-               memcpy(essidbuf, priv->desired_essid, IW_ESSID_MAX_SIZE + 1);
+               memcpy(essidbuf, priv->desired_essid, IW_ESSID_MAX_SIZE);
+               erq->length = strlen(priv->desired_essid);
                orinoco_unlock(priv, &flags);
        }
 
        erq->flags = 1;
-       erq->length = strlen(essidbuf);
 
        return 0;
 }
@@ -3075,10 +3077,10 @@ static int orinoco_ioctl_getnick(struct net_device *dev,
        if (orinoco_lock(priv, &flags) != 0)
                return -EBUSY;
 
-       memcpy(nickbuf, priv->nick, IW_ESSID_MAX_SIZE+1);
+       memcpy(nickbuf, priv->nick, IW_ESSID_MAX_SIZE);
        orinoco_unlock(priv, &flags);
 
-       nrq->length = strlen(nickbuf);
+       nrq->length = strlen(priv->nick);
 
        return 0;
 }
index fb5700d6c454b8e2cc54d74de8db72c560550a14..4720fb20d66d1c730582e8ecf5d4552a7b4540b5 100644 (file)
@@ -128,7 +128,7 @@ extern void free_orinocodev(struct net_device *dev);
 extern int __orinoco_up(struct net_device *dev);
 extern int __orinoco_down(struct net_device *dev);
 extern int orinoco_reinit_firmware(struct net_device *dev);
-extern irqreturn_t orinoco_interrupt(int irq, void * dev_id, struct pt_regs *regs);
+extern irqreturn_t orinoco_interrupt(int irq, void * dev_id);
 
 /********************************************************************/
 /* Locking and synchronization functions                            */
index ab3c5a27efd902515854f2f3dbf1f6e7945cc596..ec1c00f19eb3869e261d9e6aa878b741de28c9a6 100644 (file)
@@ -182,7 +182,7 @@ isl_upload_firmware(islpci_private *priv)
 ******************************************************************************/
 
 irqreturn_t
-islpci_interrupt(int irq, void *config, struct pt_regs *regs)
+islpci_interrupt(int irq, void *config)
 {
        u32 reg;
        islpci_private *priv = config;
index 5049f37455b1606fd1240f55f08134900359d09a..2f7e525d0cf60bbff21143ac66545607c7614e19 100644 (file)
@@ -198,7 +198,7 @@ islpci_state_t islpci_set_state(islpci_private *priv, islpci_state_t new_state);
 
 #define ISLPCI_TX_TIMEOUT               (2*HZ)
 
-irqreturn_t islpci_interrupt(int, void *, struct pt_regs *);
+irqreturn_t islpci_interrupt(int, void *);
 
 int prism54_post_setup(islpci_private *, int);
 int islpci_reset(islpci_private *, int);
index e82548ea609ac100f7310e81c8e7acdb4a946840..7fbfc9e41d07b804dea4c7704d95da10f459f69c 100644 (file)
@@ -130,7 +130,7 @@ static void ray_update_parm(struct net_device *dev, UCHAR objid, UCHAR *value, i
 static void verify_dl_startup(u_long);
 
 /* Prototypes for interrpt time functions **********************************/
-static irqreturn_t ray_interrupt (int reg, void *dev_id, struct pt_regs *regs);
+static irqreturn_t ray_interrupt (int reg, void *dev_id);
 static void clear_interrupt(ray_dev_t *local);
 static void rx_deauthenticate(ray_dev_t *local, struct rcs __iomem *prcs, 
                        unsigned int pkt_addr, int rx_len);
@@ -1198,7 +1198,6 @@ static int ray_get_essid(struct net_device *dev,
 
        /* Get the essid that was set */
        memcpy(extra, local->sparm.b5.a_current_ess_id, IW_ESSID_MAX_SIZE);
-       extra[IW_ESSID_MAX_SIZE] = '\0';
 
        /* Push it out ! */
        dwrq->length = strlen(extra);
@@ -1940,7 +1939,7 @@ static void set_multicast_list(struct net_device *dev)
 /*=============================================================================
  * All routines below here are run at interrupt time.
 =============================================================================*/
-static irqreturn_t ray_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+static irqreturn_t ray_interrupt(int irq, void *dev_id)
 {
     struct net_device *dev = (struct net_device *)dev_id;
     struct pcmcia_device *link;
index 5b69befdab7451bced8d23b0046c65371449848b..24221e476cd3ee938e667dc46f51bf44a346c817 100644 (file)
@@ -3768,7 +3768,7 @@ static int wv_check_ioaddr(unsigned long ioaddr, u8 * mac)
  * This function is the interrupt handler for the WaveLAN card. This
  * routine will be called whenever: 
  */
-static irqreturn_t wavelan_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t wavelan_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev;
        unsigned long ioaddr;
index 5cb0bc8bb1289ed3d8a2aaaa15de4d0fc5f5f703..72b646c77d5a3885caca1182dcbaab50ef8b3919 100644 (file)
@@ -642,8 +642,7 @@ static int
 /* ---------------------- INTERRUPT HANDLING ---------------------- */
 static irqreturn_t
        wavelan_interrupt(int,          /* interrupt handler */
-                         void *,
-                         struct pt_regs *);
+                         void *);
 static void
        wavelan_watchdog(struct net_device *);  /* transmission watchdog */
 /* ------------------- CONFIGURATION CALLBACKS ------------------- */
index 0065f057bb1c588d89c296fbc2161c1105f6fee0..aafb301041b124f03d672cedf2c30f4fb3472a47 100644 (file)
@@ -4117,24 +4117,14 @@ wv_pcmcia_release(struct pcmcia_device *link)
  */
 static irqreturn_t
 wavelan_interrupt(int          irq,
-                 void *        dev_id,
-                 struct pt_regs * regs)
+                 void *        dev_id)
 {
-  struct net_device *  dev;
+  struct net_device *  dev = dev_id;
   net_local *  lp;
   kio_addr_t   base;
   int          status0;
   u_int                tx_status;
 
-  if ((dev = dev_id) == NULL)
-    {
-#ifdef DEBUG_INTERRUPT_ERROR
-      printk(KERN_WARNING "wavelan_interrupt(): irq %d for unknown device.\n",
-            irq);
-#endif
-      return IRQ_NONE;
-    }
-
 #ifdef DEBUG_INTERRUPT_TRACE
   printk(KERN_DEBUG "%s: ->wavelan_interrupt()\n", dev->name);
 #endif
index f34a36b0c7b0e0ec2424d7c909b88c89ec695f0e..4d1c4905c7494d04b33a4239234dcc19395a166e 100644 (file)
@@ -738,8 +738,7 @@ static void
 /* ---------------------- INTERRUPT HANDLING ---------------------- */
 static irqreturn_t
        wavelan_interrupt(int,  /* Interrupt handler */
-                         void *,
-                         struct pt_regs *);
+                         void *);
 static void
        wavelan_watchdog(struct net_device *);  /* Transmission watchdog */
 /* ------------------- CONFIGURATION CALLBACKS ------------------- */
index e3ae5f60d5bea0bc537a38e84cf0182f7280d8c9..5b98a7876982a528e56f819016457bc4359a6d54 100644 (file)
@@ -1145,7 +1145,6 @@ static inline void wl3501_ack_interrupt(struct wl3501_card *this)
  * wl3501_interrupt - Hardware interrupt from card.
  * @irq - Interrupt number
  * @dev_id - net_device
- * @regs - registers
  *
  * We must acknowledge the interrupt as soon as possible, and block the
  * interrupt from the same card immediately to prevent re-entry.
@@ -1154,27 +1153,20 @@ static inline void wl3501_ack_interrupt(struct wl3501_card *this)
  * On the other hand, to prevent SUTRO from malfunctioning, we must
  * unlock the SUTRO as soon as possible.
  */
-static irqreturn_t wl3501_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t wl3501_interrupt(int irq, void *dev_id)
 {
-       struct net_device *dev = (struct net_device *)dev_id;
+       struct net_device *dev = dev_id;
        struct wl3501_card *this;
-       int handled = 1;
 
-       if (!dev)
-               goto unknown;
-       this = dev->priv;
+       this = netdev_priv(dev);
        spin_lock(&this->lock);
        wl3501_ack_interrupt(this);
        wl3501_block_interrupt(this);
        wl3501_rx_interrupt(dev);
        wl3501_unblock_interrupt(this);
        spin_unlock(&this->lock);
-out:
-       return IRQ_RETVAL(handled);
-unknown:
-       handled = 0;
-       printk(KERN_ERR "%s: irq %d for unknown device.\n", __FUNCTION__, irq);
-       goto out;
+
+       return IRQ_HANDLED;
 }
 
 static int wl3501_reset_board(struct wl3501_card *this)
index 80af9a9fcbb33cd3f54614019b8511a6b8d6f579..36b29ff058141a712619e55184566b39ce414efd 100644 (file)
@@ -112,7 +112,7 @@ exit:
        return err;
 }
 
-static void zd1201_usbfree(struct urb *urb, struct pt_regs *regs)
+static void zd1201_usbfree(struct urb *urb)
 {
        struct zd1201 *zd = urb->context;
 
@@ -177,7 +177,7 @@ static int zd1201_docmd(struct zd1201 *zd, int cmd, int parm0,
 }
 
 /* Callback after sending out a packet */
-static void zd1201_usbtx(struct urb *urb, struct pt_regs *regs)
+static void zd1201_usbtx(struct urb *urb)
 {
        struct zd1201 *zd = urb->context;
        netif_wake_queue(zd->dev);
@@ -185,7 +185,7 @@ static void zd1201_usbtx(struct urb *urb, struct pt_regs *regs)
 }
 
 /* Incoming data */
-static void zd1201_usbrx(struct urb *urb, struct pt_regs *regs)
+static void zd1201_usbrx(struct urb *urb)
 {
        struct zd1201 *zd = urb->context;
        int free = 0;
@@ -193,10 +193,8 @@ static void zd1201_usbrx(struct urb *urb, struct pt_regs *regs)
        struct sk_buff *skb;
        unsigned char type;
 
-       if (!zd) {
-               free = 1;
-               goto exit;
-       }
+       if (!zd)
+               return;
 
        switch(urb->status) {
                case -EILSEQ:
index 2d12837052b03f35f49e1f4ae21aa99c831653f7..a7d29bddb298a7a7d41cc1edeb3753d15bae7037 100644 (file)
@@ -1099,7 +1099,7 @@ static void link_led_handler(void *p)
        int r;
 
        spin_lock_irq(&mac->lock);
-       is_associated = sm->associated != 0;
+       is_associated = sm->associnfo.associated != 0;
        spin_unlock_irq(&mac->lock);
 
        r = zd_chip_control_leds(chip,
index 5c265ad0485af0c08a46e706dfc6b16b25f6b562..3faaeb2b7c89c9843c71cc1b5d953ba872a0be3c 100644 (file)
@@ -408,7 +408,7 @@ static inline void handle_retry_failed_int(struct urb *urb)
 }
 
 
-static void int_urb_complete(struct urb *urb, struct pt_regs *pt_regs)
+static void int_urb_complete(struct urb *urb)
 {
        int r;
        struct usb_int_header *hdr;
@@ -609,7 +609,7 @@ static void handle_rx_packet(struct zd_usb *usb, const u8 *buffer,
        }
 }
 
-static void rx_urb_complete(struct urb *urb, struct pt_regs *pt_regs)
+static void rx_urb_complete(struct urb *urb)
 {
        struct zd_usb *usb;
        struct zd_usb_rx *rx;
@@ -779,7 +779,7 @@ void zd_usb_disable_rx(struct zd_usb *usb)
        spin_unlock_irqrestore(&rx->lock, flags);
 }
 
-static void tx_urb_complete(struct urb *urb, struct pt_regs *pt_regs)
+static void tx_urb_complete(struct urb *urb)
 {
        int r;
 
index a4c4953f1365bbdec9e141c374ef5c71aa3340d8..2412ce4917f26ee9143eb07a5153fc168bb77112 100644 (file)
@@ -350,7 +350,7 @@ static void yellowfin_timer(unsigned long data);
 static void yellowfin_tx_timeout(struct net_device *dev);
 static void yellowfin_init_ring(struct net_device *dev);
 static int yellowfin_start_xmit(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t yellowfin_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
+static irqreturn_t yellowfin_interrupt(int irq, void *dev_instance);
 static int yellowfin_rx(struct net_device *dev);
 static void yellowfin_error(struct net_device *dev, int intr_status);
 static int yellowfin_close(struct net_device *dev);
@@ -888,7 +888,7 @@ static int yellowfin_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 /* The interrupt handler does all of the Rx thread work and cleans up
    after the Tx thread. */
-static irqreturn_t yellowfin_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
+static irqreturn_t yellowfin_interrupt(int irq, void *dev_instance)
 {
        struct net_device *dev = dev_instance;
        struct yellowfin_private *yp;
@@ -896,13 +896,6 @@ static irqreturn_t yellowfin_interrupt(int irq, void *dev_instance, struct pt_re
        int boguscnt = max_interrupt_work;
        unsigned int handled = 0;
 
-#ifndef final_version                  /* Can never occur. */
-       if (dev == NULL) {
-               printk (KERN_ERR "yellowfin_interrupt(): irq %d for unknown device.\n", irq);
-               return IRQ_NONE;
-       }
-#endif
-
        yp = netdev_priv(dev);
        ioaddr = yp->base;
 
index 656d5a02908b9daa18406dbb28e9480c24a503f5..b24b0727108c037c509c1a2395116d34e1ab543d 100644 (file)
@@ -158,7 +158,7 @@ struct netidblk {
 
 static int     znet_open(struct net_device *dev);
 static int     znet_send_packet(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t znet_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t znet_interrupt(int irq, void *dev_id);
 static void    znet_rx(struct net_device *dev);
 static int     znet_close(struct net_device *dev);
 static struct net_device_stats *net_get_stats(struct net_device *dev);
@@ -602,7 +602,7 @@ static int znet_send_packet(struct sk_buff *skb, struct net_device *dev)
 }
 
 /* The ZNET interrupt handler. */
-static irqreturn_t znet_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+static irqreturn_t znet_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
        struct znet_private *znet = dev->priv;
@@ -610,11 +610,6 @@ static irqreturn_t znet_interrupt(int irq, void *dev_id, struct pt_regs * regs)
        int boguscnt = 20;
        int handled = 0;
 
-       if (dev == NULL) {
-               printk(KERN_WARNING "znet_interrupt(): IRQ %d for unknown device.\n", irq);
-               return IRQ_NONE;
-       }
-
        spin_lock (&znet->lock);
 
        ioaddr = dev->base_addr;
index 0d96c50ffe9cdb26d4f353d321247c7b166fb4d9..03c763c2d0e0f0d7b6efdafc2d928363daa73620 100644 (file)
@@ -368,8 +368,7 @@ static struct hw_interrupt_type dino_interrupt_type = {
  * ilr_loop counter is a kluge to prevent a "stuck" IRQ line from
  * wedging the CPU. Could be removed or made optional at some point.
  */
-static irqreturn_t
-dino_isr(int irq, void *intr_dev, struct pt_regs *regs)
+static irqreturn_t dino_isr(int irq, void *intr_dev)
 {
        struct dino_device *dino_dev = intr_dev;
        u32 mask;
@@ -390,7 +389,7 @@ ilr_again:
                int irq = dino_dev->global_irq[local_irq];
                DBG(KERN_DEBUG "%s(%d, %p) mask 0x%x\n",
                        __FUNCTION__, irq, intr_dev, mask);
-               __do_IRQ(irq, regs);
+               __do_IRQ(irq);
                mask &= ~(1 << local_irq);
        } while (mask);
 
index 884965cedec9aee3460ef7a3be7dec52769c4a92..e97cecbc4d183e6b0772e824747e2de8d4341e69 100644 (file)
@@ -199,7 +199,7 @@ static struct hw_interrupt_type eisa_interrupt_type = {
        .end =          no_end_irq,
 };
 
-static irqreturn_t eisa_irq(int wax_irq, void *intr_dev, struct pt_regs *regs)
+static irqreturn_t eisa_irq(int wax_irq, void *intr_dev)
 {
        int irq = gsc_readb(0xfc01f000); /* EISA supports 16 irqs */
        unsigned long flags;
@@ -234,7 +234,7 @@ static irqreturn_t eisa_irq(int wax_irq, void *intr_dev, struct pt_regs *regs)
        }
        spin_unlock_irqrestore(&eisa_irq_lock, flags);
 
-       __do_IRQ(irq, regs);
+       __do_IRQ(irq);
    
        spin_lock_irqsave(&eisa_irq_lock, flags);
        /* unmask */
@@ -249,7 +249,7 @@ static irqreturn_t eisa_irq(int wax_irq, void *intr_dev, struct pt_regs *regs)
        return IRQ_HANDLED;
 }
 
-static irqreturn_t dummy_irq2_handler(int _, void *dev, struct pt_regs *regs)
+static irqreturn_t dummy_irq2_handler(int _, void *dev)
 {
        printk(KERN_ALERT "eisa: uhh, irq2?\n");
        return IRQ_HANDLED;
index b45aa5c675a0a88981e97b913ef756ec9e3de46f..1b3e3fd12d95882492c6bd86ab9f367eb925bbb8 100644 (file)
@@ -73,7 +73,7 @@ EXPORT_SYMBOL(gsc_alloc_irq);
 EXPORT_SYMBOL(gsc_claim_irq);
 
 /* Common interrupt demultiplexer used by Asp, Lasi & Wax.  */
-irqreturn_t gsc_asic_intr(int gsc_asic_irq, void *dev, struct pt_regs *regs)
+irqreturn_t gsc_asic_intr(int gsc_asic_irq, void *dev)
 {
        unsigned long irr;
        struct gsc_asic *gsc_asic = dev;
@@ -87,7 +87,7 @@ irqreturn_t gsc_asic_intr(int gsc_asic_irq, void *dev, struct pt_regs *regs)
        do {
                int local_irq = __ffs(irr);
                unsigned int irq = gsc_asic->global_irq[local_irq];
-               __do_IRQ(irq, regs);
+               __do_IRQ(irq);
                irr &= ~(1 << local_irq);
        } while (irr);
 
index a3dc456709d799be9f3949a1d915ded99eafd3ac..762a1babad604a318a9f5a22bfb7d467bc760e93 100644 (file)
@@ -44,4 +44,4 @@ void gsc_fixup_irqs(struct parisc_device *parent, void *ctrl,
                void (*choose)(struct parisc_device *child, void *ctrl));
 void gsc_asic_assign_irq(struct gsc_asic *asic, int local_irq, int *irqp);
 
-irqreturn_t gsc_asic_intr(int irq, void *dev, struct pt_regs *regs);
+irqreturn_t gsc_asic_intr(int irq, void *dev);
index 2eb3577a88c50f07d0190a6d45efcf2aed345926..97e9dc066f95fc278cbc34bc1e49753bbf2f431d 100644 (file)
@@ -188,7 +188,7 @@ static void polling_tasklet_func(unsigned long soft_power_reg)
  * powerfail interruption handler (irq IRQ_FROM_REGION(CPU_IRQ_REGION)+2) 
  */
 #if 0
-static void powerfail_interrupt(int code, void *x, struct pt_regs *regs)
+static void powerfail_interrupt(int code, void *x)
 {
        printk(KERN_CRIT "POWERFAIL INTERRUPTION !\n");
        poweroff();
index 294c1117098d69d6a0a9c13e26cd9f4727fbf528..f1e7ccd5475bb413888272112e1937d67e4d5f36 100644 (file)
@@ -1320,12 +1320,12 @@ sba_ioc_init_pluto(struct parisc_device *sba, struct ioc *ioc, int ioc_num)
        ** the GART code to handshake on.
        */
        klist_iter_init(&sba->dev.klist_children, &i);
-       while (dev = next_device(&i)) {
+       while ((dev = next_device(&i))) {
                struct parisc_device *lba = to_parisc_device(dev);
                if (IS_QUICKSILVER(lba))
                        agp_found = 1;
        }
-       klist_iter_exit(&sba->dev.klist_children, &i);
+       klist_iter_exit(&i);
 
        if (agp_found && sba_reserve_agpgart) {
                printk(KERN_INFO "%s: reserving %dMb of IOVA space for agpgart\n",
index 4ee26a6d9e2544852a29f42e637da7b60de2d5cb..1fd97f7c8b98fcb461b34f2fc73683ce0f431367 100644 (file)
@@ -94,7 +94,7 @@ static struct superio_device sio_dev;
 #define PFX    SUPERIO ": "
 
 static irqreturn_t
-superio_interrupt(int parent_irq, void *devp, struct pt_regs *regs)
+superio_interrupt(int parent_irq, void *devp)
 {
        u8 results;
        u8 local_irq;
@@ -138,7 +138,7 @@ superio_interrupt(int parent_irq, void *devp, struct pt_regs *regs)
        }
 
        /* Call the appropriate device's interrupt */
-       __do_IRQ(local_irq, regs);
+       __do_IRQ(local_irq);
 
        /* set EOI - forces a new interrupt if a lower priority device
         * still needs service.
index 83ee095ec6e277573acda23eae20945f4d36fcd4..ff9f34453530d991d668fb35737c488a107b1c17 100644 (file)
@@ -216,7 +216,7 @@ void parport_daisy_fini(struct parport *port)
 
 struct pardevice *parport_open(int devnum, const char *name,
                                int (*pf) (void *), void (*kf) (void *),
-                               void (*irqf) (int, void *, struct pt_regs *),
+                               void (*irqf) (int, void *),
                                int flags, void *handle)
 {
        struct daisydev *p = topology;
index 7ff09f0f858f76e9cea359b9b96107d815db4b25..5accaa7bde313f9d62a877a27681d404cd5ea4c8 100644 (file)
@@ -571,7 +571,7 @@ static int parport_ieee1284_ack_data_avail (struct parport *port)
 #endif /* IEEE1284 support */
 
 /* Handle an interrupt. */
-void parport_ieee1284_interrupt (int which, void *handle, struct pt_regs *regs)
+void parport_ieee1284_interrupt (int which, void *handle)
 {
        struct parport *port = handle;
        parport_ieee1284_wakeup (port);
index 5126e74ac2ec4f355a46881e51d780b722588890..a0afaee5ebe573edee706796d25371afd8d7f5ae 100644 (file)
@@ -138,9 +138,9 @@ static unsigned char amiga_read_status(struct parport *p)
 }
 
 /* as this ports irq handling is already done, we use a generic funktion */
-static irqreturn_t amiga_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t amiga_interrupt(int irq, void *dev_id)
 {
-       parport_generic_irq(irq, (struct parport *) dev_id, regs);
+       parport_generic_irq(irq, (struct parport *) dev_id);
        return IRQ_HANDLED;
 }
 
index 78c3f34108bc1b8c618b9364ac8584e0acf8598c..6ea9929b8c7f60b77e138e3863a1469ac30a3bf0 100644 (file)
@@ -104,9 +104,9 @@ parport_atari_restore_state(struct parport *p, struct parport_state *s)
 }
 
 static irqreturn_t
-parport_atari_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+parport_atari_interrupt(int irq, void *dev_id)
 {
-       parport_generic_irq(irq, (struct parport *) dev_id, regs);
+       parport_generic_irq(irq, (struct parport *) dev_id);
        return IRQ_HANDLED;
 }
 
index 1850632590fdc9def3f2290e7151b8de04fa268a..74f4e9742c6c52cdbc87e9261ad2b89b1cddb540 100644 (file)
@@ -233,9 +233,9 @@ parport_ax88796_restore_state(struct parport *p, struct parport_state *s)
 }
 
 static irqreturn_t
-parport_ax88796_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+parport_ax88796_interrupt(int irq, void *dev_id)
 {
-        parport_generic_irq(irq, dev_id, regs);
+        parport_generic_irq(irq, dev_id);
         return IRQ_HANDLED;
 }
 
index 7352104f7b306b5e01fad48bf5c6ca135b3fde94..a7c5ead9a3d38ab146811f4077a5499c5e0f8e74 100644 (file)
@@ -81,9 +81,9 @@ static int clear_epp_timeout(struct parport *pb)
  * of these are in parport_gsc.h.
  */
 
-static irqreturn_t parport_gsc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t parport_gsc_interrupt(int irq, void *dev_id)
 {
-       parport_generic_irq(irq, (struct parport *) dev_id, regs);
+       parport_generic_irq(irq, (struct parport *) dev_id);
        return IRQ_HANDLED;
 }
 
index 46e06e596d73465adb7954177d79b76600663810..e3e19277030a9517e4766bf0d351ef01dbd44720 100644 (file)
@@ -548,10 +548,8 @@ static void parport_ip32_dma_setup_context(unsigned int limit)
  * parport_ip32_dma_interrupt - DMA interrupt handler
  * @irq:       interrupt number
  * @dev_id:    unused
- * @regs:      pointer to &struct pt_regs
  */
-static irqreturn_t parport_ip32_dma_interrupt(int irq, void *dev_id,
-                                             struct pt_regs *regs)
+static irqreturn_t parport_ip32_dma_interrupt(int irq, void *dev_id)
 {
        if (parport_ip32_dma.left)
                pr_trace(NULL, "(%d): ctx=%d", irq, parport_ip32_dma.ctx);
@@ -560,8 +558,7 @@ static irqreturn_t parport_ip32_dma_interrupt(int irq, void *dev_id,
 }
 
 #if DEBUG_PARPORT_IP32
-static irqreturn_t parport_ip32_merr_interrupt(int irq, void *dev_id,
-                                              struct pt_regs *regs)
+static irqreturn_t parport_ip32_merr_interrupt(int irq, void *dev_id)
 {
        pr_trace1(NULL, "(%d)", irq);
        return IRQ_HANDLED;
@@ -772,13 +769,11 @@ static inline void parport_ip32_wakeup(struct parport *p)
  * parport_ip32_interrupt - interrupt handler
  * @irq:       interrupt number
  * @dev_id:    pointer to &struct parport
- * @regs:      pointer to &struct pt_regs
  *
  * Caught interrupts are forwarded to the upper parport layer if IRQ_mode is
  * %PARPORT_IP32_IRQ_FWD.
  */
-static irqreturn_t parport_ip32_interrupt(int irq, void *dev_id,
-                                         struct pt_regs *regs)
+static irqreturn_t parport_ip32_interrupt(int irq, void *dev_id)
 {
        struct parport * const p = dev_id;
        struct parport_ip32_private * const priv = p->physport->private_data;
index b2b8092a2b39104192de7e8a659e40fc399d8190..e5b0a544de40f4565ff9558eeb961ef4097351a0 100644 (file)
@@ -211,7 +211,7 @@ static void mfc3_change_mode( struct parport *p, int m)
 
 static int use_cnt = 0;
 
-static irqreturn_t mfc3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t mfc3_interrupt(int irq, void *dev_id)
 {
        int i;
 
@@ -219,7 +219,7 @@ static irqreturn_t mfc3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                if (this_port[i] != NULL)
                        if (pia(this_port[i])->crb & 128) { /* Board caused interrupt */
                                dummy = pia(this_port[i])->pprb; /* clear irq bit */
-                               parport_generic_irq(irq, this_port[i], regs);
+                               parport_generic_irq(irq, this_port[i]);
                        }
        return IRQ_HANDLED;
 }
index fe800dc0be9f7fedfdf69e92ff262ebe0b51d787..39c96641bc72cdf0bdc6a9d71a192a99a4f30e8b 100644 (file)
@@ -270,9 +270,9 @@ static int clear_epp_timeout(struct parport *pb)
  * of these are in parport_pc.h.
  */
 
-static irqreturn_t parport_pc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t parport_pc_interrupt(int irq, void *dev_id)
 {
-       parport_generic_irq(irq, (struct parport *) dev_id, regs);
+       parport_generic_irq(irq, (struct parport *) dev_id);
        /* FIXME! Was it really ours? */
        return IRQ_HANDLED;
 }
index fac333b279bf1f7541b2f82548079bb0bcbbfe70..9793533276ecc1958fd1d8a1cf5c599b6e08b292 100644 (file)
@@ -46,9 +46,9 @@
 #define dprintk(x)
 #endif
 
-static irqreturn_t parport_sunbpp_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t parport_sunbpp_interrupt(int irq, void *dev_id)
 {
-       parport_generic_irq(irq, (struct parport *) dev_id, regs);
+       parport_generic_irq(irq, (struct parport *) dev_id);
        return IRQ_HANDLED;
 }
 
index 94dc506b83d13ea2089105f709c9bbd62d102c10..fd9129e424f906e6e5a65de04cafb5b843385ba9 100644 (file)
@@ -519,7 +519,7 @@ void parport_remove_port(struct parport *port)
 struct pardevice *
 parport_register_device(struct parport *port, const char *name,
                        int (*pf)(void *), void (*kf)(void *),
-                       void (*irq_func)(int, void *, struct pt_regs *), 
+                       void (*irq_func)(int, void *), 
                        int flags, void *handle)
 {
        struct pardevice *tmp;
index 30294127a0aa90484b907c235d4424ee773336b0..ecc50db8585ab287a9e25ca316f039a8546eef1e 100644 (file)
@@ -55,7 +55,7 @@ config PCI_DEBUG
 config HT_IRQ
        bool "Interrupts on hypertransport devices"
        default y
-       depends on X86_LOCAL_APIC && X86_IO_APIC
+       depends on PCI && X86_LOCAL_APIC && X86_IO_APIC
        help
           This allows native hypertransport devices to use interrupts.
 
index 51cb9f817c22a6f8ec6c25db2b8f9a57c97b1d65..270a33cc08f6185dddde35c79ad5f9f1364831e9 100644 (file)
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/pci.h>
+#include <linux/pci_hotplug.h>
 #include <acpi/acpi.h>
 #include <acpi/acpi_bus.h>
 #include <acpi/actypes.h>
-#include "pci_hotplug.h"
 
 #define MY_NAME        "acpi_pcihp"
 
index 7fff07e877c71982b89b672eea06b7617d89e13e..59c5b242d86de99054f0c0486cc602e337c1db00 100644 (file)
@@ -38,7 +38,7 @@
 #include <linux/acpi.h>
 #include <linux/kobject.h>     /* for KOBJ_NAME_LEN */
 #include <linux/mutex.h>
-#include "pci_hotplug.h"
+#include <linux/pci_hotplug.h>
 
 #define dbg(format, arg...)                                    \
        do {                                                    \
index e2fef60c2d06133818c413e2d37db98617e320d9..c57d9d5ce84e572e0ff39ada8fe81a6439d637e0 100644 (file)
 
 #include <linux/kernel.h>
 #include <linux/pci.h>
+#include <linux/pci_hotplug.h>
 #include <linux/slab.h>
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
-#include "pci_hotplug.h"
 #include "acpiphp.h"
 
 #define MY_NAME        "acpiphp"
index 83e8e4412de5834fff05c3558cf911d94146f48f..c44311ac2fd36ee1de1693e8fc7695acbd2e6101 100644 (file)
 
 #include <linux/kernel.h>
 #include <linux/pci.h>
+#include <linux/pci_hotplug.h>
 #include <linux/smp_lock.h>
 #include <linux/mutex.h>
 
 #include "../pci.h"
-#include "pci_hotplug.h"
 #include "acpiphp.h"
 
 static LIST_HEAD(bridge_list);
index d0a07d9ab30c8e314dad00a2eab0becbf118d788..bd40aee10e16442b585ee374fc01ef2df476798a 100644 (file)
@@ -35,7 +35,6 @@
 #include <linux/moduleparam.h>
 
 #include "acpiphp.h"
-#include "pci_hotplug.h"
 
 #define DRIVER_VERSION "1.0.1"
 #define DRIVER_AUTHOR  "Irene Zubarev <zubarev@us.ibm.com>, Vernon Mauery <vernux@us.ibm.com>"
index d5df5871cfa200eb5cfb1c67408340c31eff82b3..684551559d4420b7b9f436ee879ceb75cf15a296 100644 (file)
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/pci.h>
+#include <linux/pci_hotplug.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/smp_lock.h>
 #include <asm/atomic.h>
 #include <linux/delay.h>
-#include "pci_hotplug.h"
 #include "cpci_hotplug.h"
 
 #define DRIVER_AUTHOR  "Scott Murray <scottm@somanetworks.com>"
@@ -342,7 +342,7 @@ cpci_hp_unregister_bus(struct pci_bus *bus)
 
 /* This is the interrupt mode interrupt handler */
 static irqreturn_t
-cpci_hp_intr(int irq, void *data, struct pt_regs *regs)
+cpci_hp_intr(int irq, void *data)
 {
        dbg("entered cpci_hp_intr");
 
index 4afcaffd031c04b3e10251101a39e29f89c03fd4..7b1beaad2752ef731a41e2be9d91e5189ce41fe8 100644 (file)
@@ -26,9 +26,9 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/pci.h>
+#include <linux/pci_hotplug.h>
 #include <linux/proc_fs.h>
 #include "../pci.h"
-#include "pci_hotplug.h"
 #include "cpci_hotplug.h"
 
 #define MY_NAME        "cpci_hotplug"
index e847f0d6c7fea74dd00e3a757a7c2ea8b4e2d159..f3852a6b74eada8b19bc732faf27b383897a9075 100644 (file)
@@ -84,7 +84,7 @@ static int __init validate_parameters(void)
 
        if(!bridge) {
                info("not configured, disabling.");
-               return 1;
+               return -EINVAL;
        }
        str = bridge;
        if(!*str)
@@ -147,7 +147,7 @@ static int __init cpcihp_generic_init(void)
 
        info(DRIVER_DESC " version: " DRIVER_VERSION);
        status = validate_parameters();
-       if(status != 0)
+       if (status)
                return status;
 
        r = request_region(port, 1, "#ENUM hotswap signal register");
index c74e9e37e76b2ddb67adf5f56232c9e32c027735..298ad7f3f4f43aada7d324f97a12d39c082fc37e 100644 (file)
@@ -28,7 +28,6 @@
 #ifndef _CPQPHP_H
 #define _CPQPHP_H
 
-#include "pci_hotplug.h"
 #include <linux/interrupt.h>
 #include <asm/io.h>            /* for read? and write? functions */
 #include <linux/delay.h>       /* for delays */
@@ -409,7 +408,7 @@ extern void cpqhp_remove_debugfs_files              (struct controller *ctrl);
 
 /* controller functions */
 extern void    cpqhp_pushbutton_thread         (unsigned long event_pointer);
-extern irqreturn_t cpqhp_ctrl_intr             (int IRQ, void *data, struct pt_regs *regs);
+extern irqreturn_t cpqhp_ctrl_intr             (int IRQ, void *data);
 extern int     cpqhp_find_available_resources  (struct controller *ctrl, void __iomem *rom_start);
 extern int     cpqhp_event_start_thread        (void);
 extern void    cpqhp_event_stop_thread         (void);
index 1fc259913b68448b5a0b7e798d0b68ca08ae57e8..5617cfdadc5c64b19b49a08c041b28fb78c52919 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/slab.h>
 #include <linux/workqueue.h>
 #include <linux/pci.h>
+#include <linux/pci_hotplug.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 
index ae2dd36efef2c0a06fbeaa6a16cc145c63e927b5..79ff6b4de3a61ea9f9b21262074625c49c563d52 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/wait.h>
 #include <linux/smp_lock.h>
 #include <linux/pci.h>
+#include <linux/pci_hotplug.h>
 #include "cpqphp.h"
 
 static u32 configure_new_device(struct controller* ctrl, struct pci_func *func,
@@ -889,7 +890,7 @@ int cpqhp_resource_sort_and_combine(struct pci_resource **head)
 }
 
 
-irqreturn_t cpqhp_ctrl_intr(int IRQ, void *data, struct pt_regs *regs)
+irqreturn_t cpqhp_ctrl_intr(int IRQ, void *data)
 {
        struct controller *ctrl = data;
        u8 schedule_flag = 0;
index cf0878917537e912425b8f619c0564765da39f94..298a6cfd84069fce3845a9ad9c14989449a9450d 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/slab.h>
 #include <linux/workqueue.h>
 #include <linux/pci.h>
+#include <linux/pci_hotplug.h>
 #include <linux/init.h>
 #include <asm/uaccess.h>
 #include "cpqphp.h"
index 0d9688952f4af4cba74e1dfb296da89693d08934..fc7c74d725955794141093e7a41217bd3964dd06 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/workqueue.h>
 #include <linux/proc_fs.h>
 #include <linux/pci.h>
+#include <linux/pci_hotplug.h>
 #include "../pci.h"
 #include "cpqphp.h"
 #include "cpqphp_nvram.h"
index 5bab666cd67e138015657f23ef837bea332c5a6e..634f74d919d3d1c8fbc9e0bc5dadc99d5bb5d5b5 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/proc_fs.h>
 #include <linux/workqueue.h>
 #include <linux/pci.h>
+#include <linux/pci_hotplug.h>
 #include <linux/debugfs.h>
 #include "cpqphp.h"
 
index 05a4f0f9018620b5f6999c701d8a73ffbb477659..e27907c91d9232ab99e7fd8261d1983c19f71680 100644 (file)
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/pci.h>
+#include <linux/pci_hotplug.h>
 #include <linux/init.h>
 #include <linux/string.h>
 #include <linux/slab.h>
-#include "pci_hotplug.h"
 #include "../pci.h"
 
 #if !defined(MODULE)
@@ -181,7 +181,9 @@ static void pci_rescan_slot(struct pci_dev *temp)
 
        if (!pci_read_config_byte(temp, PCI_HEADER_TYPE, &hdr_type)) {
                temp->hdr_type = hdr_type & 0x7f;
-               if (!pci_find_slot(bus->number, temp->devfn)) {
+               if ((dev = pci_get_slot(bus, temp->devfn)) != NULL)
+                       pci_dev_put(dev);
+               else {
                        dev = pci_scan_single_device(bus, temp->devfn);
                        if (dev) {
                                dbg("New device on %s function %x:%x\n",
@@ -205,7 +207,9 @@ static void pci_rescan_slot(struct pci_dev *temp)
                                continue;
                        temp->hdr_type = hdr_type & 0x7f;
 
-                       if (!pci_find_slot(bus->number, temp->devfn)) {
+                       if ((dev = pci_get_slot(bus, temp->devfn)) != NULL)
+                               pci_dev_put(dev);
+                       else {
                                dev = pci_scan_single_device(bus, temp->devfn);
                                if (dev) {
                                        dbg("New device on %s function %x:%x\n",
@@ -305,7 +309,7 @@ static int disable_slot(struct hotplug_slot *slot)
        /* search for subfunctions and disable them first */
        if (!(dslot->dev->devfn & 7)) {
                for (func = 1; func < 8; func++) {
-                       dev = pci_find_slot(dslot->dev->bus->number,
+                       dev = pci_get_slot(dslot->dev->bus,
                                        dslot->dev->devfn + func);
                        if (dev) {
                                hslot = get_slot_from_dev(dev);
@@ -315,6 +319,7 @@ static int disable_slot(struct hotplug_slot *slot)
                                        err("Hotplug slot not found for subfunction of PCI device\n");
                                        return -ENODEV;
                                }
+                               pci_dev_put(dev);
                        } else
                                dbg("No device in slot found\n");
                }
index dba6d8ca9bda291dd08e1651ae554ff212313d00..612d96301509c8e9d2fbb003d1a751b46e339cd7 100644 (file)
@@ -30,7 +30,7 @@
  *
  */
 
-#include "pci_hotplug.h"
+#include <linux/pci_hotplug.h>
 
 extern int ibmphp_debug;
 
diff --git a/drivers/pci/hotplug/pci_hotplug.h b/drivers/pci/hotplug/pci_hotplug.h
deleted file mode 100644 (file)
index 772523d..0000000
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * PCI HotPlug Core Functions
- *
- * Copyright (C) 1995,2001 Compaq Computer Corporation
- * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
- * Copyright (C) 2001 IBM Corp.
- *
- * 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; 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, GOOD TITLE or
- * NON INFRINGEMENT.  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.
- *
- * Send feedback to <greg@kroah.com>
- *
- */
-#ifndef _PCI_HOTPLUG_H
-#define _PCI_HOTPLUG_H
-
-
-/* These values come from the PCI Hotplug Spec */
-enum pci_bus_speed {
-       PCI_SPEED_33MHz                 = 0x00,
-       PCI_SPEED_66MHz                 = 0x01,
-       PCI_SPEED_66MHz_PCIX            = 0x02,
-       PCI_SPEED_100MHz_PCIX           = 0x03,
-       PCI_SPEED_133MHz_PCIX           = 0x04,
-       PCI_SPEED_66MHz_PCIX_ECC        = 0x05,
-       PCI_SPEED_100MHz_PCIX_ECC       = 0x06,
-       PCI_SPEED_133MHz_PCIX_ECC       = 0x07,
-       PCI_SPEED_66MHz_PCIX_266        = 0x09,
-       PCI_SPEED_100MHz_PCIX_266       = 0x0a,
-       PCI_SPEED_133MHz_PCIX_266       = 0x0b,
-       PCI_SPEED_66MHz_PCIX_533        = 0x11,
-       PCI_SPEED_100MHz_PCIX_533       = 0x12,
-       PCI_SPEED_133MHz_PCIX_533       = 0x13,
-       PCI_SPEED_UNKNOWN               = 0xff,
-};
-
-/* These values come from the PCI Express Spec */
-enum pcie_link_width {
-       PCIE_LNK_WIDTH_RESRV    = 0x00,
-       PCIE_LNK_X1             = 0x01,
-       PCIE_LNK_X2             = 0x02,
-       PCIE_LNK_X4             = 0x04,
-       PCIE_LNK_X8             = 0x08,
-       PCIE_LNK_X12            = 0x0C,
-       PCIE_LNK_X16            = 0x10,
-       PCIE_LNK_X32            = 0x20,
-       PCIE_LNK_WIDTH_UNKNOWN  = 0xFF,
-};
-
-enum pcie_link_speed {
-       PCIE_2PT5GB             = 0x14,
-       PCIE_LNK_SPEED_UNKNOWN  = 0xFF,
-};
-
-struct hotplug_slot;
-struct hotplug_slot_attribute {
-       struct attribute attr;
-       ssize_t (*show)(struct hotplug_slot *, char *);
-       ssize_t (*store)(struct hotplug_slot *, const char *, size_t);
-};
-#define to_hotplug_attr(n) container_of(n, struct hotplug_slot_attribute, attr);
-
-/**
- * struct hotplug_slot_ops -the callbacks that the hotplug pci core can use
- * @owner: The module owner of this structure
- * @enable_slot: Called when the user wants to enable a specific pci slot
- * @disable_slot: Called when the user wants to disable a specific pci slot
- * @set_attention_status: Called to set the specific slot's attention LED to
- * the specified value
- * @hardware_test: Called to run a specified hardware test on the specified
- * slot.
- * @get_power_status: Called to get the current power status of a slot.
- *     If this field is NULL, the value passed in the struct hotplug_slot_info
- *     will be used when this value is requested by a user.
- * @get_attention_status: Called to get the current attention status of a slot.
- *     If this field is NULL, the value passed in the struct hotplug_slot_info
- *     will be used when this value is requested by a user.
- * @get_latch_status: Called to get the current latch status of a slot.
- *     If this field is NULL, the value passed in the struct hotplug_slot_info
- *     will be used when this value is requested by a user.
- * @get_adapter_status: Called to get see if an adapter is present in the slot or not.
- *     If this field is NULL, the value passed in the struct hotplug_slot_info
- *     will be used when this value is requested by a user.
- * @get_address: Called to get pci address of a slot.
- *     If this field is NULL, the value passed in the struct hotplug_slot_info
- *     will be used when this value is requested by a user.
- * @get_max_bus_speed: Called to get the max bus speed for a slot.
- *     If this field is NULL, the value passed in the struct hotplug_slot_info
- *     will be used when this value is requested by a user.
- * @get_cur_bus_speed: Called to get the current bus speed for a slot.
- *     If this field is NULL, the value passed in the struct hotplug_slot_info
- *     will be used when this value is requested by a user.
- *
- * The table of function pointers that is passed to the hotplug pci core by a
- * hotplug pci driver.  These functions are called by the hotplug pci core when
- * the user wants to do something to a specific slot (query it for information,
- * set an LED, enable / disable power, etc.)
- */
-struct hotplug_slot_ops {
-       struct module *owner;
-       int (*enable_slot)              (struct hotplug_slot *slot);
-       int (*disable_slot)             (struct hotplug_slot *slot);
-       int (*set_attention_status)     (struct hotplug_slot *slot, u8 value);
-       int (*hardware_test)            (struct hotplug_slot *slot, u32 value);
-       int (*get_power_status)         (struct hotplug_slot *slot, u8 *value);
-       int (*get_attention_status)     (struct hotplug_slot *slot, u8 *value);
-       int (*get_latch_status)         (struct hotplug_slot *slot, u8 *value);
-       int (*get_adapter_status)       (struct hotplug_slot *slot, u8 *value);
-       int (*get_address)              (struct hotplug_slot *slot, u32 *value);
-       int (*get_max_bus_speed)        (struct hotplug_slot *slot, enum pci_bus_speed *value);
-       int (*get_cur_bus_speed)        (struct hotplug_slot *slot, enum pci_bus_speed *value);
-};
-
-/**
- * struct hotplug_slot_info - used to notify the hotplug pci core of the state of the slot
- * @power: if power is enabled or not (1/0)
- * @attention_status: if the attention light is enabled or not (1/0)
- * @latch_status: if the latch (if any) is open or closed (1/0)
- * @adapter_present: if there is a pci board present in the slot or not (1/0)
- * @address: (domain << 16 | bus << 8 | dev)
- *
- * Used to notify the hotplug pci core of the status of a specific slot.
- */
-struct hotplug_slot_info {
-       u8      power_status;
-       u8      attention_status;
-       u8      latch_status;
-       u8      adapter_status;
-       u32     address;
-       enum pci_bus_speed      max_bus_speed;
-       enum pci_bus_speed      cur_bus_speed;
-};
-
-/**
- * struct hotplug_slot - used to register a physical slot with the hotplug pci core
- * @name: the name of the slot being registered.  This string must
- * be unique amoung slots registered on this system.
- * @ops: pointer to the &struct hotplug_slot_ops to be used for this slot
- * @info: pointer to the &struct hotplug_slot_info for the initial values for
- * this slot.
- * @release: called during pci_hp_deregister to free memory allocated in a
- * hotplug_slot structure.
- * @private: used by the hotplug pci controller driver to store whatever it
- * needs.
- */
-struct hotplug_slot {
-       char                            *name;
-       struct hotplug_slot_ops         *ops;
-       struct hotplug_slot_info        *info;
-       void (*release) (struct hotplug_slot *slot);
-       void                            *private;
-
-       /* Variables below this are for use only by the hotplug pci core. */
-       struct list_head                slot_list;
-       struct kobject                  kobj;
-};
-#define to_hotplug_slot(n) container_of(n, struct hotplug_slot, kobj)
-
-extern int pci_hp_register             (struct hotplug_slot *slot);
-extern int pci_hp_deregister           (struct hotplug_slot *slot);
-extern int __must_check pci_hp_change_slot_info        (struct hotplug_slot *slot,
-                                                struct hotplug_slot_info *info);
-extern struct subsystem pci_hotplug_slots_subsys;
-
-/* PCI Setting Record (Type 0) */
-struct hpp_type0 {
-       u32 revision;
-       u8  cache_line_size;
-       u8  latency_timer;
-       u8  enable_serr;
-       u8  enable_perr;
-};
-
-/* PCI-X Setting Record (Type 1) */
-struct hpp_type1 {
-       u32 revision;
-       u8  max_mem_read;
-       u8  avg_max_split;
-       u16 tot_max_split;
-};
-
-/* PCI Express Setting Record (Type 2) */
-struct hpp_type2 {
-       u32 revision;
-       u32 unc_err_mask_and;
-       u32 unc_err_mask_or;
-       u32 unc_err_sever_and;
-       u32 unc_err_sever_or;
-       u32 cor_err_mask_and;
-       u32 cor_err_mask_or;
-       u32 adv_err_cap_and;
-       u32 adv_err_cap_or;
-       u16 pci_exp_devctl_and;
-       u16 pci_exp_devctl_or;
-       u16 pci_exp_lnkctl_and;
-       u16 pci_exp_lnkctl_or;
-       u32 sec_unc_err_sever_and;
-       u32 sec_unc_err_sever_or;
-       u32 sec_unc_err_mask_and;
-       u32 sec_unc_err_mask_or;
-};
-
-struct hotplug_params {
-       struct hpp_type0 *t0;           /* Type0: NULL if not available */
-       struct hpp_type1 *t1;           /* Type1: NULL if not available */
-       struct hpp_type2 *t2;           /* Type2: NULL if not available */
-       struct hpp_type0 type0_data;
-       struct hpp_type1 type1_data;
-       struct hpp_type2 type2_data;
-};
-
-#ifdef CONFIG_ACPI
-#include <acpi/acpi.h>
-#include <acpi/acpi_bus.h>
-#include <acpi/actypes.h>
-extern acpi_status acpi_run_oshp(acpi_handle handle);
-extern acpi_status acpi_get_hp_params_from_firmware(struct pci_bus *bus,
-                               struct hotplug_params *hpp);
-int acpi_root_bridge(acpi_handle handle);
-#endif
-#endif
-
index e2823ea9c4ed829ffda3298da97ac3574dc40312..f5d632e723236b556289e5af2b12ae32ad6abc78 100644 (file)
@@ -21,9 +21,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * Send feedback to <greg@kroah.com>
- *
- * Filesystem portion based on work done by Pat Mochel on ddfs/driverfs
+ * Send feedback to <kristen.c.accardi@intel.com>
  *
  */
 
@@ -32,6 +30,8 @@
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/list.h>
+#include <linux/kobject.h>
+#include <linux/sysfs.h>
 #include <linux/pagemap.h>
 #include <linux/slab.h>
 #include <linux/smp_lock.h>
 #include <linux/mount.h>
 #include <linux/namei.h>
 #include <linux/pci.h>
+#include <linux/pci_hotplug.h>
 #include <asm/uaccess.h>
-#include <linux/kobject.h>
-#include <linux/sysfs.h>
-#include "pci_hotplug.h"
-
 
 #define MY_NAME        "pci_hotplug"
 
index eaea9d36a1bb2096104372b751decf81163efad7..4fb12fcda563efb2f581a3f65156a6b759b681c6 100644 (file)
 
 #include <linux/types.h>
 #include <linux/pci.h>
+#include <linux/pci_hotplug.h>
 #include <linux/delay.h>
 #include <linux/sched.h>               /* signal_pending() */
 #include <linux/pcieport_if.h>
 #include <linux/mutex.h>
-#include "pci_hotplug.h"
 
 #define MY_NAME        "pciehp"
 
@@ -92,6 +92,7 @@ struct php_ctlr_state_s {
 struct controller {
        struct controller *next;
        struct mutex crit_sect;         /* critical section mutex */
+       struct mutex ctrl_lock;         /* controller lock */
        struct php_ctlr_state_s *hpc_ctlr_handle; /* HPC controller handle */
        int num_slots;                  /* Number of slots on ctlr */
        int slot_num_inc;               /* 1 or -1 */
@@ -166,10 +167,10 @@ struct controller {
  * error Messages
  */
 #define msg_initialization_err "Initialization failure, error=%d\n"
-#define msg_button_on          "PCI slot #%d - powering on due to button press.\n"
-#define msg_button_off         "PCI slot #%d - powering off due to button press.\n"
-#define msg_button_cancel      "PCI slot #%d - action canceled due to button press.\n"
-#define msg_button_ignore      "PCI slot #%d - button press ignored.  (action in progress...)\n"
+#define msg_button_on          "PCI slot #%s - powering on due to button press.\n"
+#define msg_button_off         "PCI slot #%s - powering off due to button press.\n"
+#define msg_button_cancel      "PCI slot #%s - action canceled due to button press.\n"
+#define msg_button_ignore      "PCI slot #%s - button press ignored.  (action in progress...)\n"
 
 /* controller functions */
 extern int     pciehp_event_start_thread       (void);
index c67b7c3f1ddf3e485df6b5c820c6338214b5c670..f93e81e2d2c7873d408eca03365d88474ec1451d 100644 (file)
@@ -448,7 +448,7 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
        }
 
        /* Wait for exclusive access to hardware */
-       mutex_lock(&ctrl->crit_sect);
+       mutex_lock(&ctrl->ctrl_lock);
 
        t_slot->hpc_ops->get_adapter_status(t_slot, &value); /* Check if slot is occupied */
        
@@ -456,7 +456,7 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
                rc = t_slot->hpc_ops->power_off_slot(t_slot); /* Power off slot if not occupied*/
                if (rc) {
                        /* Done with exclusive hardware access */
-                       mutex_unlock(&ctrl->crit_sect);
+                       mutex_unlock(&ctrl->ctrl_lock);
                        goto err_out_free_ctrl_slot;
                } else
                        /* Wait for the command to complete */
@@ -464,7 +464,7 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
        }
 
        /* Done with exclusive hardware access */
-       mutex_unlock(&ctrl->crit_sect);
+       mutex_unlock(&ctrl->ctrl_lock);
 
        return 0;
 
index 41290a106bd8c4661fd1f1204c213a5db64c32ef..372c63e35aa99b47561c746f11fe00dbd661d9c3 100644 (file)
@@ -43,6 +43,11 @@ static int event_finished;
 static unsigned long pushbutton_pending;       /* = 0 */
 static unsigned long surprise_rm_pending;      /* = 0 */
 
+static inline char *slot_name(struct slot *p_slot)
+{
+       return p_slot->hotplug_slot->name;
+}
+
 u8 pciehp_handle_attention_button(u8 hp_slot, void *inst_id)
 {
        struct controller *ctrl = (struct controller *) inst_id;
@@ -68,7 +73,7 @@ u8 pciehp_handle_attention_button(u8 hp_slot, void *inst_id)
        /*
         *  Button pressed - See if need to TAKE ACTION!!!
         */
-       info("Button pressed on Slot(%d)\n", ctrl->first_slot + hp_slot);
+       info("Button pressed on Slot(%s)\n", slot_name(p_slot));
        taskInfo->event_type = INT_BUTTON_PRESS;
 
        if ((p_slot->state == BLINKINGON_STATE)
@@ -78,7 +83,7 @@ u8 pciehp_handle_attention_button(u8 hp_slot, void *inst_id)
                 * or hot-remove
                 */
                taskInfo->event_type = INT_BUTTON_CANCEL;
-               info("Button cancel on Slot(%d)\n", ctrl->first_slot + hp_slot);
+               info("Button cancel on Slot(%s)\n", slot_name(p_slot));
        } else if ((p_slot->state == POWERON_STATE)
                   || (p_slot->state == POWEROFF_STATE)) {
                /* Ignore if the slot is on power-on or power-off state; this 
@@ -86,7 +91,7 @@ u8 pciehp_handle_attention_button(u8 hp_slot, void *inst_id)
                 * hot-remove is undergoing
                 */
                taskInfo->event_type = INT_BUTTON_IGNORE;
-               info("Button ignore on Slot(%d)\n", ctrl->first_slot + hp_slot);
+               info("Button ignore on Slot(%s)\n", slot_name(p_slot));
        }
 
        if (rc)
@@ -122,13 +127,13 @@ u8 pciehp_handle_switch_change(u8 hp_slot, void *inst_id)
                /*
                 * Switch opened
                 */
-               info("Latch open on Slot(%d)\n", ctrl->first_slot + hp_slot);
+               info("Latch open on Slot(%s)\n", slot_name(p_slot));
                taskInfo->event_type = INT_SWITCH_OPEN;
        } else {
                /*
                 *  Switch closed
                 */
-               info("Latch close on Slot(%d)\n", ctrl->first_slot + hp_slot);
+               info("Latch close on Slot(%s)\n", slot_name(p_slot));
                taskInfo->event_type = INT_SWITCH_CLOSE;
        }
 
@@ -166,13 +171,13 @@ u8 pciehp_handle_presence_change(u8 hp_slot, void *inst_id)
                /*
                 * Card Present
                 */
-               info("Card present on Slot(%d)\n", ctrl->first_slot + hp_slot);
+               info("Card present on Slot(%s)\n", slot_name(p_slot));
                taskInfo->event_type = INT_PRESENCE_ON;
        } else {
                /*
                 * Not Present
                 */
-               info("Card not present on Slot(%d)\n", ctrl->first_slot + hp_slot);
+               info("Card not present on Slot(%s)\n", slot_name(p_slot));
                taskInfo->event_type = INT_PRESENCE_OFF;
        }
 
@@ -206,13 +211,13 @@ u8 pciehp_handle_power_fault(u8 hp_slot, void *inst_id)
                /*
                 * power fault Cleared
                 */
-               info("Power fault cleared on Slot(%d)\n", ctrl->first_slot + hp_slot);
+               info("Power fault cleared on Slot(%s)\n", slot_name(p_slot));
                taskInfo->event_type = INT_POWER_FAULT_CLEAR;
        } else {
                /*
                 *   power fault
                 */
-               info("Power fault on Slot(%d)\n", ctrl->first_slot + hp_slot);
+               info("Power fault on Slot(%s)\n", slot_name(p_slot));
                taskInfo->event_type = INT_POWER_FAULT;
                info("power fault bit %x set\n", hp_slot);
        }
@@ -229,13 +234,13 @@ u8 pciehp_handle_power_fault(u8 hp_slot, void *inst_id)
 static void set_slot_off(struct controller *ctrl, struct slot * pslot)
 {
        /* Wait for exclusive access to hardware */
-       mutex_lock(&ctrl->crit_sect);
+       mutex_lock(&ctrl->ctrl_lock);
 
        /* turn off slot, turn on Amber LED, turn off Green LED if supported*/
        if (POWER_CTRL(ctrl->ctrlcap)) {
                if (pslot->hpc_ops->power_off_slot(pslot)) {   
                        err("%s: Issue of Slot Power Off command failed\n", __FUNCTION__);
-                       mutex_unlock(&ctrl->crit_sect);
+                       mutex_unlock(&ctrl->ctrl_lock);
                        return;
                }
                wait_for_ctrl_irq (ctrl);
@@ -249,14 +254,14 @@ static void set_slot_off(struct controller *ctrl, struct slot * pslot)
        if (ATTN_LED(ctrl->ctrlcap)) { 
                if (pslot->hpc_ops->set_attention_status(pslot, 1)) {   
                        err("%s: Issue of Set Attention Led command failed\n", __FUNCTION__);
-                       mutex_unlock(&ctrl->crit_sect);
+                       mutex_unlock(&ctrl->ctrl_lock);
                        return;
                }
                wait_for_ctrl_irq (ctrl);
        }
 
        /* Done with exclusive hardware access */
-       mutex_unlock(&ctrl->crit_sect);
+       mutex_unlock(&ctrl->ctrl_lock);
 }
 
 /**
@@ -279,13 +284,13 @@ static int board_added(struct slot *p_slot)
                        ctrl->slot_device_offset, hp_slot);
 
        /* Wait for exclusive access to hardware */
-       mutex_lock(&ctrl->crit_sect);
+       mutex_lock(&ctrl->ctrl_lock);
 
        if (POWER_CTRL(ctrl->ctrlcap)) {
                /* Power on slot */
                rc = p_slot->hpc_ops->power_on_slot(p_slot);
                if (rc) {
-                       mutex_unlock(&ctrl->crit_sect);
+                       mutex_unlock(&ctrl->ctrl_lock);
                        return -1;
                }
 
@@ -301,7 +306,7 @@ static int board_added(struct slot *p_slot)
        }
 
        /* Done with exclusive hardware access */
-       mutex_unlock(&ctrl->crit_sect);
+       mutex_unlock(&ctrl->ctrl_lock);
 
        /* Wait for ~1 second */
        wait_for_ctrl_irq (ctrl);
@@ -335,7 +340,7 @@ static int board_added(struct slot *p_slot)
                pci_fixup_device(pci_fixup_final, ctrl->pci_dev);
        if (PWR_LED(ctrl->ctrlcap)) {
                /* Wait for exclusive access to hardware */
-               mutex_lock(&ctrl->crit_sect);
+               mutex_lock(&ctrl->ctrl_lock);
 
                p_slot->hpc_ops->green_led_on(p_slot);
   
@@ -343,7 +348,7 @@ static int board_added(struct slot *p_slot)
                wait_for_ctrl_irq (ctrl);
        
                /* Done with exclusive hardware access */
-               mutex_unlock(&ctrl->crit_sect);
+               mutex_unlock(&ctrl->ctrl_lock);
        }
        return 0;
 
@@ -375,14 +380,14 @@ static int remove_board(struct slot *p_slot)
        dbg("In %s, hp_slot = %d\n", __FUNCTION__, hp_slot);
 
        /* Wait for exclusive access to hardware */
-       mutex_lock(&ctrl->crit_sect);
+       mutex_lock(&ctrl->ctrl_lock);
 
        if (POWER_CTRL(ctrl->ctrlcap)) {
                /* power off slot */
                rc = p_slot->hpc_ops->power_off_slot(p_slot);
                if (rc) {
                        err("%s: Issue of Slot Disable command failed\n", __FUNCTION__);
-                       mutex_unlock(&ctrl->crit_sect);
+                       mutex_unlock(&ctrl->ctrl_lock);
                        return rc;
                }
                /* Wait for the command to complete */
@@ -398,7 +403,7 @@ static int remove_board(struct slot *p_slot)
        }
 
        /* Done with exclusive hardware access */
-       mutex_unlock(&ctrl->crit_sect);
+       mutex_unlock(&ctrl->ctrl_lock);
 
        return 0;
 }
@@ -445,7 +450,7 @@ static void pciehp_pushbutton_thread(unsigned long slot)
 
                if (pciehp_enable_slot(p_slot) && PWR_LED(p_slot->ctrl->ctrlcap)) {
                        /* Wait for exclusive access to hardware */
-                       mutex_lock(&p_slot->ctrl->crit_sect);
+                       mutex_lock(&p_slot->ctrl->ctrl_lock);
 
                        p_slot->hpc_ops->green_led_off(p_slot);
 
@@ -453,7 +458,7 @@ static void pciehp_pushbutton_thread(unsigned long slot)
                        wait_for_ctrl_irq (p_slot->ctrl);
 
                        /* Done with exclusive hardware access */
-                       mutex_unlock(&p_slot->ctrl->crit_sect);
+                       mutex_unlock(&p_slot->ctrl->ctrl_lock);
                }
                p_slot->state = STATIC_STATE;
        }
@@ -495,7 +500,7 @@ static void pciehp_surprise_rm_thread(unsigned long slot)
 
                if (pciehp_enable_slot(p_slot) && PWR_LED(p_slot->ctrl->ctrlcap)) {
                        /* Wait for exclusive access to hardware */
-                       mutex_lock(&p_slot->ctrl->crit_sect);
+                       mutex_lock(&p_slot->ctrl->ctrl_lock);
 
                        p_slot->hpc_ops->green_led_off(p_slot);
 
@@ -503,7 +508,7 @@ static void pciehp_surprise_rm_thread(unsigned long slot)
                        wait_for_ctrl_irq (p_slot->ctrl);
 
                        /* Done with exclusive hardware access */
-                       mutex_unlock(&p_slot->ctrl->crit_sect);
+                       mutex_unlock(&p_slot->ctrl->ctrl_lock);
                }
                p_slot->state = STATIC_STATE;
        }
@@ -616,7 +621,7 @@ static void interrupt_event_handler(struct controller *ctrl)
                                        switch (p_slot->state) {
                                        case BLINKINGOFF_STATE:
                                                /* Wait for exclusive access to hardware */
-                                               mutex_lock(&ctrl->crit_sect);
+                                               mutex_lock(&ctrl->ctrl_lock);
                                                
                                                if (PWR_LED(ctrl->ctrlcap)) {
                                                        p_slot->hpc_ops->green_led_on(p_slot);
@@ -630,11 +635,11 @@ static void interrupt_event_handler(struct controller *ctrl)
                                                        wait_for_ctrl_irq (ctrl);
                                                }
                                                /* Done with exclusive hardware access */
-                                               mutex_unlock(&ctrl->crit_sect);
+                                               mutex_unlock(&ctrl->ctrl_lock);
                                                break;
                                        case BLINKINGON_STATE:
                                                /* Wait for exclusive access to hardware */
-                                               mutex_lock(&ctrl->crit_sect);
+                                               mutex_lock(&ctrl->ctrl_lock);
 
                                                if (PWR_LED(ctrl->ctrlcap)) {
                                                        p_slot->hpc_ops->green_led_off(p_slot);
@@ -647,14 +652,14 @@ static void interrupt_event_handler(struct controller *ctrl)
                                                        wait_for_ctrl_irq (ctrl);
                                                }
                                                /* Done with exclusive hardware access */
-                                               mutex_unlock(&ctrl->crit_sect);
+                                               mutex_unlock(&ctrl->ctrl_lock);
 
                                                break;
                                        default:
                                                warn("Not a valid state\n");
                                                return;
                                        }
-                                       info(msg_button_cancel, p_slot->number);
+                                       info(msg_button_cancel, slot_name(p_slot));
                                        p_slot->state = STATIC_STATE;
                                }
                                /* ***********Button Pressed (No action on 1st press...) */
@@ -667,16 +672,16 @@ static void interrupt_event_handler(struct controller *ctrl)
                                                        /* slot is on */
                                                        dbg("slot is on\n");
                                                        p_slot->state = BLINKINGOFF_STATE;
-                                                       info(msg_button_off, p_slot->number);
+                                                       info(msg_button_off, slot_name(p_slot));
                                                } else {
                                                        /* slot is off */
                                                        dbg("slot is off\n");
                                                        p_slot->state = BLINKINGON_STATE;
-                                                       info(msg_button_on, p_slot->number);
+                                                       info(msg_button_on, slot_name(p_slot));
                                                }
 
                                                /* Wait for exclusive access to hardware */
-                                               mutex_lock(&ctrl->crit_sect);
+                                               mutex_lock(&ctrl->ctrl_lock);
 
                                                /* blink green LED and turn off amber */
                                                if (PWR_LED(ctrl->ctrlcap)) {
@@ -693,7 +698,7 @@ static void interrupt_event_handler(struct controller *ctrl)
                                                }
 
                                                /* Done with exclusive hardware access */
-                                               mutex_unlock(&ctrl->crit_sect);
+                                               mutex_unlock(&ctrl->ctrl_lock);
 
                                                init_timer(&p_slot->task_event);
                                                p_slot->task_event.expires = jiffies + 5 * HZ;   /* 5 second delay */
@@ -708,7 +713,7 @@ static void interrupt_event_handler(struct controller *ctrl)
                                        if (POWER_CTRL(ctrl->ctrlcap)) {
                                                dbg("power fault\n");
                                                /* Wait for exclusive access to hardware */
-                                               mutex_lock(&ctrl->crit_sect);
+                                               mutex_lock(&ctrl->ctrl_lock);
 
                                                if (ATTN_LED(ctrl->ctrlcap)) {
                                                        p_slot->hpc_ops->set_attention_status(p_slot, 1);
@@ -721,7 +726,7 @@ static void interrupt_event_handler(struct controller *ctrl)
                                                }
 
                                                /* Done with exclusive hardware access */
-                                               mutex_unlock(&ctrl->crit_sect);
+                                               mutex_unlock(&ctrl->ctrl_lock);
                                        }
                                }
                                /***********SURPRISE REMOVAL********************/
@@ -760,14 +765,16 @@ int pciehp_enable_slot(struct slot *p_slot)
 
        rc = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus);
        if (rc || !getstatus) {
-               info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number);
+               info("%s: no adapter on slot(%s)\n", __FUNCTION__,
+                    slot_name(p_slot));
                mutex_unlock(&p_slot->ctrl->crit_sect);
                return -ENODEV;
        }
        if (MRL_SENS(p_slot->ctrl->ctrlcap)) {  
                rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
                if (rc || getstatus) {
-                       info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number);
+                       info("%s: latch open on slot(%s)\n", __FUNCTION__,
+                            slot_name(p_slot));
                        mutex_unlock(&p_slot->ctrl->crit_sect);
                        return -ENODEV;
                }
@@ -776,12 +783,12 @@ int pciehp_enable_slot(struct slot *p_slot)
        if (POWER_CTRL(p_slot->ctrl->ctrlcap)) {        
                rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
                if (rc || getstatus) {
-                       info("%s: already enabled on slot(%x)\n", __FUNCTION__, p_slot->number);
+                       info("%s: already enabled on slot(%s)\n", __FUNCTION__,
+                            slot_name(p_slot));
                        mutex_unlock(&p_slot->ctrl->crit_sect);
                        return -EINVAL;
                }
        }
-       mutex_unlock(&p_slot->ctrl->crit_sect);
 
        p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
 
@@ -790,9 +797,9 @@ int pciehp_enable_slot(struct slot *p_slot)
                p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
        }
 
-       if (p_slot)
-               update_slot_info(p_slot);
+       update_slot_info(p_slot);
 
+       mutex_unlock(&p_slot->ctrl->crit_sect);
        return rc;
 }
 
@@ -811,7 +818,8 @@ int pciehp_disable_slot(struct slot *p_slot)
        if (!HP_SUPR_RM(p_slot->ctrl->ctrlcap)) {       
                ret = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus);
                if (ret || !getstatus) {
-                       info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number);
+                       info("%s: no adapter on slot(%s)\n", __FUNCTION__,
+                            slot_name(p_slot));
                        mutex_unlock(&p_slot->ctrl->crit_sect);
                        return -ENODEV;
                }
@@ -820,7 +828,8 @@ int pciehp_disable_slot(struct slot *p_slot)
        if (MRL_SENS(p_slot->ctrl->ctrlcap)) {  
                ret = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
                if (ret || getstatus) {
-                       info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number);
+                       info("%s: latch open on slot(%s)\n", __FUNCTION__,
+                            slot_name(p_slot));
                        mutex_unlock(&p_slot->ctrl->crit_sect);
                        return -ENODEV;
                }
@@ -829,16 +838,17 @@ int pciehp_disable_slot(struct slot *p_slot)
        if (POWER_CTRL(p_slot->ctrl->ctrlcap)) {        
                ret = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
                if (ret || !getstatus) {
-                       info("%s: already disabled slot(%x)\n", __FUNCTION__, p_slot->number);
+                       info("%s: already disabled slot(%s)\n", __FUNCTION__,
+                            slot_name(p_slot));
                        mutex_unlock(&p_slot->ctrl->crit_sect);
                        return -EINVAL;
                }
        }
 
-       mutex_unlock(&p_slot->ctrl->crit_sect);
-
        ret = remove_board(p_slot);
        update_slot_info(p_slot);
+
+       mutex_unlock(&p_slot->ctrl->crit_sect);
        return ret;
 }
 
index 6ab3b6cd2b54095fe3d1bdda65440b4e7c7129db..1c551c697c35bd8207ce349595850ddd8f8eefc9 100644 (file)
@@ -222,7 +222,7 @@ static struct php_ctlr_state_s *php_ctlr_list_head; /* HPC state linked list */
 static int ctlr_seq_num = 0;   /* Controller sequence # */
 static spinlock_t list_lock;
 
-static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs);
+static irqreturn_t pcie_isr(int IRQ, void *dev_id);
 
 static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int seconds);
 
@@ -239,7 +239,7 @@ static void int_poll_timeout(unsigned long lphp_ctlr)
        }
 
        /* Poll for interrupt events.  regs == NULL => polling */
-       pcie_isr( 0, (void *)php_ctlr, NULL );
+       pcie_isr( 0, (void *)php_ctlr );
 
        init_timer(&php_ctlr->int_poll_timer);
 
@@ -863,7 +863,7 @@ static int hpc_power_off_slot(struct slot * slot)
        return retval;
 }
 
-static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
+static irqreturn_t pcie_isr(int IRQ, void *dev_id)
 {
        struct controller *ctrl = NULL;
        struct php_ctlr_state_s *php_ctlr;
@@ -1402,6 +1402,8 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev)
                pdev->subsystem_vendor, pdev->subsystem_device);
 
        mutex_init(&ctrl->crit_sect);
+       mutex_init(&ctrl->ctrl_lock);
+
        /* setup wait queue */
        init_waitqueue_head(&ctrl->queue);
 
index 2b9e10e38613327bee8c6767609c2522892d12f8..50bcd3fe61da75d1eed921221726266b76a03f4e 100644 (file)
@@ -33,8 +33,8 @@
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/pci.h>
+#include <linux/pci_hotplug.h>
 #include <linux/init.h>
-#include "pci_hotplug.h"
 
 #define SLOT_NAME_SIZE 10
 struct slot {
index db69be85b4583100907368d580d03c35779a7576..6c5be3ff578c24b7a2755557b28f4b9602e17dda 100644 (file)
@@ -14,7 +14,7 @@
  */
 #include <linux/kobject.h>
 #include <linux/string.h>
-#include "pci_hotplug.h"
+#include <linux/pci_hotplug.h>
 #include "rpadlpar.h"
 
 #define DLPAR_KOBJ_NAME       "control"
index 310b6186c0e5f45aa19f11654a49c38fcb839458..2e7accf0f734fbfd2837b7635ce24d002548f7dd 100644 (file)
@@ -28,7 +28,7 @@
 #define _PPC64PHP_H
 
 #include <linux/pci.h>
-#include "pci_hotplug.h"
+#include <linux/pci_hotplug.h>
 
 #define DR_INDICATOR 9002
 #define DR_ENTITY_SENSE 9003
index 7288a3eccfb3e34b1bab1a8d2d9e6a762858d746..141486df235b6ec8ef60908086661778f031c3c3 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/pci.h>
+#include <linux/pci_hotplug.h>
 #include <linux/slab.h>
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
@@ -36,7 +37,6 @@
 #include "../pci.h"            /* for pci_add_new_bus */
                                /* and pci_do_scan_bus */
 #include "rpaphp.h"
-#include "pci_hotplug.h"
 
 int debug;
 static struct semaphore rpaphp_sem;
index f31d83c2c633c678d040190ff57b2f7246cce626..b62ad31a9739934e1c38b6138cf12f65e6629ee2 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/pci.h>
+#include <linux/pci_hotplug.h>
 #include <linux/proc_fs.h>
 #include <linux/types.h>
 #include <linux/mutex.h>
@@ -29,7 +30,6 @@
 #include <asm/sn/types.h>
 
 #include "../pci.h"
-#include "pci_hotplug.h"
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("SGI (prarit@sgi.com, dickie@sgi.com, habeck@sgi.com)");
index c7103ac5cd06b76da2c0ec60381003601bd98bc1..ea2087c34149f23244401e480b9cf491693b8a7c 100644 (file)
 
 #include <linux/types.h>
 #include <linux/pci.h>
+#include <linux/pci_hotplug.h>
 #include <linux/delay.h>
 #include <linux/sched.h>       /* signal_pending(), struct timer_list */
 #include <linux/mutex.h>
 
-#include "pci_hotplug.h"
-
 #if !defined(MODULE)
        #define MY_NAME "shpchp"
 #else
@@ -103,7 +102,6 @@ struct controller {
        u32 cap_offset;
        unsigned long mmio_base;
        unsigned long mmio_size;
-       volatile int cmd_busy;
 };
 
 
index 0f9798df470429a90f08d7f4e8824d5f234fc191..83a5226ba9ed4918c4e46fb8f964aaf9a1b90922 100644 (file)
@@ -218,7 +218,7 @@ static spinlock_t list_lock;
 
 static atomic_t shpchp_num_controllers = ATOMIC_INIT(0);
 
-static irqreturn_t shpc_isr(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t shpc_isr(int irq, void *dev_id);
 static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int sec);
 static int hpc_check_cmd_status(struct controller *ctrl);
 
@@ -276,7 +276,7 @@ static void int_poll_timeout(unsigned long lphp_ctlr)
        DBG_ENTER_ROUTINE
 
        /* Poll for interrupt events.  regs == NULL => polling */
-       shpc_isr(0, php_ctlr->callback_instance_id, NULL);
+       shpc_isr(0, php_ctlr->callback_instance_id);
 
        init_timer(&php_ctlr->int_poll_timer);
        if (!shpchp_poll_time)
@@ -302,21 +302,51 @@ static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int sec)
        add_timer(&php_ctlr->int_poll_timer);
 }
 
+static inline int is_ctrl_busy(struct controller *ctrl)
+{
+       u16 cmd_status = shpc_readw(ctrl, CMD_STATUS);
+       return cmd_status & 0x1;
+}
+
+/*
+ * Returns 1 if SHPC finishes executing a command within 1 sec,
+ * otherwise returns 0.
+ */
+static inline int shpc_poll_ctrl_busy(struct controller *ctrl)
+{
+       int i;
+
+       if (!is_ctrl_busy(ctrl))
+               return 1;
+
+       /* Check every 0.1 sec for a total of 1 sec */
+       for (i = 0; i < 10; i++) {
+               msleep(100);
+               if (!is_ctrl_busy(ctrl))
+                       return 1;
+       }
+
+       return 0;
+}
+
 static inline int shpc_wait_cmd(struct controller *ctrl)
 {
        int retval = 0;
-       unsigned int timeout_msec = shpchp_poll_mode ? 2000 : 1000;
-       unsigned long timeout = msecs_to_jiffies(timeout_msec);
-       int rc = wait_event_interruptible_timeout(ctrl->queue,
-                                                 !ctrl->cmd_busy, timeout);
-       if (!rc) {
+       unsigned long timeout = msecs_to_jiffies(1000);
+       int rc;
+
+       if (shpchp_poll_mode)
+               rc = shpc_poll_ctrl_busy(ctrl);
+       else
+               rc = wait_event_interruptible_timeout(ctrl->queue,
+                                               !is_ctrl_busy(ctrl), timeout);
+       if (!rc && is_ctrl_busy(ctrl)) {
                retval = -EIO;
-               err("Command not completed in %d msec\n", timeout_msec);
+               err("Command not completed in 1000 msec\n");
        } else if (rc < 0) {
                retval = -EINTR;
                info("Command was interrupted by a signal\n");
        }
-       ctrl->cmd_busy = 0;
 
        return retval;
 }
@@ -327,26 +357,15 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd)
        u16 cmd_status;
        int retval = 0;
        u16 temp_word;
-       int i;
 
        DBG_ENTER_ROUTINE 
 
        mutex_lock(&slot->ctrl->cmd_lock);
 
-       for (i = 0; i < 10; i++) {
-               cmd_status = shpc_readw(ctrl, CMD_STATUS);
-               
-               if (!(cmd_status & 0x1))
-                       break;
-               /*  Check every 0.1 sec for a total of 1 sec*/
-               msleep(100);
-       }
-
-       cmd_status = shpc_readw(ctrl, CMD_STATUS);
-       
-       if (cmd_status & 0x1) { 
+       if (!shpc_poll_ctrl_busy(ctrl)) {
                /* After 1 sec and and the controller is still busy */
-               err("%s : Controller is still busy after 1 sec.\n", __FUNCTION__);
+               err("%s : Controller is still busy after 1 sec.\n",
+                   __FUNCTION__);
                retval = -EBUSY;
                goto out;
        }
@@ -358,7 +377,6 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd)
        /* To make sure the Controller Busy bit is 0 before we send out the
         * command. 
         */
-       slot->ctrl->cmd_busy = 1;
        shpc_writew(ctrl, CMD, temp_word);
 
        /*
@@ -870,7 +888,7 @@ static int hpc_set_bus_speed_mode(struct slot * slot, enum pci_bus_speed value)
        return retval;
 }
 
-static irqreturn_t shpc_isr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t shpc_isr(int irq, void *dev_id)
 {
        struct controller *ctrl = (struct controller *)dev_id;
        struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle;
@@ -908,7 +926,6 @@ static irqreturn_t shpc_isr(int irq, void *dev_id, struct pt_regs *regs)
                serr_int &= ~SERR_INTR_RSVDZ_MASK;
                shpc_writel(ctrl, SERR_INTR_ENABLE, serr_int);
 
-               ctrl->cmd_busy = 0;
                wake_up_interruptible(&ctrl->queue);
        }
 
@@ -1101,7 +1118,7 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
 {
        struct php_ctlr_state_s *php_ctlr, *p;
        void *instance_id = ctrl;
-       int rc, num_slots = 0;
+       int rc = -1, num_slots = 0;
        u8 hp_slot;
        u32 shpc_base_offset;
        u32 tempdword, slot_reg, slot_config;
@@ -1167,11 +1184,15 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
        info("HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n", pdev->vendor, pdev->device, pdev->subsystem_vendor, 
                pdev->subsystem_device);
        
-       if (pci_enable_device(pdev))
+       rc = pci_enable_device(pdev);
+       if (rc) {
+               err("%s: pci_enable_device failed\n", __FUNCTION__);
                goto abort_free_ctlr;
+       }
 
        if (!request_mem_region(ctrl->mmio_base, ctrl->mmio_size, MY_NAME)) {
                err("%s: cannot reserve MMIO region\n", __FUNCTION__);
+               rc = -1;
                goto abort_free_ctlr;
        }
 
@@ -1180,6 +1201,7 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
                err("%s: cannot remap MMIO region %lx @ %lx\n", __FUNCTION__,
                    ctrl->mmio_size, ctrl->mmio_base);
                release_mem_region(ctrl->mmio_base, ctrl->mmio_size);
+               rc = -1;
                goto abort_free_ctlr;
        }
        dbg("%s: php_ctlr->creg %p\n", __FUNCTION__, php_ctlr->creg);
@@ -1282,8 +1304,10 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
         */
        if (atomic_add_return(1, &shpchp_num_controllers) == 1) {
                shpchp_wq = create_singlethread_workqueue("shpchpd");
-               if (!shpchp_wq)
-                       return -ENOMEM;
+               if (!shpchp_wq) {
+                       rc = -ENOMEM;
+                       goto abort_free_ctlr;
+               }
        }
 
        /*
@@ -1313,8 +1337,10 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
 
        /* We end up here for the many possible ways to fail this API.  */
 abort_free_ctlr:
+       if (php_ctlr->creg)
+               iounmap(php_ctlr->creg);
        kfree(php_ctlr);
 abort:
        DBG_LEAVE_ROUTINE
-       return -1;
+       return rc;
 }
index f9fdc54473c4aed27a7f0e865dae74017c352563..9fc9a34ef24a28e74ec07ca725eb0c6db91f29ac 100644 (file)
@@ -627,22 +627,24 @@ static int msix_capability_init(struct pci_dev *dev,
  * pci_msi_supported - check whether MSI may be enabled on device
  * @dev: pointer to the pci_dev data structure of MSI device function
  *
- * MSI must be globally enabled and supported by the device and its root
- * bus. But, the root bus is not easy to find since some architectures
- * have virtual busses on top of the PCI hierarchy (for instance the
- * hypertransport bus), while the actual bus where MSI must be supported
- * is below. So we test the MSI flag on all parent busses and assume
- * that no quirk will ever set the NO_MSI flag on a non-root bus.
+ * Look at global flags, the device itself, and its parent busses
+ * to return 0 if MSI are supported for the device.
  **/
 static
 int pci_msi_supported(struct pci_dev * dev)
 {
        struct pci_bus *bus;
 
+       /* MSI must be globally enabled and supported by the device */
        if (!pci_msi_enable || !dev || dev->no_msi)
                return -EINVAL;
 
-       /* check MSI flags of all parent busses */
+       /* Any bridge which does NOT route MSI transactions from it's
+        * secondary bus to it's primary bus must set NO_MSI flag on
+        * the secondary pci_bus.
+        * We expect only arch-specific PCI host bus controller driver
+        * or quirks for specific PCI bridges to be setting NO_MSI.
+        */
        for (bus = dev->bus; bus; bus = bus->parent)
                if (bus->bus_flags & PCI_BUS_FLAGS_NO_MSI)
                        return -EINVAL;
index 0d4ac027d53e832c508b4232bf961bec25915a90..04c43ef529ac279dcded06e2f9aad4fda716ff46 100644 (file)
@@ -85,11 +85,10 @@ static struct pcie_port_service_driver aerdrv = {
  * aer_irq - Root Port's ISR
  * @irq: IRQ assigned to Root Port
  * @context: pointer to Root Port data structure
- * @r: pointer struct pt_regs
  *
  * Invoked when Root Port detects AER messages.
  **/
-static irqreturn_t aer_irq(int irq, void *context, struct pt_regs * r)
+static irqreturn_t aer_irq(int irq, void *context)
 {
        unsigned int status, id;
        struct pcie_device *pdev = (struct pcie_device *)context;
index 67fcd176babdb8182242d9d038f5b665364654d6..3656e0349dd1d6ee4c6917203298b0d3b635d486 100644 (file)
@@ -9,6 +9,8 @@
 #ifndef _PORTDRV_H_
 #define _PORTDRV_H_
 
+#include <linux/compiler.h>
+
 #if !defined(PCI_CAP_ID_PME)
 #define PCI_CAP_ID_PME                 1
 #endif
@@ -39,7 +41,7 @@ extern int pcie_port_device_suspend(struct pci_dev *dev, pm_message_t state);
 extern int pcie_port_device_resume(struct pci_dev *dev);
 #endif
 extern void pcie_port_device_remove(struct pci_dev *dev);
-extern int pcie_port_bus_register(void);
+extern int __must_check pcie_port_bus_register(void);
 extern void pcie_port_bus_unregister(void);
 
 #endif /* _PORTDRV_H_ */
index bd6615b4d40eb7546521a41898b39bd3a0da47d1..b20a9b81dae2df5e9cca491b4c1504def575858c 100644 (file)
@@ -6,7 +6,6 @@
  * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com)
  */
 
-#include <linux/compiler.h>
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/kernel.h>
@@ -401,7 +400,7 @@ void pcie_port_device_remove(struct pci_dev *dev)
                pci_disable_msi(dev);
 }
 
-int __must_check pcie_port_bus_register(void)
+int pcie_port_bus_register(void)
 {
        return bus_register(&pcie_port_bus_type);
 }
index 037690e08f5f023a0e012806efbe9627b2450c7c..b4da7954611e2388025afe2fb80e8bb19ebb92cc 100644 (file)
@@ -37,7 +37,6 @@ static int pcie_portdrv_save_config(struct pci_dev *dev)
        return pci_save_state(dev);
 }
 
-#ifdef CONFIG_PM
 static int pcie_portdrv_restore_config(struct pci_dev *dev)
 {
        int retval;
@@ -50,6 +49,7 @@ static int pcie_portdrv_restore_config(struct pci_dev *dev)
        return 0;
 }
 
+#ifdef CONFIG_PM
 static int pcie_portdrv_suspend(struct pci_dev *dev, pm_message_t state)
 {
        int ret = pcie_port_device_suspend(dev, state);
index a3b0a5eb5054fefcc0e76e72b838fac1146fd310..e159d6604494acd62a617efcca0b6a3b26a8d4d4 100644 (file)
@@ -1067,3 +1067,95 @@ EXPORT_SYMBOL(pci_scan_bridge);
 EXPORT_SYMBOL(pci_scan_single_device);
 EXPORT_SYMBOL_GPL(pci_scan_child_bus);
 #endif
+
+static int __init pci_sort_bf_cmp(const struct pci_dev *a, const struct pci_dev *b)
+{
+       if      (pci_domain_nr(a->bus) < pci_domain_nr(b->bus)) return -1;
+       else if (pci_domain_nr(a->bus) > pci_domain_nr(b->bus)) return  1;
+
+       if      (a->bus->number < b->bus->number) return -1;
+       else if (a->bus->number > b->bus->number) return  1;
+
+       if      (a->devfn < b->devfn) return -1;
+       else if (a->devfn > b->devfn) return  1;
+
+       return 0;
+}
+
+/*
+ * Yes, this forcably breaks the klist abstraction temporarily.  It
+ * just wants to sort the klist, not change reference counts and
+ * take/drop locks rapidly in the process.  It does all this while
+ * holding the lock for the list, so objects can't otherwise be
+ * added/removed while we're swizzling.
+ */
+static void __init pci_insertion_sort_klist(struct pci_dev *a, struct list_head *list)
+{
+       struct list_head *pos;
+       struct klist_node *n;
+       struct device *dev;
+       struct pci_dev *b;
+
+       list_for_each(pos, list) {
+               n = container_of(pos, struct klist_node, n_node);
+               dev = container_of(n, struct device, knode_bus);
+               b = to_pci_dev(dev);
+               if (pci_sort_bf_cmp(a, b) <= 0) {
+                       list_move_tail(&a->dev.knode_bus.n_node, &b->dev.knode_bus.n_node);
+                       return;
+               }
+       }
+       list_move_tail(&a->dev.knode_bus.n_node, list);
+}
+
+static void __init pci_sort_breadthfirst_klist(void)
+{
+       LIST_HEAD(sorted_devices);
+       struct list_head *pos, *tmp;
+       struct klist_node *n;
+       struct device *dev;
+       struct pci_dev *pdev;
+
+       spin_lock(&pci_bus_type.klist_devices.k_lock);
+       list_for_each_safe(pos, tmp, &pci_bus_type.klist_devices.k_list) {
+               n = container_of(pos, struct klist_node, n_node);
+               dev = container_of(n, struct device, knode_bus);
+               pdev = to_pci_dev(dev);
+               pci_insertion_sort_klist(pdev, &sorted_devices);
+       }
+       list_splice(&sorted_devices, &pci_bus_type.klist_devices.k_list);
+       spin_unlock(&pci_bus_type.klist_devices.k_lock);
+}
+
+static void __init pci_insertion_sort_devices(struct pci_dev *a, struct list_head *list)
+{
+       struct pci_dev *b;
+
+       list_for_each_entry(b, list, global_list) {
+               if (pci_sort_bf_cmp(a, b) <= 0) {
+                       list_move_tail(&a->global_list, &b->global_list);
+                       return;
+               }
+       }
+       list_move_tail(&a->global_list, list);
+}
+
+static void __init pci_sort_breadthfirst_devices(void)
+{
+       LIST_HEAD(sorted_devices);
+       struct pci_dev *dev, *tmp;
+
+       down_write(&pci_bus_sem);
+       list_for_each_entry_safe(dev, tmp, &pci_devices, global_list) {
+               pci_insertion_sort_devices(dev, &sorted_devices);
+       }
+       list_splice(&sorted_devices, &pci_devices);
+       up_write(&pci_bus_sem);
+}
+
+void __init pci_sort_breadthfirst(void)
+{
+       pci_sort_breadthfirst_devices();
+       pci_sort_breadthfirst_klist();
+}
+
index 23b599d6a9d540db8b2727533f74ffcd7e72f06d..e8a7f1b1b2bc4289546066375d1ef4b2e5792217 100644 (file)
@@ -453,6 +453,12 @@ static void __devinit quirk_ich6_lpc_acpi(struct pci_dev *dev)
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_ICH6_0, quirk_ich6_lpc_acpi );
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_ICH6_1, quirk_ich6_lpc_acpi );
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_ICH7_0, quirk_ich6_lpc_acpi );
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_ICH7_1, quirk_ich6_lpc_acpi );
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_ICH7_31, quirk_ich6_lpc_acpi );
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_ICH8_0, quirk_ich6_lpc_acpi );
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_ICH8_2, quirk_ich6_lpc_acpi );
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_ICH8_3, quirk_ich6_lpc_acpi );
 
 /*
  * VIA ACPI: One IO region pointed to by longword at
@@ -648,11 +654,43 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA,       PCI_DEVICE_ID_VIA_82C686_4,     quirk_vi
  * Some of the on-chip devices are actually '586 devices' so they are
  * listed here.
  */
+
+static int via_irq_fixup_needed = -1;
+
+/*
+ * As some VIA hardware is available in PCI-card form, we need to restrict
+ * this quirk to VIA PCI hardware built onto VIA-based motherboards only.
+ * We try to locate a VIA southbridge before deciding whether the quirk
+ * should be applied.
+ */
+static const struct pci_device_id via_irq_fixup_tbl[] = {
+       {
+               .vendor         = PCI_VENDOR_ID_VIA,
+               .device         = PCI_ANY_ID,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .class          = PCI_CLASS_BRIDGE_ISA << 8,
+               .class_mask     = 0xffff00,
+       },
+       { 0, },
+};
+
 static void quirk_via_irq(struct pci_dev *dev)
 {
        u8 irq, new_irq;
 
-       new_irq = dev->irq & 0xf;
+       if (via_irq_fixup_needed == -1)
+               via_irq_fixup_needed = pci_dev_present(via_irq_fixup_tbl);
+
+       if (!via_irq_fixup_needed)
+               return;
+
+       new_irq = dev->irq;
+
+       /* Don't quirk interrupts outside the legacy IRQ range */
+       if (!new_irq || new_irq > 15)
+               return;
+
        pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq);
        if (new_irq != irq) {
                printk(KERN_INFO "PCI: VIA IRQ fixup for %s, from %d to %d\n",
@@ -661,14 +699,7 @@ static void quirk_via_irq(struct pci_dev *dev)
                pci_write_config_byte(dev, PCI_INTERRUPT_LINE, new_irq);
        }
 }
-DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_0, quirk_via_irq);
-DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, quirk_via_irq);
-DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_2, quirk_via_irq);
-DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3, quirk_via_irq);
-DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235_USB_2, quirk_via_irq);
-DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, quirk_via_irq);
-DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_via_irq);
-DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_5, quirk_via_irq);
+DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_ANY_ID, quirk_via_irq);
 
 /*
  * VIA VT82C598 has its device ID settable and many BIOSes
@@ -1588,6 +1619,51 @@ static void __devinit fixup_rev1_53c810(struct pci_dev* dev)
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C810, fixup_rev1_53c810);
 
+/*
+ * Fixup to mark boot BIOS video selected by BIOS before it changes
+ *
+ * From information provided by "Jon Smirl" <jonsmirl@gmail.com>
+ *
+ * The standard boot ROM sequence for an x86 machine uses the BIOS
+ * to select an initial video card for boot display. This boot video
+ * card will have it's BIOS copied to C0000 in system RAM.
+ * IORESOURCE_ROM_SHADOW is used to associate the boot video
+ * card with this copy. On laptops this copy has to be used since
+ * the main ROM may be compressed or combined with another image.
+ * See pci_map_rom() for use of this flag. IORESOURCE_ROM_SHADOW
+ * is marked here since the boot video device will be the only enabled
+ * video device at this point.
+ */
+
+static void __devinit fixup_video(struct pci_dev *pdev)
+{
+       struct pci_dev *bridge;
+       struct pci_bus *bus;
+       u16 config;
+
+       if ((pdev->class >> 8) != PCI_CLASS_DISPLAY_VGA)
+               return;
+
+       /* Is VGA routed to us? */
+       bus = pdev->bus;
+       while (bus) {
+               bridge = bus->self;
+               if (bridge) {
+                       pci_read_config_word(bridge, PCI_BRIDGE_CONTROL,
+                                               &config);
+                       if (!(config & PCI_BRIDGE_CTL_VGA))
+                               return;
+               }
+               bus = bus->parent;
+       }
+       pci_read_config_word(pdev, PCI_COMMAND, &config);
+       if (config & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) {
+               pdev->resource[PCI_ROM_RESOURCE].flags |= IORESOURCE_ROM_SHADOW;
+               printk(KERN_DEBUG "Boot video device is %s\n", pci_name(pdev));
+       }
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, fixup_video);
+
 
 static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, struct pci_fixup *end)
 {
@@ -1764,7 +1840,7 @@ static void __devinit quirk_nvidia_ck804_msi_ht_cap(struct pci_dev *dev)
        /* check HT MSI cap on this chipset and the root one.
         * a single one having MSI is enough to be sure that MSI are supported.
         */
-       pdev = pci_find_slot(dev->bus->number, 0);
+       pdev = pci_get_slot(dev->bus, 0);
        if (dev->subordinate && !msi_ht_cap_enabled(dev)
            && !msi_ht_cap_enabled(pdev)) {
                printk(KERN_WARNING "PCI: MSI quirk detected. "
@@ -1772,6 +1848,7 @@ static void __devinit quirk_nvidia_ck804_msi_ht_cap(struct pci_dev *dev)
                       pci_name(dev));
                dev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MSI;
        }
+       pci_dev_put(pdev);
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE,
                        quirk_nvidia_ck804_msi_ht_cap);
index f5ee7ce16fa61ea6fc4c3e096edc86140fa4e668..43e4a49f2cc428275cc77a74bb52c61fe9d428b3 100644 (file)
@@ -71,7 +71,10 @@ void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size)
        void __iomem *image;
        int last_image;
 
-       /* IORESOURCE_ROM_SHADOW only set on x86 */
+       /*
+        * IORESOURCE_ROM_SHADOW set if the VGA enable bit of the Bridge Control
+        * register is set for embedded VGA.
+        */
        if (res->flags & IORESOURCE_ROM_SHADOW) {
                /* primary video rom always starts here */
                start = (loff_t)0xC0000;
index d529462d1b53e6b8083aab301eca87f02ebac35a..2f13eba5d5aebf9c7a9f0930cbc1022bde441f75 100644 (file)
@@ -139,6 +139,31 @@ struct pci_dev * pci_get_slot(struct pci_bus *bus, unsigned int devfn)
        return dev;
 }
 
+/**
+ * pci_get_bus_and_slot - locate PCI device from a given PCI slot
+ * @bus: number of PCI bus on which desired PCI device resides
+ * @devfn: encodes number of PCI slot in which the desired PCI
+ * device resides and the logical device number within that slot
+ * in case of multi-function devices.
+ *
+ * Given a PCI bus and slot/function number, the desired PCI device
+ * is located in system global list of PCI devices.  If the device
+ * is found, a pointer to its data structure is returned.  If no
+ * device is found, %NULL is returned. The returned device has its
+ * reference count bumped by one.
+ */
+
+struct pci_dev * pci_get_bus_and_slot(unsigned int bus, unsigned int devfn)
+{
+       struct pci_dev *dev = NULL;
+
+       while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
+               if (dev->bus->number == bus && dev->devfn == devfn)
+                       return dev;
+       }
+       return NULL;
+}
+
 /**
  * pci_find_subsys - begin or continue searching for a PCI device by vendor/subvendor/device/subdevice id
  * @vendor: PCI vendor id to match, or %PCI_ANY_ID to match all vendor ids
@@ -274,6 +299,45 @@ pci_get_device(unsigned int vendor, unsigned int device, struct pci_dev *from)
        return pci_get_subsys(vendor, device, PCI_ANY_ID, PCI_ANY_ID, from);
 }
 
+/**
+ * pci_get_device_reverse - begin or continue searching for a PCI device by vendor/device id
+ * @vendor: PCI vendor id to match, or %PCI_ANY_ID to match all vendor ids
+ * @device: PCI device id to match, or %PCI_ANY_ID to match all device ids
+ * @from: Previous PCI device found in search, or %NULL for new search.
+ *
+ * Iterates through the list of known PCI devices in the reverse order of
+ * pci_get_device.
+ * If a PCI device is found with a matching @vendor and @device, the reference
+ * count to the  device is incremented and a pointer to its device structure
+ * is returned Otherwise, %NULL is returned.  A new search is initiated by
+ * passing %NULL as the @from argument.  Otherwise if @from is not %NULL,
+ * searches continue from next device on the global list.  The reference
+ * count for @from is always decremented if it is not %NULL.
+ */
+struct pci_dev *
+pci_get_device_reverse(unsigned int vendor, unsigned int device, struct pci_dev *from)
+{
+       struct list_head *n;
+       struct pci_dev *dev;
+
+       WARN_ON(in_interrupt());
+       down_read(&pci_bus_sem);
+       n = from ? from->global_list.prev : pci_devices.prev;
+
+       while (n && (n != &pci_devices)) {
+               dev = pci_dev_g(n);
+               if ((vendor == PCI_ANY_ID || dev->vendor == vendor) &&
+                   (device == PCI_ANY_ID || dev->device == device))
+                       goto exit;
+               n = n->prev;
+       }
+       dev = NULL;
+exit:
+       dev = pci_dev_get(dev);
+       up_read(&pci_bus_sem);
+       pci_dev_put(from);
+       return dev;
+}
 
 /**
  * pci_find_device_reverse - begin or continue searching for a PCI device by vendor/device id
@@ -382,12 +446,16 @@ exit:
 }
 EXPORT_SYMBOL(pci_dev_present);
 
-EXPORT_SYMBOL(pci_find_bus);
-EXPORT_SYMBOL(pci_find_next_bus);
 EXPORT_SYMBOL(pci_find_device);
 EXPORT_SYMBOL(pci_find_device_reverse);
 EXPORT_SYMBOL(pci_find_slot);
+/* For boot time work */
+EXPORT_SYMBOL(pci_find_bus);
+EXPORT_SYMBOL(pci_find_next_bus);
+/* For everyone */
 EXPORT_SYMBOL(pci_get_device);
+EXPORT_SYMBOL(pci_get_device_reverse);
 EXPORT_SYMBOL(pci_get_subsys);
 EXPORT_SYMBOL(pci_get_slot);
+EXPORT_SYMBOL(pci_get_bus_and_slot);
 EXPORT_SYMBOL(pci_get_class);
index 40569f40e90e8f44d54968413c3dc166de45d620..7f5df9a9f3932c65df09fec78251fc0d7317ccb8 100644 (file)
@@ -64,9 +64,9 @@ static int at91_cf_ss_init(struct pcmcia_socket *s)
        return 0;
 }
 
-static irqreturn_t at91_cf_irq(int irq, void *_cf, struct pt_regs *r)
+static irqreturn_t at91_cf_irq(int irq, void *_cf)
 {
-       struct at91_cf_socket   *cf = (struct at91_cf_socket *) _cf;
+       struct at91_cf_socket *cf = _cf;
 
        if (irq == cf->board->det_pin) {
                unsigned present = at91_cf_present(cf);
index ad02629c8be21255ed14c595b580b6a93e8a5464..caca0dc9d30f74f4d05adc50444e927a48e202a9 100644 (file)
@@ -650,7 +650,7 @@ static int hs_set_mem_map(struct pcmcia_socket *s, struct pccard_mem_map *mem)
  */
 static int hs_irq_demux(int irq, void *dev)
 {
-       hs_socket_t *sp = (hs_socket_t *)dev;
+       hs_socket_t *sp = dev;
        u_int cscr;
        
        DPRINTK("hs_irq_demux(irq=%d)\n", irq);
@@ -671,13 +671,12 @@ static int hs_irq_demux(int irq, void *dev)
  * Interrupt handling routine.
  */
  
-static irqreturn_t hs_interrupt(int irq, void *dev, struct pt_regs *regs)
+static irqreturn_t hs_interrupt(int irq, void *dev)
 {
-       hs_socket_t *sp = (hs_socket_t *)dev;
+       hs_socket_t *sp = dev;
        u_int events = 0;
        u_int cscr;
-       
-       
+
        cscr = hs_in(sp, CSCR);
        
        DPRINTK("hs_interrupt, cscr=%04x\n", cscr);
index 2163aa75a25759525ac2570a3d92c6980199c012..82715f4489573c935b7084772bee155167c351a9 100644 (file)
@@ -315,7 +315,7 @@ static int to_cycles(int ns)
 
 /* Interrupt handler functionality */
 
-static irqreturn_t i82092aa_interrupt(int irq, void *dev, struct pt_regs *regs)
+static irqreturn_t i82092aa_interrupt(int irq, void *dev)
 {
        int i;
        int loopcount = 0;
index 9c14599d06737371262f754f09c9811cd7052c61..b0d453303c5deb852e917af9e2757ba1b10edfbb 100644 (file)
@@ -23,7 +23,7 @@
 static int  i82092aa_pci_probe(struct pci_dev *dev, const struct pci_device_id *id);
 static void i82092aa_pci_remove(struct pci_dev *dev);
 static int card_present(int socketno);
-static irqreturn_t i82092aa_interrupt(int irq, void *dev, struct pt_regs *regs);
+static irqreturn_t i82092aa_interrupt(int irq, void *dev);
 
 
 
index 1cc2682394b1557e677ca7c122722d8aa301b71d..ea74f98a73503447014ce060b5812f2506ea6f72 100644 (file)
@@ -80,7 +80,7 @@ module_param(pc_debug, int, 0644);
 #define debug(lvl, fmt, arg...) do { } while (0)
 #endif
 
-static irqreturn_t i365_count_irq(int, void *, struct pt_regs *);
+static irqreturn_t i365_count_irq(int, void *);
 static inline int _check_irq(int irq, int flags)
 {
     if (request_irq(irq, i365_count_irq, flags, "x", i365_count_irq) != 0)
@@ -498,7 +498,7 @@ static u_int __init set_bridge_opts(u_short s, u_short ns)
 static volatile u_int irq_hits;
 static u_short irq_sock;
 
-static irqreturn_t i365_count_irq(int irq, void *dev, struct pt_regs *regs)
+static irqreturn_t i365_count_irq(int irq, void *dev)
 {
     i365_get(irq_sock, I365_CSC);
     irq_hits++;
@@ -848,8 +848,7 @@ static void __init isa_probe(void)
 
 /*====================================================================*/
 
-static irqreturn_t pcic_interrupt(int irq, void *dev,
-                                   struct pt_regs *regs)
+static irqreturn_t pcic_interrupt(int irq, void *dev)
 {
     int i, j, csc;
     u_int events, active;
@@ -898,7 +897,7 @@ static irqreturn_t pcic_interrupt(int irq, void *dev,
 
 static void pcic_interrupt_wrapper(u_long data)
 {
-    pcic_interrupt(0, NULL, NULL);
+    pcic_interrupt(0, NULL);
     poll_timer.expires = jiffies + poll_interval;
     add_timer(&poll_timer);
 }
index 9e768eaef17a39955dbed341a1410861d732f679..36fdaa58458ca43969bf019d923dc7592256d5d6 100644 (file)
@@ -254,7 +254,7 @@ static pcc_t pcc[] = {
 #endif /* CONFIG_PLAT_USRV */
 };
 
-static irqreturn_t pcc_interrupt(int, void *, struct pt_regs *);
+static irqreturn_t pcc_interrupt(int, void *);
 
 /*====================================================================*/
 
@@ -372,14 +372,13 @@ static void add_pcc_socket(ulong base, int irq, ulong mapaddr, kio_addr_t ioaddr
 
 /*====================================================================*/
 
-static irqreturn_t pcc_interrupt(int irq, void *dev, struct pt_regs *regs)
+static irqreturn_t pcc_interrupt(int irq, void *dev)
 {
        int i;
        u_int events = 0;
        int handled = 0;
 
-       debug(3, "m32r_cfc: pcc_interrupt: irq=%d, dev=%p, regs=%p\n",
-               irq, dev, regs);
+       debug(3, "m32r_cfc: pcc_interrupt: irq=%d, dev=%p\n", irq, dev);
        for (i = 0; i < pcc_sockets; i++) {
                if (socket[i].cs_irq1 != irq && socket[i].cs_irq2 != irq)
                        continue;
index 61d50b5620ddab3ef749bb5322fdf43e40e2250b..bbf025874d0c358cda4a2d6033b0876db3b2f1d5 100644 (file)
@@ -267,7 +267,7 @@ static pcc_t pcc[] = {
        { "xnux2", 0 }, { "xnux2", 0 },
 };
 
-static irqreturn_t pcc_interrupt(int, void *, struct pt_regs *);
+static irqreturn_t pcc_interrupt(int, void *);
 
 /*====================================================================*/
 
@@ -352,7 +352,7 @@ static void add_pcc_socket(ulong base, int irq, ulong mapaddr, kio_addr_t ioaddr
 
 /*====================================================================*/
 
-static irqreturn_t pcc_interrupt(int irq, void *dev, struct pt_regs *regs)
+static irqreturn_t pcc_interrupt(int irq, void *dev)
 {
        int i, j, irc;
        u_int events, active;
@@ -395,7 +395,7 @@ static irqreturn_t pcc_interrupt(int irq, void *dev, struct pt_regs *regs)
 
 static void pcc_interrupt_wrapper(u_long data)
 {
-       pcc_interrupt(0, NULL, NULL);
+       pcc_interrupt(0, NULL);
        init_timer(&poll_timer);
        poll_timer.expires = jiffies + poll_interval;
        add_timer(&poll_timer);
index d0f68ab8f04119c12661a27e1785d76b6a372be4..e070a2896769ff2d2f27b640239b3a27fbd015fa 100644 (file)
@@ -266,7 +266,7 @@ static const u32 m8xx_size_to_gray[M8XX_SIZES_NO] =
 
 /* ------------------------------------------------------------------------- */
 
-static irqreturn_t m8xx_interrupt(int irq, void *dev, struct pt_regs *regs);
+static irqreturn_t m8xx_interrupt(int irq, void *dev);
 
 #define PCMCIA_BMT_LIMIT (15*4)  /* Bus Monitor Timeout value */
 
@@ -646,7 +646,7 @@ static struct platform_device m8xx_device = {
 static u32 pending_events[PCMCIA_SOCKETS_NO];
 static DEFINE_SPINLOCK(pending_event_lock);
 
-static irqreturn_t m8xx_interrupt(int irq, void *dev, struct pt_regs *regs)
+static irqreturn_t m8xx_interrupt(int irq, void *dev)
 {
        struct socket_info *s;
        struct event_table *e;
index 01be47e72730b5fa847ac9e8245fa2e9d9cda23d..c8e838c69766b5417b3e9722f0338fa1b9b924f9 100644 (file)
@@ -102,7 +102,7 @@ static void omap_cf_timer(unsigned long _cf)
  * claim the card's IRQ.  It may also detect some card insertions, but
  * not removals; it can't always eliminate timer irqs.
  */
-static irqreturn_t omap_cf_irq(int irq, void *_cf, struct pt_regs *r)
+static irqreturn_t omap_cf_irq(int irq, void *_cf)
 {
        omap_cf_timer((unsigned long)_cf);
        return IRQ_HANDLED;
index c8323399e9e4d03ec0b9cced174a8834b9b60e4a..74cebd42403299e7d72d9e7fd0c628ca1f5b5389 100644 (file)
@@ -784,7 +784,7 @@ EXPORT_SYMBOL(pcmcia_request_io);
  */
 
 #ifdef CONFIG_PCMCIA_PROBE
-static irqreturn_t test_action(int cpl, void *dev_id, struct pt_regs *regs)
+static irqreturn_t test_action(int cpl, void *dev_id)
 {
        return IRQ_NONE;
 }
index 22c5e7427dddd13f60575e7b9c18145293f8b19e..c83a0a6b158f9e22e77d507dca0ad07543fe20f7 100644 (file)
@@ -182,7 +182,7 @@ static void indirect_write16(struct pd6729_socket *socket, unsigned short reg,
 
 /* Interrupt handler functionality */
 
-static irqreturn_t pd6729_interrupt(int irq, void *dev, struct pt_regs *regs)
+static irqreturn_t pd6729_interrupt(int irq, void *dev)
 {
        struct pd6729_socket *socket = (struct pd6729_socket *)dev;
        int i;
@@ -249,7 +249,7 @@ static void pd6729_interrupt_wrapper(unsigned long data)
 {
        struct pd6729_socket *socket = (struct pd6729_socket *) data;
 
-       pd6729_interrupt(0, (void *)socket, NULL);
+       pd6729_interrupt(0, (void *)socket);
        mod_timer(&socket->poll_timer, jiffies + HZ);
 }
 
@@ -575,7 +575,7 @@ static struct pccard_operations pd6729_operations = {
        .set_mem_map            = pd6729_set_mem_map,
 };
 
-static irqreturn_t pd6729_test(int irq, void *dev, struct pt_regs *regs)
+static irqreturn_t pd6729_test(int irq, void *dev)
 {
        dprintk("-> hit on irq %d\n", irq);
        return IRQ_HANDLED;
index ecaa132fa5924aefd4ef7b0e8d4dc2ee5bc6c0b7..3627e52e0c278f5edad7fc8315423f67932a1b6e 100644 (file)
@@ -256,7 +256,7 @@ static void soc_common_pcmcia_poll_event(unsigned long dummy)
  * handling code performs scheduling operations which cannot be
  * executed from within an interrupt context.
  */
-static irqreturn_t soc_common_pcmcia_interrupt(int irq, void *dev, struct pt_regs *regs)
+static irqreturn_t soc_common_pcmcia_interrupt(int irq, void *dev)
 {
        struct soc_pcmcia_socket *skt = dev;
 
index 65a60671659f1e1c77861a2235e5d31bbcc1035b..2d2f415f80a830e4f35f7f3f5fe73907f430b597 100644 (file)
@@ -116,7 +116,7 @@ module_param(cycle_time, int, 0444);
 
 /*====================================================================*/
 
-static irqreturn_t tcic_interrupt(int irq, void *dev, struct pt_regs *regs);
+static irqreturn_t tcic_interrupt(int irq, void *dev);
 static void tcic_timer(u_long data);
 static struct pccard_operations tcic_operations;
 
@@ -218,7 +218,7 @@ static int to_cycles(int ns)
 
 static volatile u_int irq_hits;
 
-static irqreturn_t __init tcic_irq_count(int irq, void *dev, struct pt_regs *regs)
+static irqreturn_t __init tcic_irq_count(int irq, void *dev)
 {
     irq_hits++;
     return IRQ_HANDLED;
@@ -505,7 +505,7 @@ static int __init init_tcic(void)
     }
     
     /* jump start interrupt handler, if needed */
-    tcic_interrupt(0, NULL, NULL);
+    tcic_interrupt(0, NULL);
 
     platform_device_register(&tcic_device);
 
@@ -547,7 +547,7 @@ static void __exit exit_tcic(void)
 
 /*====================================================================*/
 
-static irqreturn_t tcic_interrupt(int irq, void *dev, struct pt_regs *regs)
+static irqreturn_t tcic_interrupt(int irq, void *dev)
 {
     int i, quick = 0;
     u_char latch, sstat;
@@ -606,7 +606,7 @@ static void tcic_timer(u_long data)
 {
     debug(2, "tcic_timer()\n");
     tcic_timer_pending = 0;
-    tcic_interrupt(0, NULL, NULL);
+    tcic_interrupt(0, NULL);
 } /* tcic_timer */
 
 /*====================================================================*/
index e076a13db555bafa93f1f6fb7da46b1cb361d79a..e90d8e8c5fd686068aab91962cad29d89c5f10ad 100644 (file)
@@ -514,7 +514,7 @@ static inline unsigned int get_events(int slot)
        return events;
 }
 
-static irqreturn_t pccard_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t pccard_interrupt(int irq, void *dev_id)
 {
        vrc4171_socket_t *socket;
        unsigned int events;
index d19a9138135f0181b54ef034623bd2ce5dbd7118..812f038e9bdaeea761c66dc978b583bc571bf9b0 100644 (file)
@@ -440,7 +440,7 @@ static uint16_t get_events(vrc4173_socket_t *socket)
        return events;
 }
 
-static void cardu_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static void cardu_interrupt(int irq, void *dev_id)
 {
        vrc4173_socket_t *socket = (vrc4173_socket_t *)dev_id;
        uint16_t events;
index 1344746381e8dce0fb6020760956d083fb5815ac..26229d9da76263d0cb2611363a5ea24935c42917 100644 (file)
@@ -442,7 +442,7 @@ static int yenta_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *
 
 
 
-static irqreturn_t yenta_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t yenta_interrupt(int irq, void *dev_id)
 {
        unsigned int events;
        struct yenta_socket *socket = (struct yenta_socket *) dev_id;
@@ -478,7 +478,7 @@ static void yenta_interrupt_wrapper(unsigned long data)
 {
        struct yenta_socket *socket = (struct yenta_socket *) data;
 
-       yenta_interrupt(0, (void *)socket, NULL);
+       yenta_interrupt(0, (void *)socket);
        socket->poll_timer.expires = jiffies + HZ;
        add_timer(&socket->poll_timer);
 }
@@ -896,7 +896,7 @@ static unsigned int yenta_probe_irq(struct yenta_socket *socket, u32 isa_irq_mas
 #ifdef CONFIG_YENTA_TI
 
 /* interrupt handler, only used during probing */
-static irqreturn_t yenta_probe_handler(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t yenta_probe_handler(int irq, void *dev_id)
 {
        struct yenta_socket *socket = (struct yenta_socket *) dev_id;
        u8 csc;
index dc79b0a0059f6206c22dd6a611c591d62b83aa7a..379048fdf05dccf01575a5727219529ac7d39fac 100644 (file)
@@ -776,21 +776,32 @@ static void pnpacpi_encode_dma(struct acpi_resource *resource,
        struct resource *p)
 {
        /* Note: pnp_assign_dma will copy pnp_dma->flags into p->flags */
-       if (p->flags & IORESOURCE_DMA_COMPATIBLE)
-               resource->data.dma.type = ACPI_COMPATIBILITY;
-       else if (p->flags & IORESOURCE_DMA_TYPEA)
-               resource->data.dma.type = ACPI_TYPE_A;
-       else if (p->flags & IORESOURCE_DMA_TYPEB)
-               resource->data.dma.type = ACPI_TYPE_B;
-       else if (p->flags & IORESOURCE_DMA_TYPEF)
-               resource->data.dma.type = ACPI_TYPE_F;
-       if (p->flags & IORESOURCE_DMA_8BIT)
-               resource->data.dma.transfer = ACPI_TRANSFER_8;
-       else if (p->flags & IORESOURCE_DMA_8AND16BIT)
-               resource->data.dma.transfer = ACPI_TRANSFER_8_16;
-       else if (p->flags & IORESOURCE_DMA_16BIT)
-               resource->data.dma.transfer = ACPI_TRANSFER_16;
-       resource->data.dma.bus_master = p->flags & IORESOURCE_DMA_MASTER;
+       switch (p->flags & IORESOURCE_DMA_SPEED_MASK) {
+               case IORESOURCE_DMA_TYPEA:
+                       resource->data.dma.type = ACPI_TYPE_A;
+                       break;
+               case IORESOURCE_DMA_TYPEB:
+                       resource->data.dma.type = ACPI_TYPE_B;
+                       break;
+               case IORESOURCE_DMA_TYPEF:
+                       resource->data.dma.type = ACPI_TYPE_F;
+                       break;
+               default:
+                       resource->data.dma.type = ACPI_COMPATIBILITY;
+       }
+
+       switch (p->flags & IORESOURCE_DMA_TYPE_MASK) {
+               case IORESOURCE_DMA_8BIT:
+                       resource->data.dma.transfer = ACPI_TRANSFER_8;
+                       break;
+               case IORESOURCE_DMA_8AND16BIT:
+                       resource->data.dma.transfer = ACPI_TRANSFER_8_16;
+                       break;
+               default:
+                       resource->data.dma.transfer = ACPI_TRANSFER_16;
+       }
+
+       resource->data.dma.bus_master = !!(p->flags & IORESOURCE_DMA_MASTER);
        resource->data.dma.channel_count = 1;
        resource->data.dma.channels[0] = p->start;
 }
index 5c8ec21e1086c71a0440508f6774098d9a504a35..a685fbec4604e861bdb004ff10bacf95befbaf7f 100644 (file)
@@ -348,7 +348,7 @@ int pnp_check_mem(struct pnp_dev * dev, int idx)
        return 1;
 }
 
-static irqreturn_t pnp_test_handler(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t pnp_test_handler(int irq, void *dev_id)
 {
        return IRQ_HANDLED;
 }
index c0714da44920287fc1be7ad76d2cacccc0bd927c..bd61e99540a330450478a5c45832adda143fdc00 100644 (file)
@@ -238,8 +238,7 @@ static int at91_rtc_proc(struct device *dev, struct seq_file *seq)
 /*
  * IRQ handler for the RTC
  */
-static irqreturn_t at91_rtc_interrupt(int irq, void *dev_id,
-                                       struct pt_regs *regs)
+static irqreturn_t at91_rtc_interrupt(int irq, void *dev_id)
 {
        struct platform_device *pdev = dev_id;
        struct rtc_device *rtc = platform_get_drvdata(pdev);
index 9647188fee2c66c4c172bce9923b919a2a17eef5..78552e6e76aa252d8065ec93cc95abde426e92dd 100644 (file)
@@ -189,8 +189,7 @@ static int ds1553_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
        return 0;
 }
 
-static irqreturn_t ds1553_rtc_interrupt(int irq, void *dev_id,
-                                       struct pt_regs *regs)
+static irqreturn_t ds1553_rtc_interrupt(int irq, void *dev_id)
 {
        struct platform_device *pdev = dev_id;
        struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
index 0b20dfacbf595c6fcc1c00855771688582f3780c..d9417072807506771280912c887d5c8c9da27877 100644 (file)
@@ -136,7 +136,7 @@ static int max6902_get_datetime(struct device *dev, struct rtc_time *dt)
        dt->tm_min      = BCD2BIN(chip->buf[2]);
        dt->tm_hour     = BCD2BIN(chip->buf[3]);
        dt->tm_mday     = BCD2BIN(chip->buf[4]);
-       dt->tm_mon      = BCD2BIN(chip->buf[5] - 1);
+       dt->tm_mon      = BCD2BIN(chip->buf[5]) - 1;
        dt->tm_wday     = BCD2BIN(chip->buf[6]);
        dt->tm_year = BCD2BIN(chip->buf[7]);
 
index 739d1a6e14eb9054d717bda6eef4f8266d3213fd..f13daa9fecaa1891c1201c6015eac4ebf40c6d3a 100644 (file)
@@ -47,7 +47,7 @@ struct pl031_local {
        void __iomem *base;
 };
 
-static irqreturn_t pl031_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t pl031_interrupt(int irq, void *dev_id)
 {
        struct rtc_device *rtc = dev_id;
 
index 625dad2eeb4f4fa2b8f787ce805bf44c67eccf56..e301dea57bb37fff0918791a2f6e74117c079b88 100644 (file)
@@ -46,7 +46,7 @@ static unsigned int tick_count;
 
 /* IRQ Handlers */
 
-static irqreturn_t s3c_rtc_alarmirq(int irq, void *id, struct pt_regs *r)
+static irqreturn_t s3c_rtc_alarmirq(int irq, void *id)
 {
        struct rtc_device *rdev = id;
 
@@ -54,7 +54,7 @@ static irqreturn_t s3c_rtc_alarmirq(int irq, void *id, struct pt_regs *r)
        return IRQ_HANDLED;
 }
 
-static irqreturn_t s3c_rtc_tickirq(int irq, void *id, struct pt_regs *r)
+static irqreturn_t s3c_rtc_tickirq(int irq, void *id)
 {
        struct rtc_device *rdev = id;
 
index 439c41aea31c9d091bcfe66f326d2ba3afdd2679..bd4d7d174ef4a01a7d58d5835cea904d910e50dc 100644 (file)
@@ -68,8 +68,7 @@ static int rtc_update_alarm(struct rtc_time *alrm)
        return ret;
 }
 
-static irqreturn_t sa1100_rtc_interrupt(int irq, void *dev_id,
-               struct pt_regs *regs)
+static irqreturn_t sa1100_rtc_interrupt(int irq, void *dev_id)
 {
        struct platform_device *pdev = to_platform_device(dev_id);
        struct rtc_device *rtc = platform_get_drvdata(pdev);
@@ -106,8 +105,7 @@ static irqreturn_t sa1100_rtc_interrupt(int irq, void *dev_id,
 
 static int rtc_timer1_count;
 
-static irqreturn_t timer1_interrupt(int irq, void *dev_id,
-               struct pt_regs *regs)
+static irqreturn_t timer1_interrupt(int irq, void *dev_id)
 {
        struct platform_device *pdev = to_platform_device(dev_id);
        struct rtc_device *rtc = platform_get_drvdata(pdev);
index d2ce0c8bb8f3ffc1be2afc4c0472b9839969ff1b..143302a8e79c5ed283a86b960850aa753014592e 100644 (file)
@@ -73,7 +73,7 @@ struct sh_rtc {
        spinlock_t lock;
 };
 
-static irqreturn_t sh_rtc_interrupt(int irq, void *id, struct pt_regs *regs)
+static irqreturn_t sh_rtc_interrupt(int irq, void *id)
 {
        struct platform_device *pdev = id;
        struct sh_rtc *rtc = platform_get_drvdata(pdev);
@@ -97,7 +97,7 @@ static irqreturn_t sh_rtc_interrupt(int irq, void *id, struct pt_regs *regs)
        return IRQ_HANDLED;
 }
 
-static irqreturn_t sh_rtc_periodic(int irq, void *id, struct pt_regs *regs)
+static irqreturn_t sh_rtc_periodic(int irq, void *id)
 {
        struct sh_rtc *rtc = dev_get_drvdata(id);
 
@@ -160,7 +160,7 @@ static int sh_rtc_open(struct device *dev)
        tmp |= RCR1_CIE;
        writeb(tmp, rtc->regbase + RCR1);
 
-       ret = request_irq(rtc->periodic_irq, sh_rtc_periodic, SA_INTERRUPT,
+       ret = request_irq(rtc->periodic_irq, sh_rtc_periodic, IRQF_DISABLED,
                          "sh-rtc period", dev);
        if (unlikely(ret)) {
                dev_err(dev, "request period IRQ failed with %d, IRQ %d\n",
@@ -168,7 +168,7 @@ static int sh_rtc_open(struct device *dev)
                return ret;
        }
 
-       ret = request_irq(rtc->carry_irq, sh_rtc_interrupt, SA_INTERRUPT,
+       ret = request_irq(rtc->carry_irq, sh_rtc_interrupt, IRQF_DISABLED,
                          "sh-rtc carry", dev);
        if (unlikely(ret)) {
                dev_err(dev, "request carry IRQ failed with %d, IRQ %d\n",
@@ -177,7 +177,7 @@ static int sh_rtc_open(struct device *dev)
                goto err_bad_carry;
        }
 
-       ret = request_irq(rtc->alarm_irq, sh_rtc_interrupt, SA_INTERRUPT,
+       ret = request_irq(rtc->alarm_irq, sh_rtc_interrupt, IRQF_DISABLED,
                          "sh-rtc alarm", dev);
        if (unlikely(ret)) {
                dev_err(dev, "request alarm IRQ failed with %d, IRQ %d\n",
index 09b714f1cdc39f9dedb4cad38b5b036677a0d9dd..3b58d3d5d38a703ebc658564199d3644e016d0d3 100644 (file)
@@ -195,9 +195,9 @@ static int rtc_probe(struct platform_device *pdev)
         * are all disabled */
        v3020_set_reg(chip, V3020_STATUS_0, 0x0);
 
-       dev_info(&pdev->dev, "Chip available at physical address 0x%p,"
+       dev_info(&pdev->dev, "Chip available at physical address 0x%llx,"
                "data connected to D%d\n",
-               (void*)pdev->resource[0].start,
+               (unsigned long long)pdev->resource[0].start,
                chip->leftshift);
 
        platform_set_drvdata(pdev, chip);
index 58e5ed0aa12702fc9798f03eb915f262d7f92a8c..e40322b71938100a2dc5578c010ba7c523344cb3 100644 (file)
@@ -268,7 +268,7 @@ static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long
        return 0;
 }
 
-static irqreturn_t elapsedtime_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t elapsedtime_interrupt(int irq, void *dev_id)
 {
        struct platform_device *pdev = (struct platform_device *)dev_id;
        struct rtc_device *rtc = platform_get_drvdata(pdev);
@@ -280,7 +280,7 @@ static irqreturn_t elapsedtime_interrupt(int irq, void *dev_id, struct pt_regs *
        return IRQ_HANDLED;
 }
 
-static irqreturn_t rtclong1_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t rtclong1_interrupt(int irq, void *dev_id)
 {
        struct platform_device *pdev = (struct platform_device *)dev_id;
        struct rtc_device *rtc = platform_get_drvdata(pdev);
index d0647d116eaa1da8fa5474d982270043b2569290..79ffef6bfaf8a02a802659392e599bbd11f1e468 100644 (file)
@@ -203,6 +203,7 @@ dasd_state_basic_to_known(struct dasd_device * device)
        rc = dasd_flush_ccw_queue(device, 1);
        if (rc)
                return rc;
+       dasd_clear_timer(device);
 
        DBF_DEV_EVENT(DBF_EMERG, device, "%p debug area deleted", device);
        if (device->debug_area != NULL) {
index 222a8a71a5e8b439dd11df7e31ee389270a1dab9..53db58a68617e618df4b8333ec0ba32f98d4ef45 100644 (file)
@@ -218,7 +218,7 @@ dasd_diag_term_IO(struct dasd_ccw_req * cqr)
 
 /* Handle external interruption. */
 static void
-dasd_ext_handler(struct pt_regs *regs, __u16 code)
+dasd_ext_handler(__u16 code)
 {
        struct dasd_ccw_req *cqr, *next;
        struct dasd_device *device;
index d83eb6358bac503f6a12d30ec533e9023dc458ba..49e9628d9297d632c1b20847957f811bde719f48 100644 (file)
@@ -20,7 +20,7 @@ static int ctrlchar_sysrq_key;
 static void
 ctrlchar_handle_sysrq(void *tty)
 {
-       handle_sysrq(ctrlchar_sysrq_key, NULL, (struct tty_struct *) tty);
+       handle_sysrq(ctrlchar_sysrq_key, (struct tty_struct *) tty);
 }
 
 static DECLARE_WORK(ctrlchar_work, ctrlchar_handle_sysrq, NULL);
index 3be06569180de398d936796111a07d49753a48ca..e3491a5f52196eeedbad1d7ee3a16f35cd3c2184 100644 (file)
@@ -304,7 +304,7 @@ kbd_keycode(struct kbd_data *kbd, unsigned int keycode)
                if (kbd->sysrq) {
                        if (kbd->sysrq == K(KT_LATIN, '-')) {
                                kbd->sysrq = 0;
-                               handle_sysrq(value, NULL, kbd->tty);
+                               handle_sysrq(value, kbd->tty);
                                return;
                        }
                        if (value == '-') {
index 1e3939aeb8ab73ececacb62ad621d23868ddd9b4..b9b0fc3f812bf6350c88dd6a89f2bcc139e0c08d 100644 (file)
@@ -26,6 +26,7 @@
 #define MONWRITE_MAX_DATALEN   4024
 
 static int mon_max_bufs = 255;
+static int mon_buf_count;
 
 struct mon_buf {
        struct list_head list;
@@ -40,7 +41,6 @@ struct mon_private {
        size_t hdr_to_read;
        size_t data_to_read;
        struct mon_buf *current_buf;
-       int mon_buf_count;
 };
 
 /*
@@ -73,12 +73,15 @@ static inline struct mon_buf *monwrite_find_hdr(struct mon_private *monpriv,
        struct mon_buf *entry, *next;
 
        list_for_each_entry_safe(entry, next, &monpriv->list, list)
-               if (entry->hdr.applid == monhdr->applid &&
+               if ((entry->hdr.mon_function == monhdr->mon_function ||
+                    monhdr->mon_function == MONWRITE_STOP_INTERVAL) &&
+                   entry->hdr.applid == monhdr->applid &&
                    entry->hdr.record_num == monhdr->record_num &&
                    entry->hdr.version == monhdr->version &&
                    entry->hdr.release == monhdr->release &&
                    entry->hdr.mod_level == monhdr->mod_level)
                        return entry;
+
        return NULL;
 }
 
@@ -92,25 +95,27 @@ static int monwrite_new_hdr(struct mon_private *monpriv)
            monhdr->mon_function > MONWRITE_START_CONFIG ||
            monhdr->hdrlen != sizeof(struct monwrite_hdr))
                return -EINVAL;
-       monbuf = monwrite_find_hdr(monpriv, monhdr);
+       monbuf = NULL;
+       if (monhdr->mon_function != MONWRITE_GEN_EVENT)
+               monbuf = monwrite_find_hdr(monpriv, monhdr);
        if (monbuf) {
                if (monhdr->mon_function == MONWRITE_STOP_INTERVAL) {
                        monhdr->datalen = monbuf->hdr.datalen;
                        rc = monwrite_diag(monhdr, monbuf->data,
                                           APPLDATA_STOP_REC);
                        list_del(&monbuf->list);
-                       monpriv->mon_buf_count--;
+                       mon_buf_count--;
                        kfree(monbuf->data);
                        kfree(monbuf);
                        monbuf = NULL;
                }
-       } else {
-               if (monpriv->mon_buf_count >= mon_max_bufs)
+       } else if (monhdr->mon_function != MONWRITE_STOP_INTERVAL) {
+               if (mon_buf_count >= mon_max_bufs)
                        return -ENOSPC;
                monbuf = kzalloc(sizeof(struct mon_buf), GFP_KERNEL);
                if (!monbuf)
                        return -ENOMEM;
-               monbuf->data = kzalloc(monbuf->hdr.datalen,
+               monbuf->data = kzalloc(monhdr->datalen,
                                       GFP_KERNEL | GFP_DMA);
                if (!monbuf->data) {
                        kfree(monbuf);
@@ -118,7 +123,8 @@ static int monwrite_new_hdr(struct mon_private *monpriv)
                }
                monbuf->hdr = *monhdr;
                list_add_tail(&monbuf->list, &monpriv->list);
-               monpriv->mon_buf_count++;
+               if (monhdr->mon_function != MONWRITE_GEN_EVENT)
+                       mon_buf_count++;
        }
        monpriv->current_buf = monbuf;
        return 0;
@@ -186,7 +192,7 @@ static int monwrite_close(struct inode *inode, struct file *filp)
                if (entry->hdr.mon_function != MONWRITE_GEN_EVENT)
                        monwrite_diag(&entry->hdr, entry->data,
                                      APPLDATA_STOP_REC);
-               monpriv->mon_buf_count--;
+               mon_buf_count--;
                list_del(&entry->list);
                kfree(entry->data);
                kfree(entry);
index 31e335751d6d5a3788aee3676c2cfb5e4d123a18..8a056df09d6b2dfd33885402103b8ee53be18bfd 100644 (file)
@@ -324,7 +324,7 @@ __sclp_find_req(u32 sccb)
  * Prepare read event data request if necessary. Start processing of next
  * request on queue. */
 static void
-sclp_interrupt_handler(struct pt_regs *regs, __u16 code)
+sclp_interrupt_handler(__u16 code)
 {
        struct sclp_req *req;
        u32 finished_sccb;
@@ -743,7 +743,7 @@ EXPORT_SYMBOL(sclp_reactivate);
 /* Handler for external interruption used during initialization. Modify
  * request state to done. */
 static void
-sclp_check_handler(struct pt_regs *regs, __u16 code)
+sclp_check_handler(__u16 code)
 {
        u32 finished_sccb;
 
index 3bb4e472d73de1f03d111467d9efdd9665067718..2d78f0f4a40fce98c589403106525fbf7a999058 100644 (file)
@@ -200,11 +200,13 @@ css_get_ssd_info(struct subchannel *sch)
        spin_unlock_irq(&sch->lock);
        free_page((unsigned long)page);
        if (!ret) {
-               int j, chpid;
+               int j, chpid, mask;
                /* Allocate channel path structures, if needed. */
                for (j = 0; j < 8; j++) {
+                       mask = 0x80 >> j;
                        chpid = sch->ssd_info.chpid[j];
-                       if (chpid && (get_chp_status(chpid) < 0))
+                       if ((sch->schib.pmcw.pim & mask) &&
+                           (get_chp_status(chpid) < 0))
                            new_channel_path(chpid);
                }
        }
@@ -222,13 +224,15 @@ s390_subchannel_remove_chpid(struct device *dev, void *data)
 
        sch = to_subchannel(dev);
        chpid = data;
-       for (j = 0; j < 8; j++)
-               if (sch->schib.pmcw.chpid[j] == chpid->id)
+       for (j = 0; j < 8; j++) {
+               mask = 0x80 >> j;
+               if ((sch->schib.pmcw.pim & mask) &&
+                   (sch->schib.pmcw.chpid[j] == chpid->id))
                        break;
+       }
        if (j >= 8)
                return 0;
 
-       mask = 0x80 >> j;
        spin_lock_irq(&sch->lock);
 
        stsch(sch->schid, &schib);
@@ -366,7 +370,7 @@ __s390_process_res_acc(struct subchannel_id schid, void *data)
        struct res_acc_data *res_data;
        struct subchannel *sch;
 
-       res_data = (struct res_acc_data *)data;
+       res_data = data;
        sch = get_subchannel_by_schid(schid);
        if (!sch)
                /* Check if a subchannel is newly available. */
@@ -440,7 +444,7 @@ __get_chpid_from_lir(void *data)
                u32 isinfo[28];
        } *lir;
 
-       lir = (struct lir*) data;
+       lir = data;
        if (!(lir->iq&0x80))
                /* NULL link incident record */
                return -EINVAL;
@@ -620,18 +624,20 @@ __chp_add_new_sch(struct subchannel_id schid)
 static int
 __chp_add(struct subchannel_id schid, void *data)
 {
-       int i;
+       int i, mask;
        struct channel_path *chp;
        struct subchannel *sch;
 
-       chp = (struct channel_path *)data;
+       chp = data;
        sch = get_subchannel_by_schid(schid);
        if (!sch)
                /* Check if the subchannel is now available. */
                return __chp_add_new_sch(schid);
        spin_lock_irq(&sch->lock);
-       for (i=0; i<8; i++)
-               if (sch->schib.pmcw.chpid[i] == chp->id) {
+       for (i=0; i<8; i++) {
+               mask = 0x80 >> i;
+               if ((sch->schib.pmcw.pim & mask) &&
+                   (sch->schib.pmcw.chpid[i] == chp->id)) {
                        if (stsch(sch->schid, &sch->schib) != 0) {
                                /* Endgame. */
                                spin_unlock_irq(&sch->lock);
@@ -639,6 +645,7 @@ __chp_add(struct subchannel_id schid, void *data)
                        }
                        break;
                }
+       }
        if (i==8) {
                spin_unlock_irq(&sch->lock);
                return 0;
@@ -646,7 +653,7 @@ __chp_add(struct subchannel_id schid, void *data)
        sch->lpm = ((sch->schib.pmcw.pim &
                     sch->schib.pmcw.pam &
                     sch->schib.pmcw.pom)
-                   | 0x80 >> i) & sch->opm;
+                   | mask) & sch->opm;
 
        if (sch->driver && sch->driver->verify)
                sch->driver->verify(&sch->dev);
@@ -700,8 +707,7 @@ chp_process_crw(int chpid, int on)
        return chp_add(chpid);
 }
 
-static inline int
-__check_for_io_and_kill(struct subchannel *sch, int index)
+static inline int check_for_io_on_path(struct subchannel *sch, int index)
 {
        int cc;
 
@@ -711,10 +717,8 @@ __check_for_io_and_kill(struct subchannel *sch, int index)
        cc = stsch(sch->schid, &sch->schib);
        if (cc)
                return 0;
-       if (sch->schib.scsw.actl && sch->schib.pmcw.lpum == (0x80 >> index)) {
-               device_set_waiting(sch);
+       if (sch->schib.scsw.actl && sch->schib.pmcw.lpum == (0x80 >> index))
                return 1;
-       }
        return 0;
 }
 
@@ -743,12 +747,10 @@ __s390_subchannel_vary_chpid(struct subchannel *sch, __u8 chpid, int on)
                } else {
                        sch->opm &= ~(0x80 >> chp);
                        sch->lpm &= ~(0x80 >> chp);
-                       /*
-                        * Give running I/O a grace period in which it
-                        * can successfully terminate, even using the
-                        * just varied off path. Then kill it.
-                        */
-                       if (!__check_for_io_and_kill(sch, chp) && !sch->lpm) {
+                       if (check_for_io_on_path(sch, chp))
+                               /* Path verification is done after killing. */
+                               device_kill_io(sch);
+                       else if (!sch->lpm) {
                                if (css_enqueue_subchannel_slow(sch->schid)) {
                                        css_clear_subchannel_slow_list();
                                        need_rescan = 1;
index 2e2882daefbbd5985d233e3a011cce15d42c4695..8936e460a807cae8995eba957d224e9b9468c434 100644 (file)
@@ -19,6 +19,7 @@
 #include <asm/cio.h>
 #include <asm/delay.h>
 #include <asm/irq.h>
+#include <asm/irq_regs.h>
 #include <asm/setup.h>
 #include "airq.h"
 #include "cio.h"
@@ -606,15 +607,17 @@ do_IRQ (struct pt_regs *regs)
        struct tpi_info *tpi_info;
        struct subchannel *sch;
        struct irb *irb;
+       struct pt_regs *old_regs;
 
-       irq_enter ();
+       old_regs = set_irq_regs(regs);
+       irq_enter();
        asm volatile ("mc 0,0");
        if (S390_lowcore.int_clock >= S390_lowcore.jiffy_timer)
                /**
                 * Make sure that the i/o interrupt did not "overtake"
                 * the last HZ timer interrupt.
                 */
-               account_ticks(regs);
+               account_ticks();
        /*
         * Get interrupt information from lowcore
         */
@@ -652,7 +655,8 @@ do_IRQ (struct pt_regs *regs)
                 * out of the sie which costs more cycles than it saves.
                 */
        } while (!MACHINE_IS_VM && tpi (NULL) != 0);
-       irq_exit ();
+       irq_exit();
+       set_irq_regs(old_regs);
 }
 
 #ifdef CONFIG_CCW_CONSOLE
index 7086a74e9871df9f42ba4ff74a217761fcb83967..a2dee5bf5a17aa03b878bd91cffff090f2e27450 100644 (file)
@@ -177,7 +177,7 @@ get_subchannel_by_schid(struct subchannel_id schid)
        struct device *dev;
 
        dev = bus_find_device(&css_bus_type, NULL,
-                             (void *)&schid, check_subchannel);
+                             &schid, check_subchannel);
 
        return dev ? to_subchannel(dev) : NULL;
 }
index 8aabb4adeb5f08eb79ad7642005985f257e78815..4c2ff83362887aafe64fea2a5ebf6137b8456b9a 100644 (file)
@@ -76,9 +76,8 @@ struct ccw_device_private {
        int state;              /* device state */
        atomic_t onoff;
        unsigned long registered;
-       __u16 devno;            /* device number */
-       __u16 sch_no;           /* subchannel number */
-       __u8 ssid;              /* subchannel set id */
+       struct ccw_dev_id dev_id;       /* device id */
+       struct subchannel_id schid;     /* subchannel number */
        __u8 imask;             /* lpm mask for SNID/SID/SPGID */
        int iretry;             /* retry counter SNID/SID/SPGID */
        struct {
@@ -171,7 +170,7 @@ void device_trigger_reprobe(struct subchannel *);
 
 /* Helper functions for vary on/off. */
 int device_is_online(struct subchannel *);
-void device_set_waiting(struct subchannel *);
+void device_kill_io(struct subchannel *);
 
 /* Machine check helper function. */
 void device_kill_pending_timer(struct subchannel *);
index 688945662c151e16abbc65074dba3b6ed0ac06c8..94bdd4d8a4c9c205b72ef1b92dc598fb37b38d0e 100644 (file)
@@ -552,21 +552,19 @@ ccw_device_register(struct ccw_device *cdev)
 }
 
 struct match_data {
-       unsigned int devno;
-       unsigned int ssid;
+       struct ccw_dev_id dev_id;
        struct ccw_device * sibling;
 };
 
 static int
 match_devno(struct device * dev, void * data)
 {
-       struct match_data * d = (struct match_data *)data;
+       struct match_data * d = data;
        struct ccw_device * cdev;
 
        cdev = to_ccwdev(dev);
        if ((cdev->private->state == DEV_STATE_DISCONNECTED) &&
-           (cdev->private->devno == d->devno) &&
-           (cdev->private->ssid == d->ssid) &&
+           ccw_dev_id_is_equal(&cdev->private->dev_id, &d->dev_id) &&
            (cdev != d->sibling)) {
                cdev->private->state = DEV_STATE_NOT_OPER;
                return 1;
@@ -574,15 +572,13 @@ match_devno(struct device * dev, void * data)
        return 0;
 }
 
-static struct ccw_device *
-get_disc_ccwdev_by_devno(unsigned int devno, unsigned int ssid,
-                        struct ccw_device *sibling)
+static struct ccw_device * get_disc_ccwdev_by_dev_id(struct ccw_dev_id *dev_id,
+                                                    struct ccw_device *sibling)
 {
        struct device *dev;
        struct match_data data;
 
-       data.devno = devno;
-       data.ssid = ssid;
+       data.dev_id = *dev_id;
        data.sibling = sibling;
        dev = bus_find_device(&ccw_bus_type, NULL, &data, match_devno);
 
@@ -595,7 +591,7 @@ ccw_device_add_changed(void *data)
 
        struct ccw_device *cdev;
 
-       cdev = (struct ccw_device *)data;
+       cdev = data;
        if (device_add(&cdev->dev)) {
                put_device(&cdev->dev);
                return;
@@ -616,9 +612,9 @@ ccw_device_do_unreg_rereg(void *data)
        struct subchannel *sch;
        int need_rename;
 
-       cdev = (struct ccw_device *)data;
+       cdev = data;
        sch = to_subchannel(cdev->dev.parent);
-       if (cdev->private->devno != sch->schib.pmcw.dev) {
+       if (cdev->private->dev_id.devno != sch->schib.pmcw.dev) {
                /*
                 * The device number has changed. This is usually only when
                 * a device has been detached under VM and then re-appeared
@@ -633,10 +629,12 @@ ccw_device_do_unreg_rereg(void *data)
                 *        get possibly sick...
                 */
                struct ccw_device *other_cdev;
+               struct ccw_dev_id dev_id;
 
                need_rename = 1;
-               other_cdev = get_disc_ccwdev_by_devno(sch->schib.pmcw.dev,
-                                                     sch->schid.ssid, cdev);
+               dev_id.devno = sch->schib.pmcw.dev;
+               dev_id.ssid = sch->schid.ssid;
+               other_cdev = get_disc_ccwdev_by_dev_id(&dev_id, cdev);
                if (other_cdev) {
                        struct subchannel *other_sch;
 
@@ -652,7 +650,7 @@ ccw_device_do_unreg_rereg(void *data)
                }
                /* Update ssd info here. */
                css_get_ssd_info(sch);
-               cdev->private->devno = sch->schib.pmcw.dev;
+               cdev->private->dev_id.devno = sch->schib.pmcw.dev;
        } else
                need_rename = 0;
        device_remove_files(&cdev->dev);
@@ -662,7 +660,7 @@ ccw_device_do_unreg_rereg(void *data)
                snprintf (cdev->dev.bus_id, BUS_ID_SIZE, "0.%x.%04x",
                          sch->schid.ssid, sch->schib.pmcw.dev);
        PREPARE_WORK(&cdev->private->kick_work,
-                    ccw_device_add_changed, (void *)cdev);
+                    ccw_device_add_changed, cdev);
        queue_work(ccw_device_work, &cdev->private->kick_work);
 }
 
@@ -687,7 +685,7 @@ io_subchannel_register(void *data)
        int ret;
        unsigned long flags;
 
-       cdev = (struct ccw_device *) data;
+       cdev = data;
        sch = to_subchannel(cdev->dev.parent);
 
        if (klist_node_attached(&cdev->dev.knode_parent)) {
@@ -759,7 +757,7 @@ io_subchannel_recog_done(struct ccw_device *cdev)
                        break;
                sch = to_subchannel(cdev->dev.parent);
                PREPARE_WORK(&cdev->private->kick_work,
-                            ccw_device_call_sch_unregister, (void *) cdev);
+                            ccw_device_call_sch_unregister, cdev);
                queue_work(slow_path_wq, &cdev->private->kick_work);
                if (atomic_dec_and_test(&ccw_device_init_count))
                        wake_up(&ccw_device_init_wq);
@@ -774,7 +772,7 @@ io_subchannel_recog_done(struct ccw_device *cdev)
                if (!get_device(&cdev->dev))
                        break;
                PREPARE_WORK(&cdev->private->kick_work,
-                            io_subchannel_register, (void *) cdev);
+                            io_subchannel_register, cdev);
                queue_work(slow_path_wq, &cdev->private->kick_work);
                break;
        }
@@ -792,9 +790,9 @@ io_subchannel_recog(struct ccw_device *cdev, struct subchannel *sch)
 
        /* Init private data. */
        priv = cdev->private;
-       priv->devno = sch->schib.pmcw.dev;
-       priv->ssid = sch->schid.ssid;
-       priv->sch_no = sch->schid.sch_no;
+       priv->dev_id.devno = sch->schib.pmcw.dev;
+       priv->dev_id.ssid = sch->schid.ssid;
+       priv->schid = sch->schid;
        priv->state = DEV_STATE_NOT_OPER;
        INIT_LIST_HEAD(&priv->cmb_list);
        init_waitqueue_head(&priv->wait_q);
@@ -912,7 +910,7 @@ io_subchannel_remove (struct subchannel *sch)
         */
        if (get_device(&cdev->dev)) {
                PREPARE_WORK(&cdev->private->kick_work,
-                            ccw_device_unregister, (void *) cdev);
+                            ccw_device_unregister, cdev);
                queue_work(ccw_device_work, &cdev->private->kick_work);
        }
        return 0;
@@ -1055,7 +1053,7 @@ __ccwdev_check_busid(struct device *dev, void *id)
 {
        char *bus_id;
 
-       bus_id = (char *)id;
+       bus_id = id;
 
        return (strncmp(bus_id, dev->bus_id, BUS_ID_SIZE) == 0);
 }
index 00be9a5b4acde18141a76d7aef38ad4b90b2347c..c6140cc97a80933bc129ca3b091183fdcd3ec747 100644 (file)
@@ -21,7 +21,6 @@ enum dev_state {
        /* states to wait for i/o completion before doing something */
        DEV_STATE_CLEAR_VERIFY,
        DEV_STATE_TIMEOUT_KILL,
-       DEV_STATE_WAIT4IO,
        DEV_STATE_QUIESCE,
        /* special states for devices gone not operational */
        DEV_STATE_DISCONNECTED,
index b67620208f36e2f463b4022a2a25e897197f3067..de3d0857db9fb83b3526a5d0557876d35dc2b154 100644 (file)
@@ -59,18 +59,6 @@ device_set_disconnected(struct subchannel *sch)
        cdev->private->state = DEV_STATE_DISCONNECTED;
 }
 
-void
-device_set_waiting(struct subchannel *sch)
-{
-       struct ccw_device *cdev;
-
-       if (!sch->dev.driver_data)
-               return;
-       cdev = sch->dev.driver_data;
-       ccw_device_set_timeout(cdev, 10*HZ);
-       cdev->private->state = DEV_STATE_WAIT4IO;
-}
-
 /*
  * Timeout function. It just triggers a DEV_EVENT_TIMEOUT.
  */
@@ -183,9 +171,9 @@ ccw_device_handle_oper(struct ccw_device *cdev)
            cdev->id.cu_model != cdev->private->senseid.cu_model ||
            cdev->id.dev_type != cdev->private->senseid.dev_type ||
            cdev->id.dev_model != cdev->private->senseid.dev_model ||
-           cdev->private->devno != sch->schib.pmcw.dev) {
+           cdev->private->dev_id.devno != sch->schib.pmcw.dev) {
                PREPARE_WORK(&cdev->private->kick_work,
-                            ccw_device_do_unreg_rereg, (void *)cdev);
+                            ccw_device_do_unreg_rereg, cdev);
                queue_work(ccw_device_work, &cdev->private->kick_work);
                return 0;
        }
@@ -255,7 +243,7 @@ ccw_device_recog_done(struct ccw_device *cdev, int state)
        case DEV_STATE_NOT_OPER:
                CIO_DEBUG(KERN_WARNING, 2,
                          "SenseID : unknown device %04x on subchannel "
-                         "0.%x.%04x\n", cdev->private->devno,
+                         "0.%x.%04x\n", cdev->private->dev_id.devno,
                          sch->schid.ssid, sch->schid.sch_no);
                break;
        case DEV_STATE_OFFLINE:
@@ -282,14 +270,15 @@ ccw_device_recog_done(struct ccw_device *cdev, int state)
                CIO_DEBUG(KERN_INFO, 2, "SenseID : device 0.%x.%04x reports: "
                          "CU  Type/Mod = %04X/%02X, Dev Type/Mod = "
                          "%04X/%02X\n",
-                         cdev->private->ssid, cdev->private->devno,
+                         cdev->private->dev_id.ssid,
+                         cdev->private->dev_id.devno,
                          cdev->id.cu_type, cdev->id.cu_model,
                          cdev->id.dev_type, cdev->id.dev_model);
                break;
        case DEV_STATE_BOXED:
                CIO_DEBUG(KERN_WARNING, 2,
                          "SenseID : boxed device %04x on subchannel "
-                         "0.%x.%04x\n", cdev->private->devno,
+                         "0.%x.%04x\n", cdev->private->dev_id.devno,
                          sch->schid.ssid, sch->schid.sch_no);
                break;
        }
@@ -325,13 +314,13 @@ ccw_device_oper_notify(void *data)
        struct subchannel *sch;
        int ret;
 
-       cdev = (struct ccw_device *)data;
+       cdev = data;
        sch = to_subchannel(cdev->dev.parent);
        ret = (sch->driver && sch->driver->notify) ?
                sch->driver->notify(&sch->dev, CIO_OPER) : 0;
        if (!ret)
                /* Driver doesn't want device back. */
-               ccw_device_do_unreg_rereg((void *)cdev);
+               ccw_device_do_unreg_rereg(cdev);
        else {
                /* Reenable channel measurements, if needed. */
                cmf_reenable(cdev);
@@ -363,12 +352,12 @@ ccw_device_done(struct ccw_device *cdev, int state)
        if (state == DEV_STATE_BOXED)
                CIO_DEBUG(KERN_WARNING, 2,
                          "Boxed device %04x on subchannel %04x\n",
-                         cdev->private->devno, sch->schid.sch_no);
+                         cdev->private->dev_id.devno, sch->schid.sch_no);
 
        if (cdev->private->flags.donotify) {
                cdev->private->flags.donotify = 0;
                PREPARE_WORK(&cdev->private->kick_work, ccw_device_oper_notify,
-                            (void *)cdev);
+                            cdev);
                queue_work(ccw_device_notify_work, &cdev->private->kick_work);
        }
        wake_up(&cdev->private->wait_q);
@@ -412,7 +401,8 @@ static void __ccw_device_get_common_pgid(struct ccw_device *cdev)
                /* PGID mismatch, can't pathgroup. */
                CIO_MSG_EVENT(0, "SNID - pgid mismatch for device "
                              "0.%x.%04x, can't pathgroup\n",
-                             cdev->private->ssid, cdev->private->devno);
+                             cdev->private->dev_id.ssid,
+                             cdev->private->dev_id.devno);
                cdev->private->options.pgroup = 0;
                return;
        }
@@ -523,7 +513,7 @@ ccw_device_nopath_notify(void *data)
        struct subchannel *sch;
        int ret;
 
-       cdev = (struct ccw_device *)data;
+       cdev = data;
        sch = to_subchannel(cdev->dev.parent);
        /* Extra sanity. */
        if (sch->lpm)
@@ -537,7 +527,7 @@ ccw_device_nopath_notify(void *data)
                        if (get_device(&cdev->dev)) {
                                PREPARE_WORK(&cdev->private->kick_work,
                                             ccw_device_call_sch_unregister,
-                                            (void *)cdev);
+                                            cdev);
                                queue_work(ccw_device_work,
                                           &cdev->private->kick_work);
                        } else
@@ -588,11 +578,15 @@ ccw_device_verify_done(struct ccw_device *cdev, int err)
                }
                break;
        case -ETIME:
+               /* Reset oper notify indication after verify error. */
+               cdev->private->flags.donotify = 0;
                ccw_device_done(cdev, DEV_STATE_BOXED);
                break;
        default:
+               /* Reset oper notify indication after verify error. */
+               cdev->private->flags.donotify = 0;
                PREPARE_WORK(&cdev->private->kick_work,
-                            ccw_device_nopath_notify, (void *)cdev);
+                            ccw_device_nopath_notify, cdev);
                queue_work(ccw_device_notify_work, &cdev->private->kick_work);
                ccw_device_done(cdev, DEV_STATE_NOT_OPER);
                break;
@@ -723,7 +717,7 @@ ccw_device_offline_notoper(struct ccw_device *cdev, enum dev_event dev_event)
        sch = to_subchannel(cdev->dev.parent);
        if (get_device(&cdev->dev)) {
                PREPARE_WORK(&cdev->private->kick_work,
-                            ccw_device_call_sch_unregister, (void *)cdev);
+                            ccw_device_call_sch_unregister, cdev);
                queue_work(ccw_device_work, &cdev->private->kick_work);
        }
        wake_up(&cdev->private->wait_q);
@@ -754,7 +748,7 @@ ccw_device_online_notoper(struct ccw_device *cdev, enum dev_event dev_event)
        }
        if (get_device(&cdev->dev)) {
                PREPARE_WORK(&cdev->private->kick_work,
-                            ccw_device_call_sch_unregister, (void *)cdev);
+                            ccw_device_call_sch_unregister, cdev);
                queue_work(ccw_device_work, &cdev->private->kick_work);
        }
        wake_up(&cdev->private->wait_q);
@@ -859,7 +853,7 @@ ccw_device_online_timeout(struct ccw_device *cdev, enum dev_event dev_event)
                sch = to_subchannel(cdev->dev.parent);
                if (!sch->lpm) {
                        PREPARE_WORK(&cdev->private->kick_work,
-                                    ccw_device_nopath_notify, (void *)cdev);
+                                    ccw_device_nopath_notify, cdev);
                        queue_work(ccw_device_notify_work,
                                   &cdev->private->kick_work);
                } else
@@ -885,7 +879,8 @@ ccw_device_w4sense(struct ccw_device *cdev, enum dev_event dev_event)
                        /* Basic sense hasn't started. Try again. */
                        ccw_device_do_sense(cdev, irb);
                else {
-                       printk("Huh? %s(%s): unsolicited interrupt...\n",
+                       printk(KERN_INFO "Huh? %s(%s): unsolicited "
+                              "interrupt...\n",
                               __FUNCTION__, cdev->dev.bus_id);
                        if (cdev->handler)
                                cdev->handler (cdev, 0, irb);
@@ -944,10 +939,10 @@ ccw_device_killing_irq(struct ccw_device *cdev, enum dev_event dev_event)
        cdev->private->state = DEV_STATE_ONLINE;
        if (cdev->handler)
                cdev->handler(cdev, cdev->private->intparm,
-                             ERR_PTR(-ETIMEDOUT));
+                             ERR_PTR(-EIO));
        if (!sch->lpm) {
                PREPARE_WORK(&cdev->private->kick_work,
-                            ccw_device_nopath_notify, (void *)cdev);
+                            ccw_device_nopath_notify, cdev);
                queue_work(ccw_device_notify_work, &cdev->private->kick_work);
        } else if (cdev->private->flags.doverify)
                /* Start delayed path verification. */
@@ -970,7 +965,7 @@ ccw_device_killing_timeout(struct ccw_device *cdev, enum dev_event dev_event)
                sch = to_subchannel(cdev->dev.parent);
                if (!sch->lpm) {
                        PREPARE_WORK(&cdev->private->kick_work,
-                                    ccw_device_nopath_notify, (void *)cdev);
+                                    ccw_device_nopath_notify, cdev);
                        queue_work(ccw_device_notify_work,
                                   &cdev->private->kick_work);
                } else
@@ -981,51 +976,15 @@ ccw_device_killing_timeout(struct ccw_device *cdev, enum dev_event dev_event)
        cdev->private->state = DEV_STATE_ONLINE;
        if (cdev->handler)
                cdev->handler(cdev, cdev->private->intparm,
-                             ERR_PTR(-ETIMEDOUT));
-}
-
-static void
-ccw_device_wait4io_irq(struct ccw_device *cdev, enum dev_event dev_event)
-{
-       struct irb *irb;
-       struct subchannel *sch;
-
-       irb = (struct irb *) __LC_IRB;
-       /*
-        * Accumulate status and find out if a basic sense is needed.
-        * This is fine since we have already adapted the lpm.
-        */
-       ccw_device_accumulate_irb(cdev, irb);
-       if (cdev->private->flags.dosense) {
-               if (ccw_device_do_sense(cdev, irb) == 0) {
-                       cdev->private->state = DEV_STATE_W4SENSE;
-               }
-               return;
-       }
-
-       /* Iff device is idle, reset timeout. */
-       sch = to_subchannel(cdev->dev.parent);
-       if (!stsch(sch->schid, &sch->schib))
-               if (sch->schib.scsw.actl == 0)
-                       ccw_device_set_timeout(cdev, 0);
-       /* Call the handler. */
-       ccw_device_call_handler(cdev);
-       if (!sch->lpm) {
-               PREPARE_WORK(&cdev->private->kick_work,
-                            ccw_device_nopath_notify, (void *)cdev);
-               queue_work(ccw_device_notify_work, &cdev->private->kick_work);
-       } else if (cdev->private->flags.doverify)
-               ccw_device_online_verify(cdev, 0);
+                             ERR_PTR(-EIO));
 }
 
-static void
-ccw_device_wait4io_timeout(struct ccw_device *cdev, enum dev_event dev_event)
+void device_kill_io(struct subchannel *sch)
 {
        int ret;
-       struct subchannel *sch;
+       struct ccw_device *cdev;
 
-       sch = to_subchannel(cdev->dev.parent);
-       ccw_device_set_timeout(cdev, 0);
+       cdev = sch->dev.driver_data;
        ret = ccw_device_cancel_halt_clear(cdev);
        if (ret == -EBUSY) {
                ccw_device_set_timeout(cdev, 3*HZ);
@@ -1035,7 +994,7 @@ ccw_device_wait4io_timeout(struct ccw_device *cdev, enum dev_event dev_event)
        if (ret == -ENODEV) {
                if (!sch->lpm) {
                        PREPARE_WORK(&cdev->private->kick_work,
-                                    ccw_device_nopath_notify, (void *)cdev);
+                                    ccw_device_nopath_notify, cdev);
                        queue_work(ccw_device_notify_work,
                                   &cdev->private->kick_work);
                } else
@@ -1044,12 +1003,12 @@ ccw_device_wait4io_timeout(struct ccw_device *cdev, enum dev_event dev_event)
        }
        if (cdev->handler)
                cdev->handler(cdev, cdev->private->intparm,
-                             ERR_PTR(-ETIMEDOUT));
+                             ERR_PTR(-EIO));
        if (!sch->lpm) {
                PREPARE_WORK(&cdev->private->kick_work,
-                            ccw_device_nopath_notify, (void *)cdev);
+                            ccw_device_nopath_notify, cdev);
                queue_work(ccw_device_notify_work, &cdev->private->kick_work);
-       } else if (cdev->private->flags.doverify)
+       } else
                /* Start delayed path verification. */
                ccw_device_online_verify(cdev, 0);
 }
@@ -1286,12 +1245,6 @@ fsm_func_t *dev_jumptable[NR_DEV_STATES][NR_DEV_EVENTS] = {
                [DEV_EVENT_TIMEOUT]     = ccw_device_killing_timeout,
                [DEV_EVENT_VERIFY]      = ccw_device_nop, //FIXME
        },
-       [DEV_STATE_WAIT4IO] = {
-               [DEV_EVENT_NOTOPER]     = ccw_device_online_notoper,
-               [DEV_EVENT_INTERRUPT]   = ccw_device_wait4io_irq,
-               [DEV_EVENT_TIMEOUT]     = ccw_device_wait4io_timeout,
-               [DEV_EVENT_VERIFY]      = ccw_device_delay_verify,
-       },
        [DEV_STATE_QUIESCE] = {
                [DEV_EVENT_NOTOPER]     = ccw_device_quiesce_done,
                [DEV_EVENT_INTERRUPT]   = ccw_device_quiesce_done,
index 1398367b5f68ef14f3591f9daf53e582475557b9..a74785b9e4ebe9303c4864d857a682f7f79f0259 100644 (file)
@@ -251,7 +251,7 @@ ccw_device_check_sense_id(struct ccw_device *cdev)
                 */
                CIO_MSG_EVENT(2, "SenseID : device %04x on Subchannel "
                              "0.%x.%04x reports cmd reject\n",
-                             cdev->private->devno, sch->schid.ssid,
+                             cdev->private->dev_id.devno, sch->schid.ssid,
                              sch->schid.sch_no);
                return -EOPNOTSUPP;
        }
@@ -259,7 +259,8 @@ ccw_device_check_sense_id(struct ccw_device *cdev)
                CIO_MSG_EVENT(2, "SenseID : UC on dev 0.%x.%04x, "
                              "lpum %02X, cnt %02d, sns :"
                              " %02X%02X%02X%02X %02X%02X%02X%02X ...\n",
-                             cdev->private->ssid, cdev->private->devno,
+                             cdev->private->dev_id.ssid,
+                             cdev->private->dev_id.devno,
                              irb->esw.esw0.sublog.lpum,
                              irb->esw.esw0.erw.scnt,
                              irb->ecw[0], irb->ecw[1],
@@ -274,14 +275,15 @@ ccw_device_check_sense_id(struct ccw_device *cdev)
                        CIO_MSG_EVENT(2, "SenseID : path %02X for device %04x "
                                      "on subchannel 0.%x.%04x is "
                                      "'not operational'\n", sch->orb.lpm,
-                                     cdev->private->devno, sch->schid.ssid,
-                                     sch->schid.sch_no);
+                                     cdev->private->dev_id.devno,
+                                     sch->schid.ssid, sch->schid.sch_no);
                return -EACCES;
        }
        /* Hmm, whatever happened, try again. */
        CIO_MSG_EVENT(2, "SenseID : start_IO() for device %04x on "
                      "subchannel 0.%x.%04x returns status %02X%02X\n",
-                     cdev->private->devno, sch->schid.ssid, sch->schid.sch_no,
+                     cdev->private->dev_id.devno, sch->schid.ssid,
+                     sch->schid.sch_no,
                      irb->scsw.dstat, irb->scsw.cstat);
        return -EAGAIN;
 }
@@ -330,7 +332,7 @@ ccw_device_sense_id_irq(struct ccw_device *cdev, enum dev_event dev_event)
                /* fall through. */
        default:                /* Sense ID failed. Try asking VM. */
                if (MACHINE_IS_VM) {
-                       VM_virtual_device_info (cdev->private->devno,
+                       VM_virtual_device_info (cdev->private->dev_id.devno,
                                                &cdev->private->senseid);
                        if (cdev->private->senseid.cu_type != 0xFFFF) {
                                /* Got the device information from VM. */
index 84b9b18eabc25159d752ea1f78a0792263e97bd3..b39c1fa48acd22cac1fd92990da9699193913510 100644 (file)
@@ -50,7 +50,6 @@ ccw_device_clear(struct ccw_device *cdev, unsigned long intparm)
        if (cdev->private->state == DEV_STATE_NOT_OPER)
                return -ENODEV;
        if (cdev->private->state != DEV_STATE_ONLINE &&
-           cdev->private->state != DEV_STATE_WAIT4IO &&
            cdev->private->state != DEV_STATE_W4SENSE)
                return -EINVAL;
        sch = to_subchannel(cdev->dev.parent);
@@ -155,7 +154,6 @@ ccw_device_halt(struct ccw_device *cdev, unsigned long intparm)
        if (cdev->private->state == DEV_STATE_NOT_OPER)
                return -ENODEV;
        if (cdev->private->state != DEV_STATE_ONLINE &&
-           cdev->private->state != DEV_STATE_WAIT4IO &&
            cdev->private->state != DEV_STATE_W4SENSE)
                return -EINVAL;
        sch = to_subchannel(cdev->dev.parent);
@@ -592,13 +590,13 @@ ccw_device_get_chp_desc(struct ccw_device *cdev, int chp_no)
 int
 _ccw_device_get_subchannel_number(struct ccw_device *cdev)
 {
-       return cdev->private->sch_no;
+       return cdev->private->schid.sch_no;
 }
 
 int
 _ccw_device_get_device_number(struct ccw_device *cdev)
 {
-       return cdev->private->devno;
+       return cdev->private->dev_id.devno;
 }
 
 
index 84917b39de458c66ea57225e2d60a9f590e29257..2975ce888c19ca3c2dc2b7fcf32ba79442323a46 100644 (file)
@@ -79,7 +79,8 @@ __ccw_device_sense_pgid_start(struct ccw_device *cdev)
                        CIO_MSG_EVENT(2, "SNID - Device %04x on Subchannel "
                                      "0.%x.%04x, lpm %02X, became 'not "
                                      "operational'\n",
-                                     cdev->private->devno, sch->schid.ssid,
+                                     cdev->private->dev_id.devno,
+                                     sch->schid.ssid,
                                      sch->schid.sch_no, cdev->private->imask);
 
                }
@@ -135,7 +136,8 @@ __ccw_device_check_sense_pgid(struct ccw_device *cdev)
                CIO_MSG_EVENT(2, "SNID - device 0.%x.%04x, unit check, "
                              "lpum %02X, cnt %02d, sns : "
                              "%02X%02X%02X%02X %02X%02X%02X%02X ...\n",
-                             cdev->private->ssid, cdev->private->devno,
+                             cdev->private->dev_id.ssid,
+                             cdev->private->dev_id.devno,
                              irb->esw.esw0.sublog.lpum,
                              irb->esw.esw0.erw.scnt,
                              irb->ecw[0], irb->ecw[1],
@@ -147,7 +149,7 @@ __ccw_device_check_sense_pgid(struct ccw_device *cdev)
        if (irb->scsw.cc == 3) {
                CIO_MSG_EVENT(2, "SNID - Device %04x on Subchannel 0.%x.%04x,"
                              " lpm %02X, became 'not operational'\n",
-                             cdev->private->devno, sch->schid.ssid,
+                             cdev->private->dev_id.devno, sch->schid.ssid,
                              sch->schid.sch_no, sch->orb.lpm);
                return -EACCES;
        }
@@ -155,7 +157,7 @@ __ccw_device_check_sense_pgid(struct ccw_device *cdev)
        if (cdev->private->pgid[i].inf.ps.state2 == SNID_STATE2_RESVD_ELSE) {
                CIO_MSG_EVENT(2, "SNID - Device %04x on Subchannel 0.%x.%04x "
                              "is reserved by someone else\n",
-                             cdev->private->devno, sch->schid.ssid,
+                             cdev->private->dev_id.devno, sch->schid.ssid,
                              sch->schid.sch_no);
                return -EUSERS;
        }
@@ -261,7 +263,7 @@ __ccw_device_do_pgid(struct ccw_device *cdev, __u8 func)
        /* PGID command failed on this path. */
        CIO_MSG_EVENT(2, "SPID - Device %04x on Subchannel "
                      "0.%x.%04x, lpm %02X, became 'not operational'\n",
-                     cdev->private->devno, sch->schid.ssid,
+                     cdev->private->dev_id.devno, sch->schid.ssid,
                      sch->schid.sch_no, cdev->private->imask);
        return ret;
 }
@@ -301,7 +303,7 @@ static int __ccw_device_do_nop(struct ccw_device *cdev)
        /* nop command failed on this path. */
        CIO_MSG_EVENT(2, "NOP - Device %04x on Subchannel "
                      "0.%x.%04x, lpm %02X, became 'not operational'\n",
-                     cdev->private->devno, sch->schid.ssid,
+                     cdev->private->dev_id.devno, sch->schid.ssid,
                      sch->schid.sch_no, cdev->private->imask);
        return ret;
 }
@@ -328,8 +330,9 @@ __ccw_device_check_pgid(struct ccw_device *cdev)
                CIO_MSG_EVENT(2, "SPID - device 0.%x.%04x, unit check, "
                              "cnt %02d, "
                              "sns : %02X%02X%02X%02X %02X%02X%02X%02X ...\n",
-                             cdev->private->ssid,
-                             cdev->private->devno, irb->esw.esw0.erw.scnt,
+                             cdev->private->dev_id.ssid,
+                             cdev->private->dev_id.devno,
+                             irb->esw.esw0.erw.scnt,
                              irb->ecw[0], irb->ecw[1],
                              irb->ecw[2], irb->ecw[3],
                              irb->ecw[4], irb->ecw[5],
@@ -339,7 +342,7 @@ __ccw_device_check_pgid(struct ccw_device *cdev)
        if (irb->scsw.cc == 3) {
                CIO_MSG_EVENT(2, "SPID - Device %04x on Subchannel 0.%x.%04x,"
                              " lpm %02X, became 'not operational'\n",
-                             cdev->private->devno, sch->schid.ssid,
+                             cdev->private->dev_id.devno, sch->schid.ssid,
                              sch->schid.sch_no, cdev->private->imask);
                return -EACCES;
        }
@@ -362,7 +365,7 @@ static int __ccw_device_check_nop(struct ccw_device *cdev)
        if (irb->scsw.cc == 3) {
                CIO_MSG_EVENT(2, "NOP - Device %04x on Subchannel 0.%x.%04x,"
                              " lpm %02X, became 'not operational'\n",
-                             cdev->private->devno, sch->schid.ssid,
+                             cdev->private->dev_id.devno, sch->schid.ssid,
                              sch->schid.sch_no, cdev->private->imask);
                return -EACCES;
        }
index caf148d5caadb55ec6eab663168ebc8180b908ea..3f7cbce4cd87ee6bad825f8ae130744405274c8a 100644 (file)
@@ -32,19 +32,18 @@ ccw_device_msg_control_check(struct ccw_device *cdev, struct irb *irb)
                                 SCHN_STAT_CHN_CTRL_CHK |
                                 SCHN_STAT_INTF_CTRL_CHK)))
                return;
-               
        CIO_MSG_EVENT(0, "Channel-Check or Interface-Control-Check "
                      "received"
                      " ... device %04x on subchannel 0.%x.%04x, dev_stat "
                      ": %02X sch_stat : %02X\n",
-                     cdev->private->devno, cdev->private->ssid,
-                     cdev->private->sch_no,
+                     cdev->private->dev_id.devno, cdev->private->schid.ssid,
+                     cdev->private->schid.sch_no,
                      irb->scsw.dstat, irb->scsw.cstat);
 
        if (irb->scsw.cc != 3) {
                char dbf_text[15];
 
-               sprintf(dbf_text, "chk%x", cdev->private->sch_no);
+               sprintf(dbf_text, "chk%x", cdev->private->schid.sch_no);
                CIO_TRACE_EVENT(0, dbf_text);
                CIO_HEX_EVENT(0, irb, sizeof (struct irb));
        }
index cde822d8b5c82041698cf2b96f206f09ac2eec4e..476aa1da5cbcc0cd8e4e27ecccfc6f50c18f4935 100644 (file)
@@ -1741,7 +1741,7 @@ qdio_fill_qs(struct qdio_irq *irq_ptr, struct ccw_device *cdev,
        void *ptr;
        int available;
 
-       sprintf(dbf_text,"qfqs%4x",cdev->private->sch_no);
+       sprintf(dbf_text,"qfqs%4x",cdev->private->schid.sch_no);
        QDIO_DBF_TEXT0(0,setup,dbf_text);
        for (i=0;i<no_input_qs;i++) {
                q=irq_ptr->input_qs[i];
@@ -2924,7 +2924,7 @@ qdio_establish_handle_irq(struct ccw_device *cdev, int cstat, int dstat)
 
        irq_ptr = cdev->private->qdio_data;
 
-       sprintf(dbf_text,"qehi%4x",cdev->private->sch_no);
+       sprintf(dbf_text,"qehi%4x",cdev->private->schid.sch_no);
        QDIO_DBF_TEXT0(0,setup,dbf_text);
        QDIO_DBF_TEXT0(0,trace,dbf_text);
 
@@ -2943,7 +2943,7 @@ qdio_initialize(struct qdio_initialize *init_data)
        int rc;
        char dbf_text[15];
 
-       sprintf(dbf_text,"qini%4x",init_data->cdev->private->sch_no);
+       sprintf(dbf_text,"qini%4x",init_data->cdev->private->schid.sch_no);
        QDIO_DBF_TEXT0(0,setup,dbf_text);
        QDIO_DBF_TEXT0(0,trace,dbf_text);
 
@@ -2964,7 +2964,7 @@ qdio_allocate(struct qdio_initialize *init_data)
        struct qdio_irq *irq_ptr;
        char dbf_text[15];
 
-       sprintf(dbf_text,"qalc%4x",init_data->cdev->private->sch_no);
+       sprintf(dbf_text,"qalc%4x",init_data->cdev->private->schid.sch_no);
        QDIO_DBF_TEXT0(0,setup,dbf_text);
        QDIO_DBF_TEXT0(0,trace,dbf_text);
        if ( (init_data->no_input_qs>QDIO_MAX_QUEUES_PER_IRQ) ||
@@ -3187,7 +3187,7 @@ qdio_establish(struct qdio_initialize *init_data)
                tiqdio_set_delay_target(irq_ptr,TIQDIO_DELAY_TARGET);
        }
 
-       sprintf(dbf_text,"qest%4x",cdev->private->sch_no);
+       sprintf(dbf_text,"qest%4x",cdev->private->schid.sch_no);
        QDIO_DBF_TEXT0(0,setup,dbf_text);
        QDIO_DBF_TEXT0(0,trace,dbf_text);
 
@@ -3529,7 +3529,7 @@ do_QDIO(struct ccw_device *cdev,unsigned int callflags,
 #ifdef CONFIG_QDIO_DEBUG
        char dbf_text[20];
 
-       sprintf(dbf_text,"doQD%04x",cdev->private->sch_no);
+       sprintf(dbf_text,"doQD%04x",cdev->private->schid.sch_no);
        QDIO_DBF_TEXT3(0,trace,dbf_text);
 #endif /* CONFIG_QDIO_DEBUG */
 
index cd30f37fceae4512b3c99088a006ced4c6eb5600..c5ccd20b110cc9b035088f9fe2b8b252ec6c6f03 100644 (file)
@@ -1062,7 +1062,7 @@ static int ap_poll_thread(void *data)
        unsigned long flags;
        int requests;
 
-       set_user_nice(current, -20);
+       set_user_nice(current, 19);
        while (1) {
                if (need_resched()) {
                        schedule();
index 809dd8d7f47ab034510e88ccf06dfcb39ddf3e15..1476ce2b437cb498f7e47b680767b71cdd80f99e 100644 (file)
@@ -116,7 +116,7 @@ static DEFINE_SPINLOCK(iucv_irq_queue_lock);
  *Internal function prototypes
  */
 static void iucv_tasklet_handler(unsigned long);
-static void iucv_irq_handler(struct pt_regs *, __u16);
+static void iucv_irq_handler(__u16);
 
 static DECLARE_TASKLET(iucv_tasklet,iucv_tasklet_handler,0);
 
@@ -2251,7 +2251,7 @@ iucv_sever(__u16 pathid, __u8 user_data[16])
  * Places the interrupt buffer on a queue and schedules iucv_tasklet_handler().
  */
 static void
-iucv_irq_handler(struct pt_regs *regs, __u16 code)
+iucv_irq_handler(__u16 code)
 {
        iucv_irqdata *irqdata;
 
index 862a411a4aa01739e772377db6d27e2bc46f18b6..c88babce9bca813117249eb45f87a5960bdfe76c 100644 (file)
@@ -1987,7 +1987,7 @@ zfcp_erp_adapter_strategy_open_qdio(struct zfcp_erp_action *erp_action)
                sbale = &(adapter->response_queue.buffer[i]->element[0]);
                sbale->length = 0;
                sbale->flags = SBAL_FLAGS_LAST_ENTRY;
-               sbale->addr = 0;
+               sbale->addr = NULL;
        }
 
        ZFCP_LOG_TRACE("calling do_QDIO on adapter %s (flags=0x%x, "
index a305d4091547f9180a367a26bc67d410d1e926cc..a54b4ac67568471d39b0dac80c8503482cb0540b 100644 (file)
@@ -254,7 +254,7 @@ for(i=0;i<TYPE_1_IRQS;i++)
 return 0;
 }
 
-static irqreturn_t aurora_interrupt(int irq, void * dev_id, struct pt_regs * regs);
+static irqreturn_t aurora_interrupt(int irq, void * dev_id);
 
 /* Main probing routine, also sets irq. */
 static int aurora_probe(void)
@@ -689,7 +689,7 @@ static void aurora_check_modem(struct Aurora_board const * bp, int chip)
 }
 
 /* The main interrupt processing routine */
-static irqreturn_t aurora_interrupt(int irq, void * dev_id, struct pt_regs * regs)
+static irqreturn_t aurora_interrupt(int irq, void * dev_id)
 {
        unsigned char status;
        unsigned char ack,chip/*,chip_id*/;
index d27e4f6d7045a3a5f21e38d6bab32455d83c3d8a..a54e4140683aea238d28e48f50621e801c7d9450 100644 (file)
@@ -4,11 +4,9 @@
  * Copyright (C) 2001 David S. Miller (davem@redhat.com)
  */
 
-#include <linux/kernel.h>
 #include <linux/kthread.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
+#include <linux/kmod.h>
 #include <asm/oplib.h>
 #include <asm/ebus.h>
 
@@ -197,7 +195,7 @@ static void do_envctrl_shutdown(struct bbc_cpu_temperature *tp)
        printk(KERN_CRIT "kenvctrld: Shutting down the system now.\n");
 
        shutting_down = 1;
-       if (kernel_execve("/sbin/shutdown", argv, envp) < 0)
+       if (call_usermodehelper("/sbin/shutdown", argv, envp, 0) < 0)
                printk(KERN_CRIT "envctrl: shutdown execution failed\n");
 }
 
index 7186235594f999580325bfe5791de8075c3c2278..22631f8b9b481208ae19c6daacea6ae2bab3a2e6 100644 (file)
@@ -331,7 +331,7 @@ EXPORT_SYMBOL(bbc_i2c_readb);
 EXPORT_SYMBOL(bbc_i2c_write_buf);
 EXPORT_SYMBOL(bbc_i2c_read_buf);
 
-static irqreturn_t bbc_i2c_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t bbc_i2c_interrupt(int irq, void *dev_id)
 {
        struct bbc_i2c_bus *bp = dev_id;
 
index 40b6fc86f6a8301a5c0fec1e2c3a6dba5a807d4f..f5803ecb19995cc200ef5eefa0cc882fba04d149 100644 (file)
@@ -185,7 +185,7 @@ MODULE_SUPPORTED_DEVICE
 #ifdef WD_DEBUG
 static void wd_dumpregs(void);
 #endif
-static irqreturn_t wd_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t wd_interrupt(int irq, void *dev_id);
 static void wd_toggleintr(struct wd_timer* pTimer, int enable);
 static void wd_pingtimer(struct wd_timer* pTimer);
 static void wd_starttimer(struct wd_timer* pTimer);
@@ -444,7 +444,7 @@ static ssize_t wd_read(struct file * file, char __user *buffer,
 #endif /* ifdef WD_DEBUG */
 }
 
-static irqreturn_t wd_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t wd_interrupt(int irq, void *dev_id)
 {
        /* Only WD0 will interrupt-- others are NMI and we won't
         * see them here....
index 728a133d0fc5b7c306443280e63d296e047cc5dc..fff4660cdf96e34880f7242d0fdecc588c05536a 100644 (file)
  */
 
 #include <linux/module.h>
-#include <linux/sched.h>
+#include <linux/init.h>
 #include <linux/kthread.h>
-#include <linux/errno.h>
 #include <linux/delay.h>
 #include <linux/ioport.h>
-#include <linux/init.h>
 #include <linux/miscdevice.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <linux/kernel.h>
+#include <linux/kmod.h>
 
 #include <asm/ebus.h>
 #include <asm/uaccess.h>
@@ -980,7 +976,7 @@ static void envctrl_do_shutdown(void)
 
        inprog = 1;
        printk(KERN_CRIT "kenvctrld: WARNING: Shutting down the system now.\n");
-       ret = kernel_execve("/sbin/shutdown", argv, envp);
+       ret = call_usermodehelper("/sbin/shutdown", argv, envp, 0);
        if (ret < 0) {
                printk(KERN_CRIT "kenvctrld: WARNING: system shutdown failed!\n"); 
                inprog = 0;  /* unlikely to succeed, but we could try again */
index 2f698763ba5d5c6ee4b2cca28e6198961f575527..81ba2d71cee2aa4e206a361fa909a6dd82a2974c 100644 (file)
@@ -630,7 +630,7 @@ static int openprom_ioctl(struct inode * inode, struct file * file,
        case OPROMPATH2NODE:
                if ((file->f_mode & FMODE_READ) == 0)
                        return -EPERM;
-               return openprom_sunos_ioctl(inode, file, cmd, arg, 0);
+               return openprom_sunos_ioctl(inode, file, cmd, arg, NULL);
 
        case OPIOCGET:
        case OPIOCNEXTPROP:
index 575b1f7ed410b738233865a67f4d46cb5a31f804..b30372f17f1cb94d9ee924d79ff49ac4b78e4a31 100644 (file)
@@ -217,7 +217,7 @@ uctrl_open(struct inode *inode, struct file *file)
        return 0;
 }
 
-static irqreturn_t uctrl_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t uctrl_interrupt(int irq, void *dev_id)
 {
        struct uctrl_driver *driver = (struct uctrl_driver *)dev_id;
        printk("in uctrl_interrupt\n");
@@ -400,7 +400,7 @@ static int __init ts102_uctrl_init(void)
        }
 
        driver->regs->uctrl_intr = UCTRL_INTR_RXNE_REQ|UCTRL_INTR_RXNE_MSK;
-       printk("uctrl: 0x%x (irq %d)\n", driver->regs, driver->irq);
+       printk("uctrl: 0x%p (irq %d)\n", driver->regs, driver->irq);
        uctrl_get_event_status();
        uctrl_get_external_status();
         return 0;
index 5a9475e56d0eb7baea0b33d0188787aaffb799c0..5f8c26cd66ca77c130b2cfc9c26ed1c1cacdf0df 100644 (file)
@@ -1192,7 +1192,7 @@ out:
 } /* End twa_initialize_device_extension() */
 
 /* This function is the interrupt service routine */
-static irqreturn_t twa_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
+static irqreturn_t twa_interrupt(int irq, void *dev_instance)
 {
        int request_id, error = 0;
        u32 status_reg_value;
@@ -2211,7 +2211,7 @@ static int __init twa_init(void)
 {
        printk(KERN_WARNING "3ware 9000 Storage Controller device driver for Linux v%s.\n", TW_DRIVER_VERSION);
 
-       return pci_module_init(&twa_driver);
+       return pci_register_driver(&twa_driver);
 } /* End twa_init() */
 
 /* This function is called on driver exit */
index f3a5f422a8e4d5f11f636a5c5ef798d239b82392..99a259c5a0c07c830b78936ee4983586d90c2dc9 100644 (file)
@@ -2078,8 +2078,7 @@ static int tw_scsi_queue(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd
 } /* End tw_scsi_queue() */
 
 /* This function is the interrupt service routine */
-static irqreturn_t tw_interrupt(int irq, void *dev_instance,
-                    struct pt_regs *regs) 
+static irqreturn_t tw_interrupt(int irq, void *dev_instance) 
 {
        int request_id;
        u32 status_reg_value;
@@ -2486,7 +2485,7 @@ static int __init tw_init(void)
 {
        printk(KERN_WARNING "3ware Storage Controller device driver for Linux v%s.\n", TW_DRIVER_VERSION);
 
-       return pci_module_init(&tw_driver);
+       return pci_register_driver(&tw_driver);
 } /* End tw_init() */
 
 /* This function is called on driver exit */
index 31fe5ea159205bb15b861a615d39b7405679c728..bbd654a2b9b1e5e15562cbbb1d3915b7e961b227 100644 (file)
@@ -74,7 +74,7 @@ static char *tw_aen_string[] = {
        [0x00D] = "ERROR: Logical unit deleted: Unit #",
        [0x00F] = "WARNING: SMART threshold exceeded: Port #",
        [0x021] = "WARNING: ATA UDMA downgrade: Port #",
-       [0x021] = "WARNING: ATA UDMA upgrade: Port #",
+       [0x022] = "WARNING: ATA UDMA upgrade: Port #",
        [0x023] = "WARNING: Sector repair occurred: Port #",
        [0x024] = "ERROR: SBUF integrity check failure",
        [0x025] = "ERROR: Lost cached write: Port #",
index 15ce40a7053a6dfae5ccfcc20fc69b507483106b..562432d017b0c39cc74704031bb4dc1a46df30d8 100644 (file)
@@ -1462,7 +1462,7 @@ NCR_700_start_command(struct scsi_cmnd *SCp)
 }
 
 irqreturn_t
-NCR_700_intr(int irq, void *dev_id, struct pt_regs *regs)
+NCR_700_intr(int irq, void *dev_id)
 {
        struct Scsi_Host *host = (struct Scsi_Host *)dev_id;
        struct NCR_700_Host_Parameters *hostdata =
index 97ebe71b701ba367427a60dc67ccdc993a8cbfd1..f5c3caf344a7626b4c87bf670595e6fa120a5bc6 100644 (file)
@@ -57,7 +57,7 @@ struct NCR_700_Host_Parameters;
 struct Scsi_Host *NCR_700_detect(struct scsi_host_template *,
                struct NCR_700_Host_Parameters *, struct device *);
 int NCR_700_release(struct Scsi_Host *host);
-irqreturn_t NCR_700_intr(int, void *, struct pt_regs *);
+irqreturn_t NCR_700_intr(int, void *);
 
 
 enum NCR_700_Host_State {
index acf292736b4e18403a59daef06da6171c1dd4282..640536ef77dcc398ec663cfe39830ba3e2c41e6b 100644 (file)
@@ -323,7 +323,7 @@ static int shutdown (struct Scsi_Host *host);
 static void abnormal_finished (struct NCR53c7x0_cmd *cmd, int result);
 static int disable (struct Scsi_Host *host);
 static int NCR53c7xx_run_tests (struct Scsi_Host *host);
-static irqreturn_t NCR53c7x0_intr(int irq, void *dev_id, struct pt_regs * regs);
+static irqreturn_t NCR53c7x0_intr(int irq, void *dev_id);
 static void NCR53c7x0_intfly (struct Scsi_Host *host);
 static int ncr_halt (struct Scsi_Host *host);
 static void intr_phase_mismatch (struct Scsi_Host *host, struct NCR53c7x0_cmd 
@@ -4227,7 +4227,7 @@ restart:
 }
 
 /*
- * Function : static irqreturn_t NCR53c7x0_intr (int irq, void *dev_id, struct pt_regs * regs)
+ * Function : static irqreturn_t NCR53c7x0_intr (int irq, void *dev_id)
  *
  * Purpose : handle NCR53c7x0 interrupts for all NCR devices sharing
  *     the same IRQ line.  
@@ -4241,7 +4241,7 @@ restart:
  */
 
 static irqreturn_t
-NCR53c7x0_intr (int irq, void *dev_id, struct pt_regs * regs)
+NCR53c7x0_intr (int irq, void *dev_id)
 {
     NCR53c7x0_local_declare();
     struct Scsi_Host *host;                    /* Host we are looking at */
index 4ea49fd7965e524875b781391f5c730d1456c378..cdd03372478617f3e13a2220cc715fb836f7d0b7 100644 (file)
@@ -2653,7 +2653,7 @@ static void BusLogic_ProcessCompletedCCBs(struct BusLogic_HostAdapter *HostAdapt
   Adapters.
 */
 
-static irqreturn_t BusLogic_InterruptHandler(int IRQ_Channel, void *DeviceIdentifier, struct pt_regs *InterruptRegisters)
+static irqreturn_t BusLogic_InterruptHandler(int IRQ_Channel, void *DeviceIdentifier)
 {
        struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) DeviceIdentifier;
        unsigned long ProcessorFlags;
@@ -3600,5 +3600,16 @@ static void __exit BusLogic_exit(void)
 
 __setup("BusLogic=", BusLogic_Setup);
 
+static struct pci_device_id BusLogic_pci_tbl[] __devinitdata = {
+       { PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER,
+         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+       { PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC,
+         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+       { PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT,
+         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+       { }
+};
+MODULE_DEVICE_TABLE(pci, BusLogic_pci_tbl);
+
 module_init(BusLogic_init);
 module_exit(BusLogic_exit);
index d6d1d5613c8aa9e6a207204cdd0127112a548761..cca6d45eee4da90a13e6b8dba1210f4fcf38accc 100644 (file)
@@ -1347,7 +1347,7 @@ static int BusLogic_BIOSDiskParameters(struct scsi_device *, struct block_device
 static int BusLogic_ProcDirectoryInfo(struct Scsi_Host *, char *, char **, off_t, int, int);
 static int BusLogic_SlaveConfigure(struct scsi_device *);
 static void BusLogic_QueueCompletedCCB(struct BusLogic_CCB *);
-static irqreturn_t BusLogic_InterruptHandler(int, void *, struct pt_regs *);
+static irqreturn_t BusLogic_InterruptHandler(int, void *);
 static int BusLogic_ResetHostAdapter(struct BusLogic_HostAdapter *, boolean HardReset);
 static void BusLogic_Message(enum BusLogic_MessageLevel, char *, struct BusLogic_HostAdapter *, ...);
 static int __init BusLogic_Setup(char *);
index c6dfb6fa13bf4192583a52556867374d570374ec..9540eb8efdcbfc5b6db2051470bf9a203112fe59 100644 (file)
@@ -1016,7 +1016,7 @@ config SCSI_SYM53C8XX_MMIO
 
 config SCSI_IPR
        tristate "IBM Power Linux RAID adapter support"
-       depends on PCI && SCSI
+       depends on PCI && SCSI && ATA
        select FW_LOADER
        ---help---
          This driver supports the IBM Power Linux family RAID adapters.
@@ -1246,6 +1246,7 @@ config SCSI_QLOGICPTI
          module will be called qlogicpti.
 
 source "drivers/scsi/qla2xxx/Kconfig"
+source "drivers/scsi/qla4xxx/Kconfig"
 
 config SCSI_LPFC
        tristate "Emulex LightPulse Fibre Channel Support"
@@ -1262,8 +1263,8 @@ config SCSI_SEAGATE
          These are 8-bit SCSI controllers; the ST-01 is also supported by
          this driver.  It is explained in section 3.9 of the SCSI-HOWTO,
          available from <http://www.tldp.org/docs.html#howto>.  If it
-         doesn't work out of the box, you may have to change some settings in
-         <file:drivers/scsi/seagate.h>.
+         doesn't work out of the box, you may have to change some macros at
+         compiletime, which are described in <file:drivers/scsi/seagate.c>.
 
          To compile this driver as a module, choose M here: the
          module will be called seagate.
index 1ef951be7a5d1a5ff0716fa3f640df16386ab215..bcca39c3bcbf33096bb3fdc5c9a493996c2c9492 100644 (file)
@@ -84,6 +84,7 @@ obj-$(CONFIG_SCSI_QLOGIC_FAS) += qlogicfas408.o       qlogicfas.o
 obj-$(CONFIG_PCMCIA_QLOGIC)    += qlogicfas408.o
 obj-$(CONFIG_SCSI_QLOGIC_1280) += qla1280.o 
 obj-$(CONFIG_SCSI_QLA_FC)      += qla2xxx/
+obj-$(CONFIG_SCSI_QLA_ISCSI)   += qla4xxx/
 obj-$(CONFIG_SCSI_LPFC)                += lpfc/
 obj-$(CONFIG_SCSI_PAS16)       += pas16.o
 obj-$(CONFIG_SCSI_SEAGATE)     += seagate.o
index 616810ad17d885200f10b3fb269975385c9c3b5c..a6aa9107288090ed544abeaf4d2a4e51bf147267 100644 (file)
@@ -558,8 +558,7 @@ static int probe_irq __initdata = 0;
  *     used by the IRQ probe code.
  */
  
-static irqreturn_t __init probe_intr(int irq, void *dev_id,
-                                       struct pt_regs *regs)
+static irqreturn_t __init probe_intr(int irq, void *dev_id)
 {
        probe_irq = irq;
        return IRQ_HANDLED;
@@ -1148,7 +1147,6 @@ static void NCR5380_main(void *p)
  *     NCR5380_intr    -       generic NCR5380 irq handler
  *     @irq: interrupt number
  *     @dev_id: device info
- *     @regs: registers (unused)
  *
  *     Handle interrupts, reestablishing I_T_L or I_T_L_Q nexuses
  *      from the disconnected queue, and restarting NCR5380_main() 
@@ -1157,7 +1155,7 @@ static void NCR5380_main(void *p)
  *     Locks: takes the needed instance locks
  */
 
-static irqreturn_t NCR5380_intr(int irq, void *dev_id, struct pt_regs *regs
+static irqreturn_t NCR5380_intr(int irq, void *dev_id) 
 {
        NCR5380_local_declare();
        struct Scsi_Host *instance = (struct Scsi_Host *)dev_id;
index c3462e358d1cb512baed35b9748c2df69b15383d..1bc73de496b01d81ae5964a2246579b37b617c92 100644 (file)
@@ -296,7 +296,7 @@ static int NCR5380_init(struct Scsi_Host *instance, int flags);
 static void NCR5380_exit(struct Scsi_Host *instance);
 static void NCR5380_information_transfer(struct Scsi_Host *instance);
 #ifndef DONT_USE_INTR
-static irqreturn_t NCR5380_intr(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t NCR5380_intr(int irq, void *dev_id);
 #endif
 static void NCR5380_main(void *ptr);
 static void NCR5380_print_options(struct Scsi_Host *instance);
index bdc6bb262bced9c235234364f84f7b2707abd841..3c912ee29da0e1fa24091849d682bab5c164bfc3 100644 (file)
@@ -96,7 +96,7 @@ enum {
 static struct NCR_ESP *espchain;
 int nesps = 0, esps_in_use = 0, esps_running = 0;
 
-irqreturn_t esp_intr(int irq, void *dev_id, struct pt_regs *pregs);
+irqreturn_t esp_intr(int irq, void *dev_id);
 
 /* Debugging routines */
 static struct esp_cmdstrings {
@@ -3533,7 +3533,7 @@ state_machine:
 }
 
 #ifndef CONFIG_SMP
-irqreturn_t esp_intr(int irq, void *dev_id, struct pt_regs *pregs)
+irqreturn_t esp_intr(int irq, void *dev_id)
 {
        struct NCR_ESP *esp;
        unsigned long flags;
@@ -3570,7 +3570,7 @@ repeat:
 }
 #else
 /* For SMP we only service one ESP on the list list at our IRQ level! */
-irqreturn_t esp_intr(int irq, void *dev_id, struct pt_regs *pregs)
+irqreturn_t esp_intr(int irq, void *dev_id)
 {
        struct NCR_ESP *esp;
        unsigned long flags;
index 481653c977cf34523dff40e5d1c727ef6f9a80b9..521e3f842cfd526e98fc451993f4080df00a4e06 100644 (file)
@@ -656,7 +656,7 @@ extern struct NCR_ESP *esp_allocate(struct scsi_host_template *, void *);
 extern void esp_deallocate(struct NCR_ESP *);
 extern void esp_release(void);
 extern void esp_initialize(struct NCR_ESP *);
-extern irqreturn_t esp_intr(int, void *, struct pt_regs *);
+extern irqreturn_t esp_intr(int, void *);
 extern const char *esp_info(struct Scsi_Host *);
 extern int esp_queue(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 extern int esp_abort(Scsi_Cmnd *);
index 8472c5359023a2cc770eea271591b7139428b359..d4613815f685d26115808d1887223e3c8d7b2e96 100644 (file)
@@ -168,8 +168,8 @@ enum Phase {
 };
 
 /* Static function prototypes */
-static void NCR53c406a_intr(int, void *, struct pt_regs *);
-static irqreturn_t do_NCR53c406a_intr(int, void *, struct pt_regs *);
+static void NCR53c406a_intr(void *);
+static irqreturn_t do_NCR53c406a_intr(int, void *);
 static void chip_init(void);
 static void calc_port_addr(void);
 #ifndef IRQ_LEV
@@ -685,7 +685,7 @@ static void wait_intr(void)
                return;
        }
 
-       NCR53c406a_intr(0, NULL, NULL);
+       NCR53c406a_intr(NULL);
 }
 #endif
 
@@ -761,19 +761,18 @@ static int NCR53c406a_biosparm(struct scsi_device *disk,
        return 0;
 }
 
-static irqreturn_t do_NCR53c406a_intr(int unused, void *dev_id,
-                                       struct pt_regs *regs)
+static irqreturn_t do_NCR53c406a_intr(int unused, void *dev_id)
 {
        unsigned long flags;
        struct Scsi_Host *dev = dev_id;
 
        spin_lock_irqsave(dev->host_lock, flags);
-       NCR53c406a_intr(0, dev_id, regs);
+       NCR53c406a_intr(dev_id);
        spin_unlock_irqrestore(dev->host_lock, flags);
        return IRQ_HANDLED;
 }
 
-static void NCR53c406a_intr(int unused, void *dev_id, struct pt_regs *regs)
+static void NCR53c406a_intr(void *dev_id)
 {
        DEB(unsigned char fifo_size;
            )
index d05681f9d81a81e55385fb2e8b621ae1d8a0a7e1..9859cd17fc574ffe4d7791ab7369039f07241f14 100644 (file)
@@ -226,14 +226,14 @@ NCR_D700_probe_one(struct NCR_D700_private *p, int siop, int irq,
 }
 
 static int
-NCR_D700_intr(int irq, void *data, struct pt_regs *regs)
+NCR_D700_intr(int irq, void *data)
 {
        struct NCR_D700_private *p = (struct NCR_D700_private *)data;
        int i, found = 0;
 
        for (i = 0; i < 2; i++)
                if (p->hosts[i] &&
-                   NCR_700_intr(irq, p->hosts[i], regs) == IRQ_HANDLED)
+                   NCR_700_intr(irq, p->hosts[i]) == IRQ_HANDLED)
                        found++;
 
        return found ? IRQ_HANDLED : IRQ_NONE;
index c39ffbb86e390e4c0cdd5b1c190cf906a5562e90..778844c3544a81c61caa39b92351f0c90735b6dd 100644 (file)
@@ -54,7 +54,7 @@ static struct scsi_host_template NCR_Q720_tpnt = {
 };
 
 static irqreturn_t
-NCR_Q720_intr(int irq, void *data, struct pt_regs * regs)
+NCR_Q720_intr(int irq, void *data)
 {
        struct NCR_Q720_private *p = (struct NCR_Q720_private *)data;
        __u8 sir = (readb(p->mem_base + 0x0d) & 0xf0) >> 4;
@@ -68,7 +68,7 @@ NCR_Q720_intr(int irq, void *data, struct pt_regs * regs)
 
        while((siop = ffz(sir)) < p->siops) {
                sir |= 1<<siop;
-               ncr53c8xx_intr(irq, p->hosts[siop], regs);
+               ncr53c8xx_intr(irq, p->hosts[siop]);
        }
        return IRQ_HANDLED;
 }
index d7e9fab54c60eb5a4ff1ae6505ecc72b1b702311..2650a5d0a161f34b03ba19e224e4752ea0e4dae7 100644 (file)
@@ -1013,7 +1013,7 @@ static void inia100SCBPost(BYTE * pHcb, BYTE * pScb)
 /*
  * Interrupt handler (main routine of the driver)
  */
-static irqreturn_t inia100_intr(int irqno, void *devid, struct pt_regs *regs)
+static irqreturn_t inia100_intr(int irqno, void *devid)
 {
        struct Scsi_Host *host = (struct Scsi_Host *)devid;
        ORC_HCS *pHcb = (ORC_HCS *)host->hostdata;
@@ -1187,7 +1187,7 @@ static struct pci_driver inia100_pci_driver = {
 
 static int __init inia100_init(void)
 {
-       return pci_module_init(&inia100_pci_driver);
+       return pci_register_driver(&inia100_pci_driver);
 }
 
 static void __exit inia100_exit(void)
index 085406928605ff116a99b5b89830342e17b52cd9..f77016d31cabc2966af6714af61add4add1f4ffc 100644 (file)
@@ -24,7 +24,7 @@
 #define DMA(ptr) ((a2091_scsiregs *)((ptr)->base))
 #define HDATA(ptr) ((struct WD33C93_hostdata *)((ptr)->hostdata))
 
-static irqreturn_t a2091_intr (int irq, void *_instance, struct pt_regs *fp)
+static irqreturn_t a2091_intr (int irq, void *_instance)
 {
     unsigned long flags;
     unsigned int status;
index 7bf46d40b5610d8a85ca30b99a213241ea735e31..1299bc8edef18b3a435a004e307418fea27598ba 100644 (file)
@@ -26,7 +26,7 @@
 
 static struct Scsi_Host *a3000_host = NULL;
 
-static irqreturn_t a3000_intr (int irq, void *dummy, struct pt_regs *fp)
+static irqreturn_t a3000_intr (int irq, void *dummy)
 {
        unsigned long flags;
        unsigned int status = DMA(a3000_host)->ISTR;
index a1d214d770eb67c2e5f8a3b4674d40cfe8bf3584..dcc8b0ea7a9d213b4605857c574702a059cbb869 100644 (file)
 
 #include "aacraid.h"
 
-static irqreturn_t aac_rx_intr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t aac_rx_intr(int irq, void *dev_id)
 {
        struct aac_dev *dev = dev_id;
 
-       dprintk((KERN_DEBUG "aac_rx_intr(%d,%p,%p)\n", irq, dev_id, regs));
+       dprintk((KERN_DEBUG "aac_rx_intr(%d,%p)\n", irq, dev_id));
        if (dev->new_comm_interface) {
                u32 Index = rx_readl(dev, MUnit.OutboundQueue);
                if (Index == 0xFFFFFFFFL)
index f906ead239dd480a3d87b7e507924df86efabce8..511b0a938fb18b4ebcd488b1fe5087e385bc0cdd 100644 (file)
@@ -46,7 +46,7 @@
 
 #include "aacraid.h"
 
-static irqreturn_t aac_sa_intr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t aac_sa_intr(int irq, void *dev_id)
 {
        struct aac_dev *dev = dev_id;
        unsigned short intstat, mask;
index 773f02e3b10b0188bdb0b0d275e2a7b21b9034c8..2b344356a29e997cd381c5697a3c82badb6c04a2 100644 (file)
@@ -3881,7 +3881,7 @@ typedef struct asc_board {
     /*
      * The following fields are used only for Wide Boards.
      */
-    void                 *ioremap_addr;         /* I/O Memory remap address. */
+    void                 __iomem *ioremap_addr; /* I/O Memory remap address. */
     ushort               ioport;                /* I/O Port address. */
     ADV_CARR_T           *orig_carrp;           /* ADV_CARR_T memory block. */
     adv_req_t            *orig_reqp;            /* adv_req_t memory block. */
@@ -3951,7 +3951,7 @@ typedef struct _PCI_CONFIG_SPACE_
 
 /* Number of boards detected in system. */
 STATIC int asc_board_count = 0;
-STATIC struct Scsi_Host    *asc_host[ASC_NUM_BOARD_SUPPORTED] = { 0 };
+STATIC struct Scsi_Host    *asc_host[ASC_NUM_BOARD_SUPPORTED] = { NULL };
 
 /* Overrun buffer used by all narrow boards. */
 STATIC uchar overrun_buf[ASC_OVERRUN_BSIZE] = { 0 };
@@ -3999,7 +3999,7 @@ STATIC PortAddr     _asc_def_iop_base[];
  * advansys.h contains function prototypes for functions global to Linux.
  */
 
-STATIC irqreturn_t advansys_interrupt(int, void *, struct pt_regs *);
+STATIC irqreturn_t advansys_interrupt(int, void *);
 STATIC int       advansys_slave_configure(struct scsi_device *);
 STATIC void       asc_scsi_done_list(struct scsi_cmnd *);
 STATIC int        asc_execute_scsi_cmnd(struct scsi_cmnd *);
@@ -5997,7 +5997,7 @@ static struct scsi_host_template driver_template = {
  * an AdvanSys adapter.
  */
 STATIC irqreturn_t
-advansys_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+advansys_interrupt(int irq, void *dev_id)
 {
     ulong           flags;
     int             i;
@@ -6621,7 +6621,7 @@ adv_build_req(asc_board_t *boardp, struct scsi_cmnd *scp,
                dma_map_single(dev, scp->request_buffer,
                               scp->request_bufflen, scp->sc_data_direction);
        } else {
-           scsiqp->vdata_addr = 0;
+           scsiqp->vdata_addr = NULL;
            scp->SCp.dma_handle = 0;
        }
        scsiqp->data_addr = cpu_to_le32(scp->SCp.dma_handle);
index fb6a476eb8738010e817a3c3bd5a14e9f917bcb7..306f46b85a5522aff952da4fe6e0759a86b2a651 100644 (file)
 #include <linux/module.h>
 #include <linux/sched.h>
 #include <asm/irq.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/blkdev.h>
 #include <asm/system.h>
 #include <linux/errno.h>
@@ -673,7 +673,7 @@ static struct {
 };
 
 /* setup & interrupt */
-static irqreturn_t intr(int irq, void *dev_id, struct pt_regs *);
+static irqreturn_t intr(int irq, void *dev_id);
 static void reset_ports(struct Scsi_Host *shpnt);
 static void aha152x_error(struct Scsi_Host *shpnt, char *msg);
 static void done(struct Scsi_Host *shpnt, int error);
@@ -757,14 +757,9 @@ static inline Scsi_Cmnd *remove_SC(Scsi_Cmnd **SC, Scsi_Cmnd *SCp)
        return ptr;
 }
 
-static irqreturn_t swintr(int irqno, void *dev_id, struct pt_regs *regs)
+static irqreturn_t swintr(int irqno, void *dev_id)
 {
-       struct Scsi_Host *shpnt = (struct Scsi_Host *)dev_id;
-
-       if (!shpnt) {
-               printk(KERN_ERR "aha152x: catched software interrupt %d for unknown controller.\n", irqno);
-               return IRQ_NONE;
-       }
+       struct Scsi_Host *shpnt = dev_id;
 
        HOSTDATA(shpnt)->swint++;
 
@@ -1463,7 +1458,7 @@ static void run(void)
  * Interrupt handler
  *
  */
-static irqreturn_t intr(int irqno, void *dev_id, struct pt_regs *regs)
+static irqreturn_t intr(int irqno, void *dev_id)
 {
        struct Scsi_Host *shpnt = (struct Scsi_Host *)dev_id;
        unsigned long flags;
index 24f0f5461792d4068c35d053a6967cb4525b6347..d7a61a6bdaae0720362b306d33fc489a790841f5 100644 (file)
@@ -174,9 +174,8 @@ static DEFINE_SPINLOCK(aha1542_lock);
 
 static void setup_mailboxes(int base_io, struct Scsi_Host *shpnt);
 static int aha1542_restart(struct Scsi_Host *shost);
-static void aha1542_intr_handle(struct Scsi_Host *shost, void *dev_id, struct pt_regs *regs);
-static irqreturn_t do_aha1542_intr_handle(int irq, void *dev_id,
-                                       struct pt_regs *regs);
+static void aha1542_intr_handle(struct Scsi_Host *shost, void *dev_id);
+static irqreturn_t do_aha1542_intr_handle(int irq, void *dev_id);
 
 #define aha1542_intr_reset(base)  outb(IRST, CONTROL(base))
 
@@ -416,8 +415,7 @@ fail:
 }
 
 /* A quick wrapper for do_aha1542_intr_handle to grab the spin lock */
-static irqreturn_t do_aha1542_intr_handle(int irq, void *dev_id,
-                                       struct pt_regs *regs)
+static irqreturn_t do_aha1542_intr_handle(int irq, void *dev_id)
 {
        unsigned long flags;
        struct Scsi_Host *shost;
@@ -427,13 +425,13 @@ static irqreturn_t do_aha1542_intr_handle(int irq, void *dev_id,
                panic("Splunge!");
 
        spin_lock_irqsave(shost->host_lock, flags);
-       aha1542_intr_handle(shost, dev_id, regs);
+       aha1542_intr_handle(shost, dev_id);
        spin_unlock_irqrestore(shost->host_lock, flags);
        return IRQ_HANDLED;
 }
 
 /* A "high" level interrupt handler */
-static void aha1542_intr_handle(struct Scsi_Host *shost, void *dev_id, struct pt_regs *regs)
+static void aha1542_intr_handle(struct Scsi_Host *shost, void *dev_id)
 {
        void (*my_done) (Scsi_Cmnd *) = NULL;
        int errstatus, mbi, mbo, mbistatus;
index 6b35ed8301e0dac3211968409505bc2f4f63fbb2..c3c38a7e8d32d091a3bbd7ee925d7e81bc1492d2 100644 (file)
@@ -223,8 +223,7 @@ static int aha1740_test_port(unsigned int base)
 }
 
 /* A "high" level interrupt handler */
-static irqreturn_t aha1740_intr_handle(int irq, void *dev_id,
-                                      struct pt_regs *regs)
+static irqreturn_t aha1740_intr_handle(int irq, void *dev_id)
 {
        struct Scsi_Host *host = (struct Scsi_Host *) dev_id;
         void (*my_done)(Scsi_Cmnd *);
index 8ad3ce945b9e5f36b20953af23ff1717d64403a4..a3266e066c00ca707a856f6035aca10198779433 100644 (file)
@@ -527,7 +527,8 @@ ahd_inw(struct ahd_softc *ahd, u_int port)
         * or have other side effects when the low byte is
         * read.
         */
-       return ((ahd_inb(ahd, port+1) << 8) | ahd_inb(ahd, port));
+       uint16_t r = ahd_inb(ahd, port+1) << 8;
+       return r | ahd_inb(ahd, port);
 }
 
 static __inline void
index 1faa008b5b817047d16c0f976523ba746105ab9a..f8e60486167da6c110111ac919543cde54e19820 100644 (file)
@@ -1557,7 +1557,7 @@ ahd_linux_run_command(struct ahd_softc *ahd, struct ahd_linux_device *dev,
  * SCSI controller interrupt handler.
  */
 irqreturn_t
-ahd_linux_isr(int irq, void *dev_id, struct pt_regs * regs)
+ahd_linux_isr(int irq, void *dev_id)
 {
        struct  ahd_softc *ahd;
        u_long  flags;
index 601340d84410a04ee6e25f615d523eae1a457f5a..fb3d4dd54413a3c09a9dc6fc68c89271db500a52 100644 (file)
@@ -862,7 +862,7 @@ int ahd_platform_abort_scbs(struct ahd_softc *ahd, int target,
                                char channel, int lun, u_int tag,
                                role_t role, uint32_t status);
 irqreturn_t
-       ahd_linux_isr(int irq, void *dev_id, struct pt_regs * regs);
+       ahd_linux_isr(int irq, void *dev_id);
 void   ahd_done(struct ahd_softc*, struct scb*);
 void   ahd_send_async(struct ahd_softc *, char channel,
                       u_int target, u_int lun, ac_code);
index 50a41eda580eb4daebac5be164fa8db2f8c8ebc2..4b53542018073c3dd1bd17f003648cbbc451d9e5 100644 (file)
@@ -198,7 +198,7 @@ ahd_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 int
 ahd_linux_pci_init(void)
 {
-       return (pci_module_init(&aic79xx_pci_driver));
+       return pci_register_driver(&aic79xx_pci_driver);
 }
 
 void
index 2cc8a17ed8b4a565f7051fcef8238fe8329d8b38..8e1954cdd84f67cd114491ad0c0072d3aaec175f 100644 (file)
@@ -300,7 +300,8 @@ ahc_fetch_transinfo(struct ahc_softc *ahc, char channel, u_int our_id,
 static __inline uint16_t
 ahc_inw(struct ahc_softc *ahc, u_int port)
 {
-       return ((ahc_inb(ahc, port+1) << 8) | ahc_inb(ahc, port));
+       uint16_t r = ahc_inb(ahc, port+1) << 8;
+       return r | ahc_inb(ahc, port);
 }
 
 static __inline void
index 339b85cb61cdbefb4a5bb9af77da7caf9f03b4ed..43ab753d2739a3d28353f4387ca6916213fcaeb6 100644 (file)
@@ -1608,7 +1608,7 @@ ahc_linux_run_command(struct ahc_softc *ahc, struct ahc_linux_device *dev,
  * SCSI controller interrupt handler.
  */
 irqreturn_t
-ahc_linux_isr(int irq, void *dev_id, struct pt_regs * regs)
+ahc_linux_isr(int irq, void *dev_id)
 {
        struct  ahc_softc *ahc;
        u_long  flags;
index d42a71ee076df62f7c59cca626398984966a1027..a87a4ce090df18c16ce56979299ecc51ebedd820 100644 (file)
@@ -830,7 +830,7 @@ int ahc_platform_abort_scbs(struct ahc_softc *ahc, int target,
                                char channel, int lun, u_int tag,
                                role_t role, uint32_t status);
 irqreturn_t
-       ahc_linux_isr(int irq, void *dev_id, struct pt_regs * regs);
+       ahc_linux_isr(int irq, void *dev_id);
 void   ahc_platform_flushwork(struct ahc_softc *ahc);
 void   ahc_done(struct ahc_softc*, struct scb*);
 void   ahc_send_async(struct ahc_softc *, char channel,
index 7e42f07a27f3d2879aec66a395f6504afe6a6fb0..d20ca514e9f36f11ba120dbe132338fa9c7f8ce6 100644 (file)
@@ -246,8 +246,7 @@ ahc_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 int
 ahc_linux_pci_init(void)
 {
-       /* Translate error or zero return into zero or one */
-       return pci_module_init(&aic7xxx_pci_driver) ? 0 : 1;
+       return pci_register_driver(&aic7xxx_pci_driver);
 }
 
 void
index 10353379a0741e5f4f4f784ad230c4cba6249192..bcd7fffab9074fbb2ab5fab1768bd5ec686657a5 100644 (file)
@@ -780,24 +780,26 @@ typedef enum {
 } ahc_bugs;
 
 struct aic7xxx_scb {
-        struct aic7xxx_hwscb  *hscb;          /* corresponding hardware scb */
-        Scsi_Cmnd             *cmd;              /* Scsi_Cmnd for this scb */
-        struct aic7xxx_scb    *q_next;        /* next scb in queue */
-        volatile scb_flag_type flags;         /* current state of scb */
-        struct hw_scatterlist *sg_list;       /* SG list in adapter format */
-        unsigned char          tag_action;
-        unsigned char          sg_count;
-        unsigned char          *sense_cmd;    /*
-                                               * Allocate 6 characters for
-                                               * sense command.
-                                               */
-       unsigned char          *cmnd;
-        unsigned int           sg_length; /* We init this during buildscb so we
-                                           * don't have to calculate anything
-                                           * during underflow/overflow/stat code
-                                           */
-        void                  *kmalloc_ptr;
-       struct aic7xxx_scb_dma *scb_dma;
+       struct aic7xxx_hwscb    *hscb;          /* corresponding hardware scb */
+       struct scsi_cmnd        *cmd;           /* scsi_cmnd for this scb */
+       struct aic7xxx_scb      *q_next;        /* next scb in queue */
+       volatile scb_flag_type  flags;          /* current state of scb */
+       struct hw_scatterlist   *sg_list;       /* SG list in adapter format */
+       unsigned char           tag_action;
+       unsigned char           sg_count;
+       unsigned char           *sense_cmd;     /*
+                                                * Allocate 6 characters for
+                                                * sense command.
+                                                */
+       unsigned char           *cmnd;
+       unsigned int            sg_length;      /*
+                                                * We init this during
+                                                * buildscb so we don't have
+                                                * to calculate anything during
+                                                * underflow/overflow/stat code
+                                                */
+       void                    *kmalloc_ptr;
+       struct aic7xxx_scb_dma  *scb_dma;
 };
 
 /*
@@ -918,79 +920,77 @@ struct aic7xxx_host {
    * We are grouping things here....first, items that get either read or
    * written with nearly every interrupt
    */
-  volatile long            flags;
-  ahc_feature              features;         /* chip features */
-  unsigned long            base;             /* card base address */
-  volatile unsigned char  __iomem *maddr;            /* memory mapped address */
-  unsigned long            isr_count;        /* Interrupt count */
-  unsigned long            spurious_int;
-  scb_data_type           *scb_data;
-  struct aic7xxx_cmd_queue {
-    Scsi_Cmnd *head;
-    Scsi_Cmnd *tail;
-  } completeq;
+       volatile long   flags;
+       ahc_feature     features;       /* chip features */
+       unsigned long   base;           /* card base address */
+       volatile unsigned char  __iomem *maddr; /* memory mapped address */
+       unsigned long   isr_count;      /* Interrupt count */
+       unsigned long   spurious_int;
+       scb_data_type   *scb_data;
+       struct aic7xxx_cmd_queue {
+               struct scsi_cmnd *head;
+               struct scsi_cmnd *tail;
+       } completeq;
 
-  /*
-   * Things read/written on nearly every entry into aic7xxx_queue()
-   */
-  volatile scb_queue_type  waiting_scbs;
-  unsigned char            unpause;          /* unpause value for HCNTRL */
-  unsigned char            pause;            /* pause value for HCNTRL */
-  volatile unsigned char   qoutfifonext;
-  volatile unsigned char   activescbs;       /* active scbs */
-  volatile unsigned char   max_activescbs;
-  volatile unsigned char   qinfifonext;
-  volatile unsigned char  *untagged_scbs;
-  volatile unsigned char  *qoutfifo;
-  volatile unsigned char  *qinfifo;
-
-  unsigned char            dev_last_queue_full[MAX_TARGETS];
-  unsigned char            dev_last_queue_full_count[MAX_TARGETS];
-  unsigned short          ultraenb;         /* Gets downloaded to card as a
-                                               bitmap */
-  unsigned short          discenable;       /* Gets downloaded to card as a
-                                               bitmap */
-  transinfo_type           user[MAX_TARGETS];
-
-  unsigned char            msg_buf[13];      /* The message for the target */
-  unsigned char            msg_type;
+       /*
+       * Things read/written on nearly every entry into aic7xxx_queue()
+       */
+       volatile scb_queue_type waiting_scbs;
+       unsigned char   unpause;        /* unpause value for HCNTRL */
+       unsigned char   pause;          /* pause value for HCNTRL */
+       volatile unsigned char  qoutfifonext;
+       volatile unsigned char  activescbs;     /* active scbs */
+       volatile unsigned char  max_activescbs;
+       volatile unsigned char  qinfifonext;
+       volatile unsigned char  *untagged_scbs;
+       volatile unsigned char  *qoutfifo;
+       volatile unsigned char  *qinfifo;
+
+       unsigned char   dev_last_queue_full[MAX_TARGETS];
+       unsigned char   dev_last_queue_full_count[MAX_TARGETS];
+       unsigned short  ultraenb; /* Gets downloaded to card as a bitmap */
+       unsigned short  discenable; /* Gets downloaded to card as a bitmap */
+       transinfo_type  user[MAX_TARGETS];
+
+       unsigned char   msg_buf[13];    /* The message for the target */
+       unsigned char   msg_type;
 #define MSG_TYPE_NONE              0x00
 #define MSG_TYPE_INITIATOR_MSGOUT  0x01
 #define MSG_TYPE_INITIATOR_MSGIN   0x02
-  unsigned char            msg_len;          /* Length of message */
-  unsigned char            msg_index;        /* Index into msg_buf array */
+       unsigned char   msg_len;        /* Length of message */
+       unsigned char   msg_index;      /* Index into msg_buf array */
 
 
-  /*
-   * We put the less frequently used host structure items after the more
-   * frequently used items to try and ease the burden on the cache subsystem.
-   * These entries are not *commonly* accessed, whereas the preceding entries
-   * are accessed very often.
-   */
-
-  unsigned int             irq;              /* IRQ for this adapter */
-  int                      instance;         /* aic7xxx instance number */
-  int                      scsi_id;          /* host adapter SCSI ID */
-  int                      scsi_id_b;        /* channel B for twin adapters */
-  unsigned int             bios_address;
-  int                      board_name_index;
-  unsigned short           bios_control;     /* bios control - SEEPROM */
-  unsigned short           adapter_control;  /* adapter control - SEEPROM */
-  struct pci_dev         *pdev;
-  unsigned char            pci_bus;
-  unsigned char            pci_device_fn;
-  struct seeprom_config    sc;
-  unsigned short           sc_type;
-  unsigned short           sc_size;
-  struct aic7xxx_host     *next;             /* allow for multiple IRQs */
-  struct Scsi_Host        *host;             /* pointer to scsi host */
-  struct list_head        aic_devs;         /* all aic_dev structs on host */
-  int                      host_no;          /* SCSI host number */
-  unsigned long            mbase;            /* I/O memory address */
-  ahc_chip                 chip;             /* chip type */
-  ahc_bugs                 bugs;
-  dma_addr_t              fifo_dma;         /* DMA handle for fifo arrays */
+       /*
+        * We put the less frequently used host structure items
+        * after the more frequently used items to try and ease
+        * the burden on the cache subsystem.
+        * These entries are not *commonly* accessed, whereas
+        * the preceding entries are accessed very often.
+        */
 
+       unsigned int    irq;            /* IRQ for this adapter */
+       int             instance;       /* aic7xxx instance number */
+       int             scsi_id;        /* host adapter SCSI ID */
+       int             scsi_id_b;      /* channel B for twin adapters */
+       unsigned int    bios_address;
+       int             board_name_index;
+       unsigned short  bios_control;           /* bios control - SEEPROM */
+       unsigned short  adapter_control;        /* adapter control - SEEPROM */
+       struct pci_dev  *pdev;
+       unsigned char   pci_bus;
+       unsigned char   pci_device_fn;
+       struct seeprom_config   sc;
+       unsigned short  sc_type;
+       unsigned short  sc_size;
+       struct aic7xxx_host     *next;  /* allow for multiple IRQs */
+       struct Scsi_Host        *host;  /* pointer to scsi host */
+       struct list_head         aic_devs; /* all aic_dev structs on host */
+       int             host_no;        /* SCSI host number */
+       unsigned long   mbase;          /* I/O memory address */
+       ahc_chip        chip;           /* chip type */
+       ahc_bugs        bugs;
+       dma_addr_t      fifo_dma;       /* DMA handle for fifo arrays */
 };
 
 /*
@@ -1271,7 +1271,7 @@ static void aic7xxx_set_syncrate(struct aic7xxx_host *p,
 static void aic7xxx_set_width(struct aic7xxx_host *p, int target, int channel,
                int lun, unsigned int width, unsigned int type,
                struct aic_dev_data *aic_dev);
-static void aic7xxx_panic_abort(struct aic7xxx_host *p, Scsi_Cmnd *cmd);
+static void aic7xxx_panic_abort(struct aic7xxx_host *p, struct scsi_cmnd *cmd);
 static void aic7xxx_print_card(struct aic7xxx_host *p);
 static void aic7xxx_print_scratch_ram(struct aic7xxx_host *p);
 static void aic7xxx_print_sequencer(struct aic7xxx_host *p, int downloaded);
@@ -2626,7 +2626,7 @@ aic7xxx_allocate_scb(struct aic7xxx_host *p)
  *   we're finished.  This function queues the completed commands.
  *-F*************************************************************************/
 static void
-aic7xxx_queue_cmd_complete(struct aic7xxx_host *p, Scsi_Cmnd *cmd)
+aic7xxx_queue_cmd_complete(struct aic7xxx_host *p, struct scsi_cmnd *cmd)
 {
   aic7xxx_position(cmd) = SCB_LIST_NULL;
   cmd->host_scribble = (char *)p->completeq.head;
@@ -2640,18 +2640,16 @@ aic7xxx_queue_cmd_complete(struct aic7xxx_host *p, Scsi_Cmnd *cmd)
  * Description:
  *   Process the completed command queue.
  *-F*************************************************************************/
-static void
-aic7xxx_done_cmds_complete(struct aic7xxx_host *p)
+static void aic7xxx_done_cmds_complete(struct aic7xxx_host *p)
 {
-  Scsi_Cmnd *cmd;
-  
-  while (p->completeq.head != NULL)
-  {
-    cmd = p->completeq.head;
-    p->completeq.head = (Scsi_Cmnd *)cmd->host_scribble;
-    cmd->host_scribble = NULL;
-    cmd->scsi_done(cmd);
-  }
+       struct scsi_cmnd *cmd;
+
+       while (p->completeq.head != NULL) {
+               cmd = p->completeq.head;
+               p->completeq.head = (struct scsi_Cmnd *) cmd->host_scribble;
+               cmd->host_scribble = NULL;
+               cmd->scsi_done(cmd);
+       }
 }
 
 /*+F*************************************************************************
@@ -2687,11 +2685,11 @@ aic7xxx_free_scb(struct aic7xxx_host *p, struct aic7xxx_scb *scb)
 static void
 aic7xxx_done(struct aic7xxx_host *p, struct aic7xxx_scb *scb)
 {
-  Scsi_Cmnd *cmd = scb->cmd;
-  struct aic_dev_data *aic_dev = cmd->device->hostdata;
-  int tindex = TARGET_INDEX(cmd);
-  struct aic7xxx_scb *scbp;
-  unsigned char queue_depth;
+       struct scsi_cmnd *cmd = scb->cmd;
+       struct aic_dev_data *aic_dev = cmd->device->hostdata;
+       int tindex = TARGET_INDEX(cmd);
+       struct aic7xxx_scb *scbp;
+       unsigned char queue_depth;
 
   if (cmd->use_sg > 1)
   {
@@ -2891,7 +2889,7 @@ aic7xxx_done(struct aic7xxx_host *p, struct aic7xxx_scb *scb)
  *   aic7xxx_run_done_queue
  *
  * Description:
- *   Calls the aic7xxx_done() for the Scsi_Cmnd of each scb in the
+ *   Calls the aic7xxx_done() for the scsi_cmnd of each scb in the
  *   aborted list, and adds each scb to the free list.  If complete
  *   is TRUE, we also process the commands complete list.
  *-F*************************************************************************/
@@ -3826,9 +3824,9 @@ aic7xxx_construct_wdtr(struct aic7xxx_host *p, unsigned char bus_width)
 static void
 aic7xxx_calculate_residual (struct aic7xxx_host *p, struct aic7xxx_scb *scb)
 {
-  struct aic7xxx_hwscb *hscb;
-  Scsi_Cmnd *cmd;
-  int actual, i;
+       struct aic7xxx_hwscb *hscb;
+       struct scsi_cmnd *cmd;
+       int actual, i;
 
   cmd = scb->cmd;
   hscb = scb->hscb;
@@ -4219,20 +4217,20 @@ aic7xxx_handle_seqint(struct aic7xxx_host *p, unsigned char intstat)
 
     case BAD_STATUS:
       {
-        unsigned char scb_index;
-        struct aic7xxx_hwscb *hscb;
-        Scsi_Cmnd *cmd;
-
-        /* The sequencer will notify us when a command has an error that
-         * would be of interest to the kernel.  This allows us to leave
-         * the sequencer running in the common case of command completes
-         * without error.  The sequencer will have DMA'd the SCB back
-         * up to us, so we can reference the drivers SCB array.
-         *
-         * Set the default return value to 0 indicating not to send
-         * sense.  The sense code will change this if needed and this
-         * reduces code duplication.
-         */
+       unsigned char scb_index;
+       struct aic7xxx_hwscb *hscb;
+       struct scsi_cmnd *cmd;
+
+       /* The sequencer will notify us when a command has an error that
+        * would be of interest to the kernel.  This allows us to leave
+        * the sequencer running in the common case of command completes
+        * without error.  The sequencer will have DMA'd the SCB back
+        * up to us, so we can reference the drivers SCB array.
+        *
+        * Set the default return value to 0 indicating not to send
+        * sense.  The sense code will change this if needed and this
+        * reduces code duplication.
+        */
         aic_outb(p, 0, RETURN_1);
         scb_index = aic_inb(p, SCB_TAG);
         if (scb_index > p->scb_data->numscbs)
@@ -5800,9 +5798,9 @@ aic7xxx_handle_scsiint(struct aic7xxx_host *p, unsigned char intstat)
   }
   else if ((status & SELTO) != 0)
   {
-    unsigned char scbptr;
-    unsigned char nextscb;
-    Scsi_Cmnd *cmd;
+       unsigned char scbptr;
+       unsigned char nextscb;
+       struct scsi_cmnd *cmd;
 
     scbptr = aic_inb(p, WAITING_SCBH);
     if (scbptr > p->scb_data->maxhscbs)
@@ -5941,11 +5939,11 @@ aic7xxx_handle_scsiint(struct aic7xxx_host *p, unsigned char intstat)
     /*
      * Determine the bus phase and queue an appropriate message.
      */
-    char  *phase;
-    Scsi_Cmnd *cmd;
-    unsigned char mesg_out = MSG_NOOP;
-    unsigned char lastphase = aic_inb(p, LASTPHASE);
-    unsigned char sstat2 = aic_inb(p, SSTAT2);
+       char  *phase;
+       struct scsi_cmnd *cmd;
+       unsigned char mesg_out = MSG_NOOP;
+       unsigned char lastphase = aic_inb(p, LASTPHASE);
+       unsigned char sstat2 = aic_inb(p, SSTAT2);
 
     cmd = scb->cmd;
     switch (lastphase)
@@ -6248,10 +6246,10 @@ aic7xxx_check_scbs(struct aic7xxx_host *p, char *buffer)
 static void
 aic7xxx_handle_command_completion_intr(struct aic7xxx_host *p)
 {
-  struct aic7xxx_scb *scb = NULL;
-  struct aic_dev_data *aic_dev;
-  Scsi_Cmnd *cmd;
-  unsigned char scb_index, tindex;
+       struct aic7xxx_scb *scb = NULL;
+       struct aic_dev_data *aic_dev;
+       struct scsi_cmnd *cmd;
+       unsigned char scb_index, tindex;
 
 #ifdef AIC7XXX_VERBOSE_DEBUGGING
   if( (p->isr_count < 16) && (aic7xxx_verbose > 0xffff) )
@@ -6347,12 +6345,12 @@ aic7xxx_handle_command_completion_intr(struct aic7xxx_host *p)
  *   SCSI controller interrupt handler.
  *-F*************************************************************************/
 static void
-aic7xxx_isr(int irq, void *dev_id, struct pt_regs *regs)
+aic7xxx_isr(void *dev_id)
 {
   struct aic7xxx_host *p;
   unsigned char intstat;
 
-  p = (struct aic7xxx_host *)dev_id;
+  p = dev_id;
 
   /*
    * Just a few sanity checks.  Make sure that we have an int pending.
@@ -6479,7 +6477,7 @@ aic7xxx_isr(int irq, void *dev_id, struct pt_regs *regs)
  *   anything like it, please inform the Gross Hack Police immediately
  *-F*************************************************************************/
 static irqreturn_t
-do_aic7xxx_isr(int irq, void *dev_id, struct pt_regs *regs)
+do_aic7xxx_isr(int irq, void *dev_id)
 {
   unsigned long cpu_flags;
   struct aic7xxx_host *p;
@@ -6491,7 +6489,7 @@ do_aic7xxx_isr(int irq, void *dev_id, struct pt_regs *regs)
   p->flags |= AHC_IN_ISR;
   do
   {
-    aic7xxx_isr(irq, dev_id, regs);
+    aic7xxx_isr(dev_id);
   } while ( (aic_inb(p, INTSTAT) & INT_PEND) );
   aic7xxx_done_cmds_complete(p);
   aic7xxx_run_waiting_queues(p);
@@ -10131,9 +10129,8 @@ skip_pci_controller:
  * Description:
  *   Build a SCB.
  *-F*************************************************************************/
-static void
-aic7xxx_buildscb(struct aic7xxx_host *p, Scsi_Cmnd *cmd,
-    struct aic7xxx_scb *scb)
+static void aic7xxx_buildscb(struct aic7xxx_host *p, struct scsi_cmnd *cmd,
+                            struct aic7xxx_scb *scb)
 {
   unsigned short mask;
   struct aic7xxx_hwscb *hscb;
@@ -10285,8 +10282,7 @@ aic7xxx_buildscb(struct aic7xxx_host *p, Scsi_Cmnd *cmd,
  * Description:
  *   Queue a SCB to the controller.
  *-F*************************************************************************/
-static int
-aic7xxx_queue(Scsi_Cmnd *cmd, void (*fn)(Scsi_Cmnd *))
+static int aic7xxx_queue(struct scsi_cmnd *cmd, void (*fn)(struct scsi_cmnd *))
 {
   struct aic7xxx_host *p;
   struct aic7xxx_scb *scb;
@@ -10319,11 +10315,11 @@ aic7xxx_queue(Scsi_Cmnd *cmd, void (*fn)(Scsi_Cmnd *))
   }
   scb->cmd = cmd;
 
-  /*
-   * Make sure the Scsi_Cmnd pointer is saved, the struct it points to
-   * is set up properly, and the parity error flag is reset, then send
-   * the SCB to the sequencer and watch the fun begin.
-   */
+       /*
+       * Make sure the scsi_cmnd pointer is saved, the struct it points to
+       * is set up properly, and the parity error flag is reset, then send
+       * the SCB to the sequencer and watch the fun begin.
+       */
   aic7xxx_position(cmd) = scb->hscb->tag;
   cmd->scsi_done = fn;
   cmd->result = DID_OK;
@@ -10356,8 +10352,7 @@ aic7xxx_queue(Scsi_Cmnd *cmd, void (*fn)(Scsi_Cmnd *))
  *   aborted, then we will reset the channel and have all devices renegotiate.
  *   Returns an enumerated type that indicates the status of the operation.
  *-F*************************************************************************/
-static int
-__aic7xxx_bus_device_reset(Scsi_Cmnd *cmd)
+static int __aic7xxx_bus_device_reset(struct scsi_cmnd *cmd)
 {
   struct aic7xxx_host  *p;
   struct aic7xxx_scb   *scb;
@@ -10382,7 +10377,7 @@ __aic7xxx_bus_device_reset(Scsi_Cmnd *cmd)
 
   hscb = scb->hscb;
 
-  aic7xxx_isr(p->irq, (void *)p, NULL);
+  aic7xxx_isr(p);
   aic7xxx_done_cmds_complete(p);
   /* If the command was already complete or just completed, then we didn't
    * do a reset, return FAILED */
@@ -10550,8 +10545,7 @@ __aic7xxx_bus_device_reset(Scsi_Cmnd *cmd)
     return SUCCESS;
 }
 
-static int
-aic7xxx_bus_device_reset(Scsi_Cmnd *cmd)
+static int aic7xxx_bus_device_reset(struct scsi_cmnd *cmd)
 {
       int rc;
 
@@ -10570,8 +10564,7 @@ aic7xxx_bus_device_reset(Scsi_Cmnd *cmd)
  * Description:
  *   Abort the current SCSI command(s).
  *-F*************************************************************************/
-static void
-aic7xxx_panic_abort(struct aic7xxx_host *p, Scsi_Cmnd *cmd)
+static void aic7xxx_panic_abort(struct aic7xxx_host *p, struct scsi_cmnd *cmd)
 {
 
   printk("aic7xxx driver version %s\n", AIC7XXX_C_VERSION);
@@ -10595,8 +10588,7 @@ aic7xxx_panic_abort(struct aic7xxx_host *p, Scsi_Cmnd *cmd)
  * Description:
  *   Abort the current SCSI command(s).
  *-F*************************************************************************/
-static int
-__aic7xxx_abort(Scsi_Cmnd *cmd)
+static int __aic7xxx_abort(struct scsi_cmnd *cmd)
 {
   struct aic7xxx_scb  *scb = NULL;
   struct aic7xxx_host *p;
@@ -10616,7 +10608,7 @@ __aic7xxx_abort(Scsi_Cmnd *cmd)
   else
     return FAILED;
 
-  aic7xxx_isr(p->irq, (void *)p, NULL);
+  aic7xxx_isr(p);
   aic7xxx_done_cmds_complete(p);
   /* If the command was already complete or just completed, then we didn't
    * do a reset, return FAILED */
@@ -10813,8 +10805,7 @@ success:
   return SUCCESS;
 }
 
-static int
-aic7xxx_abort(Scsi_Cmnd *cmd)
+static int aic7xxx_abort(struct scsi_cmnd *cmd)
 {
        int rc;
 
@@ -10836,8 +10827,7 @@ aic7xxx_abort(Scsi_Cmnd *cmd)
  *   DEVICE RESET message - on the offending target before pulling
  *   the SCSI bus reset line.
  *-F*************************************************************************/
-static int
-aic7xxx_reset(Scsi_Cmnd *cmd)
+static int aic7xxx_reset(struct scsi_cmnd *cmd)
 {
   struct aic7xxx_scb *scb;
   struct aic7xxx_host *p;
@@ -10873,7 +10863,7 @@ aic7xxx_reset(Scsi_Cmnd *cmd)
 
   while((aic_inb(p, INTSTAT) & INT_PEND) && !(p->flags & AHC_IN_ISR))
   {
-    aic7xxx_isr(p->irq, p, (void *)NULL );
+    aic7xxx_isr(p);
     pause_sequencer(p);
   }
   aic7xxx_done_cmds_complete(p);
index 0ed391d8ee84b5f51e4514131d31c7ea7935a962..c83fe751d0bb43941212d27385a90adad3a33b5b 100644 (file)
@@ -28,6 +28,7 @@ config SCSI_AIC94XX
        tristate "Adaptec AIC94xx SAS/SATA support"
        depends on PCI
        select SCSI_SAS_LIBSAS
+       select FW_LOADER
        help
                This driver supports Adaptec's SAS/SATA 3Gb/s 64 bit PCI-X
                AIC94xx chip based host adapters.
index 1d8c5e5f442e668fefb8aacd2522583182ce0f4f..3c2d7a379931af09bb9925eef434a81c96607265 100644 (file)
@@ -996,11 +996,10 @@ static inline void asd_hst_pcix_isr(struct asd_ha_struct *asd_ha)
  * asd_hw_isr -- host adapter interrupt service routine
  * @irq: ignored
  * @dev_id: pointer to host adapter structure
- * @regs: ignored
  *
  * The ISR processes done list entries and level 3 error handling.
  */
-irqreturn_t asd_hw_isr(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t asd_hw_isr(int irq, void *dev_id)
 {
        struct asd_ha_struct *asd_ha = dev_id;
        u32 chimint = asd_read_reg_dword(asd_ha, CHIMINT);
index 8498144aa5e1594eb1e2ecdc09dfb466c7bb48a6..14319d1d680449dc1a3797492a7dbfea882bdd8e 100644 (file)
@@ -371,7 +371,7 @@ static inline void asd_ascb_free_list(struct asd_ascb *ascb_list)
 /* ---------- Function declarations ---------- */
 
 int  asd_init_hw(struct asd_ha_struct *asd_ha);
-irqreturn_t asd_hw_isr(int irq, void *dev_id, struct pt_regs *regs);
+irqreturn_t asd_hw_isr(int irq, void *dev_id);
 
 
 struct asd_ascb *asd_ascb_alloc_list(struct asd_ha_struct
index 734adc9d5206c1f84177a5fadccc197264ffa0c5..99743ca29ca147df75dacd12396be71da90266c9 100644 (file)
@@ -309,11 +309,29 @@ static ssize_t asd_show_dev_pcba_sn(struct device *dev,
 }
 static DEVICE_ATTR(pcba_sn, S_IRUGO, asd_show_dev_pcba_sn, NULL);
 
-static void asd_create_dev_attrs(struct asd_ha_struct *asd_ha)
+static int asd_create_dev_attrs(struct asd_ha_struct *asd_ha)
 {
-       device_create_file(&asd_ha->pcidev->dev, &dev_attr_revision);
-       device_create_file(&asd_ha->pcidev->dev, &dev_attr_bios_build);
-       device_create_file(&asd_ha->pcidev->dev, &dev_attr_pcba_sn);
+       int err;
+
+       err = device_create_file(&asd_ha->pcidev->dev, &dev_attr_revision);
+       if (err)
+               return err;
+
+       err = device_create_file(&asd_ha->pcidev->dev, &dev_attr_bios_build);
+       if (err)
+               goto err_rev;
+
+       err = device_create_file(&asd_ha->pcidev->dev, &dev_attr_pcba_sn);
+       if (err)
+               goto err_biosb;
+
+       return 0;
+
+err_biosb:
+       device_remove_file(&asd_ha->pcidev->dev, &dev_attr_bios_build);
+err_rev:
+       device_remove_file(&asd_ha->pcidev->dev, &dev_attr_revision);
+       return err;
 }
 
 static void asd_remove_dev_attrs(struct asd_ha_struct *asd_ha)
@@ -645,7 +663,9 @@ static int __devinit asd_pci_probe(struct pci_dev *dev,
        }
        ASD_DPRINTK("escbs posted\n");
 
-       asd_create_dev_attrs(asd_ha);
+       err = asd_create_dev_attrs(asd_ha);
+       if (err)
+               goto Err_dev_attrs;
 
        err = asd_register_sas_ha(asd_ha);
        if (err)
@@ -668,6 +688,7 @@ Err_en_phys:
        asd_unregister_sas_ha(asd_ha);
 Err_reg_sas:
        asd_remove_dev_attrs(asd_ha);
+Err_dev_attrs:
 Err_escbs:
        asd_disable_ints(asd_ha);
        free_irq(dev->irq, asd_ha);
@@ -754,9 +775,9 @@ static ssize_t asd_version_show(struct device_driver *driver, char *buf)
 }
 static DRIVER_ATTR(version, S_IRUGO, asd_version_show, NULL);
 
-static void asd_create_driver_attrs(struct device_driver *driver)
+static int asd_create_driver_attrs(struct device_driver *driver)
 {
-       driver_create_file(driver, &driver_attr_version);
+       return driver_create_file(driver, &driver_attr_version);
 }
 
 static void asd_remove_driver_attrs(struct device_driver *driver)
@@ -834,10 +855,14 @@ static int __init aic94xx_init(void)
        if (err)
                goto out_release_transport;
 
-       asd_create_driver_attrs(&aic94xx_pci_driver.driver);
+       err = asd_create_driver_attrs(&aic94xx_pci_driver.driver);
+       if (err)
+               goto out_unregister_pcidrv;
 
        return err;
 
+ out_unregister_pcidrv:
+       pci_unregister_driver(&aic94xx_pci_driver);
  out_release_transport:
        sas_release_transport(aic94xx_transport_template);
  out_destroy_caches:
index 1b637592d5ae23efcda05befb8593b3ab76b680c..7cd63a996886cea6b42aa598e3d67fa39a59e79b 100644 (file)
@@ -8,7 +8,7 @@ int NCR53c7xx_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 int NCR53c7xx_abort(Scsi_Cmnd *);
 int NCR53c7x0_release (struct Scsi_Host *);
 int NCR53c7xx_reset(Scsi_Cmnd *, unsigned int);
-void NCR53c7x0_intr(int irq, void *dev_id, struct pt_regs * regs);
+void NCR53c7x0_intr(int irq, void *dev_id);
 
 #ifndef CMD_PER_LUN
 #define CMD_PER_LUN 3
index 475f978ff8f0dbad4c04074c7fcb859351296c4d..086cc97eee8c31e393cc19949eb8cc93391ca47f 100644 (file)
@@ -147,8 +147,7 @@ static struct pci_driver arcmsr_pci_driver = {
        .shutdown               = arcmsr_shutdown
 };
 
-static irqreturn_t arcmsr_do_interrupt(int irq, void *dev_id,
-       struct pt_regs *regs)
+static irqreturn_t arcmsr_do_interrupt(int irq, void *dev_id)
 {
        irqreturn_t handle_state;
        struct AdapterControlBlock *acb;
index 7621e3fa37b15fb96333eea7ed6cd2e6b89948b1..9cf902b7a12686923e036905d43acd2138eebcdd 100644 (file)
 unsigned int sdtr_period = SDTR_PERIOD;
 unsigned int sdtr_size   = SDTR_SIZE;
 
-static void acornscsi_done(AS_Host *host, Scsi_Cmnd **SCpntp, unsigned int result);
+static void acornscsi_done(AS_Host *host, struct scsi_cmnd **SCpntp,
+                          unsigned int result);
 static int acornscsi_reconnect_finish(AS_Host *host);
 static void acornscsi_dma_cleanup(AS_Host *host);
 static void acornscsi_abortcmd(AS_Host *host, unsigned char tag);
@@ -712,7 +713,7 @@ static
 intr_ret_t acornscsi_kick(AS_Host *host)
 {
     int from_queue = 0;
-    Scsi_Cmnd *SCpnt;
+    struct scsi_cmnd *SCpnt;
 
     /* first check to see if a command is waiting to be executed */
     SCpnt = host->origSCpnt;
@@ -796,15 +797,15 @@ intr_ret_t acornscsi_kick(AS_Host *host)
 }    
 
 /*
- * Function: void acornscsi_done(AS_Host *host, Scsi_Cmnd **SCpntp, unsigned int result)
+ * Function: void acornscsi_done(AS_Host *host, struct scsi_cmnd **SCpntp, unsigned int result)
  * Purpose : complete processing for command
  * Params  : host   - interface that completed
  *          result - driver byte of result
  */
-static
-void acornscsi_done(AS_Host *host, Scsi_Cmnd **SCpntp, unsigned int result)
+static void acornscsi_done(AS_Host *host, struct scsi_cmnd **SCpntp,
+                          unsigned int result)
 {
-    Scsi_Cmnd *SCpnt = *SCpntp;
+       struct scsi_cmnd *SCpnt = *SCpntp;
 
     /* clean up */
     sbic_arm_write(host->scsi.io_port, SBIC_SOURCEID, SOURCEID_ER | SOURCEID_DSP);
@@ -1318,7 +1319,7 @@ acornscsi_write_pio(AS_Host *host, char *bytes, int *ptr, int len, unsigned int
 static void
 acornscsi_sendcommand(AS_Host *host)
 {
-    Scsi_Cmnd *SCpnt = host->SCpnt;
+       struct scsi_cmnd *SCpnt = host->SCpnt;
 
     sbic_arm_write(host->scsi.io_port, SBIC_TRANSCNTH, 0);
     sbic_arm_writenext(host->scsi.io_port, 0);
@@ -1693,7 +1694,7 @@ void acornscsi_message(AS_Host *host)
                acornscsi_sbic_issuecmd(host, CMND_ASSERTATN);
                msgqueue_addmsg(&host->scsi.msgs, 1, ABORT);
            } else {
-               Scsi_Cmnd *SCpnt = host->SCpnt;
+               struct scsi_cmnd *SCpnt = host->SCpnt;
 
                acornscsi_dma_cleanup(host);
 
@@ -2460,14 +2461,13 @@ intr_ret_t acornscsi_sbicintr(AS_Host *host, int in_irq)
 }
 
 /*
- * Prototype: void acornscsi_intr(int irq, void *dev_id, struct pt_regs *regs)
+ * Prototype: void acornscsi_intr(int irq, void *dev_id)
  * Purpose  : handle interrupts from Acorn SCSI card
  * Params   : irq    - interrupt number
  *           dev_id - device specific data (AS_Host structure)
- *           regs   - processor registers when interrupt occurred
  */
 static irqreturn_t
-acornscsi_intr(int irq, void *dev_id, struct pt_regs *regs)
+acornscsi_intr(int irq, void *dev_id)
 {
     AS_Host *host = (AS_Host *)dev_id;
     intr_ret_t ret;
@@ -2509,13 +2509,14 @@ acornscsi_intr(int irq, void *dev_id, struct pt_regs *regs)
  */
 
 /*
- * Function : acornscsi_queuecmd(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
+ * Function : acornscsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
  * Purpose  : queues a SCSI command
  * Params   : cmd  - SCSI command
  *           done - function called on completion, with pointer to command descriptor
  * Returns  : 0, or < 0 on error.
  */
-int acornscsi_queuecmd(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
+int acornscsi_queuecmd(struct scsi_cmnd *SCpnt,
+                      void (*done)(struct scsi_cmnd *))
 {
     AS_Host *host = (AS_Host *)SCpnt->device->host->hostdata;
 
@@ -2565,17 +2566,18 @@ int acornscsi_queuecmd(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
 }
 
 /*
- * Prototype: void acornscsi_reportstatus(Scsi_Cmnd **SCpntp1, Scsi_Cmnd **SCpntp2, int result)
+ * Prototype: void acornscsi_reportstatus(struct scsi_cmnd **SCpntp1, struct scsi_cmnd **SCpntp2, int result)
  * Purpose  : pass a result to *SCpntp1, and check if *SCpntp1 = *SCpntp2
  * Params   : SCpntp1 - pointer to command to return
  *           SCpntp2 - pointer to command to check
  *           result  - result to pass back to mid-level done function
  * Returns  : *SCpntp2 = NULL if *SCpntp1 is the same command structure as *SCpntp2.
  */
-static inline
-void acornscsi_reportstatus(Scsi_Cmnd **SCpntp1, Scsi_Cmnd **SCpntp2, int result)
+static inline void acornscsi_reportstatus(struct scsi_cmnd **SCpntp1,
+                                         struct scsi_cmnd **SCpntp2,
+                                         int result)
 {
-    Scsi_Cmnd *SCpnt = *SCpntp1;
+       struct scsi_cmnd *SCpnt = *SCpntp1;
 
     if (SCpnt) {
        *SCpntp1 = NULL;
@@ -2591,13 +2593,12 @@ void acornscsi_reportstatus(Scsi_Cmnd **SCpntp1, Scsi_Cmnd **SCpntp2, int result
 enum res_abort { res_not_running, res_success, res_success_clear, res_snooze };
 
 /*
- * Prototype: enum res acornscsi_do_abort(Scsi_Cmnd *SCpnt)
+ * Prototype: enum res acornscsi_do_abort(struct scsi_cmnd *SCpnt)
  * Purpose  : abort a command on this host
  * Params   : SCpnt - command to abort
  * Returns  : our abort status
  */
-static enum res_abort
-acornscsi_do_abort(AS_Host *host, Scsi_Cmnd *SCpnt)
+static enum res_abort acornscsi_do_abort(AS_Host *host, struct scsi_cmnd *SCpnt)
 {
        enum res_abort res = res_not_running;
 
@@ -2684,12 +2685,12 @@ acornscsi_do_abort(AS_Host *host, Scsi_Cmnd *SCpnt)
 }
 
 /*
- * Prototype: int acornscsi_abort(Scsi_Cmnd *SCpnt)
+ * Prototype: int acornscsi_abort(struct scsi_cmnd *SCpnt)
  * Purpose  : abort a command on this host
  * Params   : SCpnt - command to abort
  * Returns  : one of SCSI_ABORT_ macros
  */
-int acornscsi_abort(Scsi_Cmnd *SCpnt)
+int acornscsi_abort(struct scsi_cmnd *SCpnt)
 {
        AS_Host *host = (AS_Host *) SCpnt->device->host->hostdata;
        int result;
@@ -2770,16 +2771,16 @@ int acornscsi_abort(Scsi_Cmnd *SCpnt)
 }
 
 /*
- * Prototype: int acornscsi_reset(Scsi_Cmnd *SCpnt, unsigned int reset_flags)
+ * Prototype: int acornscsi_reset(struct scsi_cmnd *SCpnt, unsigned int reset_flags)
  * Purpose  : reset a command on this host/reset this host
  * Params   : SCpnt  - command causing reset
  *           result - what type of reset to perform
  * Returns  : one of SCSI_RESET_ macros
  */
-int acornscsi_reset(Scsi_Cmnd *SCpnt, unsigned int reset_flags)
+int acornscsi_reset(struct scsi_cmnd *SCpnt, unsigned int reset_flags)
 {
-    AS_Host *host = (AS_Host *)SCpnt->device->host->hostdata;
-    Scsi_Cmnd *SCptr;
+       AS_Host *host = (AS_Host *)SCpnt->device->host->hostdata;
+       struct scsi_cmnd *SCptr;
     
     host->stats.resets += 1;
 
index 2142290f84046b42ed89b2ef57774ff7a4ea4151..d11424b89f4237627bbf88c216c25fad2559f32f 100644 (file)
@@ -277,8 +277,8 @@ struct status_entry {
 typedef struct acornscsi_hostdata {
     /* miscellaneous */
     struct Scsi_Host   *host;                  /* host                                 */
-    Scsi_Cmnd          *SCpnt;                 /* currently processing command         */
-    Scsi_Cmnd          *origSCpnt;             /* original connecting command          */
+    struct scsi_cmnd   *SCpnt;                 /* currently processing command         */
+    struct scsi_cmnd   *origSCpnt;             /* original connecting command          */
 
     /* driver information */
     struct {
index 719af0dcc0e580d9059cff9c2be96091435f3865..19edd9c853d9fe35fd9406afedb3e58c49aa4c28 100644 (file)
@@ -137,10 +137,9 @@ cumanascsi_2_terminator_ctl(struct Scsi_Host *host, int on_off)
  * Purpose  : handle interrupts from Cumana SCSI 2 card
  * Params   : irq    - interrupt number
  *           dev_id - user-defined (Scsi_Host structure)
- *           regs   - processor registers at interrupt
  */
 static irqreturn_t
-cumanascsi_2_intr(int irq, void *dev_id, struct pt_regs *regs)
+cumanascsi_2_intr(int irq, void *dev_id)
 {
        struct cumanascsi2_info *info = dev_id;
 
index dcbb4b2b3fe054ca4b70968b870c295c56ccfe17..3f876fb754693c7ab61496ad49dcda5f66656dd0 100644 (file)
@@ -138,10 +138,9 @@ eesoxscsi_terminator_ctl(struct Scsi_Host *host, int on_off)
  * Purpose  : handle interrupts from EESOX SCSI card
  * Params   : irq    - interrupt number
  *           dev_id - user-defined (Scsi_Host structure)
- *           regs   - processor registers at interrupt
  */
 static irqreturn_t
-eesoxscsi_intr(int irq, void *dev_id, struct pt_regs *regs)
+eesoxscsi_intr(int irq, void *dev_id)
 {
        struct eesoxscsi_info *info = dev_id;
 
index 4cf7afc31cc7f00e24414f7a08d1cd3e8733ed7b..e05f0c2fc9123a7948216d785c0c6d36e172b533 100644 (file)
@@ -297,8 +297,8 @@ fas216_do_log(FAS216_Info *info, char target, char *fmt, va_list ap)
        printk("scsi%d.%c: %s", info->host->host_no, target, buf);
 }
 
-static void
-fas216_log_command(FAS216_Info *info, int level, Scsi_Cmnd *SCpnt, char *fmt, ...)
+static void fas216_log_command(FAS216_Info *info, int level,
+                              struct scsi_cmnd *SCpnt, char *fmt, ...)
 {
        va_list args;
 
@@ -1662,7 +1662,7 @@ irqreturn_t fas216_intr(FAS216_Info *info)
        return handled;
 }
 
-static void __fas216_start_command(FAS216_Info *info, Scsi_Cmnd *SCpnt)
+static void __fas216_start_command(FAS216_Info *info, struct scsi_cmnd *SCpnt)
 {
        int tot_msglen;
 
@@ -1754,7 +1754,7 @@ static int parity_test(FAS216_Info *info, int target)
        return info->device[target].parity_check;
 }
 
-static void fas216_start_command(FAS216_Info *info, Scsi_Cmnd *SCpnt)
+static void fas216_start_command(FAS216_Info *info, struct scsi_cmnd *SCpnt)
 {
        int disconnect_ok;
 
@@ -1808,7 +1808,7 @@ static void fas216_start_command(FAS216_Info *info, Scsi_Cmnd *SCpnt)
        __fas216_start_command(info, SCpnt);
 }
 
-static void fas216_allocate_tag(FAS216_Info *info, Scsi_Cmnd *SCpnt)
+static void fas216_allocate_tag(FAS216_Info *info, struct scsi_cmnd *SCpnt)
 {
 #ifdef SCSI2_TAG
        /*
@@ -1842,7 +1842,8 @@ static void fas216_allocate_tag(FAS216_Info *info, Scsi_Cmnd *SCpnt)
        }
 }
 
-static void fas216_do_bus_device_reset(FAS216_Info *info, Scsi_Cmnd *SCpnt)
+static void fas216_do_bus_device_reset(FAS216_Info *info,
+                                      struct scsi_cmnd *SCpnt)
 {
        struct message *msg;
 
@@ -1890,7 +1891,7 @@ static void fas216_do_bus_device_reset(FAS216_Info *info, Scsi_Cmnd *SCpnt)
  */
 static void fas216_kick(FAS216_Info *info)
 {
-       Scsi_Cmnd *SCpnt = NULL;
+       struct scsi_cmnd *SCpnt = NULL;
 #define TYPE_OTHER     0
 #define TYPE_RESET     1
 #define TYPE_QUEUE     2
@@ -1978,8 +1979,8 @@ static void fas216_kick(FAS216_Info *info)
 /*
  * Clean up from issuing a BUS DEVICE RESET message to a device.
  */
-static void
-fas216_devicereset_done(FAS216_Info *info, Scsi_Cmnd *SCpnt, unsigned int result)
+static void fas216_devicereset_done(FAS216_Info *info, struct scsi_cmnd *SCpnt,
+                                   unsigned int result)
 {
        fas216_log(info, LOG_ERROR, "fas216 device reset complete");
 
@@ -1996,8 +1997,8 @@ fas216_devicereset_done(FAS216_Info *info, Scsi_Cmnd *SCpnt, unsigned int result
  *
  * Finish processing automatic request sense command
  */
-static void
-fas216_rq_sns_done(FAS216_Info *info, Scsi_Cmnd *SCpnt, unsigned int result)
+static void fas216_rq_sns_done(FAS216_Info *info, struct scsi_cmnd *SCpnt,
+                              unsigned int result)
 {
        fas216_log_target(info, LOG_CONNECT, SCpnt->device->id,
                   "request sense complete, result=0x%04x%02x%02x",
@@ -2030,7 +2031,7 @@ fas216_rq_sns_done(FAS216_Info *info, Scsi_Cmnd *SCpnt, unsigned int result)
  * Finish processing of standard command
  */
 static void
-fas216_std_done(FAS216_Info *info, Scsi_Cmnd *SCpnt, unsigned int result)
+fas216_std_done(FAS216_Info *info, struct scsi_cmnd *SCpnt, unsigned int result)
 {
        info->stats.fins += 1;
 
@@ -2142,8 +2143,8 @@ request_sense:
  */
 static void fas216_done(FAS216_Info *info, unsigned int result)
 {
-       void (*fn)(FAS216_Info *, Scsi_Cmnd *, unsigned int);
-       Scsi_Cmnd *SCpnt;
+       void (*fn)(FAS216_Info *, struct scsi_cmnd *, unsigned int);
+       struct scsi_cmnd *SCpnt;
        unsigned long flags;
 
        fas216_checkmagic(info);
@@ -2182,7 +2183,7 @@ static void fas216_done(FAS216_Info *info, unsigned int result)
        info->device[SCpnt->device->id].parity_check = 0;
        clear_bit(SCpnt->device->id * 8 + SCpnt->device->lun, info->busyluns);
 
-       fn = (void (*)(FAS216_Info *, Scsi_Cmnd *, unsigned int))SCpnt->host_scribble;
+       fn = (void (*)(FAS216_Info *, struct scsi_cmnd *, unsigned int))SCpnt->host_scribble;
        fn(info, SCpnt, result);
 
        if (info->scsi.irq != NO_IRQ) {
@@ -2207,7 +2208,8 @@ no_command:
  * Returns: 0 on success, else error.
  * Notes: io_request_lock is held, interrupts are disabled.
  */
-int fas216_queue_command(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
+int fas216_queue_command(struct scsi_cmnd *SCpnt,
+                        void (*done)(struct scsi_cmnd *))
 {
        FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
        int result;
@@ -2254,7 +2256,7 @@ int fas216_queue_command(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
  *
  * Trigger restart of a waiting thread in fas216_command
  */
-static void fas216_internal_done(Scsi_Cmnd *SCpnt)
+static void fas216_internal_done(struct scsi_cmnd *SCpnt)
 {
        FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
 
@@ -2271,7 +2273,8 @@ static void fas216_internal_done(Scsi_Cmnd *SCpnt)
  * Returns: scsi result code.
  * Notes: io_request_lock is held, interrupts are disabled.
  */
-int fas216_noqueue_command(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
+int fas216_noqueue_command(struct scsi_cmnd *SCpnt,
+                          void (*done)(struct scsi_cmnd *))
 {
        FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
 
@@ -2350,7 +2353,8 @@ enum res_find {
  * Decide how to abort a command.
  * Returns: abort status
  */
-static enum res_find fas216_find_command(FAS216_Info *info, Scsi_Cmnd *SCpnt)
+static enum res_find fas216_find_command(FAS216_Info *info,
+                                        struct scsi_cmnd *SCpnt)
 {
        enum res_find res = res_failed;
 
@@ -2417,7 +2421,7 @@ static enum res_find fas216_find_command(FAS216_Info *info, Scsi_Cmnd *SCpnt)
  * Returns: FAILED if unable to abort
  * Notes: io_request_lock is taken, and irqs are disabled
  */
-int fas216_eh_abort(Scsi_Cmnd *SCpnt)
+int fas216_eh_abort(struct scsi_cmnd *SCpnt)
 {
        FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
        int result = FAILED;
@@ -2474,7 +2478,7 @@ int fas216_eh_abort(Scsi_Cmnd *SCpnt)
  * Notes: We won't be re-entered, so we'll only have one device
  * reset on the go at one time.
  */
-int fas216_eh_device_reset(Scsi_Cmnd *SCpnt)
+int fas216_eh_device_reset(struct scsi_cmnd *SCpnt)
 {
        FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
        unsigned long flags;
@@ -2555,7 +2559,7 @@ int fas216_eh_device_reset(Scsi_Cmnd *SCpnt)
  * Returns: FAILED if unable to reset.
  * Notes: Further commands are blocked.
  */
-int fas216_eh_bus_reset(Scsi_Cmnd *SCpnt)
+int fas216_eh_bus_reset(struct scsi_cmnd *SCpnt)
 {
        FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
        unsigned long flags;
@@ -2655,7 +2659,7 @@ static void fas216_init_chip(FAS216_Info *info)
  * Returns: FAILED if unable to reset.
  * Notes: io_request_lock is taken, and irqs are disabled
  */
-int fas216_eh_host_reset(Scsi_Cmnd *SCpnt)
+int fas216_eh_host_reset(struct scsi_cmnd *SCpnt)
 {
        FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
 
index 540914d6fd32dc3a0ad29fad7c5330e387f4ec7c..00e5f055afdc5fff16d80cf7e15ab123dd209b3f 100644 (file)
@@ -218,11 +218,11 @@ typedef struct {
        unsigned long           magic_start;
        spinlock_t              host_lock;
        struct Scsi_Host        *host;                  /* host                                 */
-       Scsi_Cmnd               *SCpnt;                 /* currently processing command         */
-       Scsi_Cmnd               *origSCpnt;             /* original connecting command          */
-       Scsi_Cmnd               *reqSCpnt;              /* request sense command                */
-       Scsi_Cmnd               *rstSCpnt;              /* reset command                        */
-       Scsi_Cmnd               *pending_SCpnt[8];      /* per-device pending commands          */
+       struct scsi_cmnd        *SCpnt;                 /* currently processing command         */
+       struct scsi_cmnd        *origSCpnt;             /* original connecting command          */
+       struct scsi_cmnd        *reqSCpnt;              /* request sense command                */
+       struct scsi_cmnd        *rstSCpnt;              /* reset command                        */
+       struct scsi_cmnd        *pending_SCpnt[8];      /* per-device pending commands          */
        int                     next_pending;           /* next pending device                  */
 
        /*
@@ -328,21 +328,23 @@ extern int fas216_init (struct Scsi_Host *instance);
  */
 extern int fas216_add (struct Scsi_Host *instance, struct device *dev);
 
-/* Function: int fas216_queue_command (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
+/* Function: int fas216_queue_command(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
  * Purpose : queue a command for adapter to process.
  * Params  : SCpnt - Command to queue
  *          done  - done function to call once command is complete
  * Returns : 0 - success, else error
  */
-extern int fas216_queue_command (Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
+extern int fas216_queue_command(struct scsi_cmnd *,
+                               void (*done)(struct scsi_cmnd *));
 
-/* Function: int fas216_noqueue_command (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
+/* Function: int fas216_noqueue_command(istruct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
  * Purpose : queue a command for adapter to process, and process it to completion.
  * Params  : SCpnt - Command to queue
  *          done  - done function to call once command is complete
  * Returns : 0 - success, else error
  */
-extern int fas216_noqueue_command (Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
+extern int fas216_noqueue_command(struct scsi_cmnd *,
+                                 void (*done)(struct scsi_cmnd *));
 
 /* Function: irqreturn_t fas216_intr (FAS216_Info *info)
  * Purpose : handle interrupts from the interface to progress a command
@@ -363,32 +365,32 @@ extern int fas216_print_host(FAS216_Info *info, char *buffer);
 extern int fas216_print_stats(FAS216_Info *info, char *buffer);
 extern int fas216_print_devices(FAS216_Info *info, char *buffer);
 
-/* Function: int fas216_eh_abort(Scsi_Cmnd *SCpnt)
+/* Function: int fas216_eh_abort(struct scsi_cmnd *SCpnt)
  * Purpose : abort this command
  * Params  : SCpnt - command to abort
  * Returns : FAILED if unable to abort
  */
-extern int fas216_eh_abort(Scsi_Cmnd *SCpnt);
+extern int fas216_eh_abort(struct scsi_cmnd *SCpnt);
 
-/* Function: int fas216_eh_device_reset(Scsi_Cmnd *SCpnt)
+/* Function: int fas216_eh_device_reset(struct scsi_cmnd *SCpnt)
  * Purpose : Reset the device associated with this command
  * Params  : SCpnt - command specifing device to reset
  * Returns : FAILED if unable to reset
  */
-extern int fas216_eh_device_reset(Scsi_Cmnd *SCpnt);
+extern int fas216_eh_device_reset(struct scsi_cmnd *SCpnt);
 
-/* Function: int fas216_eh_bus_reset(Scsi_Cmnd *SCpnt)
+/* Function: int fas216_eh_bus_reset(struct scsi_cmnd *SCpnt)
  * Purpose : Reset the complete bus associated with this command
  * Params  : SCpnt - command specifing bus to reset
  * Returns : FAILED if unable to reset
  */
-extern int fas216_eh_bus_reset(Scsi_Cmnd *SCpnt);
+extern int fas216_eh_bus_reset(struct scsi_cmnd *SCpnt);
 
-/* Function: int fas216_eh_host_reset(Scsi_Cmnd *SCpnt)
+/* Function: int fas216_eh_host_reset(struct scsi_cmnd *SCpnt)
  * Purpose : Reset the host associated with this command
  * Params  : SCpnt - command specifing host to reset
  * Returns : FAILED if unable to reset
  */
-extern int fas216_eh_host_reset(Scsi_Cmnd *SCpnt);
+extern int fas216_eh_host_reset(struct scsi_cmnd *SCpnt);
 
 #endif /* FAS216_H */
index b2c346a470527543a02db9ce71c25b6e8c9ebde9..ce159c15bc86eae5e711136616e8f68aaf20f985 100644 (file)
@@ -112,10 +112,8 @@ powertecscsi_terminator_ctl(struct Scsi_Host *host, int on_off)
  * Purpose  : handle interrupts from Powertec SCSI card
  * Params   : irq    - interrupt number
  *           dev_id - user-defined (Scsi_Host structure)
- *           regs   - processor registers at interrupt
  */
-static irqreturn_t
-powertecscsi_intr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t powertecscsi_intr(int irq, void *dev_id)
 {
        struct powertec_info *info = dev_id;
 
index 8caa5903ce3841d3ee9c4b3f7f1443ce7fb349b9..cb11ccef54e5104d2825d4e6bfdfcefa8260672c 100644 (file)
@@ -29,7 +29,7 @@
 
 typedef struct queue_entry {
        struct list_head   list;
-       Scsi_Cmnd          *SCpnt;
+       struct scsi_cmnd   *SCpnt;
 #ifdef DEBUG
        unsigned long      magic;
 #endif
@@ -96,14 +96,14 @@ void queue_free (Queue_t *queue)
      
 
 /*
- * Function: int queue_add_cmd(Queue_t *queue, Scsi_Cmnd *SCpnt, int head)
+ * Function: int __queue_add(Queue_t *queue, struct scsi_cmnd *SCpnt, int head)
  * Purpose : Add a new command onto a queue, adding REQUEST_SENSE to head.
  * Params  : queue - destination queue
  *          SCpnt - command to add
  *          head  - add command to head of queue
  * Returns : 0 on error, !0 on success
  */
-int __queue_add(Queue_t *queue, Scsi_Cmnd *SCpnt, int head)
+int __queue_add(Queue_t *queue, struct scsi_cmnd *SCpnt, int head)
 {
        unsigned long flags;
        struct list_head *l;
@@ -134,7 +134,7 @@ empty:
        return ret;
 }
 
-static Scsi_Cmnd *__queue_remove(Queue_t *queue, struct list_head *ent)
+static struct scsi_cmnd *__queue_remove(Queue_t *queue, struct list_head *ent)
 {
        QE_t *q;
 
@@ -152,17 +152,17 @@ static Scsi_Cmnd *__queue_remove(Queue_t *queue, struct list_head *ent)
 }
 
 /*
- * Function: Scsi_Cmnd *queue_remove_exclude (queue, exclude)
+ * Function: struct scsi_cmnd *queue_remove_exclude (queue, exclude)
  * Purpose : remove a SCSI command from a queue
  * Params  : queue   - queue to remove command from
  *          exclude - bit array of target&lun which is busy
- * Returns : Scsi_Cmnd if successful (and a reference), or NULL if no command available
+ * Returns : struct scsi_cmnd if successful (and a reference), or NULL if no command available
  */
-Scsi_Cmnd *queue_remove_exclude(Queue_t *queue, unsigned long *exclude)
+struct scsi_cmnd *queue_remove_exclude(Queue_t *queue, unsigned long *exclude)
 {
        unsigned long flags;
        struct list_head *l;
-       Scsi_Cmnd *SCpnt = NULL;
+       struct scsi_cmnd *SCpnt = NULL;
 
        spin_lock_irqsave(&queue->queue_lock, flags);
        list_for_each(l, &queue->head) {
@@ -178,15 +178,15 @@ Scsi_Cmnd *queue_remove_exclude(Queue_t *queue, unsigned long *exclude)
 }
 
 /*
- * Function: Scsi_Cmnd *queue_remove (queue)
+ * Function: struct scsi_cmnd *queue_remove (queue)
  * Purpose : removes first SCSI command from a queue
  * Params  : queue   - queue to remove command from
- * Returns : Scsi_Cmnd if successful (and a reference), or NULL if no command available
+ * Returns : struct scsi_cmnd if successful (and a reference), or NULL if no command available
  */
-Scsi_Cmnd *queue_remove(Queue_t *queue)
+struct scsi_cmnd *queue_remove(Queue_t *queue)
 {
        unsigned long flags;
-       Scsi_Cmnd *SCpnt = NULL;
+       struct scsi_cmnd *SCpnt = NULL;
 
        spin_lock_irqsave(&queue->queue_lock, flags);
        if (!list_empty(&queue->head))
@@ -197,19 +197,20 @@ Scsi_Cmnd *queue_remove(Queue_t *queue)
 }
 
 /*
- * Function: Scsi_Cmnd *queue_remove_tgtluntag (queue, target, lun, tag)
+ * Function: struct scsi_cmnd *queue_remove_tgtluntag (queue, target, lun, tag)
  * Purpose : remove a SCSI command from the queue for a specified target/lun/tag
  * Params  : queue  - queue to remove command from
  *          target - target that we want
  *          lun    - lun on device
  *          tag    - tag on device
- * Returns : Scsi_Cmnd if successful, or NULL if no command satisfies requirements
+ * Returns : struct scsi_cmnd if successful, or NULL if no command satisfies requirements
  */
-Scsi_Cmnd *queue_remove_tgtluntag (Queue_t *queue, int target, int lun, int tag)
+struct scsi_cmnd *queue_remove_tgtluntag(Queue_t *queue, int target, int lun,
+                                        int tag)
 {
        unsigned long flags;
        struct list_head *l;
-       Scsi_Cmnd *SCpnt = NULL;
+       struct scsi_cmnd *SCpnt = NULL;
 
        spin_lock_irqsave(&queue->queue_lock, flags);
        list_for_each(l, &queue->head) {
@@ -275,13 +276,13 @@ int queue_probetgtlun (Queue_t *queue, int target, int lun)
 }
 
 /*
- * Function: int queue_remove_cmd(Queue_t *queue, Scsi_Cmnd *SCpnt)
+ * Function: int queue_remove_cmd(Queue_t *queue, struct scsi_cmnd *SCpnt)
  * Purpose : remove a specific command from the queues
  * Params  : queue - queue to look in
  *          SCpnt - command to find
  * Returns : 0 if not found
  */
-int queue_remove_cmd(Queue_t *queue, Scsi_Cmnd *SCpnt)
+int queue_remove_cmd(Queue_t *queue, struct scsi_cmnd *SCpnt)
 {
        unsigned long flags;
        struct list_head *l;
index 0c9dec4c1716a14903162ddd18be0388ecc700ee..3c519c9237b27410f07376efa5cf91dbe96916e4 100644 (file)
@@ -32,46 +32,48 @@ extern int queue_initialise (Queue_t *queue);
 extern void queue_free (Queue_t *queue);
 
 /*
- * Function: Scsi_Cmnd *queue_remove (queue)
+ * Function: struct scsi_cmnd *queue_remove (queue)
  * Purpose : removes first SCSI command from a queue
  * Params  : queue   - queue to remove command from
- * Returns : Scsi_Cmnd if successful (and a reference), or NULL if no command available
+ * Returns : struct scsi_cmnd if successful (and a reference), or NULL if no command available
  */
-extern Scsi_Cmnd *queue_remove (Queue_t *queue);
+extern struct scsi_cmnd *queue_remove (Queue_t *queue);
 
 /*
- * Function: Scsi_Cmnd *queue_remove_exclude_ref (queue, exclude)
+ * Function: struct scsi_cmnd *queue_remove_exclude_ref (queue, exclude)
  * Purpose : remove a SCSI command from a queue
  * Params  : queue   - queue to remove command from
  *          exclude - array of busy LUNs
- * Returns : Scsi_Cmnd if successful (and a reference), or NULL if no command available
+ * Returns : struct scsi_cmnd if successful (and a reference), or NULL if no command available
  */
-extern Scsi_Cmnd *queue_remove_exclude (Queue_t *queue, unsigned long *exclude);
+extern struct scsi_cmnd *queue_remove_exclude(Queue_t *queue,
+                                             unsigned long *exclude);
 
 #define queue_add_cmd_ordered(queue,SCpnt) \
        __queue_add(queue,SCpnt,(SCpnt)->cmnd[0] == REQUEST_SENSE)
 #define queue_add_cmd_tail(queue,SCpnt) \
        __queue_add(queue,SCpnt,0)
 /*
- * Function: int __queue_add(Queue_t *queue, Scsi_Cmnd *SCpnt, int head)
+ * Function: int __queue_add(Queue_t *queue, struct scsi_cmnd *SCpnt, int head)
  * Purpose : Add a new command onto a queue
  * Params  : queue - destination queue
  *          SCpnt - command to add
  *          head  - add command to head of queue
  * Returns : 0 on error, !0 on success
  */
-extern int __queue_add(Queue_t *queue, Scsi_Cmnd *SCpnt, int head);
+extern int __queue_add(Queue_t *queue, struct scsi_cmnd *SCpnt, int head);
 
 /*
- * Function: Scsi_Cmnd *queue_remove_tgtluntag (queue, target, lun, tag)
+ * Function: struct scsi_cmnd *queue_remove_tgtluntag (queue, target, lun, tag)
  * Purpose : remove a SCSI command from the queue for a specified target/lun/tag
  * Params  : queue  - queue to remove command from
  *          target - target that we want
  *          lun    - lun on device
  *          tag    - tag on device
- * Returns : Scsi_Cmnd if successful, or NULL if no command satisfies requirements
+ * Returns : struct scsi_cmnd if successful, or NULL if no command satisfies requirements
  */
-extern Scsi_Cmnd *queue_remove_tgtluntag (Queue_t *queue, int target, int lun, int tag);
+extern struct scsi_cmnd *queue_remove_tgtluntag(Queue_t *queue, int target,
+                                               int lun, int tag);
 
 /*
  * Function: queue_remove_all_target(queue, target)
@@ -94,12 +96,12 @@ extern void queue_remove_all_target(Queue_t *queue, int target);
 extern int queue_probetgtlun (Queue_t *queue, int target, int lun);
 
 /*
- * Function: int queue_remove_cmd (Queue_t *queue, Scsi_Cmnd *SCpnt)
+ * Function: int queue_remove_cmd (Queue_t *queue, struct scsi_cmnd *SCpnt)
  * Purpose : remove a specific command from the queues
  * Params  : queue - queue to look in
  *          SCpnt - command to find
  * Returns : 0 if not found
  */
-int queue_remove_cmd(Queue_t *queue, Scsi_Cmnd *SCpnt);
+int queue_remove_cmd(Queue_t *queue, struct scsi_cmnd *SCpnt);
 
 #endif /* QUEUE_H */
index 8c2600ffc6afec68e270f224ea4ba17a4d3fb7b4..3a39579bd08e9841064e012d0bb2579beb363452 100644 (file)
@@ -66,7 +66,7 @@ static inline void put_next_SCp_byte(struct scsi_pointer *SCp, unsigned char c)
        SCp->this_residual -= 1;
 }
 
-static inline void init_SCp(Scsi_Cmnd *SCpnt)
+static inline void init_SCp(struct scsi_cmnd *SCpnt)
 {
        memset(&SCpnt->SCp, 0, sizeof(struct scsi_pointer));
 
index e397129c90d188e689ac260a34fe90f49c01daea..0f920c84ac0ff18f9569cdb10796a7d4e5b25d6f 100644 (file)
@@ -1262,7 +1262,7 @@ static void NCR5380_dma_complete( struct Scsi_Host *instance )
  *
  */
 
-static irqreturn_t NCR5380_intr (int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t NCR5380_intr (int irq, void *dev_id)
 {
     struct Scsi_Host *instance = first_instance;
     int done = 1, handled = 0;
index 8d5d2a5da961e195dc2882e6523c8ed670f363e6..cdc710ea00fa48b9a75e6bbf77fd92fd4a8d3bc4 100644 (file)
@@ -110,7 +110,7 @@ static inline void set_restdata_reg(unsigned char *cur_addr)
 }
 
 /*
- * void hades_dma_emulator(int irq, void *dummy, struct pt_regs *fp)
+ * void hades_dma_emulator(int irq, void *dummy)
  * 
  * This code emulates TT SCSI DMA on the Hades.
  * 
@@ -140,7 +140,7 @@ static inline void set_restdata_reg(unsigned char *cur_addr)
  *    increased with one.
  */
 
-static irqreturn_t hades_dma_emulator(int irq, void *dummy, struct pt_regs *fp)
+static irqreturn_t hades_dma_emulator(int irq, void *dummy)
 {
        unsigned long dma_base;
        register unsigned long dma_cnt asm ("d3");
index e1be4a4387cd5309351c1bd78ae428663d4a4d62..dfb1bcfae82ebe834812e3dd8738b227110fc8c9 100644 (file)
@@ -194,8 +194,8 @@ static int falcon_classify_cmd( Scsi_Cmnd *cmd );
 static unsigned long atari_dma_xfer_len( unsigned long wanted_len,
                                          Scsi_Cmnd *cmd, int write_flag );
 #endif
-static irqreturn_t scsi_tt_intr( int irq, void *dummy, struct pt_regs *fp);
-static irqreturn_t scsi_falcon_intr( int irq, void *dummy, struct pt_regs *fp);
+static irqreturn_t scsi_tt_intr( int irq, void *dummy);
+static irqreturn_t scsi_falcon_intr( int irq, void *dummy);
 static void falcon_release_lock_if_possible( struct NCR5380_hostdata *
                                              hostdata );
 static void falcon_get_lock( void );
@@ -285,7 +285,7 @@ static int scsi_dma_is_ignored_buserr( unsigned char dma_stat )
  * end-of-DMA, both SCSI ints are triggered simultaneously, so the NCR int has
  * to clear the DMA int pending bit before it allows other level 6 interrupts.
  */
-static void scsi_dma_buserr (int irq, void *dummy, struct pt_regs *fp)
+static void scsi_dma_buserr (int irq, void *dummy)
 {
        unsigned char   dma_stat = tt_scsi_dma.dma_ctrl;
 
@@ -314,7 +314,7 @@ static void scsi_dma_buserr (int irq, void *dummy, struct pt_regs *fp)
 #endif
 
 
-static irqreturn_t scsi_tt_intr (int irq, void *dummy, struct pt_regs *fp)
+static irqreturn_t scsi_tt_intr (int irq, void *dummy)
 {
 #ifdef REAL_DMA
        int dma_stat;
@@ -406,7 +406,7 @@ static irqreturn_t scsi_tt_intr (int irq, void *dummy, struct pt_regs *fp)
 }
 
 
-static irqreturn_t scsi_falcon_intr (int irq, void *dummy, struct pt_regs *fp)
+static irqreturn_t scsi_falcon_intr (int irq, void *dummy)
 {
 #ifdef REAL_DMA
        int dma_stat;
index 0ec41f34f46261bdbcfdf934aafb44c72c5efabf..fec58cc47f1cce78de21d0fc05c878d0a92d4c74 100644 (file)
@@ -44,7 +44,7 @@ static void send_s870(struct atp_unit *dev,unsigned char c);
 static void is885(struct atp_unit *dev, unsigned int wkport,unsigned char c);
 static void tscam_885(void);
 
-static irqreturn_t atp870u_intr_handle(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t atp870u_intr_handle(int irq, void *dev_id)
 {
        unsigned long flags;
        unsigned short int tmpcip, id;
index 7c9c0366cc087e36ab0041764ee1615a7d6444e2..ea3e4b2b922000371b9a528d05e02d007f335244 100644 (file)
@@ -9,7 +9,7 @@ int NCR53c7xx_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 int NCR53c7xx_abort(Scsi_Cmnd *);
 int NCR53c7x0_release (struct Scsi_Host *);
 int NCR53c7xx_reset(Scsi_Cmnd *, unsigned int);
-void NCR53c7x0_intr(int irq, void *dev_id, struct pt_regs * regs);
+void NCR53c7x0_intr(int irq, void *dev_id);
 
 #ifndef CMD_PER_LUN
 #define CMD_PER_LUN 3
index ff2b1796fa34634ac95b3eee22051743dc706819..e95b367d09edd739af8e1739a8d9ed2a1b8d20aa 100644 (file)
@@ -1219,7 +1219,7 @@ static void dump_register_info(struct AdapterCtlBlk *acb,
                                srb, srb->cmd, srb->cmd->pid,
                                srb->cmd->cmnd[0], srb->cmd->device->id,
                                srb->cmd->device->lun);
-               printk("  sglist=%p cnt=%i idx=%i len=%i\n",
+               printk("  sglist=%p cnt=%i idx=%i len=%zu\n",
                       srb->segment_x, srb->sg_count, srb->sg_index,
                       srb->total_xfer_length);
                printk("  state=0x%04x status=0x%02x phase=0x%02x (%sconn.)\n",
@@ -1813,10 +1813,9 @@ static void dc395x_handle_interrupt(struct AdapterCtlBlk *acb,
 }
 
 
-static irqreturn_t dc395x_interrupt(int irq, void *dev_id,
-               struct pt_regs *regs)
+static irqreturn_t dc395x_interrupt(int irq, void *dev_id)
 {
-       struct AdapterCtlBlk *acb = (struct AdapterCtlBlk *)dev_id;
+       struct AdapterCtlBlk *acb = dev_id;
        u16 scsi_status;
        u8 dma_status;
        irqreturn_t handled = IRQ_NONE;
@@ -4949,7 +4948,7 @@ static struct pci_driver dc395x_driver = {
  **/
 static int __init dc395x_module_init(void)
 {
-       return pci_module_init(&dc395x_driver);
+       return pci_register_driver(&dc395x_driver);
 }
 
 
index eb32062f7e683271eb6c79c698dc74cd0fb34dc0..c29ccbc44693ab46079b652c617c2f72c147291b 100644 (file)
@@ -94,9 +94,9 @@ volatile unsigned char pmaz_cmd_buffer[16];
                                 * via PIO.
                                 */
 
-static irqreturn_t scsi_dma_merr_int(int, void *, struct pt_regs *);
-static irqreturn_t scsi_dma_err_int(int, void *, struct pt_regs *);
-static irqreturn_t scsi_dma_int(int, void *, struct pt_regs *);
+static irqreturn_t scsi_dma_merr_int(int, void *);
+static irqreturn_t scsi_dma_err_int(int, void *);
+static irqreturn_t scsi_dma_int(int, void *);
 
 static int dec_esp_detect(struct scsi_host_template * tpnt);
 
@@ -307,7 +307,7 @@ err_dealloc:
 }
 
 /************************************************************* DMA Functions */
-static irqreturn_t scsi_dma_merr_int(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t scsi_dma_merr_int(int irq, void *dev_id)
 {
        printk("Got unexpected SCSI DMA Interrupt! < ");
        printk("SCSI_DMA_MEMRDERR ");
@@ -316,14 +316,14 @@ static irqreturn_t scsi_dma_merr_int(int irq, void *dev_id, struct pt_regs *regs
        return IRQ_HANDLED;
 }
 
-static irqreturn_t scsi_dma_err_int(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t scsi_dma_err_int(int irq, void *dev_id)
 {
        /* empty */
 
        return IRQ_HANDLED;
 }
 
-static irqreturn_t scsi_dma_int(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t scsi_dma_int(int irq, void *dev_id)
 {
        u32 scsi_next_ptr;
 
index 879a2665767611dc6749df5111f6d3b6341c6ee1..fa738ec8692a24d2882901cf2d6c618a3eb05e6a 100644 (file)
@@ -155,7 +155,7 @@ static struct pci_driver dmx3191d_pci_driver = {
 
 static int __init dmx3191d_init(void)
 {
-       return pci_module_init(&dmx3191d_pci_driver);
+       return pci_register_driver(&dmx3191d_pci_driver);
 }
 
 static void __exit dmx3191d_exit(void)
index d84a281ad944a518987c28cebefddd9d11da7bdb..b3fa7ed71faf2ffdebef04f0bc3ff46a33340651 100644 (file)
  *     I2O Interface Objects
  */
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
-
-#define DECLARE_MUTEX(name) struct semaphore name=MUTEX
-
-typedef struct wait_queue *adpt_wait_queue_head_t;
-#define ADPT_DECLARE_WAIT_QUEUE_HEAD(wait) adpt_wait_queue_head_t wait = NULL
-typedef struct wait_queue adpt_wait_queue_t;
-#else
-
 #include <linux/wait.h>
 typedef wait_queue_head_t adpt_wait_queue_head_t;
 #define ADPT_DECLARE_WAIT_QUEUE_HEAD(wait) DECLARE_WAIT_QUEUE_HEAD(wait)
 typedef wait_queue_t adpt_wait_queue_t;
 
-#endif
 /*
  * message structures
  */
index 7b3bd34faf47e6857afcc8310e1cb696158b09c7..60b1b434eba75adac8707f014da4d2c95868ceaf 100644 (file)
@@ -1989,7 +1989,7 @@ static int adpt_ioctl(struct inode *inode, struct file *file, uint cmd,
 }
 
 
-static irqreturn_t adpt_isr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t adpt_isr(int irq, void *dev_id)
 {
        struct scsi_cmnd* cmd;
        adpt_hba* pHba = dev_id;
@@ -2212,7 +2212,7 @@ static s32 adpt_scsi_register(adpt_hba* pHba,struct scsi_host_template * sht)
         */
        host->io_port = 0;
        host->n_io_port = 0;
-                               /* see comments in hosts.h */
+                               /* see comments in scsi_host.h */
        host->max_id = 16;
        host->max_lun = 256;
        host->max_channel = pHba->top_scsi_channel + 1;
index 2ad2a89b5db4b2d15eaccd91a97d7219be4584fa..fd79068c586931b640eb2f1814b96eaa84bae76b 100644 (file)
@@ -44,7 +44,7 @@ static int adpt_device_reset(struct scsi_cmnd* cmd);
 
 
 /*
- * struct scsi_host_template (see hosts.h)
+ * struct scsi_host_template (see scsi/scsi_host.h)
  */
 
 #define DPT_DRIVER_NAME        "Adaptec I2O RAID"
@@ -263,7 +263,7 @@ struct sg_simple_element {
 static void adpt_i2o_sys_shutdown(void);
 static int adpt_init(void);
 static int adpt_i2o_build_sys_table(void);
-static irqreturn_t adpt_isr(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t adpt_isr(int irq, void *dev_id);
 #ifdef REBOOT_NOTIFIER
 static int adpt_reboot_event(struct notifier_block *n, ulong code, void *p);
 #endif
index 0d5713dfa204749bbe0b09f339893217918debe2..54756722dd5f74c000fde0fb1661eec92fe512c0 100644 (file)
@@ -82,7 +82,7 @@
 #include <linux/string.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include "scsi.h"
 #include <scsi/scsi_host.h>
 #include "dtc.h"
index a5ff43b1b2633ba130f2cbd6273210d9f2282001..2d38025861a50ee7aaf33e5f68ce346f1274fff5 100644 (file)
@@ -875,7 +875,7 @@ static unsigned long io_port[] = {
 /* But transfer orientation from the 16 bit data register is Little Endian */
 #define REG2H(x)   le16_to_cpu(x)
 
-static irqreturn_t do_interrupt_handler(int, void *, struct pt_regs *);
+static irqreturn_t do_interrupt_handler(int, void *);
 static void flush_dev(struct scsi_device *, unsigned long, struct hostdata *,
                      unsigned int);
 static int do_trace = 0;
@@ -2555,8 +2555,7 @@ static irqreturn_t ihdlr(int irq, struct Scsi_Host *shost)
        return IRQ_NONE;
 }
 
-static irqreturn_t do_interrupt_handler(int irq, void *shap,
-                                       struct pt_regs *regs)
+static irqreturn_t do_interrupt_handler(int irq, void *shap)
 {
        struct Scsi_Host *shost;
        unsigned int j;
index d312633db92beba41e1808e36e3b3cab2620147a..2dbb66d2f0a7398c791e3f51be5f256d06182cf9 100644 (file)
@@ -194,22 +194,21 @@ static void IncStat(struct scsi_pointer *SCp, unsigned int Increment)
        }
 }
 
-static irqreturn_t eata_pio_int_handler(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t eata_pio_int_handler(int irq, void *dev_id);
 
-static irqreturn_t do_eata_pio_int_handler(int irq, void *dev_id,
-                                               struct pt_regs *regs)
+static irqreturn_t do_eata_pio_int_handler(int irq, void *dev_id)
 {
        unsigned long flags;
        struct Scsi_Host *dev = dev_id;
        irqreturn_t ret;
 
        spin_lock_irqsave(dev->host_lock, flags);
-       ret = eata_pio_int_handler(irq, dev_id, regs);
+       ret = eata_pio_int_handler(irq, dev_id);
        spin_unlock_irqrestore(dev->host_lock, flags);
        return ret;
 }
 
-static irqreturn_t eata_pio_int_handler(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t eata_pio_int_handler(int irq, void *dev_id)
 {
        unsigned int eata_stat = 0xfffff;
        struct scsi_cmnd *cmd;
index 5630868c1b252f21f1a709890f1691e3be25d59b..2c2fe80bc42a98b76c3203cd40e69f91db7e44f4 100644 (file)
@@ -184,7 +184,7 @@ enum {
 };
 
 /* Forward declarations. */
-static irqreturn_t esp_intr(int irq, void *dev_id, struct pt_regs *pregs);
+static irqreturn_t esp_intr(int irq, void *dev_id);
 
 /* Debugging routines */
 struct esp_cmdstrings {
@@ -4282,7 +4282,7 @@ state_machine:
 }
 
 /* Service only the ESP described by dev_id. */
-static irqreturn_t esp_intr(int irq, void *dev_id, struct pt_regs *pregs)
+static irqreturn_t esp_intr(int irq, void *dev_id)
 {
        struct esp *esp = dev_id;
        unsigned long flags;
index dde3edf35c03667ed2762119dca8bcb9344327a7..ef8285c326e42f67547a390a397d01ab1d34ef21 100644 (file)
@@ -281,7 +281,7 @@ static struct fd_mcs_adapters_struct fd_mcs_adapters[] = {
 
 #define FD_BRDS ARRAY_SIZE(fd_mcs_adapters)
 
-static irqreturn_t fd_mcs_intr(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t fd_mcs_intr(int irq, void *dev_id);
 
 static unsigned long addresses[] = { 0xc8000, 0xca000, 0xce000, 0xde000 };
 static unsigned short ports[] = { 0x140, 0x150, 0x160, 0x170 };
@@ -617,7 +617,7 @@ static void my_done(struct Scsi_Host *shpnt, int error)
 }
 
 /* only my_done needs to be protected  */
-static irqreturn_t fd_mcs_intr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t fd_mcs_intr(int irq, void *dev_id)
 {
        unsigned long flags;
        int status;
index b0694dcce246e435c3936f3a7a0b37509f39effb..65e6e7b7ba07e5ab0ed0b1f5211ecb8e44b7198a 100644 (file)
 #include <linux/pci.h>
 #include <linux/stat.h>
 #include <linux/delay.h>
+#include <linux/io.h>
 #include <scsi/scsicam.h>
 
-#include <asm/io.h>
 #include <asm/system.h>
 
 #include <scsi/scsi.h>
@@ -403,8 +403,7 @@ static volatile int      in_interrupt_flag;
 static int               FIFO_Size = 0x2000; /* 8k FIFO for
                                                pre-tmc18c30 chips */
 
-static irqreturn_t       do_fdomain_16x0_intr( int irq, void *dev_id,
-                                           struct pt_regs * regs );
+static irqreturn_t       do_fdomain_16x0_intr( int irq, void *dev_id );
 /* Allow insmod parameters to be like LILO parameters.  For example:
    insmod fdomain fdomain=0x140,11 */
 static char * fdomain = NULL;
@@ -1094,8 +1093,7 @@ static void my_done(int error)
 #endif
 }
 
-static irqreturn_t do_fdomain_16x0_intr(int irq, void *dev_id,
-                                       struct pt_regs * regs )
+static irqreturn_t do_fdomain_16x0_intr(int irq, void *dev_id)
 {
    unsigned long flags;
    int      status;
@@ -1738,6 +1736,15 @@ struct scsi_host_template fdomain_driver_template = {
 };
 
 #ifndef PCMCIA
+
+static struct pci_device_id fdomain_pci_tbl[] __devinitdata = {
+       { PCI_VENDOR_ID_FD, PCI_DEVICE_ID_FD_36C70,
+         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+       { }
+};
+MODULE_DEVICE_TABLE(pci, fdomain_pci_tbl);
+
 #define driver_template fdomain_driver_template
 #include "scsi_module.c"
+
 #endif
index 0f3eb22b979a1b8345dcf75e6d3bd83c09580c6e..4bc14ad92e2264f0828043414890544756f2eb93 100644 (file)
 
 static void gdth_delay(int milliseconds);
 static void gdth_eval_mapping(ulong32 size, ulong32 *cyls, int *heads, int *secs);
-static irqreturn_t gdth_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t gdth_interrupt(int irq, void *dev_id);
 static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp);
 static int gdth_async_event(int hanum);
 static void gdth_log_event(gdth_evt_data *dvr, char *buffer);
@@ -1804,7 +1804,7 @@ static int gdth_wait(int hanum,int index,ulong32 time)
 
     gdth_from_wait = TRUE;
     do {
-        gdth_interrupt((int)ha->irq,ha,NULL);
+        gdth_interrupt((int)ha->irq,ha);
         if (wait_hanum==hanum && wait_index==index) {
             answer_found = TRUE;
             break;
@@ -3406,7 +3406,7 @@ static void gdth_clear_events(void)
 
 /* SCSI interface functions */
 
-static irqreturn_t gdth_interrupt(int irq,void *dev_id,struct pt_regs *regs)
+static irqreturn_t gdth_interrupt(int irq,void *dev_id)
 {
     gdth_ha_str *ha2 = (gdth_ha_str *)dev_id;
     register gdth_ha_str *ha;
index 47eae0299750db54b79d9428959c218f8e036b05..8c29eafd51c5f34fe57cf582e9eccc9f1e57b9c4 100644 (file)
@@ -936,18 +936,12 @@ typedef struct {
     gdth_binfo_str      binfo;                  /* controller info */
     gdth_evt_data       dvr;                    /* event structure */
     spinlock_t          smp_lock;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
     struct pci_dev      *pdev;
-#endif
     char                oem_name[8];
 #ifdef GDTH_DMA_STATISTICS
     ulong               dma32_cnt, dma64_cnt;   /* statistics: DMA buffer */
 #endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
     struct scsi_device         *sdev;
-#else
-    struct scsi_device         sdev;
-#endif
 } gdth_ha_str;
 
 /* structure for scsi_register(), SCSI bus != 0 */
@@ -1029,10 +1023,6 @@ typedef struct {
 
 /* function prototyping */
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
 int gdth_proc_info(struct Scsi_Host *, char *,char **,off_t,int,int);
-#else
-int gdth_proc_info(char *,char **,off_t,int,int,int);
-#endif
 
 #endif
index 18dbe5c27dac314aa612e01ee930011fad8cbba6..2f6c1137a6e5ffb5fa45c39728be80e954b0bb4f 100644 (file)
@@ -24,7 +24,7 @@
 #define DMA(ptr) ((gvp11_scsiregs *)((ptr)->base))
 #define HDATA(ptr) ((struct WD33C93_hostdata *)((ptr)->hostdata))
 
-static irqreturn_t gvp11_intr (int irq, void *_instance, struct pt_regs *fp)
+static irqreturn_t gvp11_intr (int irq, void *_instance)
 {
     unsigned long flags;
     unsigned int status;
diff --git a/drivers/scsi/hosts.h b/drivers/scsi/hosts.h
deleted file mode 100644 (file)
index c27264b..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-#warning "This file is obsolete, please use <scsi/scsi_host.h> instead"
-#include <scsi/scsi_host.h>
index 28bfb8f9f81d67833cf47cfa45893680ebc0f05a..bec83cbee59a6abe9cb36ca4d15bb0d384fb5f7b 100644 (file)
@@ -431,7 +431,7 @@ void hptiop_iop_request_callback(struct hptiop_hba *hba, u32 tag)
        writel(tag, &hba->iop->outbound_queue);
 }
 
-static irqreturn_t hptiop_intr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t hptiop_intr(int irq, void *dev_id)
 {
        struct hptiop_hba  *hba = dev_id;
        int  handled;
index 2be1dc5d852ad59c0bb864831503e9849497d5bc..0e57fb6964d5944c76a60e6f905fc46f38fa0272 100644 (file)
@@ -497,8 +497,7 @@ static int option_setup(char *);
 static int ldn_access_load(int, int);
 static int ldn_access_total_read_write(int);
 
-static irqreturn_t interrupt_handler(int irq, void *dev_id,
-                                       struct pt_regs *regs)
+static irqreturn_t interrupt_handler(int irq, void *dev_id)
 {
        int host_index, ihost_index;
        unsigned int intr_reg;
index 01b8ac641eb89d5460cb7383a24c865230e4c45e..227c0f2f4d74e6d580043c0adc77d22de7a1e7ca 100644 (file)
@@ -45,14 +45,11 @@ static unsigned int partition_number = -1;
  * ibmvscsi_handle_event: - Interrupt handler for crq events
  * @irq:       number of irq to handle, not used
  * @dev_instance: ibmvscsi_host_data of host that received interrupt
- * @regs:      pt_regs with registers
  *
  * Disables interrupts and schedules srp_task
  * Always returns IRQ_HANDLED
  */
-static irqreturn_t ibmvscsi_handle_event(int irq,
-                                        void *dev_instance,
-                                        struct pt_regs *regs)
+static irqreturn_t ibmvscsi_handle_event(int irq, void *dev_instance)
 {
        struct ibmvscsi_host_data *hostdata =
            (struct ibmvscsi_host_data *)dev_instance;
index 59a4097f1254127de677d042619b766d1199b0a3..312190a6938903ddb1e7206a8ce4af7eefa2444a 100644 (file)
@@ -829,7 +829,7 @@ static void transfer_bytes(Scsi_Cmnd * cmd, int data_in_dir)
  * but it _does_ need to be able to compile and run in an SMP kernel.)
  */
 
-static irqreturn_t in2000_intr(int irqnum, void *dev_id, struct pt_regs *ptregs)
+static irqreturn_t in2000_intr(int irqnum, void *dev_id)
 {
        struct Scsi_Host *instance = dev_id;
        struct IN2000_hostdata *hostdata;
index 9e10dac61cfd2857dbd3560320f737694e9cafe8..afed293dd7b99137bc4f57ee8819fc1248fbeec6 100644 (file)
 #define i91u_MAXQUEUE          2
 #define i91u_REVID "Initio INI-9X00U/UW SCSI device driver; Revision: 1.04a"
 
-#define INI_VENDOR_ID   0x1101 /* Initio's PCI vendor ID       */
-#define DMX_VENDOR_ID  0x134a  /* Domex's PCI vendor ID        */
 #define I950_DEVICE_ID 0x9500  /* Initio's inic-950 product ID   */
 #define I940_DEVICE_ID 0x9400  /* Initio's inic-940 product ID   */
 #define I935_DEVICE_ID 0x9401  /* Initio's inic-935 product ID   */
@@ -171,13 +169,16 @@ static int setup_debug = 0;
 
 static void i91uSCBPost(BYTE * pHcb, BYTE * pScb);
 
-static const PCI_ID i91u_pci_devices[] = {
-       { INI_VENDOR_ID, I950_DEVICE_ID },
-       { INI_VENDOR_ID, I940_DEVICE_ID },
-       { INI_VENDOR_ID, I935_DEVICE_ID },
-       { INI_VENDOR_ID, I920_DEVICE_ID },
-       { DMX_VENDOR_ID, I920_DEVICE_ID },
+/* PCI Devices supported by this driver */
+static struct pci_device_id i91u_pci_devices[] __devinitdata = {
+       { PCI_VENDOR_ID_INIT,  I950_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+       { PCI_VENDOR_ID_INIT,  I940_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+       { PCI_VENDOR_ID_INIT,  I935_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+       { PCI_VENDOR_ID_INIT,  I920_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+       { PCI_VENDOR_ID_DOMEX, I920_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+       { }
 };
+MODULE_DEVICE_TABLE(pci, i91u_pci_devices);
 
 #define DEBUG_INTERRUPT 0
 #define DEBUG_QUEUE     0
@@ -2748,7 +2749,7 @@ int tul_wait_done_disc(HCS * pCurHcb)
        return (tul_bad_seq(pCurHcb));
 }
 
-static irqreturn_t i91u_intr(int irqno, void *dev_id, struct pt_regs *regs)
+static irqreturn_t i91u_intr(int irqno, void *dev_id)
 {
        struct Scsi_Host *dev = dev_id;
        unsigned long flags;
@@ -2771,7 +2772,7 @@ static int tul_NewReturnNumberOfAdapters(void)
 
        for (i = 0; i < ARRAY_SIZE(i91u_pci_devices); i++)
        {
-               while ((pDev = pci_find_device(i91u_pci_devices[i].vendor_id, i91u_pci_devices[i].device_id, pDev)) != NULL) {
+               while ((pDev = pci_find_device(i91u_pci_devices[i].vendor, i91u_pci_devices[i].device, pDev)) != NULL) {
                        if (pci_enable_device(pDev))
                                continue;
                        pci_read_config_dword(pDev, 0x44, (u32 *) & dRegValue);
index 7ed4eef8347b2f719d132407886549a0563bd318..2dde821025f3a1d98cc676bc7a09db1d93c441c9 100644 (file)
@@ -70,6 +70,7 @@
 #include <linux/firmware.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
+#include <linux/libata.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/processor.h>
@@ -78,6 +79,7 @@
 #include <scsi/scsi_tcq.h>
 #include <scsi/scsi_eh.h>
 #include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_transport.h>
 #include "ipr.h"
 
 /*
@@ -199,6 +201,8 @@ struct ipr_error_table_t ipr_error_table[] = {
        "FFFA: Undefined device response recovered by the IOA"},
        {0x014A0000, 1, 1,
        "FFF6: Device bus error, message or command phase"},
+       {0x014A8000, 0, 1,
+       "FFFE: Task Management Function failed"},
        {0x015D0000, 0, 1,
        "FFF6: Failure prediction threshold exceeded"},
        {0x015D9200, 0, 1,
@@ -261,6 +265,8 @@ struct ipr_error_table_t ipr_error_table[] = {
        "Device bus status error"},
        {0x04448600, 0, 1,
        "8157: IOA error requiring IOA reset to recover"},
+       {0x04448700, 0, 0,
+       "ATA device status error"},
        {0x04490000, 0, 0,
        "Message reject received from the device"},
        {0x04449200, 0, 1,
@@ -273,6 +279,8 @@ struct ipr_error_table_t ipr_error_table[] = {
        "9082: IOA detected device error"},
        {0x044A0000, 1, 1,
        "3110: Device bus error, message or command phase"},
+       {0x044A8000, 1, 1,
+       "3110: SAS Command / Task Management Function failed"},
        {0x04670400, 0, 1,
        "9091: Incorrect hardware configuration change has been detected"},
        {0x04678000, 0, 1,
@@ -453,7 +461,8 @@ static void ipr_trc_hook(struct ipr_cmnd *ipr_cmd,
        trace_entry->time = jiffies;
        trace_entry->op_code = ipr_cmd->ioarcb.cmd_pkt.cdb[0];
        trace_entry->type = type;
-       trace_entry->cmd_index = ipr_cmd->cmd_index;
+       trace_entry->ata_op_code = ipr_cmd->ioarcb.add_data.u.regs.command;
+       trace_entry->cmd_index = ipr_cmd->cmd_index & 0xff;
        trace_entry->res_handle = ipr_cmd->ioarcb.res_handle;
        trace_entry->u.add_data = add_data;
 }
@@ -480,8 +489,10 @@ static void ipr_reinit_ipr_cmnd(struct ipr_cmnd *ipr_cmd)
        ioarcb->read_ioadl_len = 0;
        ioasa->ioasc = 0;
        ioasa->residual_data_len = 0;
+       ioasa->u.gata.status = 0;
 
        ipr_cmd->scsi_cmd = NULL;
+       ipr_cmd->qc = NULL;
        ipr_cmd->sense_buffer[0] = 0;
        ipr_cmd->dma_use_sg = 0;
 }
@@ -625,6 +636,28 @@ static int ipr_set_pcix_cmd_reg(struct ipr_ioa_cfg *ioa_cfg)
        return 0;
 }
 
+/**
+ * ipr_sata_eh_done - done function for aborted SATA commands
+ * @ipr_cmd:   ipr command struct
+ *
+ * This function is invoked for ops generated to SATA
+ * devices which are being aborted.
+ *
+ * Return value:
+ *     none
+ **/
+static void ipr_sata_eh_done(struct ipr_cmnd *ipr_cmd)
+{
+       struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
+       struct ata_queued_cmd *qc = ipr_cmd->qc;
+       struct ipr_sata_port *sata_port = qc->ap->private_data;
+
+       qc->err_mask |= AC_ERR_OTHER;
+       sata_port->ioasa.status |= ATA_BUSY;
+       list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q);
+       ata_qc_complete(qc);
+}
+
 /**
  * ipr_scsi_eh_done - mid-layer done function for aborted ops
  * @ipr_cmd:   ipr command struct
@@ -669,6 +702,8 @@ static void ipr_fail_all_ops(struct ipr_ioa_cfg *ioa_cfg)
 
                if (ipr_cmd->scsi_cmd)
                        ipr_cmd->done = ipr_scsi_eh_done;
+               else if (ipr_cmd->qc)
+                       ipr_cmd->done = ipr_sata_eh_done;
 
                ipr_trc_hook(ipr_cmd, IPR_TRACE_FINISH, IPR_IOASC_IOA_WAS_RESET);
                del_timer(&ipr_cmd->timer);
@@ -825,6 +860,7 @@ static void ipr_init_res_entry(struct ipr_resource_entry *res)
        res->del_from_ml = 0;
        res->resetting_device = 0;
        res->sdev = NULL;
+       res->sata_port = NULL;
 }
 
 /**
@@ -1316,7 +1352,7 @@ static u32 ipr_get_error(u32 ioasc)
        int i;
 
        for (i = 0; i < ARRAY_SIZE(ipr_error_table); i++)
-               if (ipr_error_table[i].ioasc == ioasc)
+               if (ipr_error_table[i].ioasc == (ioasc & IPR_IOASC_IOASC_MASK))
                        return i;
 
        return 0;
@@ -3051,6 +3087,17 @@ static int ipr_free_dump(struct ipr_ioa_cfg *ioa_cfg) { return 0; };
  **/
 static int ipr_change_queue_depth(struct scsi_device *sdev, int qdepth)
 {
+       struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)sdev->host->hostdata;
+       struct ipr_resource_entry *res;
+       unsigned long lock_flags = 0;
+
+       spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
+       res = (struct ipr_resource_entry *)sdev->hostdata;
+
+       if (res && ipr_is_gata(res) && qdepth > IPR_MAX_CMD_PER_ATA_LUN)
+               qdepth = IPR_MAX_CMD_PER_ATA_LUN;
+       spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
+
        scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), qdepth);
        return sdev->queue_depth;
 }
@@ -3165,6 +3212,122 @@ static int ipr_biosparam(struct scsi_device *sdev,
        return 0;
 }
 
+/**
+ * ipr_find_starget - Find target based on bus/target.
+ * @starget:   scsi target struct
+ *
+ * Return value:
+ *     resource entry pointer if found / NULL if not found
+ **/
+static struct ipr_resource_entry *ipr_find_starget(struct scsi_target *starget)
+{
+       struct Scsi_Host *shost = dev_to_shost(&starget->dev);
+       struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *) shost->hostdata;
+       struct ipr_resource_entry *res;
+
+       list_for_each_entry(res, &ioa_cfg->used_res_q, queue) {
+               if ((res->cfgte.res_addr.bus == starget->channel) &&
+                   (res->cfgte.res_addr.target == starget->id) &&
+                   (res->cfgte.res_addr.lun == 0)) {
+                       return res;
+               }
+       }
+
+       return NULL;
+}
+
+static struct ata_port_info sata_port_info;
+
+/**
+ * ipr_target_alloc - Prepare for commands to a SCSI target
+ * @starget:   scsi target struct
+ *
+ * If the device is a SATA device, this function allocates an
+ * ATA port with libata, else it does nothing.
+ *
+ * Return value:
+ *     0 on success / non-0 on failure
+ **/
+static int ipr_target_alloc(struct scsi_target *starget)
+{
+       struct Scsi_Host *shost = dev_to_shost(&starget->dev);
+       struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *) shost->hostdata;
+       struct ipr_sata_port *sata_port;
+       struct ata_port *ap;
+       struct ipr_resource_entry *res;
+       unsigned long lock_flags;
+
+       spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
+       res = ipr_find_starget(starget);
+       starget->hostdata = NULL;
+
+       if (res && ipr_is_gata(res)) {
+               spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
+               sata_port = kzalloc(sizeof(*sata_port), GFP_KERNEL);
+               if (!sata_port)
+                       return -ENOMEM;
+
+               ap = ata_sas_port_alloc(&ioa_cfg->ata_host, &sata_port_info, shost);
+               if (ap) {
+                       spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
+                       sata_port->ioa_cfg = ioa_cfg;
+                       sata_port->ap = ap;
+                       sata_port->res = res;
+
+                       res->sata_port = sata_port;
+                       ap->private_data = sata_port;
+                       starget->hostdata = sata_port;
+               } else {
+                       kfree(sata_port);
+                       return -ENOMEM;
+               }
+       }
+       spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
+
+       return 0;
+}
+
+/**
+ * ipr_target_destroy - Destroy a SCSI target
+ * @starget:   scsi target struct
+ *
+ * If the device was a SATA device, this function frees the libata
+ * ATA port, else it does nothing.
+ *
+ **/
+static void ipr_target_destroy(struct scsi_target *starget)
+{
+       struct ipr_sata_port *sata_port = starget->hostdata;
+
+       if (sata_port) {
+               starget->hostdata = NULL;
+               ata_sas_port_destroy(sata_port->ap);
+               kfree(sata_port);
+       }
+}
+
+/**
+ * ipr_find_sdev - Find device based on bus/target/lun.
+ * @sdev:      scsi device struct
+ *
+ * Return value:
+ *     resource entry pointer if found / NULL if not found
+ **/
+static struct ipr_resource_entry *ipr_find_sdev(struct scsi_device *sdev)
+{
+       struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *) sdev->host->hostdata;
+       struct ipr_resource_entry *res;
+
+       list_for_each_entry(res, &ioa_cfg->used_res_q, queue) {
+               if ((res->cfgte.res_addr.bus == sdev->channel) &&
+                   (res->cfgte.res_addr.target == sdev->id) &&
+                   (res->cfgte.res_addr.lun == sdev->lun))
+                       return res;
+       }
+
+       return NULL;
+}
+
 /**
  * ipr_slave_destroy - Unconfigure a SCSI device
  * @sdev:      scsi device struct
@@ -3183,8 +3346,11 @@ static void ipr_slave_destroy(struct scsi_device *sdev)
        spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
        res = (struct ipr_resource_entry *) sdev->hostdata;
        if (res) {
+               if (res->sata_port)
+                       ata_port_disable(res->sata_port->ap);
                sdev->hostdata = NULL;
                res->sdev = NULL;
+               res->sata_port = NULL;
        }
        spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
 }
@@ -3219,12 +3385,44 @@ static int ipr_slave_configure(struct scsi_device *sdev)
                }
                if (ipr_is_vset_device(res) || ipr_is_scsi_disk(res))
                        sdev->allow_restart = 1;
-               scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
+               if (ipr_is_gata(res) && res->sata_port) {
+                       scsi_adjust_queue_depth(sdev, 0, IPR_MAX_CMD_PER_ATA_LUN);
+                       ata_sas_slave_configure(sdev, res->sata_port->ap);
+               } else {
+                       scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
+               }
        }
        spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
        return 0;
 }
 
+/**
+ * ipr_ata_slave_alloc - Prepare for commands to a SATA device
+ * @sdev:      scsi device struct
+ *
+ * This function initializes an ATA port so that future commands
+ * sent through queuecommand will work.
+ *
+ * Return value:
+ *     0 on success
+ **/
+static int ipr_ata_slave_alloc(struct scsi_device *sdev)
+{
+       struct ipr_sata_port *sata_port = NULL;
+       int rc = -ENXIO;
+
+       ENTER;
+       if (sdev->sdev_target)
+               sata_port = sdev->sdev_target->hostdata;
+       if (sata_port)
+               rc = ata_sas_port_init(sata_port->ap);
+       if (rc)
+               ipr_slave_destroy(sdev);
+
+       LEAVE;
+       return rc;
+}
+
 /**
  * ipr_slave_alloc - Prepare for commands to a device.
  * @sdev:      scsi device struct
@@ -3248,18 +3446,18 @@ static int ipr_slave_alloc(struct scsi_device *sdev)
 
        spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
 
-       list_for_each_entry(res, &ioa_cfg->used_res_q, queue) {
-               if ((res->cfgte.res_addr.bus == sdev->channel) &&
-                   (res->cfgte.res_addr.target == sdev->id) &&
-                   (res->cfgte.res_addr.lun == sdev->lun)) {
-                       res->sdev = sdev;
-                       res->add_to_ml = 0;
-                       res->in_erp = 0;
-                       sdev->hostdata = res;
-                       if (!ipr_is_naca_model(res))
-                               res->needs_sync_complete = 1;
-                       rc = 0;
-                       break;
+       res = ipr_find_sdev(sdev);
+       if (res) {
+               res->sdev = sdev;
+               res->add_to_ml = 0;
+               res->in_erp = 0;
+               sdev->hostdata = res;
+               if (!ipr_is_naca_model(res))
+                       res->needs_sync_complete = 1;
+               rc = 0;
+               if (ipr_is_gata(res)) {
+                       spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
+                       return ipr_ata_slave_alloc(sdev);
                }
        }
 
@@ -3314,7 +3512,8 @@ static int ipr_eh_host_reset(struct scsi_cmnd * cmd)
  * This function issues a device reset to the affected device.
  * If the device is a SCSI device, a LUN reset will be sent
  * to the device first. If that does not work, a target reset
- * will be sent.
+ * will be sent. If the device is a SATA device, a PHY reset will
+ * be sent.
  *
  * Return value:
  *     0 on success / non-zero on failure
@@ -3325,25 +3524,78 @@ static int ipr_device_reset(struct ipr_ioa_cfg *ioa_cfg,
        struct ipr_cmnd *ipr_cmd;
        struct ipr_ioarcb *ioarcb;
        struct ipr_cmd_pkt *cmd_pkt;
+       struct ipr_ioarcb_ata_regs *regs;
        u32 ioasc;
 
        ENTER;
        ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg);
        ioarcb = &ipr_cmd->ioarcb;
        cmd_pkt = &ioarcb->cmd_pkt;
+       regs = &ioarcb->add_data.u.regs;
 
        ioarcb->res_handle = res->cfgte.res_handle;
        cmd_pkt->request_type = IPR_RQTYPE_IOACMD;
        cmd_pkt->cdb[0] = IPR_RESET_DEVICE;
+       if (ipr_is_gata(res)) {
+               cmd_pkt->cdb[2] = IPR_ATA_PHY_RESET;
+               ioarcb->add_cmd_parms_len = cpu_to_be32(sizeof(regs->flags));
+               regs->flags |= IPR_ATA_FLAG_STATUS_ON_GOOD_COMPLETION;
+       }
 
        ipr_send_blocking_cmd(ipr_cmd, ipr_timeout, IPR_DEVICE_RESET_TIMEOUT);
        ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc);
        list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q);
+       if (ipr_is_gata(res) && res->sata_port && ioasc != IPR_IOASC_IOA_WAS_RESET)
+               memcpy(&res->sata_port->ioasa, &ipr_cmd->ioasa.u.gata,
+                      sizeof(struct ipr_ioasa_gata));
 
        LEAVE;
        return (IPR_IOASC_SENSE_KEY(ioasc) ? -EIO : 0);
 }
 
+/**
+ * ipr_sata_reset - Reset the SATA port
+ * @ap:                SATA port to reset
+ * @classes:   class of the attached device
+ *
+ * This function issues a SATA phy reset to the affected ATA port.
+ *
+ * Return value:
+ *     0 on success / non-zero on failure
+ **/
+static int ipr_sata_reset(struct ata_port *ap, unsigned int *classes)
+{
+       struct ipr_sata_port *sata_port = ap->private_data;
+       struct ipr_ioa_cfg *ioa_cfg = sata_port->ioa_cfg;
+       struct ipr_resource_entry *res;
+       unsigned long lock_flags = 0;
+       int rc = -ENXIO;
+
+       ENTER;
+       spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
+       res = sata_port->res;
+       if (res) {
+               rc = ipr_device_reset(ioa_cfg, res);
+               switch(res->cfgte.proto) {
+               case IPR_PROTO_SATA:
+               case IPR_PROTO_SAS_STP:
+                       *classes = ATA_DEV_ATA;
+                       break;
+               case IPR_PROTO_SATA_ATAPI:
+               case IPR_PROTO_SAS_STP_ATAPI:
+                       *classes = ATA_DEV_ATAPI;
+                       break;
+               default:
+                       *classes = ATA_DEV_UNKNOWN;
+                       break;
+               };
+       }
+
+       spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
+       LEAVE;
+       return rc;
+}
+
 /**
  * ipr_eh_dev_reset - Reset the device
  * @scsi_cmd:  scsi command struct
@@ -3360,7 +3612,8 @@ static int __ipr_eh_dev_reset(struct scsi_cmnd * scsi_cmd)
        struct ipr_cmnd *ipr_cmd;
        struct ipr_ioa_cfg *ioa_cfg;
        struct ipr_resource_entry *res;
-       int rc;
+       struct ata_port *ap;
+       int rc = 0;
 
        ENTER;
        ioa_cfg = (struct ipr_ioa_cfg *) scsi_cmd->device->host->hostdata;
@@ -3388,7 +3641,14 @@ static int __ipr_eh_dev_reset(struct scsi_cmnd * scsi_cmd)
 
        res->resetting_device = 1;
        scmd_printk(KERN_ERR, scsi_cmd, "Resetting device\n");
-       rc = ipr_device_reset(ioa_cfg, res);
+
+       if (ipr_is_gata(res) && res->sata_port) {
+               ap = res->sata_port->ap;
+               spin_unlock_irq(scsi_cmd->device->host->host_lock);
+               ata_do_eh(ap, NULL, NULL, ipr_sata_reset, NULL);
+               spin_lock_irq(scsi_cmd->device->host->host_lock);
+       } else
+               rc = ipr_device_reset(ioa_cfg, res);
        res->resetting_device = 0;
 
        LEAVE;
@@ -3620,12 +3880,11 @@ static irqreturn_t ipr_handle_other_interrupt(struct ipr_ioa_cfg *ioa_cfg,
  * ipr_isr - Interrupt service routine
  * @irq:       irq number
  * @devp:      pointer to ioa config struct
- * @regs:      pt_regs struct
  *
  * Return value:
  *     IRQ_NONE / IRQ_HANDLED
  **/
-static irqreturn_t ipr_isr(int irq, void *devp, struct pt_regs *regs)
+static irqreturn_t ipr_isr(int irq, void *devp)
 {
        struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)devp;
        unsigned long lock_flags = 0;
@@ -4300,6 +4559,9 @@ static int ipr_queuecommand(struct scsi_cmnd *scsi_cmd,
                return 0;
        }
 
+       if (ipr_is_gata(res) && res->sata_port)
+               return ata_sas_queuecmd(scsi_cmd, done, res->sata_port->ap);
+
        ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg);
        ioarcb = &ipr_cmd->ioarcb;
        list_add_tail(&ipr_cmd->queue, &ioa_cfg->pending_q);
@@ -4344,6 +4606,26 @@ static int ipr_queuecommand(struct scsi_cmnd *scsi_cmd,
        return 0;
 }
 
+/**
+ * ipr_ioctl - IOCTL handler
+ * @sdev:      scsi device struct
+ * @cmd:       IOCTL cmd
+ * @arg:       IOCTL arg
+ *
+ * Return value:
+ *     0 on success / other on failure
+ **/
+int ipr_ioctl(struct scsi_device *sdev, int cmd, void __user *arg)
+{
+       struct ipr_resource_entry *res;
+
+       res = (struct ipr_resource_entry *)sdev->hostdata;
+       if (res && ipr_is_gata(res))
+               return ata_scsi_ioctl(sdev, cmd, arg);
+
+       return -EINVAL;
+}
+
 /**
  * ipr_info - Get information about the card/driver
  * @scsi_host: scsi host struct
@@ -4366,10 +4648,45 @@ static const char * ipr_ioa_info(struct Scsi_Host *host)
        return buffer;
 }
 
+/**
+ * ipr_scsi_timed_out - Handle scsi command timeout
+ * @scsi_cmd:  scsi command struct
+ *
+ * Return value:
+ *     EH_NOT_HANDLED
+ **/
+enum scsi_eh_timer_return ipr_scsi_timed_out(struct scsi_cmnd *scsi_cmd)
+{
+       struct ipr_ioa_cfg *ioa_cfg;
+       struct ipr_cmnd *ipr_cmd;
+       unsigned long flags;
+
+       ENTER;
+       spin_lock_irqsave(scsi_cmd->device->host->host_lock, flags);
+       ioa_cfg = (struct ipr_ioa_cfg *)scsi_cmd->device->host->hostdata;
+
+       list_for_each_entry(ipr_cmd, &ioa_cfg->pending_q, queue) {
+               if (ipr_cmd->qc && ipr_cmd->qc->scsicmd == scsi_cmd) {
+                       ipr_cmd->qc->err_mask |= AC_ERR_TIMEOUT;
+                       ipr_cmd->qc->flags |= ATA_QCFLAG_FAILED;
+                       break;
+               }
+       }
+
+       spin_unlock_irqrestore(scsi_cmd->device->host->host_lock, flags);
+       LEAVE;
+       return EH_NOT_HANDLED;
+}
+
+static struct scsi_transport_template ipr_transport_template = {
+       .eh_timed_out = ipr_scsi_timed_out
+};
+
 static struct scsi_host_template driver_template = {
        .module = THIS_MODULE,
        .name = "IPR",
        .info = ipr_ioa_info,
+       .ioctl = ipr_ioctl,
        .queuecommand = ipr_queuecommand,
        .eh_abort_handler = ipr_eh_abort,
        .eh_device_reset_handler = ipr_eh_dev_reset,
@@ -4377,6 +4694,8 @@ static struct scsi_host_template driver_template = {
        .slave_alloc = ipr_slave_alloc,
        .slave_configure = ipr_slave_configure,
        .slave_destroy = ipr_slave_destroy,
+       .target_alloc = ipr_target_alloc,
+       .target_destroy = ipr_target_destroy,
        .change_queue_depth = ipr_change_queue_depth,
        .change_queue_type = ipr_change_queue_type,
        .bios_param = ipr_biosparam,
@@ -4391,6 +4710,330 @@ static struct scsi_host_template driver_template = {
        .proc_name = IPR_NAME
 };
 
+/**
+ * ipr_ata_phy_reset - libata phy_reset handler
+ * @ap:                ata port to reset
+ *
+ **/
+static void ipr_ata_phy_reset(struct ata_port *ap)
+{
+       unsigned long flags;
+       struct ipr_sata_port *sata_port = ap->private_data;
+       struct ipr_resource_entry *res = sata_port->res;
+       struct ipr_ioa_cfg *ioa_cfg = sata_port->ioa_cfg;
+       int rc;
+
+       ENTER;
+       spin_lock_irqsave(ioa_cfg->host->host_lock, flags);
+       while(ioa_cfg->in_reset_reload) {
+               spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags);
+               wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload);
+               spin_lock_irqsave(ioa_cfg->host->host_lock, flags);
+       }
+
+       if (!ioa_cfg->allow_cmds)
+               goto out_unlock;
+
+       rc = ipr_device_reset(ioa_cfg, res);
+
+       if (rc) {
+               ap->ops->port_disable(ap);
+               goto out_unlock;
+       }
+
+       switch(res->cfgte.proto) {
+       case IPR_PROTO_SATA:
+       case IPR_PROTO_SAS_STP:
+               ap->device[0].class = ATA_DEV_ATA;
+               break;
+       case IPR_PROTO_SATA_ATAPI:
+       case IPR_PROTO_SAS_STP_ATAPI:
+               ap->device[0].class = ATA_DEV_ATAPI;
+               break;
+       default:
+               ap->device[0].class = ATA_DEV_UNKNOWN;
+               ap->ops->port_disable(ap);
+               break;
+       };
+
+out_unlock:
+       spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags);
+       LEAVE;
+}
+
+/**
+ * ipr_ata_post_internal - Cleanup after an internal command
+ * @qc:        ATA queued command
+ *
+ * Return value:
+ *     none
+ **/
+static void ipr_ata_post_internal(struct ata_queued_cmd *qc)
+{
+       struct ipr_sata_port *sata_port = qc->ap->private_data;
+       struct ipr_ioa_cfg *ioa_cfg = sata_port->ioa_cfg;
+       struct ipr_cmnd *ipr_cmd;
+       unsigned long flags;
+
+       spin_lock_irqsave(ioa_cfg->host->host_lock, flags);
+       list_for_each_entry(ipr_cmd, &ioa_cfg->pending_q, queue) {
+               if (ipr_cmd->qc == qc) {
+                       ipr_device_reset(ioa_cfg, sata_port->res);
+                       break;
+               }
+       }
+       spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags);
+}
+
+/**
+ * ipr_tf_read - Read the current ATA taskfile for the ATA port
+ * @ap:        ATA port
+ * @tf:        destination ATA taskfile
+ *
+ * Return value:
+ *     none
+ **/
+static void ipr_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
+{
+       struct ipr_sata_port *sata_port = ap->private_data;
+       struct ipr_ioasa_gata *g = &sata_port->ioasa;
+
+       tf->feature = g->error;
+       tf->nsect = g->nsect;
+       tf->lbal = g->lbal;
+       tf->lbam = g->lbam;
+       tf->lbah = g->lbah;
+       tf->device = g->device;
+       tf->command = g->status;
+       tf->hob_nsect = g->hob_nsect;
+       tf->hob_lbal = g->hob_lbal;
+       tf->hob_lbam = g->hob_lbam;
+       tf->hob_lbah = g->hob_lbah;
+       tf->ctl = g->alt_status;
+}
+
+/**
+ * ipr_copy_sata_tf - Copy a SATA taskfile to an IOA data structure
+ * @regs:      destination
+ * @tf:        source ATA taskfile
+ *
+ * Return value:
+ *     none
+ **/
+static void ipr_copy_sata_tf(struct ipr_ioarcb_ata_regs *regs,
+                            struct ata_taskfile *tf)
+{
+       regs->feature = tf->feature;
+       regs->nsect = tf->nsect;
+       regs->lbal = tf->lbal;
+       regs->lbam = tf->lbam;
+       regs->lbah = tf->lbah;
+       regs->device = tf->device;
+       regs->command = tf->command;
+       regs->hob_feature = tf->hob_feature;
+       regs->hob_nsect = tf->hob_nsect;
+       regs->hob_lbal = tf->hob_lbal;
+       regs->hob_lbam = tf->hob_lbam;
+       regs->hob_lbah = tf->hob_lbah;
+       regs->ctl = tf->ctl;
+}
+
+/**
+ * ipr_sata_done - done function for SATA commands
+ * @ipr_cmd:   ipr command struct
+ *
+ * This function is invoked by the interrupt handler for
+ * ops generated by the SCSI mid-layer to SATA devices
+ *
+ * Return value:
+ *     none
+ **/
+static void ipr_sata_done(struct ipr_cmnd *ipr_cmd)
+{
+       struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
+       struct ata_queued_cmd *qc = ipr_cmd->qc;
+       struct ipr_sata_port *sata_port = qc->ap->private_data;
+       struct ipr_resource_entry *res = sata_port->res;
+       u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc);
+
+       memcpy(&sata_port->ioasa, &ipr_cmd->ioasa.u.gata,
+              sizeof(struct ipr_ioasa_gata));
+       ipr_dump_ioasa(ioa_cfg, ipr_cmd, res);
+
+       if (be32_to_cpu(ipr_cmd->ioasa.ioasc_specific) & IPR_ATA_DEVICE_WAS_RESET)
+               scsi_report_device_reset(ioa_cfg->host, res->cfgte.res_addr.bus,
+                                        res->cfgte.res_addr.target);
+
+       if (IPR_IOASC_SENSE_KEY(ioasc) > RECOVERED_ERROR)
+               qc->err_mask |= __ac_err_mask(ipr_cmd->ioasa.u.gata.status);
+       else
+               qc->err_mask |= ac_err_mask(ipr_cmd->ioasa.u.gata.status);
+       list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q);
+       ata_qc_complete(qc);
+}
+
+/**
+ * ipr_build_ata_ioadl - Build an ATA scatter/gather list
+ * @ipr_cmd:   ipr command struct
+ * @qc:                ATA queued command
+ *
+ **/
+static void ipr_build_ata_ioadl(struct ipr_cmnd *ipr_cmd,
+                               struct ata_queued_cmd *qc)
+{
+       u32 ioadl_flags = 0;
+       struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
+       struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl;
+       int len = qc->nbytes + qc->pad_len;
+       struct scatterlist *sg;
+
+       if (len == 0)
+               return;
+
+       if (qc->dma_dir == DMA_TO_DEVICE) {
+               ioadl_flags = IPR_IOADL_FLAGS_WRITE;
+               ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ;
+               ioarcb->write_data_transfer_length = cpu_to_be32(len);
+               ioarcb->write_ioadl_len =
+                       cpu_to_be32(sizeof(struct ipr_ioadl_desc) * ipr_cmd->dma_use_sg);
+       } else if (qc->dma_dir == DMA_FROM_DEVICE) {
+               ioadl_flags = IPR_IOADL_FLAGS_READ;
+               ioarcb->read_data_transfer_length = cpu_to_be32(len);
+               ioarcb->read_ioadl_len =
+                       cpu_to_be32(sizeof(struct ipr_ioadl_desc) * ipr_cmd->dma_use_sg);
+       }
+
+       ata_for_each_sg(sg, qc) {
+               ioadl->flags_and_data_len = cpu_to_be32(ioadl_flags | sg_dma_len(sg));
+               ioadl->address = cpu_to_be32(sg_dma_address(sg));
+               if (ata_sg_is_last(sg, qc))
+                       ioadl->flags_and_data_len |= cpu_to_be32(IPR_IOADL_FLAGS_LAST);
+               else
+                       ioadl++;
+       }
+}
+
+/**
+ * ipr_qc_issue - Issue a SATA qc to a device
+ * @qc:        queued command
+ *
+ * Return value:
+ *     0 if success
+ **/
+static unsigned int ipr_qc_issue(struct ata_queued_cmd *qc)
+{
+       struct ata_port *ap = qc->ap;
+       struct ipr_sata_port *sata_port = ap->private_data;
+       struct ipr_resource_entry *res = sata_port->res;
+       struct ipr_ioa_cfg *ioa_cfg = sata_port->ioa_cfg;
+       struct ipr_cmnd *ipr_cmd;
+       struct ipr_ioarcb *ioarcb;
+       struct ipr_ioarcb_ata_regs *regs;
+
+       if (unlikely(!ioa_cfg->allow_cmds || ioa_cfg->ioa_is_dead))
+               return -EIO;
+
+       ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg);
+       ioarcb = &ipr_cmd->ioarcb;
+       regs = &ioarcb->add_data.u.regs;
+
+       memset(&ioarcb->add_data, 0, sizeof(ioarcb->add_data));
+       ioarcb->add_cmd_parms_len = cpu_to_be32(sizeof(ioarcb->add_data.u.regs));
+
+       list_add_tail(&ipr_cmd->queue, &ioa_cfg->pending_q);
+       ipr_cmd->qc = qc;
+       ipr_cmd->done = ipr_sata_done;
+       ipr_cmd->ioarcb.res_handle = res->cfgte.res_handle;
+       ioarcb->cmd_pkt.request_type = IPR_RQTYPE_ATA_PASSTHRU;
+       ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_NO_LINK_DESC;
+       ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_NO_ULEN_CHK;
+       ipr_cmd->dma_use_sg = qc->pad_len ? qc->n_elem + 1 : qc->n_elem;
+
+       ipr_build_ata_ioadl(ipr_cmd, qc);
+       regs->flags |= IPR_ATA_FLAG_STATUS_ON_GOOD_COMPLETION;
+       ipr_copy_sata_tf(regs, &qc->tf);
+       memcpy(ioarcb->cmd_pkt.cdb, qc->cdb, IPR_MAX_CDB_LEN);
+       ipr_trc_hook(ipr_cmd, IPR_TRACE_START, IPR_GET_PHYS_LOC(res->cfgte.res_addr));
+
+       switch (qc->tf.protocol) {
+       case ATA_PROT_NODATA:
+       case ATA_PROT_PIO:
+               break;
+
+       case ATA_PROT_DMA:
+               regs->flags |= IPR_ATA_FLAG_XFER_TYPE_DMA;
+               break;
+
+       case ATA_PROT_ATAPI:
+       case ATA_PROT_ATAPI_NODATA:
+               regs->flags |= IPR_ATA_FLAG_PACKET_CMD;
+               break;
+
+       case ATA_PROT_ATAPI_DMA:
+               regs->flags |= IPR_ATA_FLAG_PACKET_CMD;
+               regs->flags |= IPR_ATA_FLAG_XFER_TYPE_DMA;
+               break;
+
+       default:
+               WARN_ON(1);
+               return -1;
+       }
+
+       mb();
+       writel(be32_to_cpu(ioarcb->ioarcb_host_pci_addr),
+              ioa_cfg->regs.ioarrin_reg);
+       return 0;
+}
+
+/**
+ * ipr_ata_check_status - Return last ATA status
+ * @ap:        ATA port
+ *
+ * Return value:
+ *     ATA status
+ **/
+static u8 ipr_ata_check_status(struct ata_port *ap)
+{
+       struct ipr_sata_port *sata_port = ap->private_data;
+       return sata_port->ioasa.status;
+}
+
+/**
+ * ipr_ata_check_altstatus - Return last ATA altstatus
+ * @ap:        ATA port
+ *
+ * Return value:
+ *     Alt ATA status
+ **/
+static u8 ipr_ata_check_altstatus(struct ata_port *ap)
+{
+       struct ipr_sata_port *sata_port = ap->private_data;
+       return sata_port->ioasa.alt_status;
+}
+
+static struct ata_port_operations ipr_sata_ops = {
+       .port_disable = ata_port_disable,
+       .check_status = ipr_ata_check_status,
+       .check_altstatus = ipr_ata_check_altstatus,
+       .dev_select = ata_noop_dev_select,
+       .phy_reset = ipr_ata_phy_reset,
+       .post_internal_cmd = ipr_ata_post_internal,
+       .tf_read = ipr_tf_read,
+       .qc_prep = ata_noop_qc_prep,
+       .qc_issue = ipr_qc_issue,
+       .port_start = ata_sas_port_start,
+       .port_stop = ata_sas_port_stop
+};
+
+static struct ata_port_info sata_port_info = {
+       .flags  = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | ATA_FLAG_SATA_RESET |
+       ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA,
+       .pio_mask       = 0x10, /* pio4 */
+       .mwdma_mask = 0x07,
+       .udma_mask      = 0x7f, /* udma0-6 */
+       .port_ops       = &ipr_sata_ops
+};
+
 #ifdef CONFIG_PPC_PSERIES
 static const u16 ipr_blocked_processors[] = {
        PV_NORTHSTAR,
@@ -6352,7 +6995,7 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev,
        struct Scsi_Host *host;
        unsigned long ipr_regs_pci;
        void __iomem *ipr_regs;
-       u32 rc = PCIBIOS_SUCCESSFUL;
+       int rc = PCIBIOS_SUCCESSFUL;
        volatile u32 mask, uproc;
 
        ENTER;
@@ -6374,6 +7017,9 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev,
 
        ioa_cfg = (struct ipr_ioa_cfg *)host->hostdata;
        memset(ioa_cfg, 0, sizeof(struct ipr_ioa_cfg));
+       host->transportt = &ipr_transport_template;
+       ata_host_init(&ioa_cfg->ata_host, &pdev->dev,
+                     sata_port_info.flags, &ipr_sata_ops);
 
        ioa_cfg->chip_cfg = ipr_get_chip_cfg(dev_id);
 
@@ -6749,7 +7395,7 @@ static int __init ipr_init(void)
        ipr_info("IBM Power RAID SCSI Device Driver version: %s %s\n",
                 IPR_DRIVER_VERSION, IPR_DRIVER_DATE);
 
-       return pci_module_init(&ipr_driver);
+       return pci_register_driver(&ipr_driver);
 }
 
 /**
index 11eaff524327a60fafb0066058887152dc0843f0..6d035283af0843f00a54caa75fa7ee94d19c86f0 100644 (file)
@@ -28,6 +28,7 @@
 
 #include <linux/types.h>
 #include <linux/completion.h>
+#include <linux/libata.h>
 #include <linux/list.h>
 #include <linux/kref.h>
 #include <scsi/scsi.h>
@@ -36,8 +37,8 @@
 /*
  * Literals
  */
-#define IPR_DRIVER_VERSION "2.1.4"
-#define IPR_DRIVER_DATE "(August 2, 2006)"
+#define IPR_DRIVER_VERSION "2.2.0"
+#define IPR_DRIVER_DATE "(September 25, 2006)"
 
 /*
  * IPR_MAX_CMD_PER_LUN: This defines the maximum number of outstanding
@@ -849,6 +850,13 @@ struct ipr_bus_attributes {
        u32 max_xfer_rate;
 };
 
+struct ipr_sata_port {
+       struct ipr_ioa_cfg *ioa_cfg;
+       struct ata_port *ap;
+       struct ipr_resource_entry *res;
+       struct ipr_ioasa_gata ioasa;
+};
+
 struct ipr_resource_entry {
        struct ipr_config_table_entry cfgte;
        u8 needs_sync_complete:1;
@@ -858,6 +866,7 @@ struct ipr_resource_entry {
        u8 resetting_device:1;
 
        struct scsi_device *sdev;
+       struct ipr_sata_port *sata_port;
        struct list_head queue;
 };
 
@@ -928,10 +937,11 @@ struct ipr_trace_entry {
        u32 time;
 
        u8 op_code;
+       u8 ata_op_code;
        u8 type;
 #define IPR_TRACE_START                        0x00
 #define IPR_TRACE_FINISH               0xff
-       u16 cmd_index;
+       u8 cmd_index;
 
        __be32 res_handle;
        union {
@@ -1073,6 +1083,7 @@ struct ipr_ioa_cfg {
 
        struct ipr_cmnd *reset_cmd;
 
+       struct ata_host ata_host;
        char ipr_cmd_label[8];
 #define IPR_CMD_LABEL          "ipr_cmnd"
        struct ipr_cmnd *ipr_cmnd_list[IPR_NUM_CMD_BLKS];
@@ -1085,6 +1096,7 @@ struct ipr_cmnd {
        struct ipr_ioadl_desc ioadl[IPR_NUM_IOADL_ENTRIES];
        struct list_head queue;
        struct scsi_cmnd *scsi_cmd;
+       struct ata_queued_cmd *qc;
        struct completion completion;
        struct timer_list timer;
        void (*done) (struct ipr_cmnd *);
index 3c639286ec1edeb7496e5d11aa47422da0a6c4a0..f06a06ae6092fc3e0bc7cf05d00188596886cced 100644 (file)
 #include <linux/dma-mapping.h>
 
 #include <scsi/sg.h>
-
 #include "scsi.h"
-
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
-#include "hosts.h"
-#else
 #include <scsi/scsi_host.h>
-#endif
 
 #include "ips.h"
 
@@ -250,11 +244,11 @@ module_param(ips, charp, 0);
  */
 static int ips_detect(struct scsi_host_template *);
 static int ips_release(struct Scsi_Host *);
-static int ips_eh_abort(Scsi_Cmnd *);
-static int ips_eh_reset(Scsi_Cmnd *);
-static int ips_queue(Scsi_Cmnd *, void (*)(Scsi_Cmnd *));
+static int ips_eh_abort(struct scsi_cmnd *);
+static int ips_eh_reset(struct scsi_cmnd *);
+static int ips_queue(struct scsi_cmnd *, void (*)(struct scsi_cmnd *));
 static const char *ips_info(struct Scsi_Host *);
-static irqreturn_t do_ipsintr(int, void *, struct pt_regs *);
+static irqreturn_t do_ipsintr(int, void *);
 static int ips_hainit(ips_ha_t *);
 static int ips_map_status(ips_ha_t *, ips_scb_t *, ips_stat_t *);
 static int ips_send_wait(ips_ha_t *, ips_scb_t *, int, int);
@@ -325,24 +319,26 @@ static uint32_t ips_statupd_copperhead_memio(ips_ha_t *);
 static uint32_t ips_statupd_morpheus(ips_ha_t *);
 static ips_scb_t *ips_getscb(ips_ha_t *);
 static void ips_putq_scb_head(ips_scb_queue_t *, ips_scb_t *);
-static void ips_putq_wait_tail(ips_wait_queue_t *, Scsi_Cmnd *);
+static void ips_putq_wait_tail(ips_wait_queue_t *, struct scsi_cmnd *);
 static void ips_putq_copp_tail(ips_copp_queue_t *,
                                      ips_copp_wait_item_t *);
 static ips_scb_t *ips_removeq_scb_head(ips_scb_queue_t *);
 static ips_scb_t *ips_removeq_scb(ips_scb_queue_t *, ips_scb_t *);
-static Scsi_Cmnd *ips_removeq_wait_head(ips_wait_queue_t *);
-static Scsi_Cmnd *ips_removeq_wait(ips_wait_queue_t *, Scsi_Cmnd *);
+static struct scsi_cmnd *ips_removeq_wait_head(ips_wait_queue_t *);
+static struct scsi_cmnd *ips_removeq_wait(ips_wait_queue_t *,
+                                         struct scsi_cmnd *);
 static ips_copp_wait_item_t *ips_removeq_copp(ips_copp_queue_t *,
                                                     ips_copp_wait_item_t *);
 static ips_copp_wait_item_t *ips_removeq_copp_head(ips_copp_queue_t *);
 
-static int ips_is_passthru(Scsi_Cmnd *);
-static int ips_make_passthru(ips_ha_t *, Scsi_Cmnd *, ips_scb_t *, int);
+static int ips_is_passthru(struct scsi_cmnd *);
+static int ips_make_passthru(ips_ha_t *, struct scsi_cmnd *, ips_scb_t *, int);
 static int ips_usrcmd(ips_ha_t *, ips_passthru_t *, ips_scb_t *);
 static void ips_cleanup_passthru(ips_ha_t *, ips_scb_t *);
-static void ips_scmd_buf_write(Scsi_Cmnd * scmd, void *data,
+static void ips_scmd_buf_write(struct scsi_cmnd * scmd, void *data,
                               unsigned int count);
-static void ips_scmd_buf_read(Scsi_Cmnd * scmd, void *data, unsigned int count);
+static void ips_scmd_buf_read(struct scsi_cmnd * scmd, void *data,
+                             unsigned int count);
 
 static int ips_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int);
 static int ips_host_info(ips_ha_t *, char *, off_t, int);
@@ -812,8 +808,7 @@ ips_halt(struct notifier_block *nb, ulong event, void *buf)
 /*   Abort a command (using the new error code stuff)                       */
 /* Note: this routine is called under the io_request_lock                   */
 /****************************************************************************/
-int
-ips_eh_abort(Scsi_Cmnd * SC)
+int ips_eh_abort(struct scsi_cmnd *SC)
 {
        ips_ha_t *ha;
        ips_copp_wait_item_t *item;
@@ -871,8 +866,7 @@ ips_eh_abort(Scsi_Cmnd * SC)
 /* NOTE: this routine is called under the io_request_lock spinlock          */
 /*                                                                          */
 /****************************************************************************/
-static int
-__ips_eh_reset(Scsi_Cmnd * SC)
+static int __ips_eh_reset(struct scsi_cmnd *SC)
 {
        int ret;
        int i;
@@ -968,7 +962,7 @@ __ips_eh_reset(Scsi_Cmnd * SC)
        ret = (*ha->func.reset) (ha);
 
        if (!ret) {
-               Scsi_Cmnd *scsi_cmd;
+               struct scsi_cmnd *scsi_cmd;
 
                IPS_PRINTK(KERN_NOTICE, ha->pcidev,
                           "Controller reset failed - controller now offline.\n");
@@ -997,7 +991,7 @@ __ips_eh_reset(Scsi_Cmnd * SC)
        }
 
        if (!ips_clear_adapter(ha, IPS_INTR_IORL)) {
-               Scsi_Cmnd *scsi_cmd;
+               struct scsi_cmnd *scsi_cmd;
 
                IPS_PRINTK(KERN_NOTICE, ha->pcidev,
                           "Controller reset failed - controller now offline.\n");
@@ -1059,8 +1053,7 @@ __ips_eh_reset(Scsi_Cmnd * SC)
 
 }
 
-static int
-ips_eh_reset(Scsi_Cmnd * SC)
+static int ips_eh_reset(struct scsi_cmnd *SC)
 {
        int rc;
 
@@ -1083,8 +1076,7 @@ ips_eh_reset(Scsi_Cmnd * SC)
 /*    Linux obtains io_request_lock before calling this function            */
 /*                                                                          */
 /****************************************************************************/
-static int
-ips_queue(Scsi_Cmnd * SC, void (*done) (Scsi_Cmnd *))
+static int ips_queue(struct scsi_cmnd *SC, void (*done) (struct scsi_cmnd *))
 {
        ips_ha_t *ha;
        ips_passthru_t *pt;
@@ -1336,7 +1328,7 @@ ips_slave_configure(struct scsi_device * SDptr)
 /*                                                                          */
 /****************************************************************************/
 static irqreturn_t
-do_ipsintr(int irq, void *dev_id, struct pt_regs * regs)
+do_ipsintr(int irq, void *dev_id)
 {
        ips_ha_t *ha;
        unsigned long cpu_flags;
@@ -1602,8 +1594,7 @@ ips_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
 /*   Determine if the specified SCSI command is really a passthru command   */
 /*                                                                          */
 /****************************************************************************/
-static int
-ips_is_passthru(Scsi_Cmnd * SC)
+static int ips_is_passthru(struct scsi_cmnd *SC)
 {
        unsigned long flags;
 
@@ -1685,7 +1676,7 @@ ips_alloc_passthru_buffer(ips_ha_t * ha, int length)
 /*                                                                          */
 /****************************************************************************/
 static int
-ips_make_passthru(ips_ha_t * ha, Scsi_Cmnd * SC, ips_scb_t * scb, int intr)
+ips_make_passthru(ips_ha_t *ha, struct scsi_cmnd *SC, ips_scb_t *scb, int intr)
 {
        ips_passthru_t *pt;
        int length = 0;
@@ -2734,9 +2725,9 @@ static void
 ips_next(ips_ha_t * ha, int intr)
 {
        ips_scb_t *scb;
-       Scsi_Cmnd *SC;
-       Scsi_Cmnd *p;
-       Scsi_Cmnd *q;
+       struct scsi_cmnd *SC;
+       struct scsi_cmnd *p;
+       struct scsi_cmnd *q;
        ips_copp_wait_item_t *item;
        int ret;
        unsigned long cpu_flags = 0;
@@ -2847,7 +2838,7 @@ ips_next(ips_ha_t * ha, int intr)
                        dcdb_active[scmd_channel(p) -
                                    1] & (1 << scmd_id(p)))) {
                        ips_freescb(ha, scb);
-                       p = (Scsi_Cmnd *) p->host_scribble;
+                       p = (struct scsi_cmnd *) p->host_scribble;
                        continue;
                }
 
@@ -2962,7 +2953,7 @@ ips_next(ips_ha_t * ha, int intr)
                        break;
                }               /* end case */
 
-               p = (Scsi_Cmnd *) p->host_scribble;
+               p = (struct scsi_cmnd *) p->host_scribble;
 
        }                       /* end while */
 
@@ -3090,8 +3081,7 @@ ips_removeq_scb(ips_scb_queue_t * queue, ips_scb_t * item)
 /* ASSUMED to be called from within the HA lock                             */
 /*                                                                          */
 /****************************************************************************/
-static void
-ips_putq_wait_tail(ips_wait_queue_t * queue, Scsi_Cmnd * item)
+static void ips_putq_wait_tail(ips_wait_queue_t *queue, struct scsi_cmnd *item)
 {
        METHOD_TRACE("ips_putq_wait_tail", 1);
 
@@ -3122,10 +3112,9 @@ ips_putq_wait_tail(ips_wait_queue_t * queue, Scsi_Cmnd * item)
 /* ASSUMED to be called from within the HA lock                             */
 /*                                                                          */
 /****************************************************************************/
-static Scsi_Cmnd *
-ips_removeq_wait_head(ips_wait_queue_t * queue)
+static struct scsi_cmnd *ips_removeq_wait_head(ips_wait_queue_t *queue)
 {
-       Scsi_Cmnd *item;
+       struct scsi_cmnd *item;
 
        METHOD_TRACE("ips_removeq_wait_head", 1);
 
@@ -3135,7 +3124,7 @@ ips_removeq_wait_head(ips_wait_queue_t * queue)
                return (NULL);
        }
 
-       queue->head = (Scsi_Cmnd *) item->host_scribble;
+       queue->head = (struct scsi_cmnd *) item->host_scribble;
        item->host_scribble = NULL;
 
        if (queue->tail == item)
@@ -3157,10 +3146,10 @@ ips_removeq_wait_head(ips_wait_queue_t * queue)
 /* ASSUMED to be called from within the HA lock                             */
 /*                                                                          */
 /****************************************************************************/
-static Scsi_Cmnd *
-ips_removeq_wait(ips_wait_queue_t * queue, Scsi_Cmnd * item)
+static struct scsi_cmnd *ips_removeq_wait(ips_wait_queue_t *queue,
+                                         struct scsi_cmnd *item)
 {
-       Scsi_Cmnd *p;
+       struct scsi_cmnd *p;
 
        METHOD_TRACE("ips_removeq_wait", 1);
 
@@ -3173,8 +3162,8 @@ ips_removeq_wait(ips_wait_queue_t * queue, Scsi_Cmnd * item)
 
        p = queue->head;
 
-       while ((p) && (item != (Scsi_Cmnd *) p->host_scribble))
-               p = (Scsi_Cmnd *) p->host_scribble;
+       while ((p) && (item != (struct scsi_cmnd *) p->host_scribble))
+               p = (struct scsi_cmnd *) p->host_scribble;
 
        if (p) {
                /* found a match */
@@ -3659,11 +3648,10 @@ ips_send_wait(ips_ha_t * ha, ips_scb_t * scb, int timeout, int intr)
 /* Routine Name: ips_scmd_buf_write                                         */
 /*                                                                          */
 /* Routine Description:                                                     */
-/*  Write data to Scsi_Cmnd request_buffer at proper offsets                */
+/*  Write data to struct scsi_cmnd request_buffer at proper offsets        */
 /****************************************************************************/
 static void
-ips_scmd_buf_write(Scsi_Cmnd * scmd, void *data, unsigned
-                  int count)
+ips_scmd_buf_write(struct scsi_cmnd *scmd, void *data, unsigned int count)
 {
        if (scmd->use_sg) {
                int i;
@@ -3698,11 +3686,10 @@ ips_scmd_buf_write(Scsi_Cmnd * scmd, void *data, unsigned
 /* Routine Name: ips_scmd_buf_read                                          */
 /*                                                                          */
 /* Routine Description:                                                     */
-/*  Copy data from a Scsi_Cmnd to a new, linear buffer                      */
+/*  Copy data from a struct scsi_cmnd to a new, linear buffer              */
 /****************************************************************************/
 static void
-ips_scmd_buf_read(Scsi_Cmnd * scmd, void *data, unsigned
-                 int count)
+ips_scmd_buf_read(struct scsi_cmnd *scmd, void *data, unsigned int count)
 {
        if (scmd->use_sg) {
                int i;
@@ -7078,7 +7065,7 @@ ips_remove_device(struct pci_dev *pci_dev)
 static int __init
 ips_module_init(void)
 {
-       if (pci_module_init(&ips_pci_driver) < 0)
+       if (pci_register_driver(&ips_pci_driver) < 0)
                return -ENODEV;
        ips_driver_template.module = THIS_MODULE;
        ips_order_controllers();
index f46c382e5599aa022c87631a55f81dcdef17fb6c..34680f3dd4523e10662aa03f6605478c2a72b262 100644 (file)
@@ -6,7 +6,7 @@
 /*             David Jeffery, Adaptec, Inc.                                  */
 /*                                                                           */
 /* Copyright (C) 1999 IBM Corporation                                        */
-/* Copyright (C) 2003 Adaptec, Inc.                                          */ 
+/* Copyright (C) 2003 Adaptec, Inc.                                          */
 /*                                                                           */
 /* 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      */
@@ -1033,14 +1033,14 @@ typedef struct ips_scb_queue {
  * Wait queue_format
  */
 typedef struct ips_wait_queue {
-   Scsi_Cmnd      *head;
-   Scsi_Cmnd      *tail;
-   int             count;
+       struct scsi_cmnd *head;
+       struct scsi_cmnd *tail;
+       int count;
 } ips_wait_queue_t;
 
 typedef struct ips_copp_wait_item {
-   Scsi_Cmnd                 *scsi_cmd;
-   struct ips_copp_wait_item *next;
+       struct scsi_cmnd *scsi_cmd;
+       struct ips_copp_wait_item *next;
 } ips_copp_wait_item_t;
 
 typedef struct ips_copp_queue {
@@ -1149,7 +1149,7 @@ typedef struct ips_scb {
    uint32_t          flags;
    uint32_t          op_code;
    IPS_SG_LIST       sg_list;
-   Scsi_Cmnd        *scsi_cmd;
+   struct scsi_cmnd *scsi_cmd;
    struct ips_scb   *q_next;
    ips_scb_callback  callback;
    uint32_t          sg_busaddr;
@@ -1175,7 +1175,7 @@ typedef struct ips_scb_pt {
    uint32_t          flags;
    uint32_t          op_code;
    IPS_SG_LIST      *sg_list;
-   Scsi_Cmnd        *scsi_cmd;
+   struct scsi_cmnd *scsi_cmd;
    struct ips_scb   *q_next;
    ips_scb_callback  callback;
 } ips_scb_pt_t;
index 3d684496acde163a62759920e73b602e82a8e199..1251788ce2a36efa58b61c096c18b7350b8b5a66 100644 (file)
@@ -120,7 +120,7 @@ int lpfc_sli_queue_setup(struct lpfc_hba *);
 
 void lpfc_handle_eratt(struct lpfc_hba *);
 void lpfc_handle_latt(struct lpfc_hba *);
-irqreturn_t lpfc_intr_handler(int, void *, struct pt_regs *);
+irqreturn_t lpfc_intr_handler(int, void *);
 
 void lpfc_read_rev(struct lpfc_hba *, LPFC_MBOXQ_t *);
 void lpfc_config_ring(struct lpfc_hba *, int, LPFC_MBOXQ_t *);
index 4cdf3464267fd7decee3cfff83c9082d3050b8a8..a5723ad0a0992c9026e759c7a5899cac4f51ea96 100644 (file)
@@ -389,7 +389,8 @@ lpfc_config_port_post(struct lpfc_hba * phba)
 
        lpfc_init_link(phba, pmb, phba->cfg_topology, phba->cfg_link_speed);
        pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
-       if (lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT) != MBX_SUCCESS) {
+       rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT);
+       if (rc != MBX_SUCCESS) {
                lpfc_printf_log(phba,
                                KERN_ERR,
                                LOG_INIT,
@@ -406,7 +407,8 @@ lpfc_config_port_post(struct lpfc_hba * phba)
                readl(phba->HAregaddr); /* flush */
 
                phba->hba_state = LPFC_HBA_ERROR;
-               mempool_free(pmb, phba->mbox_mem_pool);
+               if (rc != MBX_BUSY)
+                       mempool_free(pmb, phba->mbox_mem_pool);
                return -EIO;
        }
        /* MBOX buffer will be freed in mbox compl */
index 70f4d5a1348e9f6aa39f0755d8b979f5a66a90da..24a1779b9af4366a761c19955a22b68fb6b4d368 100644 (file)
@@ -3119,7 +3119,7 @@ lpfc_sli_flush_mbox_queue(struct lpfc_hba * phba)
 }
 
 irqreturn_t
-lpfc_intr_handler(int irq, void *dev_id, struct pt_regs * regs)
+lpfc_intr_handler(int irq, void *dev_id)
 {
        struct lpfc_hba *phba;
        uint32_t ha_copy;
index 6422de72bf4334ae29b4c81b499087e24d259c0f..753d88306cd16765b03984b636f5b6142a9cf43f 100644 (file)
@@ -60,8 +60,8 @@ struct fsc_state {
 
 static void mac53c94_init(struct fsc_state *);
 static void mac53c94_start(struct fsc_state *);
-static void mac53c94_interrupt(int, void *, struct pt_regs *);
-static irqreturn_t do_mac53c94_interrupt(int, void *, struct pt_regs *);
+static void mac53c94_interrupt(int, void *);
+static irqreturn_t do_mac53c94_interrupt(int, void *);
 static void cmd_done(struct fsc_state *, int result);
 static void set_dma_cmds(struct fsc_state *, struct scsi_cmnd *);
 
@@ -177,18 +177,18 @@ static void mac53c94_start(struct fsc_state *state)
                set_dma_cmds(state, cmd);
 }
 
-static irqreturn_t do_mac53c94_interrupt(int irq, void *dev_id, struct pt_regs *ptregs)
+static irqreturn_t do_mac53c94_interrupt(int irq, void *dev_id)
 {
        unsigned long flags;
        struct Scsi_Host *dev = ((struct fsc_state *) dev_id)->current_req->device->host;
        
        spin_lock_irqsave(dev->host_lock, flags);
-       mac53c94_interrupt(irq, dev_id, ptregs);
+       mac53c94_interrupt(irq, dev_id);
        spin_unlock_irqrestore(dev->host_lock, flags);
        return IRQ_HANDLED;
 }
 
-static void mac53c94_interrupt(int irq, void *dev_id, struct pt_regs *ptregs)
+static void mac53c94_interrupt(int irq, void *dev_id)
 {
        struct fsc_state *state = (struct fsc_state *) dev_id;
        struct mac53c94_regs __iomem *regs = state->regs;
index 118206d68c6c9702030a3b66538abbcb30cc192d..3586fac9be9a03d2ff2cac73210348d8b75631ac 100644 (file)
@@ -44,7 +44,7 @@
 /* #define DEBUG_MAC_ESP */
 
 extern void esp_handle(struct NCR_ESP *esp);
-extern void mac_esp_intr(int irq, void *dev_id, struct pt_regs *pregs);
+extern void mac_esp_intr(int irq, void *dev_id);
 
 static int  dma_bytes_sent(struct NCR_ESP * esp, int fifo_count);
 static int  dma_can_transfer(struct NCR_ESP * esp, Scsi_Cmnd *sp);
@@ -88,7 +88,7 @@ static int setup_hostid = -1;
  * set up properly!
  */
 
-void mac_esp_intr(int irq, void *dev_id, struct pt_regs *pregs)
+void mac_esp_intr(int irq, void *dev_id)
 {
        struct NCR_ESP *esp = (struct NCR_ESP *) dev_id;
        int irq_p = 0;
@@ -122,24 +122,24 @@ void mac_esp_intr(int irq, void *dev_id, struct pt_regs *pregs)
  * acknowledge on the various machines
  */
 
-void scsi_esp_polled(int irq, void *dev_id, struct pt_regs *pregs)
+void scsi_esp_polled(int irq, void *dev_id)
 {
        if (esp_initialized == 0)
                return;
 
-       mac_esp_intr(irq, dev_id, pregs);
+       mac_esp_intr(irq, dev_id);
 }
 
-void fake_intr(int irq, void *dev_id, struct pt_regs *pregs)
+void fake_intr(int irq, void *dev_id)
 {
 #ifdef DEBUG_MAC_ESP
        printk("mac_esp: got irq\n");
 #endif
 
-       mac_esp_intr(irq, dev_id, pregs);
+       mac_esp_intr(irq, dev_id);
 }
 
-irqreturn_t fake_drq(int irq, void *dev_id, struct pt_regs *pregs)
+irqreturn_t fake_drq(int irq, void *dev_id)
 {
        printk("mac_esp: got drq\n");
        return IRQ_HANDLED;
index b87bef69ba0fc28b9261350cae27795df3b72f9c..86099fde1b2a6bc13866835757861e74d1b41d07 100644 (file)
@@ -1256,14 +1256,13 @@ bug_blocked_mailbox:
  * megaraid_isr_iomapped()
  * @irq - irq
  * @devp - pointer to our soft state
- * @regs - unused
  *
  * Interrupt service routine for io-mapped controllers.
  * Find out if our device is interrupting. If yes, acknowledge the interrupt
  * and service the completed commands.
  */
 static irqreturn_t
-megaraid_isr_iomapped(int irq, void *devp, struct pt_regs *regs)
+megaraid_isr_iomapped(int irq, void *devp)
 {
        adapter_t       *adapter = devp;
        unsigned long   flags;
@@ -1333,14 +1332,13 @@ megaraid_isr_iomapped(int irq, void *devp, struct pt_regs *regs)
  * megaraid_isr_memmapped()
  * @irq - irq
  * @devp - pointer to our soft state
- * @regs - unused
  *
  * Interrupt service routine for memory-mapped controllers.
  * Find out if our device is interrupting. If yes, acknowledge the interrupt
  * and service the completed commands.
  */
 static irqreturn_t
-megaraid_isr_memmapped(int irq, void *devp, struct pt_regs *regs)
+megaraid_isr_memmapped(int irq, void *devp)
 {
        adapter_t       *adapter = devp;
        unsigned long   flags;
index 4b75fe619d9cf44c7758d8636cfa47f453891bac..66529f11d23cca784e73c0cf1738d62c0f43e4c2 100644 (file)
@@ -991,8 +991,8 @@ static scb_t * mega_build_cmd(adapter_t *, Scsi_Cmnd *, int *);
 static void __mega_runpendq(adapter_t *);
 static int issue_scb_block(adapter_t *, u_char *);
 
-static irqreturn_t megaraid_isr_memmapped(int, void *, struct pt_regs *);
-static irqreturn_t megaraid_isr_iomapped(int, void *, struct pt_regs *);
+static irqreturn_t megaraid_isr_memmapped(int, void *);
+static irqreturn_t megaraid_isr_iomapped(int, void *);
 
 static void mega_free_scb(adapter_t *, scb_t *);
 
index 8cd0bd1d0f7c1b65393e8bf240e6ac8fdd28a37b..b50e27e660244ebf6e11a79adb8543557981742b 100644 (file)
@@ -175,7 +175,7 @@ typedef struct {
        uint8_t                 max_lun;
 
        uint32_t                unique_id;
-       uint8_t                 irq;
+       int                     irq;
        uint8_t                 ito;
        caddr_t                 ibuf;
        dma_addr_t              ibuf_dma_h;
index 266b3910846bb526d28cd9aa9073a3286f5a7b0d..7bac86dda88f9fdc053105ae149e9c9753125421 100644 (file)
@@ -120,7 +120,7 @@ static void megaraid_mbox_prepare_pthru(adapter_t *, scb_t *,
 static void megaraid_mbox_prepare_epthru(adapter_t *, scb_t *,
                struct scsi_cmnd *);
 
-static irqreturn_t megaraid_isr(int, void *, struct pt_regs *);
+static irqreturn_t megaraid_isr(int, void *);
 
 static void megaraid_mbox_dpc(unsigned long);
 
@@ -884,7 +884,7 @@ megaraid_init_mbox(adapter_t *adapter)
 
        if (((magic64 == HBA_SIGNATURE_64_BIT) &&
                ((adapter->pdev->subsystem_device !=
-               PCI_SUBSYS_ID_MEGARAID_SATA_150_6) ||
+               PCI_SUBSYS_ID_MEGARAID_SATA_150_6) &&
                (adapter->pdev->subsystem_device !=
                PCI_SUBSYS_ID_MEGARAID_SATA_150_4))) ||
                (adapter->pdev->vendor == PCI_VENDOR_ID_LSI_LOGIC &&
@@ -2231,7 +2231,7 @@ megaraid_ack_sequence(adapter_t *adapter)
  * Interrupt service routine for memory-mapped mailbox controllers.
  */
 static irqreturn_t
-megaraid_isr(int irq, void *devp, struct pt_regs *regs)
+megaraid_isr(int irq, void *devp)
 {
        adapter_t       *adapter = devp;
        int             handled;
index 4cab5b534b259acab51f1f1697e4f72c95f7dbc3..7e4262f2af96dd000940ae1000a1d6319f826ef8 100644 (file)
@@ -10,7 +10,7 @@
  *        2 of the License, or (at your option) any later version.
  *
  * FILE                : megaraid_sas.c
- * Version     : v00.00.03.01
+ * Version     : v00.00.03.05
  *
  * Authors:
  *     Sreenivas Bagalkote     <Sreenivas.Bagalkote@lsil.com>
@@ -71,6 +71,8 @@ static struct megasas_mgmt_info megasas_mgmt_info;
 static struct fasync_struct *megasas_async_queue;
 static DEFINE_MUTEX(megasas_async_queue_mutex);
 
+static u32 megasas_dbg_lvl;
+
 /**
  * megasas_get_cmd -   Get a command from the free pool
  * @instance:          Adapter soft state
@@ -134,6 +136,19 @@ megasas_enable_intr_xscale(struct megasas_register_set __iomem * regs)
        readl(&regs->outbound_intr_mask);
 }
 
+/**
+ * megasas_disable_intr_xscale -Disables interrupt
+ * @regs:                      MFI register set
+ */
+static inline void
+megasas_disable_intr_xscale(struct megasas_register_set __iomem * regs)
+{
+       u32 mask = 0x1f;
+       writel(mask, &regs->outbound_intr_mask);
+       /* Dummy readl to force pci flush */
+       readl(&regs->outbound_intr_mask);
+}
+
 /**
  * megasas_read_fw_status_reg_xscale - returns the current FW status value
  * @regs:                      MFI register set
@@ -185,6 +200,7 @@ static struct megasas_instance_template megasas_instance_template_xscale = {
 
        .fire_cmd = megasas_fire_cmd_xscale,
        .enable_intr = megasas_enable_intr_xscale,
+       .disable_intr = megasas_disable_intr_xscale,
        .clear_intr = megasas_clear_intr_xscale,
        .read_fw_status_reg = megasas_read_fw_status_reg_xscale,
 };
@@ -214,6 +230,19 @@ megasas_enable_intr_ppc(struct megasas_register_set __iomem * regs)
        readl(&regs->outbound_intr_mask);
 }
 
+/**
+ * megasas_disable_intr_ppc -  Disable interrupt
+ * @regs:                      MFI register set
+ */
+static inline void
+megasas_disable_intr_ppc(struct megasas_register_set __iomem * regs)
+{
+       u32 mask = 0xFFFFFFFF;
+       writel(mask, &regs->outbound_intr_mask);
+       /* Dummy readl to force pci flush */
+       readl(&regs->outbound_intr_mask);
+}
+
 /**
  * megasas_read_fw_status_reg_ppc - returns the current FW status value
  * @regs:                      MFI register set
@@ -265,6 +294,7 @@ static struct megasas_instance_template megasas_instance_template_ppc = {
        
        .fire_cmd = megasas_fire_cmd_ppc,
        .enable_intr = megasas_enable_intr_ppc,
+       .disable_intr = megasas_disable_intr_ppc,
        .clear_intr = megasas_clear_intr_ppc,
        .read_fw_status_reg = megasas_read_fw_status_reg_ppc,
 };
@@ -274,25 +304,6 @@ static struct megasas_instance_template megasas_instance_template_ppc = {
 *      specific to ppc (deviceid : 0x60) controllers
 */
 
-/**
- * megasas_disable_intr -      Disables interrupts
- * @regs:                      MFI register set
- */
-static inline void
-megasas_disable_intr(struct megasas_instance *instance)
-{
-       u32 mask = 0x1f; 
-       struct megasas_register_set __iomem *regs = instance->reg_set;
-
-       if(instance->pdev->device == PCI_DEVICE_ID_LSI_SAS1078R)
-               mask = 0xffffffff;
-
-       writel(mask, &regs->outbound_intr_mask);
-
-       /* Dummy readl to force pci flush */
-       readl(&regs->outbound_intr_mask);
-}
-
 /**
  * megasas_issue_polled -      Issues a polling command
  * @instance:                  Adapter soft state
@@ -336,6 +347,7 @@ megasas_issue_polled(struct megasas_instance *instance, struct megasas_cmd *cmd)
  * @cmd:                       Command to be issued
  *
  * This function waits on an event for the command to be returned from ISR.
+ * Max wait time is MEGASAS_INTERNAL_CMD_WAIT_TIME secs
  * Used to issue ioctl commands.
  */
 static int
@@ -346,7 +358,8 @@ megasas_issue_blocked_cmd(struct megasas_instance *instance,
 
        instance->instancet->fire_cmd(cmd->frame_phys_addr ,0,instance->reg_set);
 
-       wait_event(instance->int_cmd_wait_q, (cmd->cmd_status != ENODATA));
+       wait_event_timeout(instance->int_cmd_wait_q, (cmd->cmd_status != ENODATA),
+               MEGASAS_INTERNAL_CMD_WAIT_TIME*HZ);
 
        return 0;
 }
@@ -358,7 +371,8 @@ megasas_issue_blocked_cmd(struct megasas_instance *instance,
  *
  * MFI firmware can abort previously issued AEN comamnd (automatic event
  * notification). The megasas_issue_blocked_abort_cmd() issues such abort
- * cmd and blocks till it is completed.
+ * cmd and waits for return status.
+ * Max wait time is MEGASAS_INTERNAL_CMD_WAIT_TIME secs
  */
 static int
 megasas_issue_blocked_abort_cmd(struct megasas_instance *instance,
@@ -392,7 +406,8 @@ megasas_issue_blocked_abort_cmd(struct megasas_instance *instance,
        /*
         * Wait for this cmd to complete
         */
-       wait_event(instance->abort_cmd_wait_q, (cmd->cmd_status != 0xFF));
+       wait_event_timeout(instance->abort_cmd_wait_q, (cmd->cmd_status != 0xFF),
+               MEGASAS_INTERNAL_CMD_WAIT_TIME*HZ);
 
        megasas_return_cmd(instance, cmd);
        return 0;
@@ -495,6 +510,46 @@ megasas_make_sgl64(struct megasas_instance *instance, struct scsi_cmnd *scp,
        return sge_count;
 }
 
+ /**
+ * megasas_get_frame_count - Computes the number of frames
+ * @sge_count          : number of sg elements
+ *
+ * Returns the number of frames required for numnber of sge's (sge_count)
+ */
+
+u32 megasas_get_frame_count(u8 sge_count)
+{
+       int num_cnt;
+       int sge_bytes;
+       u32 sge_sz;
+       u32 frame_count=0;
+
+       sge_sz = (IS_DMA64) ? sizeof(struct megasas_sge64) :
+           sizeof(struct megasas_sge32);
+
+       /*
+       * Main frame can contain 2 SGEs for 64-bit SGLs and
+       * 3 SGEs for 32-bit SGLs
+       */
+       if (IS_DMA64)
+               num_cnt = sge_count - 2;
+       else
+               num_cnt = sge_count - 3;
+
+       if(num_cnt>0){
+               sge_bytes = sge_sz * num_cnt;
+
+               frame_count = (sge_bytes / MEGAMFI_FRAME_SIZE) +
+                   ((sge_bytes % MEGAMFI_FRAME_SIZE) ? 1 : 0) ;
+       }
+       /* Main frame */
+       frame_count +=1;
+
+       if (frame_count > 7)
+               frame_count = 8;
+       return frame_count;
+}
+
 /**
  * megasas_build_dcdb -        Prepares a direct cdb (DCDB) command
  * @instance:          Adapter soft state
@@ -508,8 +563,6 @@ static int
 megasas_build_dcdb(struct megasas_instance *instance, struct scsi_cmnd *scp,
                   struct megasas_cmd *cmd)
 {
-       u32 sge_sz;
-       int sge_bytes;
        u32 is_logical;
        u32 device_id;
        u16 flags = 0;
@@ -544,9 +597,6 @@ megasas_build_dcdb(struct megasas_instance *instance, struct scsi_cmnd *scp,
        /*
         * Construct SGL
         */
-       sge_sz = (IS_DMA64) ? sizeof(struct megasas_sge64) :
-           sizeof(struct megasas_sge32);
-
        if (IS_DMA64) {
                pthru->flags |= MFI_FRAME_SGL64;
                pthru->sge_count = megasas_make_sgl64(instance, scp,
@@ -562,17 +612,11 @@ megasas_build_dcdb(struct megasas_instance *instance, struct scsi_cmnd *scp,
        pthru->sense_buf_phys_addr_hi = 0;
        pthru->sense_buf_phys_addr_lo = cmd->sense_phys_addr;
 
-       sge_bytes = sge_sz * pthru->sge_count;
-
        /*
         * Compute the total number of frames this command consumes. FW uses
         * this number to pull sufficient number of frames from host memory.
         */
-       cmd->frame_count = (sge_bytes / MEGAMFI_FRAME_SIZE) +
-           ((sge_bytes % MEGAMFI_FRAME_SIZE) ? 1 : 0) + 1;
-
-       if (cmd->frame_count > 7)
-               cmd->frame_count = 8;
+       cmd->frame_count = megasas_get_frame_count(pthru->sge_count);
 
        return cmd->frame_count;
 }
@@ -589,8 +633,6 @@ static int
 megasas_build_ldio(struct megasas_instance *instance, struct scsi_cmnd *scp,
                   struct megasas_cmd *cmd)
 {
-       u32 sge_sz;
-       int sge_bytes;
        u32 device_id;
        u8 sc = scp->cmnd[0];
        u16 flags = 0;
@@ -605,7 +647,7 @@ megasas_build_ldio(struct megasas_instance *instance, struct scsi_cmnd *scp,
                flags = MFI_FRAME_DIR_READ;
 
        /*
-        * Preare the Logical IO frame: 2nd bit is zero for all read cmds
+        * Prepare the Logical IO frame: 2nd bit is zero for all read cmds
         */
        ldio->cmd = (sc & 0x02) ? MFI_CMD_LD_WRITE : MFI_CMD_LD_READ;
        ldio->cmd_status = 0x0;
@@ -674,9 +716,6 @@ megasas_build_ldio(struct megasas_instance *instance, struct scsi_cmnd *scp,
        /*
         * Construct SGL
         */
-       sge_sz = (IS_DMA64) ? sizeof(struct megasas_sge64) :
-           sizeof(struct megasas_sge32);
-
        if (IS_DMA64) {
                ldio->flags |= MFI_FRAME_SGL64;
                ldio->sge_count = megasas_make_sgl64(instance, scp, &ldio->sgl);
@@ -690,13 +729,11 @@ megasas_build_ldio(struct megasas_instance *instance, struct scsi_cmnd *scp,
        ldio->sense_buf_phys_addr_hi = 0;
        ldio->sense_buf_phys_addr_lo = cmd->sense_phys_addr;
 
-       sge_bytes = sge_sz * ldio->sge_count;
-
-       cmd->frame_count = (sge_bytes / MEGAMFI_FRAME_SIZE) +
-           ((sge_bytes % MEGAMFI_FRAME_SIZE) ? 1 : 0) + 1;
-
-       if (cmd->frame_count > 7)
-               cmd->frame_count = 8;
+       /*
+        * Compute the total number of frames this command consumes. FW uses
+        * this number to pull sufficient number of frames from host memory.
+        */
+       cmd->frame_count = megasas_get_frame_count(ldio->sge_count);
 
        return cmd->frame_count;
 }
@@ -727,6 +764,69 @@ static inline int megasas_is_ldio(struct scsi_cmnd *cmd)
        }
 }
 
+ /**
+ * megasas_dump_pending_frames -       Dumps the frame address of all pending cmds
+ *                                     in FW
+ * @instance:                          Adapter soft state
+ */
+static inline void
+megasas_dump_pending_frames(struct megasas_instance *instance)
+{
+       struct megasas_cmd *cmd;
+       int i,n;
+       union megasas_sgl *mfi_sgl;
+       struct megasas_io_frame *ldio;
+       struct megasas_pthru_frame *pthru;
+       u32 sgcount;
+       u32 max_cmd = instance->max_fw_cmds;
+
+       printk(KERN_ERR "\nmegasas[%d]: Dumping Frame Phys Address of all pending cmds in FW\n",instance->host->host_no);
+       printk(KERN_ERR "megasas[%d]: Total OS Pending cmds : %d\n",instance->host->host_no,atomic_read(&instance->fw_outstanding));
+       if (IS_DMA64)
+               printk(KERN_ERR "\nmegasas[%d]: 64 bit SGLs were sent to FW\n",instance->host->host_no);
+       else
+               printk(KERN_ERR "\nmegasas[%d]: 32 bit SGLs were sent to FW\n",instance->host->host_no);
+
+       printk(KERN_ERR "megasas[%d]: Pending OS cmds in FW : \n",instance->host->host_no);
+       for (i = 0; i < max_cmd; i++) {
+               cmd = instance->cmd_list[i];
+               if(!cmd->scmd)
+                       continue;
+               printk(KERN_ERR "megasas[%d]: Frame addr :0x%08lx : ",instance->host->host_no,(unsigned long)cmd->frame_phys_addr);
+               if (megasas_is_ldio(cmd->scmd)){
+                       ldio = (struct megasas_io_frame *)cmd->frame;
+                       mfi_sgl = &ldio->sgl;
+                       sgcount = ldio->sge_count;
+                       printk(KERN_ERR "megasas[%d]: frame count : 0x%x, Cmd : 0x%x, Tgt id : 0x%x, lba lo : 0x%x, lba_hi : 0x%x, sense_buf addr : 0x%x,sge count : 0x%x\n",instance->host->host_no, cmd->frame_count,ldio->cmd,ldio->target_id, ldio->start_lba_lo,ldio->start_lba_hi,ldio->sense_buf_phys_addr_lo,sgcount);
+               }
+               else {
+                       pthru = (struct megasas_pthru_frame *) cmd->frame;
+                       mfi_sgl = &pthru->sgl;
+                       sgcount = pthru->sge_count;
+                       printk(KERN_ERR "megasas[%d]: frame count : 0x%x, Cmd : 0x%x, Tgt id : 0x%x, lun : 0x%x, cdb_len : 0x%x, data xfer len : 0x%x, sense_buf addr : 0x%x,sge count : 0x%x\n",instance->host->host_no,cmd->frame_count,pthru->cmd,pthru->target_id,pthru->lun,pthru->cdb_len , pthru->data_xfer_len,pthru->sense_buf_phys_addr_lo,sgcount);
+               }
+       if(megasas_dbg_lvl & MEGASAS_DBG_LVL){
+               for (n = 0; n < sgcount; n++){
+                       if (IS_DMA64)
+                               printk(KERN_ERR "megasas: sgl len : 0x%x, sgl addr : 0x%08lx ",mfi_sgl->sge64[n].length , (unsigned long)mfi_sgl->sge64[n].phys_addr) ;
+                       else
+                               printk(KERN_ERR "megasas: sgl len : 0x%x, sgl addr : 0x%x ",mfi_sgl->sge32[n].length , mfi_sgl->sge32[n].phys_addr) ;
+                       }
+               }
+               printk(KERN_ERR "\n");
+       } /*for max_cmd*/
+       printk(KERN_ERR "\nmegasas[%d]: Pending Internal cmds in FW : \n",instance->host->host_no);
+       for (i = 0; i < max_cmd; i++) {
+
+               cmd = instance->cmd_list[i];
+
+               if(cmd->sync_cmd == 1){
+                       printk(KERN_ERR "0x%08lx : ", (unsigned long)cmd->frame_phys_addr);
+               }
+       }
+       printk(KERN_ERR "megasas[%d]: Dumping Done.\n\n",instance->host->host_no);
+}
+
 /**
  * megasas_queue_command -     Queue entry point
  * @scmd:                      SCSI command to be queued
@@ -832,6 +932,13 @@ static int megasas_wait_for_outstanding(struct megasas_instance *instance)
        }
 
        if (atomic_read(&instance->fw_outstanding)) {
+               /*
+               * Send signal to FW to stop processing any pending cmds.
+               * The controller will be taken offline by the OS now.
+               */
+               writel(MFI_STOP_ADP,
+                               &instance->reg_set->inbound_doorbell);
+               megasas_dump_pending_frames(instance);
                instance->hw_crit_error = 1;
                return FAILED;
        }
@@ -1168,11 +1275,6 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
 static int
 megasas_deplete_reply_queue(struct megasas_instance *instance, u8 alt_status)
 {
-       u32 producer;
-       u32 consumer;
-       u32 context;
-       struct megasas_cmd *cmd;
-
        /*
         * Check if it is our interrupt
         * Clear the interrupt 
@@ -1180,23 +1282,10 @@ megasas_deplete_reply_queue(struct megasas_instance *instance, u8 alt_status)
        if(instance->instancet->clear_intr(instance->reg_set))
                return IRQ_NONE;
 
-       producer = *instance->producer;
-       consumer = *instance->consumer;
-
-       while (consumer != producer) {
-               context = instance->reply_queue[consumer];
-
-               cmd = instance->cmd_list[context];
-
-               megasas_complete_cmd(instance, cmd, alt_status);
-
-               consumer++;
-               if (consumer == (instance->max_fw_cmds + 1)) {
-                       consumer = 0;
-               }
-       }
-
-       *instance->consumer = producer;
+        /*
+        * Schedule the tasklet for cmd completion
+        */
+       tasklet_schedule(&instance->isr_tasklet);
 
        return IRQ_HANDLED;
 }
@@ -1204,7 +1293,7 @@ megasas_deplete_reply_queue(struct megasas_instance *instance, u8 alt_status)
 /**
  * megasas_isr - isr entry point
  */
-static irqreturn_t megasas_isr(int irq, void *devp, struct pt_regs *regs)
+static irqreturn_t megasas_isr(int irq, void *devp)
 {
        return megasas_deplete_reply_queue((struct megasas_instance *)devp,
                                           DID_OK);
@@ -1229,10 +1318,12 @@ megasas_transition_to_ready(struct megasas_instance* instance)
 
        fw_state = instance->instancet->read_fw_status_reg(instance->reg_set) & MFI_STATE_MASK;
 
+       if (fw_state != MFI_STATE_READY)
+               printk(KERN_INFO "megasas: Waiting for FW to come to ready"
+                      " state\n");
+
        while (fw_state != MFI_STATE_READY) {
 
-               printk(KERN_INFO "megasas: Waiting for FW to come to ready"
-                      " state\n");
                switch (fw_state) {
 
                case MFI_STATE_FAULT:
@@ -1244,19 +1335,27 @@ megasas_transition_to_ready(struct megasas_instance* instance)
                        /*
                         * Set the CLR bit in inbound doorbell
                         */
-                       writel(MFI_INIT_CLEAR_HANDSHAKE,
+                       writel(MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG,
                                &instance->reg_set->inbound_doorbell);
 
                        max_wait = 2;
                        cur_state = MFI_STATE_WAIT_HANDSHAKE;
                        break;
 
+               case MFI_STATE_BOOT_MESSAGE_PENDING:
+                       writel(MFI_INIT_HOTPLUG,
+                               &instance->reg_set->inbound_doorbell);
+
+                       max_wait = 10;
+                       cur_state = MFI_STATE_BOOT_MESSAGE_PENDING;
+                       break;
+
                case MFI_STATE_OPERATIONAL:
                        /*
-                        * Bring it to READY state; assuming max wait 2 secs
+                        * Bring it to READY state; assuming max wait 10 secs
                         */
-                       megasas_disable_intr(instance);
-                       writel(MFI_INIT_READY, &instance->reg_set->inbound_doorbell);
+                       instance->instancet->disable_intr(instance->reg_set);
+                       writel(MFI_RESET_FLAGS, &instance->reg_set->inbound_doorbell);
 
                        max_wait = 10;
                        cur_state = MFI_STATE_OPERATIONAL;
@@ -1323,6 +1422,7 @@ megasas_transition_to_ready(struct megasas_instance* instance)
                        return -ENODEV;
                }
        };
+       printk(KERN_INFO "megasas: FW now in Ready state\n");
 
        return 0;
 }
@@ -1352,7 +1452,7 @@ static void megasas_teardown_frame_pool(struct megasas_instance *instance)
                                      cmd->frame_phys_addr);
 
                if (cmd->sense)
-                       pci_pool_free(instance->sense_dma_pool, cmd->frame,
+                       pci_pool_free(instance->sense_dma_pool, cmd->sense,
                                      cmd->sense_phys_addr);
        }
 
@@ -1627,6 +1727,39 @@ megasas_get_ctrl_info(struct megasas_instance *instance,
        return ret;
 }
 
+/**
+ * megasas_complete_cmd_dpc     -      Returns FW's controller structure
+ * @instance_addr:                     Address of adapter soft state
+ *
+ * Tasklet to complete cmds
+ */
+void megasas_complete_cmd_dpc(unsigned long instance_addr)
+{
+       u32 producer;
+       u32 consumer;
+       u32 context;
+       struct megasas_cmd *cmd;
+       struct megasas_instance *instance = (struct megasas_instance *)instance_addr;
+
+       producer = *instance->producer;
+       consumer = *instance->consumer;
+
+       while (consumer != producer) {
+               context = instance->reply_queue[consumer];
+
+               cmd = instance->cmd_list[context];
+
+               megasas_complete_cmd(instance, cmd, DID_OK);
+
+               consumer++;
+               if (consumer == (instance->max_fw_cmds + 1)) {
+                       consumer = 0;
+               }
+       }
+
+       *instance->consumer = producer;
+}
+
 /**
  * megasas_init_mfi -  Initializes the FW
  * @instance:          Adapter soft state
@@ -1690,6 +1823,12 @@ static int megasas_init_mfi(struct megasas_instance *instance)
         * Get various operational parameters from status register
         */
        instance->max_fw_cmds = instance->instancet->read_fw_status_reg(reg_set) & 0x00FFFF;
+       /*
+        * Reduce the max supported cmds by 1. This is to ensure that the
+        * reply_q_sz (1 more than the max cmd that driver may send)
+        * does not exceed max cmds that the FW can support
+        */
+       instance->max_fw_cmds = instance->max_fw_cmds-1;
        instance->max_num_sge = (instance->instancet->read_fw_status_reg(reg_set) & 0xFF0000) >> 
                                        0x10;
        /*
@@ -1754,7 +1893,7 @@ static int megasas_init_mfi(struct megasas_instance *instance)
        /*
         * disable the intr before firing the init frame to FW
         */
-       megasas_disable_intr(instance);
+       instance->instancet->disable_intr(instance->reg_set);
 
        /*
         * Issue the init frame in polled mode
@@ -1791,6 +1930,12 @@ static int megasas_init_mfi(struct megasas_instance *instance)
 
        kfree(ctrl_info);
 
+        /*
+       * Setup tasklet for cmd completion
+       */
+
+        tasklet_init(&instance->isr_tasklet, megasas_complete_cmd_dpc,
+                        (unsigned long)instance);
        return 0;
 
       fail_fw_init:
@@ -2182,6 +2327,8 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
        instance->unique_id = pdev->bus->number << 8 | pdev->devfn;
        instance->init_id = MEGASAS_DEFAULT_INIT_ID;
 
+       megasas_dbg_lvl = 0;
+
        /*
         * Initialize MFI Firmware
         */
@@ -2234,7 +2381,7 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
        megasas_mgmt_info.max_index--;
 
        pci_set_drvdata(pdev, NULL);
-       megasas_disable_intr(instance);
+       instance->instancet->disable_intr(instance->reg_set);
        free_irq(instance->pdev->irq, instance);
 
        megasas_release_mfi(instance);
@@ -2348,6 +2495,7 @@ static void megasas_detach_one(struct pci_dev *pdev)
        scsi_remove_host(instance->host);
        megasas_flush_cache(instance);
        megasas_shutdown_controller(instance);
+       tasklet_kill(&instance->isr_tasklet);
 
        /*
         * Take the instance off the instance array. Note that we will not
@@ -2364,7 +2512,7 @@ static void megasas_detach_one(struct pci_dev *pdev)
 
        pci_set_drvdata(instance->pdev, NULL);
 
-       megasas_disable_intr(instance);
+       instance->instancet->disable_intr(instance->reg_set);
 
        free_irq(instance->pdev->irq, instance);
 
@@ -2716,7 +2864,8 @@ static int megasas_mgmt_compat_ioctl_fw(struct file *file, unsigned long arg)
        int i;
        int error = 0;
 
-       clear_user(ioc, sizeof(*ioc));
+       if (clear_user(ioc, sizeof(*ioc)))
+               return -EFAULT;
 
        if (copy_in_user(&ioc->host_no, &cioc->host_no, sizeof(u16)) ||
            copy_in_user(&ioc->sgl_off, &cioc->sgl_off, sizeof(u32)) ||
@@ -2808,6 +2957,26 @@ megasas_sysfs_show_release_date(struct device_driver *dd, char *buf)
 static DRIVER_ATTR(release_date, S_IRUGO, megasas_sysfs_show_release_date,
                   NULL);
 
+static ssize_t
+megasas_sysfs_show_dbg_lvl(struct device_driver *dd, char *buf)
+{
+       return sprintf(buf,"%u",megasas_dbg_lvl);
+}
+
+static ssize_t
+megasas_sysfs_set_dbg_lvl(struct device_driver *dd, const char *buf, size_t count)
+{
+       int retval = count;
+       if(sscanf(buf,"%u",&megasas_dbg_lvl)<1){
+               printk(KERN_ERR "megasas: could not set dbg_lvl\n");
+               retval = -EINVAL;
+       }
+       return retval;
+}
+
+static DRIVER_ATTR(dbg_lvl, S_IRUGO|S_IWUGO, megasas_sysfs_show_dbg_lvl,
+                  megasas_sysfs_set_dbg_lvl);
+
 /**
  * megasas_init - Driver load entry point
  */
@@ -2842,14 +3011,33 @@ static int __init megasas_init(void)
 
        if (rval) {
                printk(KERN_DEBUG "megasas: PCI hotplug regisration failed \n");
-               unregister_chrdev(megasas_mgmt_majorno, "megaraid_sas_ioctl");
-       }
-
-       driver_create_file(&megasas_pci_driver.driver, &driver_attr_version);
-       driver_create_file(&megasas_pci_driver.driver,
-                          &driver_attr_release_date);
+               goto err_pcidrv;
+       }
+
+       rval = driver_create_file(&megasas_pci_driver.driver,
+                                 &driver_attr_version);
+       if (rval)
+               goto err_dcf_attr_ver;
+       rval = driver_create_file(&megasas_pci_driver.driver,
+                                 &driver_attr_release_date);
+       if (rval)
+               goto err_dcf_rel_date;
+       rval = driver_create_file(&megasas_pci_driver.driver,
+                                 &driver_attr_dbg_lvl);
+       if (rval)
+               goto err_dcf_dbg_lvl;
 
        return rval;
+err_dcf_dbg_lvl:
+       driver_remove_file(&megasas_pci_driver.driver,
+                          &driver_attr_release_date);
+err_dcf_rel_date:
+       driver_remove_file(&megasas_pci_driver.driver, &driver_attr_version);
+err_dcf_attr_ver:
+       pci_unregister_driver(&megasas_pci_driver);
+err_pcidrv:
+       unregister_chrdev(megasas_mgmt_majorno, "megaraid_sas_ioctl");
+       return rval;
 }
 
 /**
@@ -2857,9 +3045,11 @@ static int __init megasas_init(void)
  */
 static void __exit megasas_exit(void)
 {
-       driver_remove_file(&megasas_pci_driver.driver, &driver_attr_version);
+       driver_remove_file(&megasas_pci_driver.driver,
+                          &driver_attr_dbg_lvl);
        driver_remove_file(&megasas_pci_driver.driver,
                           &driver_attr_release_date);
+       driver_remove_file(&megasas_pci_driver.driver, &driver_attr_version);
 
        pci_unregister_driver(&megasas_pci_driver);
        unregister_chrdev(megasas_mgmt_majorno, "megaraid_sas_ioctl");
index 3531a14222a737780f8574eae0e010a71c6fd137..55eddcf8eb156896138d07e75ce79f362e65aadf 100644 (file)
@@ -18,9 +18,9 @@
 /**
  * MegaRAID SAS Driver meta data
  */
-#define MEGASAS_VERSION                                "00.00.03.01"
-#define MEGASAS_RELDATE                                "May 14, 2006"
-#define MEGASAS_EXT_VERSION                    "Sun May 14 22:49:52 PDT 2006"
+#define MEGASAS_VERSION                                "00.00.03.05"
+#define MEGASAS_RELDATE                                "Oct 02, 2006"
+#define MEGASAS_EXT_VERSION                    "Mon Oct 02 11:21:32 PDT 2006"
 
 /*
  * Device IDs
@@ -50,6 +50,7 @@
 #define MFI_STATE_WAIT_HANDSHAKE               0x60000000
 #define MFI_STATE_FW_INIT_2                    0x70000000
 #define MFI_STATE_DEVICE_SCAN                  0x80000000
+#define MFI_STATE_BOOT_MESSAGE_PENDING         0x90000000
 #define MFI_STATE_FLUSH_CACHE                  0xA0000000
 #define MFI_STATE_READY                                0xB0000000
 #define MFI_STATE_OPERATIONAL                  0xC0000000
  * READY       : Move from OPERATIONAL to READY state; discard queue info
  * MFIMODE     : Discard (possible) low MFA posted in 64-bit mode (??)
  * CLR_HANDSHAKE: FW is waiting for HANDSHAKE from BIOS or Driver
+ * HOTPLUG     : Resume from Hotplug
+ * MFI_STOP_ADP        : Send signal to FW to stop processing
  */
-#define MFI_INIT_ABORT                         0x00000000
+#define MFI_INIT_ABORT                         0x00000001
 #define MFI_INIT_READY                         0x00000002
 #define MFI_INIT_MFIMODE                       0x00000004
 #define MFI_INIT_CLEAR_HANDSHAKE               0x00000008
-#define MFI_RESET_FLAGS                                MFI_INIT_READY|MFI_INIT_MFIMODE
+#define MFI_INIT_HOTPLUG                       0x00000010
+#define MFI_STOP_ADP                           0x00000020
+#define MFI_RESET_FLAGS                                MFI_INIT_READY| \
+                                               MFI_INIT_MFIMODE| \
+                                               MFI_INIT_ABORT
 
 /**
  * MFI frame flags
@@ -530,6 +537,8 @@ struct megasas_ctrl_info {
 #define MEGASAS_MAX_LUN                                8
 #define MEGASAS_MAX_LD                         64
 
+#define MEGASAS_DBG_LVL                                1
+
 /*
  * When SCSI mid-layer calls driver's reset routine, driver waits for
  * MEGASAS_RESET_WAIT_TIME seconds for all outstanding IO to complete. Note
@@ -538,6 +547,7 @@ struct megasas_ctrl_info {
  * every MEGASAS_RESET_NOTICE_INTERVAL seconds
  */
 #define MEGASAS_RESET_WAIT_TIME                        180
+#define MEGASAS_INTERNAL_CMD_WAIT_TIME         180
 #define        MEGASAS_RESET_NOTICE_INTERVAL           5
 
 #define MEGASAS_IOCTL_CMD                      0
@@ -1042,6 +1052,7 @@ struct megasas_evt_detail {
        void (*fire_cmd)(dma_addr_t ,u32 ,struct megasas_register_set __iomem *);
 
        void (*enable_intr)(struct megasas_register_set __iomem *) ;
+       void (*disable_intr)(struct megasas_register_set __iomem *);
 
        int (*clear_intr)(struct megasas_register_set __iomem *);
 
@@ -1092,6 +1103,7 @@ struct megasas_instance {
        u32 hw_crit_error;
 
        struct megasas_instance_template *instancet;
+       struct tasklet_struct isr_tasklet;
 };
 
 #define MEGASAS_IS_LOGICAL(scp)                                                \
index 683fc7ae4b8ffb1f52823779d81b852db3fb2274..1fd3c7590d316bf93207a475dc0e32f0d009c3e2 100644 (file)
@@ -185,7 +185,7 @@ struct mesh_state {
  * Driver is too messy, we need a few prototypes...
  */
 static void mesh_done(struct mesh_state *ms, int start_next);
-static void mesh_interrupt(int irq, void *dev_id, struct pt_regs *ptregs);
+static void mesh_interrupt(int irq, void *dev_id);
 static void cmd_complete(struct mesh_state *ms);
 static void set_dma_cmds(struct mesh_state *ms, struct scsi_cmnd *cmd);
 static void halt_dma(struct mesh_state *ms);
@@ -466,7 +466,7 @@ static void mesh_start_cmd(struct mesh_state *ms, struct scsi_cmnd *cmd)
                                dlog(ms, "intr b4 arb, intr/exc/err/fc=%.8x",
                                     MKWORD(mr->interrupt, mr->exception,
                                            mr->error, mr->fifo_count));
-                               mesh_interrupt(0, (void *)ms, NULL);
+                               mesh_interrupt(0, (void *)ms);
                                if (ms->phase != arbitrating)
                                        return;
                        }
@@ -504,7 +504,7 @@ static void mesh_start_cmd(struct mesh_state *ms, struct scsi_cmnd *cmd)
                dlog(ms, "intr after disresel, intr/exc/err/fc=%.8x",
                     MKWORD(mr->interrupt, mr->exception,
                            mr->error, mr->fifo_count));
-               mesh_interrupt(0, (void *)ms, NULL);
+               mesh_interrupt(0, (void *)ms);
                if (ms->phase != arbitrating)
                        return;
                dlog(ms, "after intr after disresel, intr/exc/err/fc=%.8x",
@@ -1015,13 +1015,13 @@ static void handle_reset(struct mesh_state *ms)
        out_8(&mr->sequence, SEQ_ENBRESEL);
 }
 
-static irqreturn_t do_mesh_interrupt(int irq, void *dev_id, struct pt_regs *ptregs)
+static irqreturn_t do_mesh_interrupt(int irq, void *dev_id)
 {
        unsigned long flags;
        struct Scsi_Host *dev = ((struct mesh_state *)dev_id)->host;
        
        spin_lock_irqsave(dev->host_lock, flags);
-       mesh_interrupt(irq, dev_id, ptregs);
+       mesh_interrupt(irq, dev_id);
        spin_unlock_irqrestore(dev->host_lock, flags);
        return IRQ_HANDLED;
 }
@@ -1661,7 +1661,7 @@ static int mesh_queue(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
  * handler (do_mesh_interrupt) or by other functions in
  * exceptional circumstances
  */
-static void mesh_interrupt(int irq, void *dev_id, struct pt_regs *ptregs)
+static void mesh_interrupt(int irq, void *dev_id)
 {
        struct mesh_state *ms = (struct mesh_state *) dev_id;
        volatile struct mesh_regs __iomem *mr = ms->mesh;
index 9b991b746d1ef676e2597ff8ec515e996093f3fa..1ddd7a11a9588a22330abe898e0045af4a0862d6 100644 (file)
@@ -20,7 +20,7 @@
 
 static struct Scsi_Host *mvme147_host = NULL;
 
-static irqreturn_t mvme147_intr (int irq, void *dummy, struct pt_regs *fp)
+static irqreturn_t mvme147_intr (int irq, void *dummy)
 {
     if (irq == MVME147_IRQ_SCSI_PORT)
        wd33c93_intr (mvme147_host);
index c7a12533fb2c454b644b060075be7fa011f43a18..73e33b37a3f8636ad0487c69f15391ec3f444007 100644 (file)
@@ -9,7 +9,7 @@ int NCR53c7xx_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 int NCR53c7xx_abort(Scsi_Cmnd *);
 int NCR53c7x0_release (struct Scsi_Host *);
 int NCR53c7xx_reset(Scsi_Cmnd *, unsigned int);
-void NCR53c7x0_intr(int irq, void *dev_id, struct pt_regs * regs);
+void NCR53c7x0_intr(int irq, void *dev_id);
 
 #ifndef CMD_PER_LUN
 #define CMD_PER_LUN 3
index b28712df0b77096180d03fd378b9e6c84b2adf6d..6cc2bc2f62be8f1c22a41183c4f532a865bad23f 100644 (file)
@@ -8111,7 +8111,7 @@ printk("ncr53c8xx : command successfully queued\n");
      return sts;
 }
 
-irqreturn_t ncr53c8xx_intr(int irq, void *dev_id, struct pt_regs * regs)
+irqreturn_t ncr53c8xx_intr(int irq, void *dev_id)
 {
      unsigned long flags;
      struct Scsi_Host *shost = (struct Scsi_Host *)dev_id;
index 78818b6684f83b35105502726b5d4f8befb25e2c..cb8b7701431ef855d8b7ba656b761412306385ae 100644 (file)
@@ -1322,7 +1322,7 @@ struct ncr_device {
 
 extern struct Scsi_Host *ncr_attach(struct scsi_host_template *tpnt, int unit, struct ncr_device *device);
 extern int ncr53c8xx_release(struct Scsi_Host *host);
-irqreturn_t ncr53c8xx_intr(int irq, void *dev_id, struct pt_regs * regs);
+irqreturn_t ncr53c8xx_intr(int irq, void *dev_id);
 extern int ncr53c8xx_init(void);
 extern void ncr53c8xx_exit(void);
 
index bfb4f49e125d28b82a5dea1472641c1d43e45339..7c13f6f4a4c653d77596ed9cc005820041068180 100644 (file)
@@ -256,7 +256,7 @@ static void nsp32_sack_negate (nsp32_hw_data *);
 static void nsp32_do_bus_reset(nsp32_hw_data *);
 
 /* hardware interrupt handler */
-static irqreturn_t do_nsp32_isr(int, void *, struct pt_regs *);
+static irqreturn_t do_nsp32_isr(int, void *);
 
 /* initialize hardware */
 static int  nsp32hw_init(nsp32_hw_data *);
@@ -1201,7 +1201,7 @@ static int nsp32hw_init(nsp32_hw_data *data)
 
 
 /* interrupt routine */
-static irqreturn_t do_nsp32_isr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t do_nsp32_isr(int irq, void *dev_id)
 {
        nsp32_hw_data *data = dev_id;
        unsigned int base = data->BaseAddress;
@@ -3581,7 +3581,7 @@ static struct pci_driver nsp32_driver = {
  */
 static int __init init_nsp32(void) {
        nsp32_msg(KERN_INFO, "loading...");
-       return pci_module_init(&nsp32_driver);
+       return pci_register_driver(&nsp32_driver);
 }
 
 static void __exit exit_nsp32(void) {
index 5addf9fb1e156b774edf4ee41d72016776333714..a976e8193d163d1ff983fb405d16d7a981a8e8c1 100644 (file)
@@ -619,47 +619,5 @@ typedef struct _nsp32_hw_data {
 #define REQSACK_TIMEOUT_TIME   10000   /* max wait time for REQ/SACK assertion
                                           or negation, 10000us == 10ms */
 
-/**************************************************************************
- * Compatibility functions
- */
-
-/* for Kernel 2.4 */
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
-# define scsi_register_host(template)  scsi_register_module(MODULE_SCSI_HA, template)
-# define scsi_unregister_host(template) scsi_unregister_module(MODULE_SCSI_HA, template)
-# define scsi_host_put(host)            scsi_unregister(host)
-# define pci_name(pci_dev)              ((pci_dev)->slot_name)
-
-typedef void irqreturn_t;
-# define IRQ_NONE      /* */
-# define IRQ_HANDLED   /* */
-# define IRQ_RETVAL(x) /* */
-
-/* This is ad-hoc version of scsi_host_get_next() */
-static inline struct Scsi_Host *scsi_host_get_next(struct Scsi_Host *host)
-{
-       if (host == NULL) {
-               return scsi_hostlist;
-       } else {
-               return host->next;
-       }
-}
-
-/* This is ad-hoc version of scsi_host_hn_get() */
-static inline struct Scsi_Host *scsi_host_hn_get(unsigned short hostno)
-{
-       struct Scsi_Host *host;
-
-       for (host = scsi_host_get_next(NULL); host != NULL;
-            host = scsi_host_get_next(host)) {
-               if (host->host_no == hostno) {
-                       break;
-               }
-       }
-
-       return host;
-}
-#endif
-
 #endif /* _NSP32_H */
 /* end */
index 4a2fed350d4e21620b134d2afac1244cb87670e0..824fe080d1dc2b9d0b2e1a35b2e1a64464e615b9 100644 (file)
@@ -4843,8 +4843,7 @@ static int os_scsi_tape_close(struct inode * inode, struct file * filp)
 static int osst_ioctl(struct inode * inode,struct file * file,
         unsigned int cmd_in, unsigned long arg)
 {
-       int                   i, cmd_nr, cmd_type, retval = 0;
-       unsigned int          blk;
+       int                   i, cmd_nr, cmd_type, blk, retval = 0;
        struct st_modedef   * STm;
        struct st_partstat  * STps;
        struct osst_request * SRpnt = NULL;
@@ -5207,12 +5206,12 @@ static struct osst_buffer * new_tape_buffer( int from_initialization, int need_d
                priority = GFP_KERNEL;
 
        i = sizeof(struct osst_buffer) + (osst_max_sg_segs - 1) * sizeof(struct scatterlist);
-       tb = (struct osst_buffer *)kmalloc(i, priority);
+       tb = kzalloc(i, priority);
        if (!tb) {
                printk(KERN_NOTICE "osst :I: Can't allocate new tape buffer.\n");
                return NULL;
        }
-       memset(tb, 0, i);
+
        tb->sg_segs = tb->orig_sg_segs = 0;
        tb->use_sg = max_sg;
        tb->in_use = 1;
@@ -5575,9 +5574,9 @@ static ssize_t osst_version_show(struct device_driver *ddd, char *buf)
 
 static DRIVER_ATTR(version, S_IRUGO, osst_version_show, NULL);
 
-static void osst_create_driverfs_files(struct device_driver *driverfs)
+static int osst_create_driverfs_files(struct device_driver *driverfs)
 {
-       driver_create_file(driverfs, &driver_attr_version);
+       return driver_create_file(driverfs, &driver_attr_version);
 }
 
 static void osst_remove_driverfs_files(struct device_driver *driverfs)
@@ -5663,50 +5662,70 @@ CLASS_DEVICE_ATTR(file_count, S_IRUGO, osst_filemark_cnt_show, NULL);
 
 static struct class *osst_sysfs_class;
 
-static int osst_sysfs_valid = 0;
-
-static void osst_sysfs_init(void)
+static int osst_sysfs_init(void)
 {
        osst_sysfs_class = class_create(THIS_MODULE, "onstream_tape");
-       if ( IS_ERR(osst_sysfs_class) )
-               printk(KERN_WARNING "osst :W: Unable to register sysfs class\n");
-       else
-               osst_sysfs_valid = 1;
+       if (IS_ERR(osst_sysfs_class)) {
+               printk(KERN_ERR "osst :W: Unable to register sysfs class\n");
+               return PTR_ERR(osst_sysfs_class);
+       }
+
+       return 0;
 }
 
-static void osst_sysfs_add(dev_t dev, struct device *device, struct osst_tape * STp, char * name)
+static void osst_sysfs_destroy(dev_t dev)
 {
-       struct class_device *osst_class_member;
+       class_device_destroy(osst_sysfs_class, dev);
+}
 
-       if (!osst_sysfs_valid) return;
+static int osst_sysfs_add(dev_t dev, struct device *device, struct osst_tape * STp, char * name)
+{
+       struct class_device *osst_class_member;
+       int err;
 
-       osst_class_member = class_device_create(osst_sysfs_class, NULL, dev, device, "%s", name);
+       osst_class_member = class_device_create(osst_sysfs_class, NULL, dev,
+                                               device, "%s", name);
        if (IS_ERR(osst_class_member)) {
                printk(KERN_WARNING "osst :W: Unable to add sysfs class member %s\n", name);
-               return;
+               return PTR_ERR(osst_class_member);
        }
+
        class_set_devdata(osst_class_member, STp);
-       class_device_create_file(osst_class_member, &class_device_attr_ADR_rev);
-       class_device_create_file(osst_class_member, &class_device_attr_media_version);
-       class_device_create_file(osst_class_member, &class_device_attr_capacity);
-       class_device_create_file(osst_class_member, &class_device_attr_BOT_frame);
-       class_device_create_file(osst_class_member, &class_device_attr_EOD_frame);
-       class_device_create_file(osst_class_member, &class_device_attr_file_count);
-}
+       err = class_device_create_file(osst_class_member,
+                                      &class_device_attr_ADR_rev);
+       if (err)
+               goto err_out;
+       err = class_device_create_file(osst_class_member,
+                                      &class_device_attr_media_version);
+       if (err)
+               goto err_out;
+       err = class_device_create_file(osst_class_member,
+                                      &class_device_attr_capacity);
+       if (err)
+               goto err_out;
+       err = class_device_create_file(osst_class_member,
+                                      &class_device_attr_BOT_frame);
+       if (err)
+               goto err_out;
+       err = class_device_create_file(osst_class_member,
+                                      &class_device_attr_EOD_frame);
+       if (err)
+               goto err_out;
+       err = class_device_create_file(osst_class_member,
+                                      &class_device_attr_file_count);
+       if (err)
+               goto err_out;
 
-static void osst_sysfs_destroy(dev_t dev)
-{
-       if (!osst_sysfs_valid) return; 
+       return 0;
 
-       class_device_destroy(osst_sysfs_class, dev);
+err_out:
+       osst_sysfs_destroy(dev);
+       return err;
 }
 
 static void osst_sysfs_cleanup(void)
 {
-       if (osst_sysfs_valid) {
-               class_destroy(osst_sysfs_class);
-               osst_sysfs_valid = 0;
-       }
+       class_destroy(osst_sysfs_class);
 }
 
 /*
@@ -5721,7 +5740,7 @@ static int osst_probe(struct device *dev)
        struct st_partstat * STps;
        struct osst_buffer * buffer;
        struct gendisk     * drive;
-       int                  i, dev_num;
+       int                  i, dev_num, err = -ENODEV;
 
        if (SDp->type != TYPE_TAPE || !osst_supports(SDp))
                return -ENODEV;
@@ -5849,13 +5868,20 @@ static int osst_probe(struct device *dev)
        init_MUTEX(&tpnt->lock);
        osst_nr_dev++;
        write_unlock(&os_scsi_tapes_lock);
+
        {
                char name[8];
+
                /*  Rewind entry  */
-               osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num), dev, tpnt, tape_name(tpnt));
+               err = osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num), dev, tpnt, tape_name(tpnt));
+               if (err)
+                       goto out_free_buffer;
+
                /*  No-rewind entry  */
                snprintf(name, 8, "%s%s", "n", tape_name(tpnt));
-               osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num + 128), dev, tpnt, name);
+               err = osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num + 128), dev, tpnt, name);
+               if (err)
+                       goto out_free_sysfs1;
        }
 
        sdev_printk(KERN_INFO, SDp,
@@ -5864,9 +5890,13 @@ static int osst_probe(struct device *dev)
 
        return 0;
 
+out_free_sysfs1:
+       osst_sysfs_destroy(MKDEV(OSST_MAJOR, dev_num));
+out_free_buffer:
+       kfree(buffer);
 out_put_disk:
         put_disk(drive);
-        return -ENODEV;
+        return err;
 };
 
 static int osst_remove(struct device *dev)
@@ -5903,19 +5933,39 @@ static int osst_remove(struct device *dev)
 
 static int __init init_osst(void) 
 {
+       int err;
+
        printk(KERN_INFO "osst :I: Tape driver with OnStream support version %s\nosst :I: %s\n", osst_version, cvsid);
 
        validate_options();
-       osst_sysfs_init();
 
-       if ((register_chrdev(OSST_MAJOR,"osst", &osst_fops) < 0) || scsi_register_driver(&osst_template.gendrv)) {
+       err = osst_sysfs_init();
+       if (err)
+               return err;
+
+       err = register_chrdev(OSST_MAJOR, "osst", &osst_fops);
+       if (err < 0) {
                printk(KERN_ERR "osst :E: Unable to register major %d for OnStream tapes\n", OSST_MAJOR);
-               osst_sysfs_cleanup();
-               return 1;
+               goto err_out;
        }
-       osst_create_driverfs_files(&osst_template.gendrv);
+
+       err = scsi_register_driver(&osst_template.gendrv);
+       if (err)
+               goto err_out_chrdev;
+
+       err = osst_create_driverfs_files(&osst_template.gendrv);
+       if (err)
+               goto err_out_scsidrv;
 
        return 0;
+
+err_out_scsidrv:
+       scsi_unregister_driver(&osst_template.gendrv);
+err_out_chrdev:
+       unregister_chrdev(OSST_MAJOR, "osst");
+err_out:
+       osst_sysfs_cleanup();
+       return err;
 }
 
 static void __exit exit_osst (void)
index 0d4c04e1f3de3f941655ec67a023992e77d46f04..b1d3460495255ba1155176fd887ce52fb62c15c6 100644 (file)
@@ -80,7 +80,6 @@ static int       free_ports = 0;
 module_param(free_ports, bool, 0);
 MODULE_PARM_DESC(free_ports, "Release IO ports after configuration? (default: 0 (=no))");
 
-/* /usr/src/linux/drivers/scsi/hosts.h */
 static struct scsi_host_template nsp_driver_template = {
        .proc_name               = "nsp_cs",
        .proc_info               = nsp_proc_info,
@@ -949,7 +948,7 @@ static int nsp_nexus(Scsi_Cmnd *SCpnt)
 /*
  * interrupt handler
  */
-static irqreturn_t nspintr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t nspintr(int irq, void *dev_id)
 {
        unsigned int   base;
        unsigned char  irq_status, irq_phase, phase;
index 8908b8e5b78a993ce627ce6a59ac25b5f5014122..a88714f4c05b2d87ccee5915e1368ed50279ad8b 100644 (file)
@@ -346,7 +346,7 @@ static int  nsp_reselected       (Scsi_Cmnd *SCpnt);
 static struct Scsi_Host *nsp_detect(struct scsi_host_template *sht);
 
 /* Interrupt handler */
-//static irqreturn_t nspintr(int irq, void *dev_id, struct pt_regs *regs);
+//static irqreturn_t nspintr(int irq, void *dev_id);
 
 /* Module entry point*/
 static int  __init nsp_cs_init(void);
index 0b65099acb1a64c405bd87f31f36755373e54d34..72fe5d055de12875eaf8a5feb79a3bbaf058dbdd 100644 (file)
@@ -363,7 +363,7 @@ SYM53C500_pio_write(int fast_pio, int base, unsigned char *request, unsigned int
 }
 
 static irqreturn_t
-SYM53C500_intr(int irq, void *dev_id, struct pt_regs *regs)
+SYM53C500_intr(int irq, void *dev_id)
 {
        unsigned long flags;
        struct Scsi_Host *dev = dev_id;
index 5c2cdf523c3ba35baba4f4b16880ff71111dcade..a720c9265e6637c5cbc5b330ec1cf060a43e6b2a 100644 (file)
@@ -247,12 +247,11 @@ static ULONG DecodeError (struct Scsi_Host *pshost, UCHAR status)
  *
  *     Parameters:             irq             - Hardware IRQ number.
  *                                     dev_id  -
- *                                     regs    -
  *
  *     Returns:                TRUE if drive is not ready in time.
  *
  ****************************************************************/
-static void Irq_Handler (int irq, void *dev_id, struct pt_regs *regs)
+static void Irq_Handler (int irq, void *dev_id)
        {
        struct Scsi_Host   *shost;                      // Pointer to host data block
        PADAPTER240I            padapter;               // Pointer to adapter control structure
@@ -368,13 +367,13 @@ irqerror:;
        SCpnt->scsi_done (SCpnt);
        }
 
-static irqreturn_t do_Irq_Handler (int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t do_Irq_Handler (int irq, void *dev_id)
 {
        unsigned long flags;
        struct Scsi_Host *dev = dev_id;
        
        spin_lock_irqsave(dev->host_lock, flags);
-       Irq_Handler(irq, dev_id, regs);
+       Irq_Handler(irq, dev_id);
        spin_unlock_irqrestore(dev->host_lock, flags);
        return IRQ_HANDLED;
 }
index 332151e2a0189eb57a529eb4461afc218811a492..2521d548dd5941123bd644c6da74fd96ae510481 100644 (file)
@@ -1113,7 +1113,7 @@ qla1280_enable_intrs(struct scsi_qla_host *ha)
  *   Handles the H/W interrupt
  **************************************************************************/
 static irqreturn_t
-qla1280_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
+qla1280_intr_handler(int irq, void *dev_id)
 {
        struct scsi_qla_host *ha;
        struct device_reg __iomem *reg;
@@ -2862,7 +2862,7 @@ qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
        memset(((char *)pkt + 8), 0, (REQUEST_ENTRY_SIZE - 8));
 
        /* Set ISP command timeout. */
-       pkt->timeout = cpu_to_le16(30);
+       pkt->timeout = cpu_to_le16(cmd->timeout_per_command/HZ);
 
        /* Set device target ID and LUN */
        pkt->lun = SCSI_LUN_32(cmd);
@@ -3161,7 +3161,7 @@ qla1280_32bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
        memset(((char *)pkt + 8), 0, (REQUEST_ENTRY_SIZE - 8));
 
        /* Set ISP command timeout. */
-       pkt->timeout = cpu_to_le16(30);
+       pkt->timeout = cpu_to_le16(cmd->timeout_per_command/HZ);
 
        /* Set device target ID and LUN */
        pkt->lun = SCSI_LUN_32(cmd);
@@ -4484,7 +4484,7 @@ qla1280_init(void)
                qla1280_setup(qla1280);
 #endif
 
-       return pci_module_init(&qla1280_pci_driver);
+       return pci_register_driver(&qla1280_pci_driver);
 }
 
 static void __exit
index 87f90c4f08e94e07ae7cab8353ce67998a677a41..ee75a71f3c6608be7a4eb314284e127c6f999d03 100644 (file)
@@ -691,13 +691,13 @@ qla2x00_get_host_speed(struct Scsi_Host *shost)
        uint32_t speed = 0;
 
        switch (ha->link_data_rate) {
-       case LDR_1GB:
+       case PORT_SPEED_1GB:
                speed = 1;
                break;
-       case LDR_2GB:
+       case PORT_SPEED_2GB:
                speed = 2;
                break;
-       case LDR_4GB:
+       case PORT_SPEED_4GB:
                speed = 4;
                break;
        }
@@ -849,6 +849,49 @@ qla2x00_get_fc_host_stats(struct Scsi_Host *shost)
        return pfc_host_stat;
 }
 
+static void
+qla2x00_get_host_symbolic_name(struct Scsi_Host *shost)
+{
+       scsi_qla_host_t *ha = to_qla_host(shost);
+
+       qla2x00_get_sym_node_name(ha, fc_host_symbolic_name(shost));
+}
+
+static void
+qla2x00_set_host_system_hostname(struct Scsi_Host *shost)
+{
+       scsi_qla_host_t *ha = to_qla_host(shost);
+
+       set_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags);
+}
+
+static void
+qla2x00_get_host_fabric_name(struct Scsi_Host *shost)
+{
+       scsi_qla_host_t *ha = to_qla_host(shost);
+       u64 node_name;
+
+       if (ha->device_flags & SWITCH_FOUND)
+               node_name = wwn_to_u64(ha->fabric_node_name);
+       else
+               node_name = wwn_to_u64(ha->node_name);
+
+       fc_host_fabric_name(shost) = node_name;
+}
+
+static void
+qla2x00_get_host_port_state(struct Scsi_Host *shost)
+{
+       scsi_qla_host_t *ha = to_qla_host(shost);
+
+       if (!ha->flags.online)
+               fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE;
+       else if (atomic_read(&ha->loop_state) == LOOP_TIMEOUT)
+               fc_host_port_state(shost) = FC_PORTSTATE_UNKNOWN;
+       else
+               fc_host_port_state(shost) = FC_PORTSTATE_ONLINE;
+}
+
 struct fc_function_template qla2xxx_transport_functions = {
 
        .show_host_node_name = 1,
@@ -861,6 +904,14 @@ struct fc_function_template qla2xxx_transport_functions = {
        .show_host_speed = 1,
        .get_host_port_type = qla2x00_get_host_port_type,
        .show_host_port_type = 1,
+       .get_host_symbolic_name = qla2x00_get_host_symbolic_name,
+       .show_host_symbolic_name = 1,
+       .set_host_system_hostname = qla2x00_set_host_system_hostname,
+       .show_host_system_hostname = 1,
+       .get_host_fabric_name = qla2x00_get_host_fabric_name,
+       .show_host_fabric_name = 1,
+       .get_host_port_state = qla2x00_get_host_port_state,
+       .show_host_port_state = 1,
 
        .dd_fcrport_size = sizeof(struct fc_port *),
        .show_rport_supported_classes = 1,
index 533425338e05ec5fb43e54b54d37c2875ac08f8f..90dad7e8898563b5f358d80781bef05723cb7e4f 100644 (file)
@@ -38,7 +38,7 @@
 * Macros use for debugging the driver.
 */
 
-#define DEBUG(x)       do { if (extended_error_logging) { x; } } while (0)
+#define DEBUG(x)       do { if (qla2_extended_error_logging) { x; } } while (0)
 
 #if defined(QL_DEBUG_LEVEL_1)
 #define DEBUG1(x)      do {x;} while (0)
 #define DEBUG1(x)      do {} while (0)
 #endif
 
-#define DEBUG2(x)      do { if (extended_error_logging) { x; } } while (0)
-#define DEBUG2_3(x)    do { if (extended_error_logging) { x; } } while (0)
-#define DEBUG2_3_11(x) do { if (extended_error_logging) { x; } } while (0)
-#define DEBUG2_9_10(x) do { if (extended_error_logging) { x; } } while (0)
-#define DEBUG2_11(x)   do { if (extended_error_logging) { x; } } while (0)
-#define DEBUG2_13(x)   do { if (extended_error_logging) { x; } } while (0)
+#define DEBUG2(x)      do { if (qla2_extended_error_logging) { x; } } while (0)
+#define DEBUG2_3(x)    do { if (qla2_extended_error_logging) { x; } } while (0)
+#define DEBUG2_3_11(x) do { if (qla2_extended_error_logging) { x; } } while (0)
+#define DEBUG2_9_10(x) do { if (qla2_extended_error_logging) { x; } } while (0)
+#define DEBUG2_11(x)   do { if (qla2_extended_error_logging) { x; } } while (0)
+#define DEBUG2_13(x)   do { if (qla2_extended_error_logging) { x; } } while (0)
 
 #if defined(QL_DEBUG_LEVEL_3)
 #define DEBUG3(x)      do {x;} while (0)
index 0930260aec2cd89e272387c487c4a1156b661cf7..bab33f6d0bdb55709b42933e093d72be7d094047 100644 (file)
@@ -608,6 +608,7 @@ typedef struct {
  */
 #define MBC_SERDES_PARAMS              0x10    /* Serdes Tx Parameters. */
 #define MBC_GET_IOCB_STATUS            0x12    /* Get IOCB status command. */
+#define MBC_PORT_PARAMS                        0x1A    /* Port iDMA Parameters. */
 #define MBC_GET_TIMEOUT_PARAMS         0x22    /* Get FW timeouts. */
 #define MBC_TRACE_CONTROL              0x27    /* Trace control command. */
 #define MBC_GEN_SYSTEM_ERROR           0x2a    /* Generate System Error. */
@@ -1497,6 +1498,9 @@ typedef struct {
        port_id_t d_id;
        uint8_t node_name[WWN_SIZE];
        uint8_t port_name[WWN_SIZE];
+       uint8_t fabric_port_name[WWN_SIZE];
+       uint16_t fp_speeds;
+       uint16_t fp_speed;
 } sw_info_t;
 
 /*
@@ -1524,6 +1528,9 @@ typedef struct fc_port {
        uint16_t loop_id;
        uint16_t old_loop_id;
 
+       uint8_t fabric_port_name[WWN_SIZE];
+       uint16_t fp_speed;
+
        fc_port_type_t port_type;
 
        atomic_t state;
@@ -1635,6 +1642,15 @@ typedef struct fc_port {
 #define        RSNN_NN_REQ_SIZE (16 + 8 + 1 + 255)
 #define        RSNN_NN_RSP_SIZE 16
 
+#define        GFPN_ID_CMD     0x11C
+#define        GFPN_ID_REQ_SIZE (16 + 4)
+#define        GFPN_ID_RSP_SIZE (16 + 8)
+
+#define        GPSC_CMD        0x127
+#define        GPSC_REQ_SIZE   (16 + 8)
+#define        GPSC_RSP_SIZE   (16 + 2 + 2)
+
+
 /*
  * HBA attribute types.
  */
@@ -1748,7 +1764,7 @@ struct ct_sns_req {
        uint8_t reserved[3];
 
        union {
-               /* GA_NXT, GPN_ID, GNN_ID, GFT_ID */
+               /* GA_NXT, GPN_ID, GNN_ID, GFT_ID, GFPN_ID */
                struct {
                        uint8_t reserved;
                        uint8_t port_id[3];
@@ -1823,6 +1839,10 @@ struct ct_sns_req {
                struct {
                        uint8_t port_name[8];
                } dpa;
+
+               struct {
+                       uint8_t port_name[8];
+               } gpsc;
        } req;
 };
 
@@ -1886,6 +1906,15 @@ struct ct_sns_rsp {
                        uint8_t port_name[8];
                        struct ct_fdmi_hba_attributes attrs;
                } ghat;
+
+               struct {
+                       uint8_t port_name[8];
+               } gfpn_id;
+
+               struct {
+                       uint16_t speeds;
+                       uint16_t speed;
+               } gpsc;
        } rsp;
 };
 
@@ -1980,7 +2009,7 @@ struct isp_operations {
        char * (*pci_info_str) (struct scsi_qla_host *, char *);
        char * (*fw_version_str) (struct scsi_qla_host *, char *);
 
-       irqreturn_t (*intr_handler) (int, void *, struct pt_regs *);
+       irq_handler_t intr_handler;
        void (*enable_intrs) (struct scsi_qla_host *);
        void (*disable_intrs) (struct scsi_qla_host *);
 
@@ -2182,11 +2211,11 @@ typedef struct scsi_qla_host {
        uint16_t        max_public_loop_ids;
        uint16_t        min_external_loopid;    /* First external loop Id */
 
+#define PORT_SPEED_UNKNOWN 0xFFFF
+#define PORT_SPEED_1GB 0x00
+#define PORT_SPEED_2GB 0x01
+#define PORT_SPEED_4GB 0x03
        uint16_t        link_data_rate;         /* F/W operating speed */
-#define LDR_1GB                0
-#define LDR_2GB                1
-#define LDR_4GB                3
-#define LDR_UNKNOWN    0xFFFF
 
        uint8_t         current_topology;
        uint8_t         prev_topology;
@@ -2333,6 +2362,7 @@ typedef struct scsi_qla_host {
 
        uint8_t         *node_name;
        uint8_t         *port_name;
+       uint8_t         fabric_node_name[WWN_SIZE];
        uint32_t    isp_abort_cnt;
 
        /* Option ROM information. */
index 8311ac2b93a858c7ca5d20131e90588e6e74d15f..7da69832d74cec12007d26f463c1c6d849912ed6 100644 (file)
@@ -60,7 +60,7 @@ extern int ql2xplogiabsentdevice;
 extern int ql2xloginretrycount;
 extern int ql2xfdmienable;
 extern int ql2xallocfwdump;
-extern int extended_error_logging;
+extern int qla2_extended_error_logging;
 
 extern void qla2x00_sp_compl(scsi_qla_host_t *, srb_t *);
 
@@ -208,12 +208,18 @@ qla2x00_trace_control(scsi_qla_host_t *, uint16_t, dma_addr_t, uint16_t);
 extern int
 qla2x00_read_sfp(scsi_qla_host_t *, dma_addr_t, uint16_t, uint16_t, uint16_t);
 
+extern int
+qla2x00_get_idma_speed(scsi_qla_host_t *, uint16_t, uint16_t *, uint16_t *);
+
+extern int
+qla2x00_set_idma_speed(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t *);
+
 /*
  * Global Function Prototypes in qla_isr.c source file.
  */
-extern irqreturn_t qla2100_intr_handler(int, void *, struct pt_regs *);
-extern irqreturn_t qla2300_intr_handler(int, void *, struct pt_regs *);
-extern irqreturn_t qla24xx_intr_handler(int, void *, struct pt_regs *);
+extern irqreturn_t qla2100_intr_handler(int, void *);
+extern irqreturn_t qla2300_intr_handler(int, void *);
+extern irqreturn_t qla24xx_intr_handler(int, void *);
 extern void qla2x00_process_response_queue(struct scsi_qla_host *);
 extern void qla24xx_process_response_queue(struct scsi_qla_host *);
 
@@ -279,6 +285,9 @@ extern int qla2x00_rsnn_nn(scsi_qla_host_t *);
 extern void *qla2x00_prep_ms_fdmi_iocb(scsi_qla_host_t *, uint32_t, uint32_t);
 extern void *qla24xx_prep_ms_fdmi_iocb(scsi_qla_host_t *, uint32_t, uint32_t);
 extern int qla2x00_fdmi_register(scsi_qla_host_t *);
+extern int qla2x00_gfpn_id(scsi_qla_host_t *, sw_info_t *);
+extern int qla2x00_gpsc(scsi_qla_host_t *, sw_info_t *);
+extern void qla2x00_get_sym_node_name(scsi_qla_host_t *, uint8_t *);
 
 /*
  * Global Function Prototypes in qla_attr.c source file.
index 2ebf259fccb25902a94fcf8bb17504187eacad84..97fbc62ec66958ac4319aea507e2e4750c1ddb10 100644 (file)
@@ -612,6 +612,14 @@ qla2x00_rnn_id(scsi_qla_host_t *ha)
        return (rval);
 }
 
+void
+qla2x00_get_sym_node_name(scsi_qla_host_t *ha, uint8_t *snn)
+{
+       sprintf(snn, "%s FW:v%d.%02d.%02d DVR:v%s",ha->model_number,
+           ha->fw_major_version, ha->fw_minor_version,
+           ha->fw_subminor_version, qla2x00_version_str);
+}
+
 /**
  * qla2x00_rsnn_nn() - SNS Register Symbolic Node Name (RSNN_NN) of the HBA.
  * @ha: HA context
@@ -622,9 +630,6 @@ int
 qla2x00_rsnn_nn(scsi_qla_host_t *ha)
 {
        int             rval;
-       uint8_t         *snn;
-       uint8_t         version[20];
-
        ms_iocb_entry_t *ms_pkt;
        struct ct_sns_req       *ct_req;
        struct ct_sns_rsp       *ct_rsp;
@@ -649,20 +654,11 @@ qla2x00_rsnn_nn(scsi_qla_host_t *ha)
        memcpy(ct_req->req.rsnn_nn.node_name, ha->node_name, WWN_SIZE);
 
        /* Prepare the Symbolic Node Name */
-       /* Board type */
-       snn = ct_req->req.rsnn_nn.sym_node_name;
-       strcpy(snn, ha->model_number);
-       /* Firmware version */
-       strcat(snn, " FW:v");
-       sprintf(version, "%d.%02d.%02d", ha->fw_major_version,
-           ha->fw_minor_version, ha->fw_subminor_version);
-       strcat(snn, version);
-       /* Driver version */
-       strcat(snn, " DVR:v");
-       strcat(snn, qla2x00_version_str);
+       qla2x00_get_sym_node_name(ha, ct_req->req.rsnn_nn.sym_node_name);
 
        /* Calculate SNN length */
-       ct_req->req.rsnn_nn.name_len = (uint8_t)strlen(snn);
+       ct_req->req.rsnn_nn.name_len =
+           (uint8_t)strlen(ct_req->req.rsnn_nn.sym_node_name);
 
        /* Update MS IOCB request */
        ms_pkt->req_bytecount =
@@ -687,7 +683,6 @@ qla2x00_rsnn_nn(scsi_qla_host_t *ha)
        return (rval);
 }
 
-
 /**
  * qla2x00_prep_sns_cmd() - Prepare common SNS command request fields for query.
  * @ha: HA context
@@ -1585,6 +1580,21 @@ qla2x00_fdmi_rpa(scsi_qla_host_t *ha)
        DEBUG13(printk("%s(%ld): OS_DEVICE_NAME=%s.\n", __func__, ha->host_no,
            eiter->a.os_dev_name));
 
+       /* Hostname. */
+       if (strlen(fc_host_system_hostname(ha->host))) {
+               eiter = (struct ct_fdmi_port_attr *) (entries + size);
+               eiter->type = __constant_cpu_to_be16(FDMI_PORT_HOST_NAME);
+               snprintf(eiter->a.host_name, sizeof(eiter->a.host_name),
+                   "%s", fc_host_system_hostname(ha->host));
+               alen = strlen(eiter->a.host_name);
+               alen += (alen & 3) ? (4 - (alen & 3)) : 4;
+               eiter->len = cpu_to_be16(4 + alen);
+               size += 4 + alen;
+
+               DEBUG13(printk("%s(%ld): HOSTNAME=%s.\n", __func__,
+                   ha->host_no, eiter->a.host_name));
+       }
+
        /* Update MS request size. */
        qla2x00_update_ms_fdmi_iocb(ha, size + 16);
 
@@ -1647,3 +1657,189 @@ qla2x00_fdmi_register(scsi_qla_host_t *ha)
 
        return rval;
 }
+
+/**
+ * qla2x00_gfpn_id() - SNS Get Fabric Port Name (GFPN_ID) query.
+ * @ha: HA context
+ * @list: switch info entries to populate
+ *
+ * Returns 0 on success.
+ */
+int
+qla2x00_gfpn_id(scsi_qla_host_t *ha, sw_info_t *list)
+{
+       int             rval;
+       uint16_t        i;
+
+       ms_iocb_entry_t *ms_pkt;
+       struct ct_sns_req       *ct_req;
+       struct ct_sns_rsp       *ct_rsp;
+
+       if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha))
+               return QLA_FUNCTION_FAILED;
+
+       for (i = 0; i < MAX_FIBRE_DEVICES; i++) {
+               /* Issue GFPN_ID */
+               memset(list[i].fabric_port_name, 0, WWN_SIZE);
+
+               /* Prepare common MS IOCB */
+               ms_pkt = qla2x00_prep_ms_iocb(ha, GFPN_ID_REQ_SIZE,
+                   GFPN_ID_RSP_SIZE);
+
+               /* Prepare CT request */
+               ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GFPN_ID_CMD,
+                   GFPN_ID_RSP_SIZE);
+               ct_rsp = &ha->ct_sns->p.rsp;
+
+               /* Prepare CT arguments -- port_id */
+               ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain;
+               ct_req->req.port_id.port_id[1] = list[i].d_id.b.area;
+               ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa;
+
+               /* Execute MS IOCB */
+               rval = qla2x00_issue_iocb(ha, ha->ms_iocb, ha->ms_iocb_dma,
+                   sizeof(ms_iocb_entry_t));
+               if (rval != QLA_SUCCESS) {
+                       /*EMPTY*/
+                       DEBUG2_3(printk("scsi(%ld): GFPN_ID issue IOCB "
+                           "failed (%d).\n", ha->host_no, rval));
+               } else if (qla2x00_chk_ms_status(ha, ms_pkt, ct_rsp,
+                   "GFPN_ID") != QLA_SUCCESS) {
+                       rval = QLA_FUNCTION_FAILED;
+               } else {
+                       /* Save fabric portname */
+                       memcpy(list[i].fabric_port_name,
+                           ct_rsp->rsp.gfpn_id.port_name, WWN_SIZE);
+               }
+
+               /* Last device exit. */
+               if (list[i].d_id.b.rsvd_1 != 0)
+                       break;
+       }
+
+       return (rval);
+}
+
+static inline void *
+qla24xx_prep_ms_fm_iocb(scsi_qla_host_t *ha, uint32_t req_size,
+    uint32_t rsp_size)
+{
+       struct ct_entry_24xx *ct_pkt;
+
+       ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb;
+       memset(ct_pkt, 0, sizeof(struct ct_entry_24xx));
+
+       ct_pkt->entry_type = CT_IOCB_TYPE;
+       ct_pkt->entry_count = 1;
+       ct_pkt->nport_handle = cpu_to_le16(ha->mgmt_svr_loop_id);
+       ct_pkt->timeout = __constant_cpu_to_le16(59);
+       ct_pkt->cmd_dsd_count = __constant_cpu_to_le16(1);
+       ct_pkt->rsp_dsd_count = __constant_cpu_to_le16(1);
+       ct_pkt->rsp_byte_count = cpu_to_le32(rsp_size);
+       ct_pkt->cmd_byte_count = cpu_to_le32(req_size);
+
+       ct_pkt->dseg_0_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
+       ct_pkt->dseg_0_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
+       ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count;
+
+       ct_pkt->dseg_1_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
+       ct_pkt->dseg_1_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
+       ct_pkt->dseg_1_len = ct_pkt->rsp_byte_count;
+
+       return ct_pkt;
+}
+
+
+static inline struct ct_sns_req *
+qla24xx_prep_ct_fm_req(struct ct_sns_req *ct_req, uint16_t cmd,
+    uint16_t rsp_size)
+{
+       memset(ct_req, 0, sizeof(struct ct_sns_pkt));
+
+       ct_req->header.revision = 0x01;
+       ct_req->header.gs_type = 0xFA;
+       ct_req->header.gs_subtype = 0x01;
+       ct_req->command = cpu_to_be16(cmd);
+       ct_req->max_rsp_size = cpu_to_be16((rsp_size - 16) / 4);
+
+       return ct_req;
+}
+
+/**
+ * qla2x00_gpsc() - FCS Get Port Speed Capabilities (GPSC) query.
+ * @ha: HA context
+ * @list: switch info entries to populate
+ *
+ * Returns 0 on success.
+ */
+int
+qla2x00_gpsc(scsi_qla_host_t *ha, sw_info_t *list)
+{
+       int             rval;
+       uint16_t        i;
+
+       ms_iocb_entry_t *ms_pkt;
+       struct ct_sns_req       *ct_req;
+       struct ct_sns_rsp       *ct_rsp;
+
+       if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha))
+               return QLA_FUNCTION_FAILED;
+
+       rval = qla2x00_mgmt_svr_login(ha);
+       if (rval)
+               return rval;
+
+       for (i = 0; i < MAX_FIBRE_DEVICES; i++) {
+               /* Issue GFPN_ID */
+               list[i].fp_speeds = list[i].fp_speed = 0;
+
+               /* Prepare common MS IOCB */
+               ms_pkt = qla24xx_prep_ms_fm_iocb(ha, GPSC_REQ_SIZE,
+                   GPSC_RSP_SIZE);
+
+               /* Prepare CT request */
+               ct_req = qla24xx_prep_ct_fm_req(&ha->ct_sns->p.req,
+                   GPSC_CMD, GPSC_RSP_SIZE);
+               ct_rsp = &ha->ct_sns->p.rsp;
+
+               /* Prepare CT arguments -- port_name */
+               memcpy(ct_req->req.gpsc.port_name, list[i].fabric_port_name,
+                   WWN_SIZE);
+
+               /* Execute MS IOCB */
+               rval = qla2x00_issue_iocb(ha, ha->ms_iocb, ha->ms_iocb_dma,
+                   sizeof(ms_iocb_entry_t));
+               if (rval != QLA_SUCCESS) {
+                       /*EMPTY*/
+                       DEBUG2_3(printk("scsi(%ld): GPSC issue IOCB "
+                           "failed (%d).\n", ha->host_no, rval));
+               } else if (qla2x00_chk_ms_status(ha, ms_pkt, ct_rsp,
+                   "GPSC") != QLA_SUCCESS) {
+                       rval = QLA_FUNCTION_FAILED;
+               } else {
+                       /* Save portname */
+                       list[i].fp_speeds = ct_rsp->rsp.gpsc.speeds;
+                       list[i].fp_speed = ct_rsp->rsp.gpsc.speed;
+
+                       DEBUG2_3(printk("scsi(%ld): GPSC ext entry - "
+                           "fpn %02x%02x%02x%02x%02x%02x%02x%02x speeds=%04x "
+                           "speed=%04x.\n", ha->host_no,
+                           list[i].fabric_port_name[0],
+                           list[i].fabric_port_name[1],
+                           list[i].fabric_port_name[2],
+                           list[i].fabric_port_name[3],
+                           list[i].fabric_port_name[4],
+                           list[i].fabric_port_name[5],
+                           list[i].fabric_port_name[6],
+                           list[i].fabric_port_name[7],
+                           be16_to_cpu(list[i].fp_speeds),
+                           be16_to_cpu(list[i].fp_speed)));
+               }
+
+               /* Last device exit. */
+               if (list[i].d_id.b.rsvd_1 != 0)
+                       break;
+       }
+
+       return (rval);
+}
index 859649160caaa795b4fe3213e98e27fa98849913..833b93085fd3d0bdb577f61f61d2d9d77a321166 100644 (file)
@@ -1644,7 +1644,7 @@ qla2x00_nvram_config(scsi_qla_host_t *ha)
         * Set host adapter parameters.
         */
        if (nv->host_p[0] & BIT_7)
-               extended_error_logging = 1;
+               qla2_extended_error_logging = 1;
        ha->flags.disable_risc_code_load = ((nv->host_p[0] & BIT_4) ? 1 : 0);
        /* Always load RISC code on non ISP2[12]00 chips. */
        if (!IS_QLA2100(ha) && !IS_QLA2200(ha))
@@ -2074,6 +2074,19 @@ qla2x00_configure_local_loop(scsi_qla_host_t *ha)
                        new_fcport->flags &= ~FCF_FABRIC_DEVICE;
                }
 
+               /* Base iIDMA settings on HBA port speed. */
+               switch (ha->link_data_rate) {
+               case PORT_SPEED_1GB:
+                       fcport->fp_speed = cpu_to_be16(BIT_15);
+                       break;
+               case PORT_SPEED_2GB:
+                       fcport->fp_speed = cpu_to_be16(BIT_14);
+                       break;
+               case PORT_SPEED_4GB:
+                       fcport->fp_speed = cpu_to_be16(BIT_13);
+                       break;
+               }
+
                qla2x00_update_fcport(ha, fcport);
 
                found_devs++;
@@ -2109,6 +2122,62 @@ qla2x00_probe_for_all_luns(scsi_qla_host_t *ha)
        }
 }
 
+static void
+qla2x00_iidma_fcport(scsi_qla_host_t *ha, fc_port_t *fcport)
+{
+#define LS_UNKNOWN      2
+       static char *link_speeds[5] = { "1", "2", "?", "4" };
+       int rval;
+       uint16_t port_speed, mb[6];
+
+       if (!IS_QLA24XX(ha))
+               return;
+
+       switch (be16_to_cpu(fcport->fp_speed)) {
+       case BIT_15:
+               port_speed = PORT_SPEED_1GB;
+               break;
+       case BIT_14:
+               port_speed = PORT_SPEED_2GB;
+               break;
+       case BIT_13:
+               port_speed = PORT_SPEED_4GB;
+               break;
+       default:
+               DEBUG2(printk("scsi(%ld): %02x%02x%02x%02x%02x%02x%02x%02x -- "
+                   "unsupported FM port operating speed (%04x).\n",
+                   ha->host_no, fcport->port_name[0], fcport->port_name[1],
+                   fcport->port_name[2], fcport->port_name[3],
+                   fcport->port_name[4], fcport->port_name[5],
+                   fcport->port_name[6], fcport->port_name[7],
+                   be16_to_cpu(fcport->fp_speed)));
+               port_speed = PORT_SPEED_UNKNOWN;
+               break;
+       }
+       if (port_speed == PORT_SPEED_UNKNOWN)
+               return;
+
+       rval = qla2x00_set_idma_speed(ha, fcport->loop_id, port_speed, mb);
+       if (rval != QLA_SUCCESS) {
+               DEBUG2(printk("scsi(%ld): Unable to adjust iIDMA "
+                   "%02x%02x%02x%02x%02x%02x%02x%02x -- %04x %x %04x %04x.\n",
+                   ha->host_no, fcport->port_name[0], fcport->port_name[1],
+                   fcport->port_name[2], fcport->port_name[3],
+                   fcport->port_name[4], fcport->port_name[5],
+                   fcport->port_name[6], fcport->port_name[7], rval,
+                   port_speed, mb[0], mb[1]));
+       } else {
+               DEBUG2(qla_printk(KERN_INFO, ha,
+                   "iIDMA adjusted to %s GB/s on "
+                   "%02x%02x%02x%02x%02x%02x%02x%02x.\n",
+                   link_speeds[port_speed], fcport->port_name[0],
+                   fcport->port_name[1], fcport->port_name[2],
+                   fcport->port_name[3], fcport->port_name[4],
+                   fcport->port_name[5], fcport->port_name[6],
+                   fcport->port_name[7]));
+       }
+}
+
 /*
  * qla2x00_update_fcport
  *     Updates device on list.
@@ -2135,6 +2204,8 @@ qla2x00_update_fcport(scsi_qla_host_t *ha, fc_port_t *fcport)
            PORT_RETRY_TIME);
        fcport->flags &= ~FCF_LOGIN_NEEDED;
 
+       qla2x00_iidma_fcport(ha, fcport);
+
        atomic_set(&fcport->state, FCS_ONLINE);
 
        if (ha->flags.init_done)
@@ -2209,7 +2280,7 @@ qla2x00_configure_fabric(scsi_qla_host_t *ha)
                loop_id = NPH_F_PORT;
        else
                loop_id = SNS_FL_PORT;
-       rval = qla2x00_get_port_name(ha, loop_id, NULL, 0);
+       rval = qla2x00_get_port_name(ha, loop_id, ha->fabric_node_name, 1);
        if (rval != QLA_SUCCESS) {
                DEBUG2(printk("scsi(%ld): MBC_GET_PORT_NAME Failed, No FL "
                    "Port\n", ha->host_no));
@@ -2217,6 +2288,7 @@ qla2x00_configure_fabric(scsi_qla_host_t *ha)
                ha->device_flags &= ~SWITCH_FOUND;
                return (QLA_SUCCESS);
        }
+       ha->device_flags |= SWITCH_FOUND;
 
        /* Mark devices that need re-synchronization. */
        rval2 = qla2x00_device_resync(ha);
@@ -2416,6 +2488,8 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *ha, struct list_head *new_fcports)
                } else if (qla2x00_gnn_id(ha, swl) != QLA_SUCCESS) {
                        kfree(swl);
                        swl = NULL;
+               } else if (qla2x00_gfpn_id(ha, swl) == QLA_SUCCESS) {
+                       qla2x00_gpsc(ha, swl);
                }
        }
        swl_idx = 0;
@@ -2450,6 +2524,9 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *ha, struct list_head *new_fcports)
                                    swl[swl_idx].node_name, WWN_SIZE);
                                memcpy(new_fcport->port_name,
                                    swl[swl_idx].port_name, WWN_SIZE);
+                               memcpy(new_fcport->fabric_port_name,
+                                   swl[swl_idx].fabric_port_name, WWN_SIZE);
+                               new_fcport->fp_speed = swl[swl_idx].fp_speed;
 
                                if (swl[swl_idx].d_id.b.rsvd_1 != 0) {
                                        last_dev = 1;
@@ -2507,6 +2584,11 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *ha, struct list_head *new_fcports)
 
                        found++;
 
+                       /* Update port state. */
+                       memcpy(fcport->fabric_port_name,
+                           new_fcport->fabric_port_name, WWN_SIZE);
+                       fcport->fp_speed = new_fcport->fp_speed;
+
                        /*
                         * If address the same and state FCS_ONLINE, nothing
                         * changed.
index 45007ee58067bd125055a8398a96a067315629bb..d3023338628ff844560baea4c84dd6f43faa8599 100644 (file)
@@ -104,7 +104,7 @@ static __inline__ void qla2x00_poll(scsi_qla_host_t *);
 static inline void
 qla2x00_poll(scsi_qla_host_t *ha)
 {
-       ha->isp_ops.intr_handler(0, ha, NULL);
+       ha->isp_ops.intr_handler(0, ha);
 }
 
 static __inline__ void qla2x00_check_fabric_devices(scsi_qla_host_t *);
index de0613135f702b42096786172f4063aa4fe66c10..626c7178a4341bbf2b482c74d13b6abee23c66cc 100644 (file)
@@ -20,14 +20,13 @@ static void qla24xx_ms_entry(scsi_qla_host_t *, struct ct_entry_24xx *);
  * qla2100_intr_handler() - Process interrupts for the ISP2100 and ISP2200.
  * @irq:
  * @dev_id: SCSI driver HA context
- * @regs:
  *
  * Called by system whenever the host adapter generates an interrupt.
  *
  * Returns handled flag.
  */
 irqreturn_t
-qla2100_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
+qla2100_intr_handler(int irq, void *dev_id)
 {
        scsi_qla_host_t *ha;
        struct device_reg_2xxx __iomem *reg;
@@ -100,14 +99,13 @@ qla2100_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
  * qla2300_intr_handler() - Process interrupts for the ISP23xx and ISP63xx.
  * @irq:
  * @dev_id: SCSI driver HA context
- * @regs:
  *
  * Called by system whenever the host adapter generates an interrupt.
  *
  * Returns handled flag.
  */
 irqreturn_t
-qla2300_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
+qla2300_intr_handler(int irq, void *dev_id)
 {
        scsi_qla_host_t *ha;
        struct device_reg_2xxx __iomem *reg;
@@ -400,7 +398,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
        case MBA_LOOP_UP:               /* Loop Up Event */
                if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
                        link_speed = link_speeds[0];
-                       ha->link_data_rate = LDR_1GB;
+                       ha->link_data_rate = PORT_SPEED_1GB;
                } else {
                        link_speed = link_speeds[LS_UNKNOWN];
                        if (mb[1] < 5)
@@ -429,7 +427,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
                }
 
                ha->flags.management_server_logged_in = 0;
-               ha->link_data_rate = LDR_UNKNOWN;
+               ha->link_data_rate = PORT_SPEED_UNKNOWN;
                if (ql2xfdmienable)
                        set_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags);
                break;
@@ -1338,14 +1336,13 @@ qla24xx_process_response_queue(struct scsi_qla_host *ha)
  * qla24xx_intr_handler() - Process interrupts for the ISP23xx and ISP63xx.
  * @irq:
  * @dev_id: SCSI driver HA context
- * @regs:
  *
  * Called by system whenever the host adapter generates an interrupt.
  *
  * Returns handled flag.
  */
 irqreturn_t
-qla24xx_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
+qla24xx_intr_handler(int irq, void *dev_id)
 {
        scsi_qla_host_t *ha;
        struct device_reg_24xx __iomem *reg;
index 879f281e2ea219a0cb580157a8ba8e99a6c66fc9..4cde76c85cb39a72610e2183fd7dc82fd6b7db95 100644 (file)
@@ -2540,3 +2540,89 @@ qla2x00_read_sfp(scsi_qla_host_t *ha, dma_addr_t sfp_dma, uint16_t addr,
 
        return rval;
 }
+
+int
+qla2x00_get_idma_speed(scsi_qla_host_t *ha, uint16_t loop_id,
+    uint16_t *port_speed, uint16_t *mb)
+{
+       int rval;
+       mbx_cmd_t mc;
+       mbx_cmd_t *mcp = &mc;
+
+       if (!IS_QLA24XX(ha))
+               return QLA_FUNCTION_FAILED;
+
+       DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));
+
+       mcp->mb[0] = MBC_PORT_PARAMS;
+       mcp->mb[1] = loop_id;
+       mcp->mb[2] = mcp->mb[3] = mcp->mb[4] = mcp->mb[5] = 0;
+       mcp->out_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
+       mcp->in_mb = MBX_5|MBX_4|MBX_3|MBX_1|MBX_0;
+       mcp->tov = 30;
+       mcp->flags = 0;
+       rval = qla2x00_mailbox_command(ha, mcp);
+
+       /* Return mailbox statuses. */
+       if (mb != NULL) {
+               mb[0] = mcp->mb[0];
+               mb[1] = mcp->mb[1];
+               mb[3] = mcp->mb[3];
+               mb[4] = mcp->mb[4];
+               mb[5] = mcp->mb[5];
+       }
+
+       if (rval != QLA_SUCCESS) {
+               DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__,
+                   ha->host_no, rval));
+       } else {
+               DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no));
+               if (port_speed)
+                       *port_speed = mcp->mb[3];
+       }
+
+       return rval;
+}
+
+int
+qla2x00_set_idma_speed(scsi_qla_host_t *ha, uint16_t loop_id,
+    uint16_t port_speed, uint16_t *mb)
+{
+       int rval;
+       mbx_cmd_t mc;
+       mbx_cmd_t *mcp = &mc;
+
+       if (!IS_QLA24XX(ha))
+               return QLA_FUNCTION_FAILED;
+
+       DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));
+
+       mcp->mb[0] = MBC_PORT_PARAMS;
+       mcp->mb[1] = loop_id;
+       mcp->mb[2] = BIT_0;
+       mcp->mb[3] = port_speed & (BIT_2|BIT_1|BIT_0);
+       mcp->mb[4] = mcp->mb[5] = 0;
+       mcp->out_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
+       mcp->in_mb = MBX_5|MBX_4|MBX_3|MBX_1|MBX_0;
+       mcp->tov = 30;
+       mcp->flags = 0;
+       rval = qla2x00_mailbox_command(ha, mcp);
+
+       /* Return mailbox statuses. */
+       if (mb != NULL) {
+               mb[0] = mcp->mb[0];
+               mb[1] = mcp->mb[1];
+               mb[3] = mcp->mb[3];
+               mb[4] = mcp->mb[4];
+               mb[5] = mcp->mb[5];
+       }
+
+       if (rval != QLA_SUCCESS) {
+               DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__,
+                   ha->host_no, rval));
+       } else {
+               DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no));
+       }
+
+       return rval;
+}
index 65cbe2f5eea24c110438c4404e85e5cba09214bc..3f20d765563eba4f013375e5694269135c8b1a3a 100644 (file)
@@ -61,9 +61,9 @@ MODULE_PARM_DESC(ql2xallocfwdump,
                "during HBA initialization.  Memory allocation requirements "
                "vary by ISP type.  Default is 1 - allocate memory.");
 
-int extended_error_logging;
-module_param(extended_error_logging, int, S_IRUGO|S_IRUSR);
-MODULE_PARM_DESC(extended_error_logging,
+int qla2_extended_error_logging;
+module_param(qla2_extended_error_logging, int, S_IRUGO|S_IRUSR);
+MODULE_PARM_DESC(qla2_extended_error_logging,
                "Option to enable extended error logging, "
                "Default is 0 - no logging. 1 - log errors.");
 
@@ -589,6 +589,23 @@ qla2x00_wait_for_loop_ready(scsi_qla_host_t *ha)
        return (return_status);
 }
 
+static void
+qla2x00_block_error_handler(struct scsi_cmnd *cmnd)
+{
+       struct Scsi_Host *shost = cmnd->device->host;
+       struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device));
+       unsigned long flags;
+
+       spin_lock_irqsave(shost->host_lock, flags);
+       while (rport->port_state == FC_PORTSTATE_BLOCKED) {
+               spin_unlock_irqrestore(shost->host_lock, flags);
+               msleep(1000);
+               spin_lock_irqsave(shost->host_lock, flags);
+       }
+       spin_unlock_irqrestore(shost->host_lock, flags);
+       return;
+}
+
 /**************************************************************************
 * qla2xxx_eh_abort
 *
@@ -615,6 +632,8 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
        unsigned long flags;
        int wait = 0;
 
+       qla2x00_block_error_handler(cmd);
+
        if (!CMD_SP(cmd))
                return SUCCESS;
 
@@ -748,6 +767,8 @@ qla2xxx_eh_device_reset(struct scsi_cmnd *cmd)
        unsigned int id, lun;
        unsigned long serial;
 
+       qla2x00_block_error_handler(cmd);
+
        ret = FAILED;
 
        id = cmd->device->id;
@@ -877,6 +898,8 @@ qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd)
        unsigned int id, lun;
        unsigned long serial;
 
+       qla2x00_block_error_handler(cmd);
+
        ret = FAILED;
 
        id = cmd->device->id;
@@ -936,6 +959,8 @@ qla2xxx_eh_host_reset(struct scsi_cmnd *cmd)
        unsigned int id, lun;
        unsigned long serial;
 
+       qla2x00_block_error_handler(cmd);
+
        ret = FAILED;
 
        id = cmd->device->id;
@@ -1385,7 +1410,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
        ha->prev_topology = 0;
        ha->init_cb_size = sizeof(init_cb_t);
        ha->mgmt_svr_loop_id = MANAGEMENT_SERVER;
-       ha->link_data_rate = LDR_UNKNOWN;
+       ha->link_data_rate = PORT_SPEED_UNKNOWN;
        ha->optrom_size = OPTROM_SIZE_2300;
 
        /* Assign ISP specific operations. */
@@ -2564,14 +2589,20 @@ qla2x00_down_timeout(struct semaphore *sema, unsigned long timeout)
 #define FW_ISP2322     3
 #define FW_ISP24XX     4
 
+#define FW_FILE_ISP21XX        "ql2100_fw.bin"
+#define FW_FILE_ISP22XX        "ql2200_fw.bin"
+#define FW_FILE_ISP2300        "ql2300_fw.bin"
+#define FW_FILE_ISP2322        "ql2322_fw.bin"
+#define FW_FILE_ISP24XX        "ql2400_fw.bin"
+
 static DECLARE_MUTEX(qla_fw_lock);
 
 static struct fw_blob qla_fw_blobs[FW_BLOBS] = {
-       { .name = "ql2100_fw.bin", .segs = { 0x1000, 0 }, },
-       { .name = "ql2200_fw.bin", .segs = { 0x1000, 0 }, },
-       { .name = "ql2300_fw.bin", .segs = { 0x800, 0 }, },
-       { .name = "ql2322_fw.bin", .segs = { 0x800, 0x1c000, 0x1e000, 0 }, },
-       { .name = "ql2400_fw.bin", },
+       { .name = FW_FILE_ISP21XX, .segs = { 0x1000, 0 }, },
+       { .name = FW_FILE_ISP22XX, .segs = { 0x1000, 0 }, },
+       { .name = FW_FILE_ISP2300, .segs = { 0x800, 0 }, },
+       { .name = FW_FILE_ISP2322, .segs = { 0x800, 0x1c000, 0x1e000, 0 }, },
+       { .name = FW_FILE_ISP24XX, },
 };
 
 struct fw_blob *
@@ -2666,7 +2697,7 @@ qla2x00_module_init(void)
 
        /* Derive version string. */
        strcpy(qla2x00_version_str, QLA2XXX_VERSION);
-       if (extended_error_logging)
+       if (qla2_extended_error_logging)
                strcat(qla2x00_version_str, "-debug");
 
        qla2xxx_transport_template =
@@ -2702,3 +2733,8 @@ MODULE_AUTHOR("QLogic Corporation");
 MODULE_DESCRIPTION("QLogic Fibre Channel HBA Driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(QLA2XXX_VERSION);
+MODULE_FIRMWARE(FW_FILE_ISP21XX);
+MODULE_FIRMWARE(FW_FILE_ISP22XX);
+MODULE_FIRMWARE(FW_FILE_ISP2300);
+MODULE_FIRMWARE(FW_FILE_ISP2322);
+MODULE_FIRMWARE(FW_FILE_ISP24XX);
index 971259032ef71b9a0caaea13e1512e3e5c7f7d17..e57bf45a33936d29aea8fcc90c1450329ce8cec5 100644 (file)
@@ -7,7 +7,7 @@
 /*
  * Driver version
  */
-#define QLA2XXX_VERSION      "8.01.07-k1"
+#define QLA2XXX_VERSION      "8.01.07-k2"
 
 #define QLA_DRIVER_MAJOR_VER   8
 #define QLA_DRIVER_MINOR_VER   1
diff --git a/drivers/scsi/qla4xxx/Kconfig b/drivers/scsi/qla4xxx/Kconfig
new file mode 100644 (file)
index 0000000..08a07f0
--- /dev/null
@@ -0,0 +1,7 @@
+config SCSI_QLA_ISCSI
+       tristate "QLogic ISP4XXX host adapter family support"
+       depends on PCI && SCSI
+       select SCSI_ISCSI_ATTRS
+       ---help---
+       This driver supports the QLogic 40xx (ISP4XXX) iSCSI host
+       adapter family.
diff --git a/drivers/scsi/qla4xxx/Makefile b/drivers/scsi/qla4xxx/Makefile
new file mode 100644 (file)
index 0000000..86ea37b
--- /dev/null
@@ -0,0 +1,5 @@
+qla4xxx-y := ql4_os.o ql4_init.o ql4_mbx.o ql4_iocb.o ql4_isr.o \
+               ql4_nvram.o ql4_dbg.o
+
+obj-$(CONFIG_SCSI_QLA_ISCSI) += qla4xxx.o
+
diff --git a/drivers/scsi/qla4xxx/ql4_dbg.c b/drivers/scsi/qla4xxx/ql4_dbg.c
new file mode 100644 (file)
index 0000000..752031f
--- /dev/null
@@ -0,0 +1,197 @@
+/*
+ * QLogic iSCSI HBA Driver
+ * Copyright (c)  2003-2006 QLogic Corporation
+ *
+ * See LICENSE.qla4xxx for copyright and licensing details.
+ */
+
+#include "ql4_def.h"
+#include <scsi/scsi_dbg.h>
+
+static void qla4xxx_print_srb_info(struct srb * srb)
+{
+       printk("%s: srb = 0x%p, flags=0x%02x\n", __func__, srb, srb->flags);
+       printk("%s: cmd = 0x%p, saved_dma_handle = 0x%lx\n",
+              __func__, srb->cmd, (unsigned long) srb->dma_handle);
+       printk("%s: fw_ddb_index = %d, lun = %d\n",
+              __func__, srb->fw_ddb_index, srb->cmd->device->lun);
+       printk("%s: iocb_tov = %d\n",
+              __func__, srb->iocb_tov);
+       printk("%s: cc_stat = 0x%x, r_start = 0x%lx, u_start = 0x%lx\n\n",
+              __func__, srb->cc_stat, srb->r_start, srb->u_start);
+}
+
+void qla4xxx_print_scsi_cmd(struct scsi_cmnd *cmd)
+{
+       printk("SCSI Command = 0x%p, Handle=0x%p\n", cmd, cmd->host_scribble);
+       printk("  b=%d, t=%02xh, l=%02xh, cmd_len = %02xh\n",
+              cmd->device->channel, cmd->device->id, cmd->device->lun,
+              cmd->cmd_len);
+       scsi_print_command(cmd);
+       printk("  seg_cnt = %d\n", cmd->use_sg);
+       printk("  request buffer = 0x%p, request buffer len = 0x%x\n",
+              cmd->request_buffer, cmd->request_bufflen);
+       if (cmd->use_sg) {
+               struct scatterlist *sg;
+               sg = (struct scatterlist *)cmd->request_buffer;
+               printk("  SG buffer: \n");
+               qla4xxx_dump_buffer((caddr_t) sg,
+                                   (cmd->use_sg * sizeof(*sg)));
+       }
+       printk("  tag = %d, transfersize = 0x%x \n", cmd->tag,
+              cmd->transfersize);
+       printk("  Pid = %d, SP = 0x%p\n", (int)cmd->pid, cmd->SCp.ptr);
+       printk("  underflow size = 0x%x, direction=0x%x\n", cmd->underflow,
+              cmd->sc_data_direction);
+       printk("  Current time (jiffies) = 0x%lx, "
+              "timeout expires = 0x%lx\n", jiffies, cmd->eh_timeout.expires);
+       qla4xxx_print_srb_info((struct srb *) cmd->SCp.ptr);
+}
+
+void __dump_registers(struct scsi_qla_host *ha)
+{
+       uint8_t i;
+       for (i = 0; i < MBOX_REG_COUNT; i++) {
+               printk(KERN_INFO "0x%02X mailbox[%d]      = 0x%08X\n",
+                      (uint8_t) offsetof(struct isp_reg, mailbox[i]), i,
+                      readw(&ha->reg->mailbox[i]));
+       }
+       printk(KERN_INFO "0x%02X flash_address   = 0x%08X\n",
+              (uint8_t) offsetof(struct isp_reg, flash_address),
+              readw(&ha->reg->flash_address));
+       printk(KERN_INFO "0x%02X flash_data      = 0x%08X\n",
+              (uint8_t) offsetof(struct isp_reg, flash_data),
+              readw(&ha->reg->flash_data));
+       printk(KERN_INFO "0x%02X ctrl_status     = 0x%08X\n",
+              (uint8_t) offsetof(struct isp_reg, ctrl_status),
+              readw(&ha->reg->ctrl_status));
+       if (is_qla4010(ha)) {
+               printk(KERN_INFO "0x%02X nvram           = 0x%08X\n",
+                      (uint8_t) offsetof(struct isp_reg, u1.isp4010.nvram),
+                      readw(&ha->reg->u1.isp4010.nvram));
+       }
+
+       else if (is_qla4022(ha)) {
+               printk(KERN_INFO "0x%02X intr_mask       = 0x%08X\n",
+                      (uint8_t) offsetof(struct isp_reg,
+                                         u1.isp4022.intr_mask),
+                      readw(&ha->reg->u1.isp4022.intr_mask));
+               printk(KERN_INFO "0x%02X nvram           = 0x%08X\n",
+                      (uint8_t) offsetof(struct isp_reg, u1.isp4022.nvram),
+                      readw(&ha->reg->u1.isp4022.nvram));
+               printk(KERN_INFO "0x%02X semaphore       = 0x%08X\n",
+                      (uint8_t) offsetof(struct isp_reg,
+                                         u1.isp4022.semaphore),
+                      readw(&ha->reg->u1.isp4022.semaphore));
+       }
+       printk(KERN_INFO "0x%02X req_q_in        = 0x%08X\n",
+              (uint8_t) offsetof(struct isp_reg, req_q_in),
+              readw(&ha->reg->req_q_in));
+       printk(KERN_INFO "0x%02X rsp_q_out       = 0x%08X\n",
+              (uint8_t) offsetof(struct isp_reg, rsp_q_out),
+              readw(&ha->reg->rsp_q_out));
+       if (is_qla4010(ha)) {
+               printk(KERN_INFO "0x%02X ext_hw_conf     = 0x%08X\n",
+                      (uint8_t) offsetof(struct isp_reg,
+                                         u2.isp4010.ext_hw_conf),
+                      readw(&ha->reg->u2.isp4010.ext_hw_conf));
+               printk(KERN_INFO "0x%02X port_ctrl       = 0x%08X\n",
+                      (uint8_t) offsetof(struct isp_reg,
+                                         u2.isp4010.port_ctrl),
+                      readw(&ha->reg->u2.isp4010.port_ctrl));
+               printk(KERN_INFO "0x%02X port_status     = 0x%08X\n",
+                      (uint8_t) offsetof(struct isp_reg,
+                                         u2.isp4010.port_status),
+                      readw(&ha->reg->u2.isp4010.port_status));
+               printk(KERN_INFO "0x%02X req_q_out       = 0x%08X\n",
+                      (uint8_t) offsetof(struct isp_reg,
+                                         u2.isp4010.req_q_out),
+                      readw(&ha->reg->u2.isp4010.req_q_out));
+               printk(KERN_INFO "0x%02X gp_out          = 0x%08X\n",
+                      (uint8_t) offsetof(struct isp_reg, u2.isp4010.gp_out),
+                      readw(&ha->reg->u2.isp4010.gp_out));
+               printk(KERN_INFO "0x%02X gp_in           = 0x%08X\n",
+                      (uint8_t) offsetof(struct isp_reg, u2.isp4010.gp_in),
+                      readw(&ha->reg->u2.isp4010.gp_in));
+               printk(KERN_INFO "0x%02X port_err_status = 0x%08X\n",
+                      (uint8_t) offsetof(struct isp_reg,
+                                         u2.isp4010.port_err_status),
+                      readw(&ha->reg->u2.isp4010.port_err_status));
+       }
+
+       else if (is_qla4022(ha)) {
+               printk(KERN_INFO "Page 0 Registers:\n");
+               printk(KERN_INFO "0x%02X ext_hw_conf     = 0x%08X\n",
+                      (uint8_t) offsetof(struct isp_reg,
+                                         u2.isp4022.p0.ext_hw_conf),
+                      readw(&ha->reg->u2.isp4022.p0.ext_hw_conf));
+               printk(KERN_INFO "0x%02X port_ctrl       = 0x%08X\n",
+                      (uint8_t) offsetof(struct isp_reg,
+                                         u2.isp4022.p0.port_ctrl),
+                      readw(&ha->reg->u2.isp4022.p0.port_ctrl));
+               printk(KERN_INFO "0x%02X port_status     = 0x%08X\n",
+                      (uint8_t) offsetof(struct isp_reg,
+                                         u2.isp4022.p0.port_status),
+                      readw(&ha->reg->u2.isp4022.p0.port_status));
+               printk(KERN_INFO "0x%02X gp_out          = 0x%08X\n",
+                      (uint8_t) offsetof(struct isp_reg,
+                                         u2.isp4022.p0.gp_out),
+                      readw(&ha->reg->u2.isp4022.p0.gp_out));
+               printk(KERN_INFO "0x%02X gp_in           = 0x%08X\n",
+                      (uint8_t) offsetof(struct isp_reg, u2.isp4022.p0.gp_in),
+                      readw(&ha->reg->u2.isp4022.p0.gp_in));
+               printk(KERN_INFO "0x%02X port_err_status = 0x%08X\n",
+                      (uint8_t) offsetof(struct isp_reg,
+                                         u2.isp4022.p0.port_err_status),
+                      readw(&ha->reg->u2.isp4022.p0.port_err_status));
+               printk(KERN_INFO "Page 1 Registers:\n");
+               writel(HOST_MEM_CFG_PAGE & set_rmask(CSR_SCSI_PAGE_SELECT),
+                      &ha->reg->ctrl_status);
+               printk(KERN_INFO "0x%02X req_q_out       = 0x%08X\n",
+                      (uint8_t) offsetof(struct isp_reg,
+                                         u2.isp4022.p1.req_q_out),
+                      readw(&ha->reg->u2.isp4022.p1.req_q_out));
+               writel(PORT_CTRL_STAT_PAGE & set_rmask(CSR_SCSI_PAGE_SELECT),
+                      &ha->reg->ctrl_status);
+       }
+}
+
+void qla4xxx_dump_mbox_registers(struct scsi_qla_host *ha)
+{
+       unsigned long flags = 0;
+       int i = 0;
+       spin_lock_irqsave(&ha->hardware_lock, flags);
+       for (i = 1; i < MBOX_REG_COUNT; i++)
+               printk(KERN_INFO "  Mailbox[%d] = %08x\n", i,
+                      readw(&ha->reg->mailbox[i]));
+       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+}
+
+void qla4xxx_dump_registers(struct scsi_qla_host *ha)
+{
+       unsigned long flags = 0;
+       spin_lock_irqsave(&ha->hardware_lock, flags);
+       __dump_registers(ha);
+       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+}
+
+void qla4xxx_dump_buffer(void *b, uint32_t size)
+{
+       uint32_t cnt;
+       uint8_t *c = b;
+
+       printk(" 0   1   2   3   4   5   6   7   8   9  Ah  Bh  Ch  Dh  Eh  "
+              "Fh\n");
+       printk("------------------------------------------------------------"
+              "--\n");
+       for (cnt = 0; cnt < size; cnt++, c++) {
+               printk(KERN_DEBUG "%02x", *c);
+               if (!(cnt % 16))
+                       printk(KERN_DEBUG "\n");
+
+               else
+                       printk(KERN_DEBUG "  ");
+       }
+       if (cnt % 16)
+               printk(KERN_DEBUG "\n");
+}
diff --git a/drivers/scsi/qla4xxx/ql4_dbg.h b/drivers/scsi/qla4xxx/ql4_dbg.h
new file mode 100644 (file)
index 0000000..3e99dcf
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * QLogic iSCSI HBA Driver
+ * Copyright (c)  2003-2006 QLogic Corporation
+ *
+ * See LICENSE.qla4xxx for copyright and licensing details.
+ */
+
+/*
+ * Driver debug definitions.
+ */
+/* #define QL_DEBUG  */                        /* DEBUG messages */
+/* #define QL_DEBUG_LEVEL_3  */                /* Output function tracing */
+/* #define QL_DEBUG_LEVEL_4  */
+/* #define QL_DEBUG_LEVEL_5  */
+/* #define QL_DEBUG_LEVEL_9  */
+
+#define QL_DEBUG_LEVEL_2       /* ALways enable error messagess */
+#if defined(QL_DEBUG)
+#define DEBUG(x)   do {x;} while (0);
+#else
+#define DEBUG(x)       do {} while (0);
+#endif
+
+#if defined(QL_DEBUG_LEVEL_2)
+#define DEBUG2(x)      do {if(qla4_extended_error_logging == 2) x;} while (0);
+#define DEBUG2_3(x)   do {x;} while (0);
+#else                          /*  */
+#define DEBUG2(x)      do {} while (0);
+#endif                         /*  */
+
+#if defined(QL_DEBUG_LEVEL_3)
+#define DEBUG3(x)      do {if(qla4_extended_error_logging == 3) x;} while (0);
+#else                          /*  */
+#define DEBUG3(x)      do {} while (0);
+#if !defined(QL_DEBUG_LEVEL_2)
+#define DEBUG2_3(x)    do {} while (0);
+#endif                         /*  */
+#endif                         /*  */
+#if defined(QL_DEBUG_LEVEL_4)
+#define DEBUG4(x)      do {x;} while (0);
+#else                          /*  */
+#define DEBUG4(x)      do {} while (0);
+#endif                         /*  */
+
+#if defined(QL_DEBUG_LEVEL_5)
+#define DEBUG5(x)      do {x;} while (0);
+#else                          /*  */
+#define DEBUG5(x)      do {} while (0);
+#endif                         /*  */
+
+#if defined(QL_DEBUG_LEVEL_9)
+#define DEBUG9(x)      do {x;} while (0);
+#else                          /*  */
+#define DEBUG9(x)      do {} while (0);
+#endif                         /*  */
diff --git a/drivers/scsi/qla4xxx/ql4_def.h b/drivers/scsi/qla4xxx/ql4_def.h
new file mode 100644 (file)
index 0000000..a7f6c7b
--- /dev/null
@@ -0,0 +1,586 @@
+/*
+ * QLogic iSCSI HBA Driver
+ * Copyright (c)  2003-2006 QLogic Corporation
+ *
+ * See LICENSE.qla4xxx for copyright and licensing details.
+ */
+
+#ifndef __QL4_DEF_H
+#define __QL4_DEF_H
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/list.h>
+#include <linux/pci.h>
+#include <linux/dma-mapping.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/dmapool.h>
+#include <linux/mempool.h>
+#include <linux/spinlock.h>
+#include <linux/workqueue.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/mutex.h>
+
+#include <net/tcp.h>
+#include <scsi/scsi.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_transport.h>
+#include <scsi/scsi_transport_iscsi.h>
+
+
+#ifndef PCI_DEVICE_ID_QLOGIC_ISP4010
+#define PCI_DEVICE_ID_QLOGIC_ISP4010   0x4010
+#endif
+
+#ifndef PCI_DEVICE_ID_QLOGIC_ISP4022
+#define PCI_DEVICE_ID_QLOGIC_ISP4022   0x4022
+#endif                         /*  */
+
+#define QLA_SUCCESS                    0
+#define QLA_ERROR                      1
+
+/*
+ * Data bit definitions
+ */
+#define BIT_0  0x1
+#define BIT_1  0x2
+#define BIT_2  0x4
+#define BIT_3  0x8
+#define BIT_4  0x10
+#define BIT_5  0x20
+#define BIT_6  0x40
+#define BIT_7  0x80
+#define BIT_8  0x100
+#define BIT_9  0x200
+#define BIT_10 0x400
+#define BIT_11 0x800
+#define BIT_12 0x1000
+#define BIT_13 0x2000
+#define BIT_14 0x4000
+#define BIT_15 0x8000
+#define BIT_16 0x10000
+#define BIT_17 0x20000
+#define BIT_18 0x40000
+#define BIT_19 0x80000
+#define BIT_20 0x100000
+#define BIT_21 0x200000
+#define BIT_22 0x400000
+#define BIT_23 0x800000
+#define BIT_24 0x1000000
+#define BIT_25 0x2000000
+#define BIT_26 0x4000000
+#define BIT_27 0x8000000
+#define BIT_28 0x10000000
+#define BIT_29 0x20000000
+#define BIT_30 0x40000000
+#define BIT_31 0x80000000
+
+/*
+ * Host adapter default definitions
+ ***********************************/
+#define MAX_HBAS               16
+#define MAX_BUSES              1
+#define MAX_TARGETS            (MAX_PRST_DEV_DB_ENTRIES +  MAX_DEV_DB_ENTRIES)
+#define MAX_LUNS               0xffff
+#define MAX_AEN_ENTRIES                256 /* should be > EXT_DEF_MAX_AEN_QUEUE */
+#define MAX_DDB_ENTRIES                (MAX_PRST_DEV_DB_ENTRIES + MAX_DEV_DB_ENTRIES)
+#define MAX_PDU_ENTRIES                32
+#define INVALID_ENTRY          0xFFFF
+#define MAX_CMDS_TO_RISC       1024
+#define MAX_SRBS               MAX_CMDS_TO_RISC
+#define MBOX_AEN_REG_COUNT     5
+#define MAX_INIT_RETRIES       5
+#define IOCB_HIWAT_CUSHION     16
+
+/*
+ * Buffer sizes
+ */
+#define REQUEST_QUEUE_DEPTH            MAX_CMDS_TO_RISC
+#define RESPONSE_QUEUE_DEPTH           64
+#define QUEUE_SIZE                     64
+#define DMA_BUFFER_SIZE                        512
+
+/*
+ * Misc
+ */
+#define MAC_ADDR_LEN                   6       /* in bytes */
+#define IP_ADDR_LEN                    4       /* in bytes */
+#define DRIVER_NAME                    "qla4xxx"
+
+#define MAX_LINKED_CMDS_PER_LUN                3
+#define MAX_REQS_SERVICED_PER_INTR     16
+
+#define ISCSI_IPADDR_SIZE              4       /* IP address size */
+#define ISCSI_ALIAS_SIZE               32      /* ISCSI Alais name size */
+#define ISCSI_NAME_SIZE                        255     /* ISCSI Name size -
+                                                * usually a string */
+
+#define LSDW(x) ((u32)((u64)(x)))
+#define MSDW(x) ((u32)((((u64)(x)) >> 16) >> 16))
+
+/*
+ * Retry & Timeout Values
+ */
+#define MBOX_TOV                       60
+#define SOFT_RESET_TOV                 30
+#define RESET_INTR_TOV                 3
+#define SEMAPHORE_TOV                  10
+#define ADAPTER_INIT_TOV               120
+#define ADAPTER_RESET_TOV              180
+#define EXTEND_CMD_TOV                 60
+#define WAIT_CMD_TOV                   30
+#define EH_WAIT_CMD_TOV                        120
+#define FIRMWARE_UP_TOV                        60
+#define RESET_FIRMWARE_TOV             30
+#define LOGOUT_TOV                     10
+#define IOCB_TOV_MARGIN                        10
+#define RELOGIN_TOV                    18
+#define ISNS_DEREG_TOV                 5
+
+#define MAX_RESET_HA_RETRIES           2
+
+/*
+ * SCSI Request Block structure         (srb)  that is placed
+ * on cmd->SCp location of every I/O    [We have 22 bytes available]
+ */
+struct srb {
+       struct list_head list;  /* (8)   */
+       struct scsi_qla_host *ha;       /* HA the SP is queued on */
+       struct ddb_entry        *ddb;
+       uint16_t flags;         /* (1) Status flags. */
+
+#define SRB_DMA_VALID          BIT_3   /* DMA Buffer mapped. */
+#define SRB_GOT_SENSE          BIT_4   /* sense data recieved. */
+       uint8_t state;          /* (1) Status flags. */
+
+#define SRB_NO_QUEUE_STATE      0      /* Request is in between states */
+#define SRB_FREE_STATE          1
+#define SRB_ACTIVE_STATE        3
+#define SRB_ACTIVE_TIMEOUT_STATE 4
+#define SRB_SUSPENDED_STATE     7      /* Request in suspended state */
+
+       struct scsi_cmnd *cmd;  /* (4) SCSI command block */
+       dma_addr_t dma_handle;  /* (4) for unmap of single transfers */
+       atomic_t ref_count;     /* reference count for this srb */
+       uint32_t fw_ddb_index;
+       uint8_t err_id;         /* error id */
+#define SRB_ERR_PORT      1    /* Request failed because "port down" */
+#define SRB_ERR_LOOP      2    /* Request failed because "loop down" */
+#define SRB_ERR_DEVICE    3    /* Request failed because "device error" */
+#define SRB_ERR_OTHER     4
+
+       uint16_t reserved;
+       uint16_t iocb_tov;
+       uint16_t iocb_cnt;      /* Number of used iocbs */
+       uint16_t cc_stat;
+       u_long r_start;         /* Time we recieve a cmd from OS */
+       u_long u_start;         /* Time when we handed the cmd to F/W */
+};
+
+       /*
+        * Device Database (DDB) structure
+        */
+struct ddb_entry {
+       struct list_head list;  /* ddb list */
+       struct scsi_qla_host *ha;
+       struct iscsi_cls_session *sess;
+       struct iscsi_cls_conn *conn;
+
+       atomic_t state;         /* DDB State */
+
+       unsigned long flags;    /* DDB Flags */
+
+       unsigned long dev_scan_wait_to_start_relogin;
+       unsigned long dev_scan_wait_to_complete_relogin;
+
+       uint16_t os_target_id;  /* Target ID */
+       uint16_t fw_ddb_index;  /* DDB firmware index */
+       uint8_t reserved[2];
+       uint32_t fw_ddb_device_state; /* F/W Device State  -- see ql4_fw.h */
+
+       uint32_t CmdSn;
+       uint16_t target_session_id;
+       uint16_t connection_id;
+       uint16_t exe_throttle;  /* Max mumber of cmds outstanding
+                                * simultaneously */
+       uint16_t task_mgmt_timeout; /* Min time for task mgmt cmds to
+                                    * complete */
+       uint16_t default_relogin_timeout; /*  Max time to wait for
+                                          *  relogin to complete */
+       uint16_t tcp_source_port_num;
+       uint32_t default_time2wait; /* Default Min time between
+                                    * relogins (+aens) */
+
+       atomic_t port_down_timer; /* Device connection timer */
+       atomic_t retry_relogin_timer; /* Min Time between relogins
+                                      * (4000 only) */
+       atomic_t relogin_timer; /* Max Time to wait for relogin to complete */
+       atomic_t relogin_retry_count; /* Num of times relogin has been
+                                      * retried */
+
+       uint16_t port;
+       uint32_t tpgt;
+       uint8_t ip_addr[ISCSI_IPADDR_SIZE];
+       uint8_t iscsi_name[ISCSI_NAME_SIZE];    /* 72 x48 */
+       uint8_t iscsi_alias[0x20];
+};
+
+/*
+ * DDB states.
+ */
+#define DDB_STATE_DEAD         0       /* We can no longer talk to
+                                        * this device */
+#define DDB_STATE_ONLINE       1       /* Device ready to accept
+                                        * commands */
+#define DDB_STATE_MISSING      2       /* Device logged off, trying
+                                        * to re-login */
+
+/*
+ * DDB flags.
+ */
+#define DF_RELOGIN             0       /* Relogin to device */
+#define DF_NO_RELOGIN          1       /* Do not relogin if IOCTL
+                                        * logged it out */
+#define DF_ISNS_DISCOVERED     2       /* Device was discovered via iSNS */
+#define DF_FO_MASKED           3
+
+/*
+ * Asynchronous Event Queue structure
+ */
+struct aen {
+       uint32_t mbox_sts[MBOX_AEN_REG_COUNT];
+};
+
+
+#include "ql4_fw.h"
+#include "ql4_nvram.h"
+
+/*
+ * Linux Host Adapter structure
+ */
+struct scsi_qla_host {
+       /* Linux adapter configuration data */
+       struct Scsi_Host *host; /* pointer to host data */
+       uint32_t tot_ddbs;
+       unsigned long flags;
+
+#define AF_ONLINE                    0 /* 0x00000001 */
+#define AF_INIT_DONE                 1 /* 0x00000002 */
+#define AF_MBOX_COMMAND                      2 /* 0x00000004 */
+#define AF_MBOX_COMMAND_DONE         3 /* 0x00000008 */
+#define AF_INTERRUPTS_ON             6 /* 0x00000040 Not Used */
+#define AF_GET_CRASH_RECORD          7 /* 0x00000080 */
+#define AF_LINK_UP                   8 /* 0x00000100 */
+#define AF_TOPCAT_CHIP_PRESENT       9 /* 0x00000200 */
+#define AF_IRQ_ATTACHED                     10 /* 0x00000400 */
+#define AF_ISNS_CMD_IN_PROCESS      12 /* 0x00001000 */
+#define AF_ISNS_CMD_DONE            13 /* 0x00002000 */
+
+       unsigned long dpc_flags;
+
+#define DPC_RESET_HA                 1 /* 0x00000002 */
+#define DPC_RETRY_RESET_HA           2 /* 0x00000004 */
+#define DPC_RELOGIN_DEVICE           3 /* 0x00000008 */
+#define DPC_RESET_HA_DESTROY_DDB_LIST 4 /* 0x00000010 */
+#define DPC_RESET_HA_INTR            5 /* 0x00000020 */
+#define DPC_ISNS_RESTART             7 /* 0x00000080 */
+#define DPC_AEN                              9 /* 0x00000200 */
+#define DPC_GET_DHCP_IP_ADDR        15 /* 0x00008000 */
+
+       uint16_t        iocb_cnt;
+       uint16_t        iocb_hiwat;
+
+       /* SRB cache. */
+#define SRB_MIN_REQ    128
+       mempool_t *srb_mempool;
+
+       /* pci information */
+       struct pci_dev *pdev;
+
+       struct isp_reg __iomem *reg; /* Base I/O address */
+       unsigned long pio_address;
+       unsigned long pio_length;
+#define MIN_IOBASE_LEN         0x100
+
+       uint16_t req_q_count;
+       uint8_t marker_needed;
+       uint8_t rsvd1;
+
+       unsigned long host_no;
+
+       /* NVRAM registers */
+       struct eeprom_data *nvram;
+       spinlock_t hardware_lock ____cacheline_aligned;
+       spinlock_t list_lock;
+       uint32_t   eeprom_cmd_data;
+
+       /* Counters for general statistics */
+       uint64_t adapter_error_count;
+       uint64_t device_error_count;
+       uint64_t total_io_count;
+       uint64_t total_mbytes_xferred;
+       uint64_t link_failure_count;
+       uint64_t invalid_crc_count;
+       uint32_t spurious_int_count;
+       uint32_t aborted_io_count;
+       uint32_t io_timeout_count;
+       uint32_t mailbox_timeout_count;
+       uint32_t seconds_since_last_intr;
+       uint32_t seconds_since_last_heartbeat;
+       uint32_t mac_index;
+
+       /* Info Needed for Management App */
+       /* --- From GetFwVersion --- */
+       uint32_t firmware_version[2];
+       uint32_t patch_number;
+       uint32_t build_number;
+
+       /* --- From Init_FW --- */
+       /* init_cb_t *init_cb; */
+       uint16_t firmware_options;
+       uint16_t tcp_options;
+       uint8_t ip_address[IP_ADDR_LEN];
+       uint8_t subnet_mask[IP_ADDR_LEN];
+       uint8_t gateway[IP_ADDR_LEN];
+       uint8_t alias[32];
+       uint8_t name_string[256];
+       uint8_t heartbeat_interval;
+       uint8_t rsvd;
+
+       /* --- From FlashSysInfo --- */
+       uint8_t my_mac[MAC_ADDR_LEN];
+       uint8_t serial_number[16];
+
+       /* --- From GetFwState --- */
+       uint32_t firmware_state;
+       uint32_t board_id;
+       uint32_t addl_fw_state;
+
+       /* Linux kernel thread */
+       struct workqueue_struct *dpc_thread;
+       struct work_struct dpc_work;
+
+       /* Linux timer thread */
+       struct timer_list timer;
+       uint32_t timer_active;
+
+       /* Recovery Timers */
+       uint32_t port_down_retry_count;
+       uint32_t discovery_wait;
+       atomic_t check_relogin_timeouts;
+       uint32_t retry_reset_ha_cnt;
+       uint32_t isp_reset_timer;       /* reset test timer */
+       uint32_t nic_reset_timer;       /* simulated nic reset test timer */
+       int eh_start;
+       struct list_head free_srb_q;
+       uint16_t free_srb_q_count;
+       uint16_t num_srbs_allocated;
+
+       /* DMA Memory Block */
+       void *queues;
+       dma_addr_t queues_dma;
+       unsigned long queues_len;
+
+#define MEM_ALIGN_VALUE \
+           ((max(REQUEST_QUEUE_DEPTH, RESPONSE_QUEUE_DEPTH)) * \
+            sizeof(struct queue_entry))
+       /* request and response queue variables */
+       dma_addr_t request_dma;
+       struct queue_entry *request_ring;
+       struct queue_entry *request_ptr;
+       dma_addr_t response_dma;
+       struct queue_entry *response_ring;
+       struct queue_entry *response_ptr;
+       dma_addr_t shadow_regs_dma;
+       struct shadow_regs *shadow_regs;
+       uint16_t request_in;    /* Current indexes. */
+       uint16_t request_out;
+       uint16_t response_in;
+       uint16_t response_out;
+
+       /* aen queue variables */
+       uint16_t aen_q_count;   /* Number of available aen_q entries */
+       uint16_t aen_in;        /* Current indexes */
+       uint16_t aen_out;
+       struct aen aen_q[MAX_AEN_ENTRIES];
+
+       /* This mutex protects several threads to do mailbox commands
+        * concurrently.
+        */
+       struct mutex  mbox_sem;
+       wait_queue_head_t mailbox_wait_queue;
+
+       /* temporary mailbox status registers */
+       volatile uint8_t mbox_status_count;
+       volatile uint32_t mbox_status[MBOX_REG_COUNT];
+
+       /* local device database list (contains internal ddb entries) */
+       struct list_head ddb_list;
+
+       /* Map ddb_list entry by FW ddb index */
+       struct ddb_entry *fw_ddb_index_map[MAX_DDB_ENTRIES];
+
+};
+
+static inline int is_qla4010(struct scsi_qla_host *ha)
+{
+       return ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP4010;
+}
+
+static inline int is_qla4022(struct scsi_qla_host *ha)
+{
+       return ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP4022;
+}
+
+static inline int adapter_up(struct scsi_qla_host *ha)
+{
+       return (test_bit(AF_ONLINE, &ha->flags) != 0) &&
+               (test_bit(AF_LINK_UP, &ha->flags) != 0);
+}
+
+static inline struct scsi_qla_host* to_qla_host(struct Scsi_Host *shost)
+{
+       return (struct scsi_qla_host *)shost->hostdata;
+}
+
+static inline void __iomem* isp_semaphore(struct scsi_qla_host *ha)
+{
+       return (is_qla4022(ha) ?
+               &ha->reg->u1.isp4022.semaphore :
+               &ha->reg->u1.isp4010.nvram);
+}
+
+static inline void __iomem* isp_nvram(struct scsi_qla_host *ha)
+{
+       return (is_qla4022(ha) ?
+               &ha->reg->u1.isp4022.nvram :
+               &ha->reg->u1.isp4010.nvram);
+}
+
+static inline void __iomem* isp_ext_hw_conf(struct scsi_qla_host *ha)
+{
+       return (is_qla4022(ha) ?
+               &ha->reg->u2.isp4022.p0.ext_hw_conf :
+               &ha->reg->u2.isp4010.ext_hw_conf);
+}
+
+static inline void __iomem* isp_port_status(struct scsi_qla_host *ha)
+{
+       return (is_qla4022(ha) ?
+               &ha->reg->u2.isp4022.p0.port_status :
+               &ha->reg->u2.isp4010.port_status);
+}
+
+static inline void __iomem* isp_port_ctrl(struct scsi_qla_host *ha)
+{
+       return (is_qla4022(ha) ?
+               &ha->reg->u2.isp4022.p0.port_ctrl :
+               &ha->reg->u2.isp4010.port_ctrl);
+}
+
+static inline void __iomem* isp_port_error_status(struct scsi_qla_host *ha)
+{
+       return (is_qla4022(ha) ?
+               &ha->reg->u2.isp4022.p0.port_err_status :
+               &ha->reg->u2.isp4010.port_err_status);
+}
+
+static inline void __iomem * isp_gp_out(struct scsi_qla_host *ha)
+{
+       return (is_qla4022(ha) ?
+               &ha->reg->u2.isp4022.p0.gp_out :
+               &ha->reg->u2.isp4010.gp_out);
+}
+
+static inline int eeprom_ext_hw_conf_offset(struct scsi_qla_host *ha)
+{
+       return (is_qla4022(ha) ?
+               offsetof(struct eeprom_data, isp4022.ext_hw_conf) / 2 :
+               offsetof(struct eeprom_data, isp4010.ext_hw_conf) / 2);
+}
+
+int ql4xxx_sem_spinlock(struct scsi_qla_host * ha, u32 sem_mask, u32 sem_bits);
+void ql4xxx_sem_unlock(struct scsi_qla_host * ha, u32 sem_mask);
+int ql4xxx_sem_lock(struct scsi_qla_host * ha, u32 sem_mask, u32 sem_bits);
+
+static inline int ql4xxx_lock_flash(struct scsi_qla_host *a)
+{
+       if (is_qla4022(a))
+               return ql4xxx_sem_spinlock(a, QL4022_FLASH_SEM_MASK,
+                                          (QL4022_RESOURCE_BITS_BASE_CODE |
+                                           (a->mac_index)) << 13);
+       else
+               return ql4xxx_sem_spinlock(a, QL4010_FLASH_SEM_MASK,
+                                          QL4010_FLASH_SEM_BITS);
+}
+
+static inline void ql4xxx_unlock_flash(struct scsi_qla_host *a)
+{
+       if (is_qla4022(a))
+               ql4xxx_sem_unlock(a, QL4022_FLASH_SEM_MASK);
+       else
+               ql4xxx_sem_unlock(a, QL4010_FLASH_SEM_MASK);
+}
+
+static inline int ql4xxx_lock_nvram(struct scsi_qla_host *a)
+{
+       if (is_qla4022(a))
+               return ql4xxx_sem_spinlock(a, QL4022_NVRAM_SEM_MASK,
+                                          (QL4022_RESOURCE_BITS_BASE_CODE |
+                                           (a->mac_index)) << 10);
+       else
+               return ql4xxx_sem_spinlock(a, QL4010_NVRAM_SEM_MASK,
+                                          QL4010_NVRAM_SEM_BITS);
+}
+
+static inline void ql4xxx_unlock_nvram(struct scsi_qla_host *a)
+{
+       if (is_qla4022(a))
+               ql4xxx_sem_unlock(a, QL4022_NVRAM_SEM_MASK);
+       else
+               ql4xxx_sem_unlock(a, QL4010_NVRAM_SEM_MASK);
+}
+
+static inline int ql4xxx_lock_drvr(struct scsi_qla_host *a)
+{
+       if (is_qla4022(a))
+               return ql4xxx_sem_lock(a, QL4022_DRVR_SEM_MASK,
+                                      (QL4022_RESOURCE_BITS_BASE_CODE |
+                                       (a->mac_index)) << 1);
+       else
+               return ql4xxx_sem_lock(a, QL4010_DRVR_SEM_MASK,
+                                      QL4010_DRVR_SEM_BITS);
+}
+
+static inline void ql4xxx_unlock_drvr(struct scsi_qla_host *a)
+{
+       if (is_qla4022(a))
+               ql4xxx_sem_unlock(a, QL4022_DRVR_SEM_MASK);
+       else
+               ql4xxx_sem_unlock(a, QL4010_DRVR_SEM_MASK);
+}
+
+/*---------------------------------------------------------------------------*/
+
+/* Defines for qla4xxx_initialize_adapter() and qla4xxx_recover_adapter() */
+#define PRESERVE_DDB_LIST      0
+#define REBUILD_DDB_LIST       1
+
+/* Defines for process_aen() */
+#define PROCESS_ALL_AENS        0
+#define FLUSH_DDB_CHANGED_AENS  1
+#define RELOGIN_DDB_CHANGED_AENS 2
+
+#include "ql4_version.h"
+#include "ql4_glbl.h"
+#include "ql4_dbg.h"
+#include "ql4_inline.h"
+
+
+#endif /*_QLA4XXX_H */
diff --git a/drivers/scsi/qla4xxx/ql4_fw.h b/drivers/scsi/qla4xxx/ql4_fw.h
new file mode 100644 (file)
index 0000000..427489d
--- /dev/null
@@ -0,0 +1,843 @@
+/*
+ * QLogic iSCSI HBA Driver
+ * Copyright (c)  2003-2006 QLogic Corporation
+ *
+ * See LICENSE.qla4xxx for copyright and licensing details.
+ */
+
+#ifndef _QLA4X_FW_H
+#define _QLA4X_FW_H
+
+
+#define MAX_PRST_DEV_DB_ENTRIES                64
+#define MIN_DISC_DEV_DB_ENTRY          MAX_PRST_DEV_DB_ENTRIES
+#define MAX_DEV_DB_ENTRIES 512
+
+/*************************************************************************
+ *
+ *             ISP 4010 I/O Register Set Structure and Definitions
+ *
+ *************************************************************************/
+
+struct port_ctrl_stat_regs {
+       __le32 ext_hw_conf;     /*  80 x50  R/W */
+       __le32 intChipConfiguration; /*  84 x54 */
+       __le32 port_ctrl;       /*  88 x58 */
+       __le32 port_status;     /*  92 x5c */
+       __le32 HostPrimMACHi;   /*  96 x60 */
+       __le32 HostPrimMACLow;  /* 100 x64 */
+       __le32 HostSecMACHi;    /* 104 x68 */
+       __le32 HostSecMACLow;   /* 108 x6c */
+       __le32 EPPrimMACHi;     /* 112 x70 */
+       __le32 EPPrimMACLow;    /* 116 x74 */
+       __le32 EPSecMACHi;      /* 120 x78 */
+       __le32 EPSecMACLow;     /* 124 x7c */
+       __le32 HostPrimIPHi;    /* 128 x80 */
+       __le32 HostPrimIPMidHi; /* 132 x84 */
+       __le32 HostPrimIPMidLow;        /* 136 x88 */
+       __le32 HostPrimIPLow;   /* 140 x8c */
+       __le32 HostSecIPHi;     /* 144 x90 */
+       __le32 HostSecIPMidHi;  /* 148 x94 */
+       __le32 HostSecIPMidLow; /* 152 x98 */
+       __le32 HostSecIPLow;    /* 156 x9c */
+       __le32 EPPrimIPHi;      /* 160 xa0 */
+       __le32 EPPrimIPMidHi;   /* 164 xa4 */
+       __le32 EPPrimIPMidLow;  /* 168 xa8 */
+       __le32 EPPrimIPLow;     /* 172 xac */
+       __le32 EPSecIPHi;       /* 176 xb0 */
+       __le32 EPSecIPMidHi;    /* 180 xb4 */
+       __le32 EPSecIPMidLow;   /* 184 xb8 */
+       __le32 EPSecIPLow;      /* 188 xbc */
+       __le32 IPReassemblyTimeout; /* 192 xc0 */
+       __le32 EthMaxFramePayload; /* 196 xc4 */
+       __le32 TCPMaxWindowSize; /* 200 xc8 */
+       __le32 TCPCurrentTimestampHi; /* 204 xcc */
+       __le32 TCPCurrentTimestampLow; /* 208 xd0 */
+       __le32 LocalRAMAddress; /* 212 xd4 */
+       __le32 LocalRAMData;    /* 216 xd8 */
+       __le32 PCSReserved1;    /* 220 xdc */
+       __le32 gp_out;          /* 224 xe0 */
+       __le32 gp_in;           /* 228 xe4 */
+       __le32 ProbeMuxAddr;    /* 232 xe8 */
+       __le32 ProbeMuxData;    /* 236 xec */
+       __le32 ERMQueueBaseAddr0; /* 240 xf0 */
+       __le32 ERMQueueBaseAddr1; /* 244 xf4 */
+       __le32 MACConfiguration; /* 248 xf8 */
+       __le32 port_err_status; /* 252 xfc  COR */
+};
+
+struct host_mem_cfg_regs {
+       __le32 NetRequestQueueOut; /*  80 x50 */
+       __le32 NetRequestQueueOutAddrHi; /*  84 x54 */
+       __le32 NetRequestQueueOutAddrLow; /*  88 x58 */
+       __le32 NetRequestQueueBaseAddrHi; /*  92 x5c */
+       __le32 NetRequestQueueBaseAddrLow; /*  96 x60 */
+       __le32 NetRequestQueueLength; /* 100 x64 */
+       __le32 NetResponseQueueIn; /* 104 x68 */
+       __le32 NetResponseQueueInAddrHi; /* 108 x6c */
+       __le32 NetResponseQueueInAddrLow; /* 112 x70 */
+       __le32 NetResponseQueueBaseAddrHi; /* 116 x74 */
+       __le32 NetResponseQueueBaseAddrLow; /* 120 x78 */
+       __le32 NetResponseQueueLength; /* 124 x7c */
+       __le32 req_q_out;       /* 128 x80 */
+       __le32 RequestQueueOutAddrHi; /* 132 x84 */
+       __le32 RequestQueueOutAddrLow; /* 136 x88 */
+       __le32 RequestQueueBaseAddrHi; /* 140 x8c */
+       __le32 RequestQueueBaseAddrLow; /* 144 x90 */
+       __le32 RequestQueueLength; /* 148 x94 */
+       __le32 ResponseQueueIn; /* 152 x98 */
+       __le32 ResponseQueueInAddrHi; /* 156 x9c */
+       __le32 ResponseQueueInAddrLow; /* 160 xa0 */
+       __le32 ResponseQueueBaseAddrHi; /* 164 xa4 */
+       __le32 ResponseQueueBaseAddrLow; /* 168 xa8 */
+       __le32 ResponseQueueLength; /* 172 xac */
+       __le32 NetRxLargeBufferQueueOut; /* 176 xb0 */
+       __le32 NetRxLargeBufferQueueBaseAddrHi; /* 180 xb4 */
+       __le32 NetRxLargeBufferQueueBaseAddrLow; /* 184 xb8 */
+       __le32 NetRxLargeBufferQueueLength; /* 188 xbc */
+       __le32 NetRxLargeBufferLength; /* 192 xc0 */
+       __le32 NetRxSmallBufferQueueOut; /* 196 xc4 */
+       __le32 NetRxSmallBufferQueueBaseAddrHi; /* 200 xc8 */
+       __le32 NetRxSmallBufferQueueBaseAddrLow; /* 204 xcc */
+       __le32 NetRxSmallBufferQueueLength; /* 208 xd0 */
+       __le32 NetRxSmallBufferLength; /* 212 xd4 */
+       __le32 HMCReserved0[10]; /* 216 xd8 */
+};
+
+struct local_ram_cfg_regs {
+       __le32 BufletSize;      /*  80 x50 */
+       __le32 BufletMaxCount;  /*  84 x54 */
+       __le32 BufletCurrCount; /*  88 x58 */
+       __le32 BufletPauseThresholdCount; /*  92 x5c */
+       __le32 BufletTCPWinThresholdHi; /*  96 x60 */
+       __le32 BufletTCPWinThresholdLow; /* 100 x64 */
+       __le32 IPHashTableBaseAddr; /* 104 x68 */
+       __le32 IPHashTableSize; /* 108 x6c */
+       __le32 TCPHashTableBaseAddr; /* 112 x70 */
+       __le32 TCPHashTableSize; /* 116 x74 */
+       __le32 NCBAreaBaseAddr; /* 120 x78 */
+       __le32 NCBMaxCount;     /* 124 x7c */
+       __le32 NCBCurrCount;    /* 128 x80 */
+       __le32 DRBAreaBaseAddr; /* 132 x84 */
+       __le32 DRBMaxCount;     /* 136 x88 */
+       __le32 DRBCurrCount;    /* 140 x8c */
+       __le32 LRCReserved[28]; /* 144 x90 */
+};
+
+struct prot_stat_regs {
+       __le32 MACTxFrameCount; /*  80 x50   R */
+       __le32 MACTxByteCount;  /*  84 x54   R */
+       __le32 MACRxFrameCount; /*  88 x58   R */
+       __le32 MACRxByteCount;  /*  92 x5c   R */
+       __le32 MACCRCErrCount;  /*  96 x60   R */
+       __le32 MACEncErrCount;  /* 100 x64   R */
+       __le32 MACRxLengthErrCount; /* 104 x68   R */
+       __le32 IPTxPacketCount; /* 108 x6c   R */
+       __le32 IPTxByteCount;   /* 112 x70   R */
+       __le32 IPTxFragmentCount; /* 116 x74   R */
+       __le32 IPRxPacketCount; /* 120 x78   R */
+       __le32 IPRxByteCount;   /* 124 x7c   R */
+       __le32 IPRxFragmentCount; /* 128 x80   R */
+       __le32 IPDatagramReassemblyCount; /* 132 x84   R */
+       __le32 IPV6RxPacketCount; /* 136 x88   R */
+       __le32 IPErrPacketCount; /* 140 x8c   R */
+       __le32 IPReassemblyErrCount; /* 144 x90   R */
+       __le32 TCPTxSegmentCount; /* 148 x94   R */
+       __le32 TCPTxByteCount;  /* 152 x98   R */
+       __le32 TCPRxSegmentCount; /* 156 x9c   R */
+       __le32 TCPRxByteCount;  /* 160 xa0   R */
+       __le32 TCPTimerExpCount; /* 164 xa4   R */
+       __le32 TCPRxAckCount;   /* 168 xa8   R */
+       __le32 TCPTxAckCount;   /* 172 xac   R */
+       __le32 TCPRxErrOOOCount; /* 176 xb0   R */
+       __le32 PSReserved0;     /* 180 xb4 */
+       __le32 TCPRxWindowProbeUpdateCount; /* 184 xb8   R */
+       __le32 ECCErrCorrectionCount; /* 188 xbc   R */
+       __le32 PSReserved1[16]; /* 192 xc0 */
+};
+
+
+/*  remote register set (access via PCI memory read/write) */
+struct isp_reg {
+#define MBOX_REG_COUNT 8
+       __le32 mailbox[MBOX_REG_COUNT];
+
+       __le32 flash_address;   /* 0x20 */
+       __le32 flash_data;
+       __le32 ctrl_status;
+
+       union {
+               struct {
+                       __le32 nvram;
+                       __le32 reserved1[2]; /* 0x30 */
+               } __attribute__ ((packed)) isp4010;
+               struct {
+                       __le32 intr_mask;
+                       __le32 nvram; /* 0x30 */
+                       __le32 semaphore;
+               } __attribute__ ((packed)) isp4022;
+       } u1;
+
+       __le32 req_q_in;    /* SCSI Request Queue Producer Index */
+       __le32 rsp_q_out;   /* SCSI Completion Queue Consumer Index */
+
+       __le32 reserved2[4];    /* 0x40 */
+
+       union {
+               struct {
+                       __le32 ext_hw_conf; /* 0x50 */
+                       __le32 flow_ctrl;
+                       __le32 port_ctrl;
+                       __le32 port_status;
+
+                       __le32 reserved3[8]; /* 0x60 */
+
+                       __le32 req_q_out; /* 0x80 */
+
+                       __le32 reserved4[23]; /* 0x84 */
+
+                       __le32 gp_out; /* 0xe0 */
+                       __le32 gp_in;
+
+                       __le32 reserved5[5];
+
+                       __le32 port_err_status; /* 0xfc */
+               } __attribute__ ((packed)) isp4010;
+               struct {
+                       union {
+                               struct port_ctrl_stat_regs p0;
+                               struct host_mem_cfg_regs p1;
+                               struct local_ram_cfg_regs p2;
+                               struct prot_stat_regs p3;
+                               __le32 r_union[44];
+                       };
+
+               } __attribute__ ((packed)) isp4022;
+       } u2;
+};                             /* 256 x100 */
+
+
+/* Semaphore Defines for 4010 */
+#define QL4010_DRVR_SEM_BITS   0x00000030
+#define QL4010_GPIO_SEM_BITS   0x000000c0
+#define QL4010_SDRAM_SEM_BITS  0x00000300
+#define QL4010_PHY_SEM_BITS    0x00000c00
+#define QL4010_NVRAM_SEM_BITS  0x00003000
+#define QL4010_FLASH_SEM_BITS  0x0000c000
+
+#define QL4010_DRVR_SEM_MASK   0x00300000
+#define QL4010_GPIO_SEM_MASK   0x00c00000
+#define QL4010_SDRAM_SEM_MASK  0x03000000
+#define QL4010_PHY_SEM_MASK    0x0c000000
+#define QL4010_NVRAM_SEM_MASK  0x30000000
+#define QL4010_FLASH_SEM_MASK  0xc0000000
+
+/* Semaphore Defines for 4022 */
+#define QL4022_RESOURCE_MASK_BASE_CODE 0x7
+#define QL4022_RESOURCE_BITS_BASE_CODE 0x4
+
+
+#define QL4022_DRVR_SEM_MASK   (QL4022_RESOURCE_MASK_BASE_CODE << (1+16))
+#define QL4022_DDR_RAM_SEM_MASK (QL4022_RESOURCE_MASK_BASE_CODE << (4+16))
+#define QL4022_PHY_GIO_SEM_MASK (QL4022_RESOURCE_MASK_BASE_CODE << (7+16))
+#define QL4022_NVRAM_SEM_MASK  (QL4022_RESOURCE_MASK_BASE_CODE << (10+16))
+#define QL4022_FLASH_SEM_MASK  (QL4022_RESOURCE_MASK_BASE_CODE << (13+16))
+
+
+
+/* Page # defines for 4022 */
+#define PORT_CTRL_STAT_PAGE                    0       /* 4022 */
+#define HOST_MEM_CFG_PAGE                      1       /* 4022 */
+#define LOCAL_RAM_CFG_PAGE                     2       /* 4022 */
+#define PROT_STAT_PAGE                         3       /* 4022 */
+
+/* Register Mask - sets corresponding mask bits in the upper word */
+static inline uint32_t set_rmask(uint32_t val)
+{
+       return (val & 0xffff) | (val << 16);
+}
+
+
+static inline uint32_t clr_rmask(uint32_t val)
+{
+       return 0 | (val << 16);
+}
+
+/*  ctrl_status definitions */
+#define CSR_SCSI_PAGE_SELECT                   0x00000003
+#define CSR_SCSI_INTR_ENABLE                   0x00000004      /* 4010 */
+#define CSR_SCSI_RESET_INTR                    0x00000008
+#define CSR_SCSI_COMPLETION_INTR               0x00000010
+#define CSR_SCSI_PROCESSOR_INTR                        0x00000020
+#define CSR_INTR_RISC                          0x00000040
+#define CSR_BOOT_ENABLE                                0x00000080
+#define CSR_NET_PAGE_SELECT                    0x00000300      /* 4010 */
+#define CSR_FUNC_NUM                           0x00000700      /* 4022 */
+#define CSR_NET_RESET_INTR                     0x00000800      /* 4010 */
+#define CSR_FORCE_SOFT_RESET                   0x00002000      /* 4022 */
+#define CSR_FATAL_ERROR                                0x00004000
+#define CSR_SOFT_RESET                         0x00008000
+#define ISP_CONTROL_FN_MASK                    CSR_FUNC_NUM
+#define ISP_CONTROL_FN0_SCSI                   0x0500
+#define ISP_CONTROL_FN1_SCSI                   0x0700
+
+#define INTR_PENDING                           (CSR_SCSI_COMPLETION_INTR |\
+                                                CSR_SCSI_PROCESSOR_INTR |\
+                                                CSR_SCSI_RESET_INTR)
+
+/* ISP InterruptMask definitions */
+#define IMR_SCSI_INTR_ENABLE                   0x00000004      /* 4022 */
+
+/* ISP 4022 nvram definitions */
+#define NVR_WRITE_ENABLE                       0x00000010      /* 4022 */
+
+/*  ISP port_status definitions */
+
+/*  ISP Semaphore definitions */
+
+/*  ISP General Purpose Output definitions */
+#define GPOR_TOPCAT_RESET                      0x00000004
+
+/*  shadow registers (DMA'd from HA to system memory.  read only) */
+struct shadow_regs {
+       /* SCSI Request Queue Consumer Index */
+       __le32 req_q_out;       /*  0 x0   R */
+
+       /* SCSI Completion Queue Producer Index */
+       __le32 rsp_q_in;        /*  4 x4   R */
+};               /*  8 x8 */
+
+
+/*  External hardware configuration register */
+union external_hw_config_reg {
+       struct {
+               /* FIXME: Do we even need this?  All values are
+                * referred to by 16 bit quantities.  Platform and
+                * endianess issues. */
+               __le32 bReserved0:1;
+               __le32 bSDRAMProtectionMethod:2;
+               __le32 bSDRAMBanks:1;
+               __le32 bSDRAMChipWidth:1;
+               __le32 bSDRAMChipSize:2;
+               __le32 bParityDisable:1;
+               __le32 bExternalMemoryType:1;
+               __le32 bFlashBIOSWriteEnable:1;
+               __le32 bFlashUpperBankSelect:1;
+               __le32 bWriteBurst:2;
+               __le32 bReserved1:3;
+               __le32 bMask:16;
+       };
+       uint32_t Asuint32_t;
+};
+
+/*************************************************************************
+ *
+ *             Mailbox Commands Structures and Definitions
+ *
+ *************************************************************************/
+
+/*  Mailbox command definitions */
+#define MBOX_CMD_ABOUT_FW                      0x0009
+#define MBOX_CMD_LUN_RESET                     0x0016
+#define MBOX_CMD_GET_FW_STATUS                 0x001F
+#define MBOX_CMD_SET_ISNS_SERVICE              0x0021
+#define ISNS_DISABLE                           0
+#define ISNS_ENABLE                            1
+#define MBOX_CMD_READ_FLASH                    0x0026
+#define MBOX_CMD_CLEAR_DATABASE_ENTRY          0x0031
+#define MBOX_CMD_CONN_CLOSE_SESS_LOGOUT                0x0056
+#define LOGOUT_OPTION_CLOSE_SESSION            0x01
+#define LOGOUT_OPTION_RELOGIN                  0x02
+#define MBOX_CMD_EXECUTE_IOCB_A64              0x005A
+#define MBOX_CMD_INITIALIZE_FIRMWARE           0x0060
+#define MBOX_CMD_GET_INIT_FW_CTRL_BLOCK                0x0061
+#define MBOX_CMD_REQUEST_DATABASE_ENTRY                0x0062
+#define MBOX_CMD_SET_DATABASE_ENTRY            0x0063
+#define MBOX_CMD_GET_DATABASE_ENTRY            0x0064
+#define DDB_DS_UNASSIGNED                      0x00
+#define DDB_DS_NO_CONNECTION_ACTIVE            0x01
+#define DDB_DS_SESSION_ACTIVE                  0x04
+#define DDB_DS_SESSION_FAILED                  0x06
+#define DDB_DS_LOGIN_IN_PROCESS                        0x07
+#define MBOX_CMD_GET_FW_STATE                  0x0069
+
+/* Mailbox 1 */
+#define FW_STATE_READY                         0x0000
+#define FW_STATE_CONFIG_WAIT                   0x0001
+#define FW_STATE_ERROR                         0x0004
+#define FW_STATE_DHCP_IN_PROGRESS              0x0008
+
+/* Mailbox 3 */
+#define FW_ADDSTATE_OPTICAL_MEDIA              0x0001
+#define FW_ADDSTATE_DHCP_ENABLED               0x0002
+#define FW_ADDSTATE_LINK_UP                    0x0010
+#define FW_ADDSTATE_ISNS_SVC_ENABLED           0x0020
+#define MBOX_CMD_GET_DATABASE_ENTRY_DEFAULTS   0x006B
+#define MBOX_CMD_CONN_OPEN_SESS_LOGIN          0x0074
+#define MBOX_CMD_GET_CRASH_RECORD              0x0076  /* 4010 only */
+#define MBOX_CMD_GET_CONN_EVENT_LOG            0x0077
+
+/*  Mailbox status definitions */
+#define MBOX_COMPLETION_STATUS                 4
+#define MBOX_STS_BUSY                          0x0007
+#define MBOX_STS_INTERMEDIATE_COMPLETION       0x1000
+#define MBOX_STS_COMMAND_COMPLETE              0x4000
+#define MBOX_STS_COMMAND_ERROR                 0x4005
+
+#define MBOX_ASYNC_EVENT_STATUS                        8
+#define MBOX_ASTS_SYSTEM_ERROR                 0x8002
+#define MBOX_ASTS_REQUEST_TRANSFER_ERROR       0x8003
+#define MBOX_ASTS_RESPONSE_TRANSFER_ERROR      0x8004
+#define MBOX_ASTS_PROTOCOL_STATISTIC_ALARM     0x8005
+#define MBOX_ASTS_SCSI_COMMAND_PDU_REJECTED    0x8006
+#define MBOX_ASTS_LINK_UP                      0x8010
+#define MBOX_ASTS_LINK_DOWN                    0x8011
+#define MBOX_ASTS_DATABASE_CHANGED             0x8014
+#define MBOX_ASTS_UNSOLICITED_PDU_RECEIVED     0x8015
+#define MBOX_ASTS_SELF_TEST_FAILED             0x8016
+#define MBOX_ASTS_LOGIN_FAILED                 0x8017
+#define MBOX_ASTS_DNS                          0x8018
+#define MBOX_ASTS_HEARTBEAT                    0x8019
+#define MBOX_ASTS_NVRAM_INVALID                        0x801A
+#define MBOX_ASTS_MAC_ADDRESS_CHANGED          0x801B
+#define MBOX_ASTS_IP_ADDRESS_CHANGED           0x801C
+#define MBOX_ASTS_DHCP_LEASE_EXPIRED           0x801D
+#define MBOX_ASTS_DHCP_LEASE_ACQUIRED          0x801F
+#define MBOX_ASTS_ISNS_UNSOLICITED_PDU_RECEIVED 0x8021
+#define ISNS_EVENT_DATA_RECEIVED               0x0000
+#define ISNS_EVENT_CONNECTION_OPENED           0x0001
+#define ISNS_EVENT_CONNECTION_FAILED           0x0002
+#define MBOX_ASTS_IPSEC_SYSTEM_FATAL_ERROR     0x8022
+#define MBOX_ASTS_SUBNET_STATE_CHANGE          0x8027
+
+/*************************************************************************/
+
+/* Host Adapter Initialization Control Block (from host) */
+struct init_fw_ctrl_blk {
+       uint8_t Version;        /* 00 */
+       uint8_t Control;        /* 01 */
+
+       uint16_t FwOptions;     /* 02-03 */
+#define         FWOPT_HEARTBEAT_ENABLE           0x1000
+#define         FWOPT_SESSION_MODE               0x0040
+#define         FWOPT_INITIATOR_MODE             0x0020
+#define         FWOPT_TARGET_MODE                0x0010
+
+       uint16_t ExecThrottle;  /* 04-05 */
+       uint8_t RetryCount;     /* 06 */
+       uint8_t RetryDelay;     /* 07 */
+       uint16_t MaxEthFrPayloadSize;   /* 08-09 */
+       uint16_t AddFwOptions;  /* 0A-0B */
+
+       uint8_t HeartbeatInterval;      /* 0C */
+       uint8_t InstanceNumber; /* 0D */
+       uint16_t RES2;          /* 0E-0F */
+       uint16_t ReqQConsumerIndex;     /* 10-11 */
+       uint16_t ComplQProducerIndex;   /* 12-13 */
+       uint16_t ReqQLen;       /* 14-15 */
+       uint16_t ComplQLen;     /* 16-17 */
+       uint32_t ReqQAddrLo;    /* 18-1B */
+       uint32_t ReqQAddrHi;    /* 1C-1F */
+       uint32_t ComplQAddrLo;  /* 20-23 */
+       uint32_t ComplQAddrHi;  /* 24-27 */
+       uint32_t ShadowRegBufAddrLo;    /* 28-2B */
+       uint32_t ShadowRegBufAddrHi;    /* 2C-2F */
+
+       uint16_t iSCSIOptions;  /* 30-31 */
+
+       uint16_t TCPOptions;    /* 32-33 */
+
+       uint16_t IPOptions;     /* 34-35 */
+
+       uint16_t MaxPDUSize;    /* 36-37 */
+       uint16_t RcvMarkerInt;  /* 38-39 */
+       uint16_t SndMarkerInt;  /* 3A-3B */
+       uint16_t InitMarkerlessInt;     /* 3C-3D */
+       uint16_t FirstBurstSize;        /* 3E-3F */
+       uint16_t DefaultTime2Wait;      /* 40-41 */
+       uint16_t DefaultTime2Retain;    /* 42-43 */
+       uint16_t MaxOutStndngR2T;       /* 44-45 */
+       uint16_t KeepAliveTimeout;      /* 46-47 */
+       uint16_t PortNumber;    /* 48-49 */
+       uint16_t MaxBurstSize;  /* 4A-4B */
+       uint32_t RES4;          /* 4C-4F */
+       uint8_t IPAddr[4];      /* 50-53 */
+       uint8_t RES5[12];       /* 54-5F */
+       uint8_t SubnetMask[4];  /* 60-63 */
+       uint8_t RES6[12];       /* 64-6F */
+       uint8_t GatewayIPAddr[4];       /* 70-73 */
+       uint8_t RES7[12];       /* 74-7F */
+       uint8_t PriDNSIPAddr[4];        /* 80-83 */
+       uint8_t SecDNSIPAddr[4];        /* 84-87 */
+       uint8_t RES8[8];        /* 88-8F */
+       uint8_t Alias[32];      /* 90-AF */
+       uint8_t TargAddr[8];    /* B0-B7 *//* /FIXME: Remove?? */
+       uint8_t CHAPNameSecretsTable[8];        /* B8-BF */
+       uint8_t EthernetMACAddr[6];     /* C0-C5 */
+       uint16_t TargetPortalGroup;     /* C6-C7 */
+       uint8_t SendScale;      /* C8    */
+       uint8_t RecvScale;      /* C9    */
+       uint8_t TypeOfService;  /* CA    */
+       uint8_t Time2Live;      /* CB    */
+       uint16_t VLANPriority;  /* CC-CD */
+       uint16_t Reserved8;     /* CE-CF */
+       uint8_t SecIPAddr[4];   /* D0-D3 */
+       uint8_t Reserved9[12];  /* D4-DF */
+       uint8_t iSNSIPAddr[4];  /* E0-E3 */
+       uint16_t iSNSServerPortNumber;  /* E4-E5 */
+       uint8_t Reserved10[10]; /* E6-EF */
+       uint8_t SLPDAIPAddr[4]; /* F0-F3 */
+       uint8_t Reserved11[12]; /* F4-FF */
+       uint8_t iSCSINameString[256];   /* 100-1FF */
+};
+
+/*************************************************************************/
+
+struct dev_db_entry {
+       uint8_t options;        /* 00 */
+#define DDB_OPT_DISC_SESSION  0x10
+#define DDB_OPT_TARGET       0x02 /* device is a target */
+
+       uint8_t control;        /* 01 */
+
+       uint16_t exeThrottle;   /* 02-03 */
+       uint16_t exeCount;      /* 04-05 */
+       uint8_t retryCount;     /* 06    */
+       uint8_t retryDelay;     /* 07    */
+       uint16_t iSCSIOptions;  /* 08-09 */
+
+       uint16_t TCPOptions;    /* 0A-0B */
+
+       uint16_t IPOptions;     /* 0C-0D */
+
+       uint16_t maxPDUSize;    /* 0E-0F */
+       uint16_t rcvMarkerInt;  /* 10-11 */
+       uint16_t sndMarkerInt;  /* 12-13 */
+       uint16_t iSCSIMaxSndDataSegLen; /* 14-15 */
+       uint16_t firstBurstSize;        /* 16-17 */
+       uint16_t minTime2Wait;  /* 18-19 : RA :default_time2wait */
+       uint16_t maxTime2Retain;        /* 1A-1B */
+       uint16_t maxOutstndngR2T;       /* 1C-1D */
+       uint16_t keepAliveTimeout;      /* 1E-1F */
+       uint8_t ISID[6];        /* 20-25 big-endian, must be converted
+                                * to little-endian */
+       uint16_t TSID;          /* 26-27 */
+       uint16_t portNumber;    /* 28-29 */
+       uint16_t maxBurstSize;  /* 2A-2B */
+       uint16_t taskMngmntTimeout;     /* 2C-2D */
+       uint16_t reserved1;     /* 2E-2F */
+       uint8_t ipAddr[0x10];   /* 30-3F */
+       uint8_t iSCSIAlias[0x20];       /* 40-5F */
+       uint8_t targetAddr[0x20];       /* 60-7F */
+       uint8_t userID[0x20];   /* 80-9F */
+       uint8_t password[0x20]; /* A0-BF */
+       uint8_t iscsiName[0x100];       /* C0-1BF : xxzzy Make this a
+                                        * pointer to a string so we
+                                        * don't have to reserve soooo
+                                        * much RAM */
+       uint16_t ddbLink;       /* 1C0-1C1 */
+       uint16_t CHAPTableIndex; /* 1C2-1C3 */
+       uint16_t TargetPortalGroup; /* 1C4-1C5 */
+       uint16_t reserved2[2];  /* 1C6-1C7 */
+       uint32_t statSN;        /* 1C8-1CB */
+       uint32_t expStatSN;     /* 1CC-1CF */
+       uint16_t reserved3[0x2C]; /* 1D0-1FB */
+       uint16_t ddbValidCookie; /* 1FC-1FD */
+       uint16_t ddbValidSize;  /* 1FE-1FF */
+};
+
+/*************************************************************************/
+
+/* Flash definitions */
+
+#define FLASH_OFFSET_SYS_INFO  0x02000000
+#define FLASH_DEFAULTBLOCKSIZE 0x20000
+#define FLASH_EOF_OFFSET       (FLASH_DEFAULTBLOCKSIZE-8) /* 4 bytes
+                                                           * for EOF
+                                                           * signature */
+
+struct sys_info_phys_addr {
+       uint8_t address[6];     /* 00-05 */
+       uint8_t filler[2];      /* 06-07 */
+};
+
+struct flash_sys_info {
+       uint32_t cookie;        /* 00-03 */
+       uint32_t physAddrCount; /* 04-07 */
+       struct sys_info_phys_addr physAddr[4]; /* 08-27 */
+       uint8_t vendorId[128];  /* 28-A7 */
+       uint8_t productId[128]; /* A8-127 */
+       uint32_t serialNumber;  /* 128-12B */
+
+       /*  PCI Configuration values */
+       uint32_t pciDeviceVendor;       /* 12C-12F */
+       uint32_t pciDeviceId;   /* 130-133 */
+       uint32_t pciSubsysVendor;       /* 134-137 */
+       uint32_t pciSubsysId;   /* 138-13B */
+
+       /*  This validates version 1. */
+       uint32_t crumbs;        /* 13C-13F */
+
+       uint32_t enterpriseNumber;      /* 140-143 */
+
+       uint32_t mtu;           /* 144-147 */
+       uint32_t reserved0;     /* 148-14b */
+       uint32_t crumbs2;       /* 14c-14f */
+       uint8_t acSerialNumber[16];     /* 150-15f */
+       uint32_t crumbs3;       /* 160-16f */
+
+       /* Leave this last in the struct so it is declared invalid if
+        * any new items are added.
+        */
+       uint32_t reserved1[39]; /* 170-1ff */
+};     /* 200 */
+
+struct crash_record {
+       uint16_t fw_major_version;      /* 00 - 01 */
+       uint16_t fw_minor_version;      /* 02 - 03 */
+       uint16_t fw_patch_version;      /* 04 - 05 */
+       uint16_t fw_build_version;      /* 06 - 07 */
+
+       uint8_t build_date[16]; /* 08 - 17 */
+       uint8_t build_time[16]; /* 18 - 27 */
+       uint8_t build_user[16]; /* 28 - 37 */
+       uint8_t card_serial_num[16];    /* 38 - 47 */
+
+       uint32_t time_of_crash_in_secs; /* 48 - 4B */
+       uint32_t time_of_crash_in_ms;   /* 4C - 4F */
+
+       uint16_t out_RISC_sd_num_frames;        /* 50 - 51 */
+       uint16_t OAP_sd_num_words;      /* 52 - 53 */
+       uint16_t IAP_sd_num_frames;     /* 54 - 55 */
+       uint16_t in_RISC_sd_num_words;  /* 56 - 57 */
+
+       uint8_t reserved1[28];  /* 58 - 7F */
+
+       uint8_t out_RISC_reg_dump[256]; /* 80 -17F */
+       uint8_t in_RISC_reg_dump[256];  /*180 -27F */
+       uint8_t in_out_RISC_stack_dump[0];      /*280 - ??? */
+};
+
+struct conn_event_log_entry {
+#define MAX_CONN_EVENT_LOG_ENTRIES     100
+       uint32_t timestamp_sec; /* 00 - 03 seconds since boot */
+       uint32_t timestamp_ms;  /* 04 - 07 milliseconds since boot */
+       uint16_t device_index;  /* 08 - 09  */
+       uint16_t fw_conn_state; /* 0A - 0B  */
+       uint8_t event_type;     /* 0C - 0C  */
+       uint8_t error_code;     /* 0D - 0D  */
+       uint16_t error_code_detail;     /* 0E - 0F  */
+       uint8_t num_consecutive_events; /* 10 - 10  */
+       uint8_t rsvd[3];        /* 11 - 13  */
+};
+
+/*************************************************************************
+ *
+ *                             IOCB Commands Structures and Definitions
+ *
+ *************************************************************************/
+#define IOCB_MAX_CDB_LEN           16  /* Bytes in a CBD */
+#define IOCB_MAX_SENSEDATA_LEN     32  /* Bytes of sense data */
+
+/* IOCB header structure */
+struct qla4_header {
+       uint8_t entryType;
+#define ET_STATUS               0x03
+#define ET_MARKER               0x04
+#define ET_CONT_T1              0x0A
+#define ET_STATUS_CONTINUATION  0x10
+#define ET_CMND_T3              0x19
+#define ET_PASSTHRU0            0x3A
+#define ET_PASSTHRU_STATUS      0x3C
+
+       uint8_t entryStatus;
+       uint8_t systemDefined;
+       uint8_t entryCount;
+
+       /* SyetemDefined definition */
+};
+
+/* Generic queue entry structure*/
+struct queue_entry {
+       uint8_t data[60];
+       uint32_t signature;
+
+};
+
+/* 64 bit addressing segment counts*/
+
+#define COMMAND_SEG_A64          1
+#define CONTINUE_SEG_A64  5
+
+/* 64 bit addressing segment definition*/
+
+struct data_seg_a64 {
+       struct {
+               uint32_t addrLow;
+               uint32_t addrHigh;
+
+       } base;
+
+       uint32_t count;
+
+};
+
+/* Command Type 3 entry structure*/
+
+struct command_t3_entry {
+       struct qla4_header hdr; /* 00-03 */
+
+       uint32_t handle;        /* 04-07 */
+       uint16_t target;        /* 08-09 */
+       uint16_t connection_id; /* 0A-0B */
+
+       uint8_t control_flags;  /* 0C */
+
+       /* data direction  (bits 5-6) */
+#define CF_WRITE               0x20
+#define CF_READ                        0x40
+#define CF_NO_DATA             0x00
+
+       /* task attributes (bits 2-0) */
+#define CF_HEAD_TAG            0x03
+#define CF_ORDERED_TAG         0x02
+#define CF_SIMPLE_TAG          0x01
+
+       /* STATE FLAGS FIELD IS A PLACE HOLDER. THE FW WILL SET BITS
+        * IN THIS FIELD AS THE COMMAND IS PROCESSED. WHEN THE IOCB IS
+        * CHANGED TO AN IOSB THIS FIELD WILL HAVE THE STATE FLAGS SET
+        * PROPERLY.
+        */
+       uint8_t state_flags;    /* 0D */
+       uint8_t cmdRefNum;      /* 0E */
+       uint8_t reserved1;      /* 0F */
+       uint8_t cdb[IOCB_MAX_CDB_LEN];  /* 10-1F */
+       struct scsi_lun lun;    /* FCP LUN (BE). */
+       uint32_t cmdSeqNum;     /* 28-2B */
+       uint16_t timeout;       /* 2C-2D */
+       uint16_t dataSegCnt;    /* 2E-2F */
+       uint32_t ttlByteCnt;    /* 30-33 */
+       struct data_seg_a64 dataseg[COMMAND_SEG_A64];   /* 34-3F */
+
+};
+
+
+/* Continuation Type 1 entry structure*/
+struct continuation_t1_entry {
+       struct qla4_header hdr;
+
+       struct data_seg_a64 dataseg[CONTINUE_SEG_A64];
+
+};
+
+/* Parameterize for 64 or 32 bits */
+#define COMMAND_SEG    COMMAND_SEG_A64
+#define CONTINUE_SEG   CONTINUE_SEG_A64
+
+#define ET_COMMAND     ET_CMND_T3
+#define ET_CONTINUE    ET_CONT_T1
+
+/* Marker entry structure*/
+struct marker_entry {
+       struct qla4_header hdr; /* 00-03 */
+
+       uint32_t system_defined; /* 04-07 */
+       uint16_t target;        /* 08-09 */
+       uint16_t modifier;      /* 0A-0B */
+#define MM_LUN_RESET        0
+
+       uint16_t flags;         /* 0C-0D */
+       uint16_t reserved1;     /* 0E-0F */
+       struct scsi_lun lun;    /* FCP LUN (BE). */
+       uint64_t reserved2;     /* 18-1F */
+       uint64_t reserved3;     /* 20-27 */
+       uint64_t reserved4;     /* 28-2F */
+       uint64_t reserved5;     /* 30-37 */
+       uint64_t reserved6;     /* 38-3F */
+};
+
+/* Status entry structure*/
+struct status_entry {
+       struct qla4_header hdr; /* 00-03 */
+
+       uint32_t handle;        /* 04-07 */
+
+       uint8_t scsiStatus;     /* 08 */
+#define SCSI_CHECK_CONDITION             0x02
+
+       uint8_t iscsiFlags;     /* 09 */
+#define ISCSI_FLAG_RESIDUAL_UNDER        0x02
+#define ISCSI_FLAG_RESIDUAL_OVER         0x04
+
+       uint8_t iscsiResponse;  /* 0A */
+
+       uint8_t completionStatus;       /* 0B */
+#define SCS_COMPLETE                     0x00
+#define SCS_INCOMPLETE                   0x01
+#define SCS_RESET_OCCURRED               0x04
+#define SCS_ABORTED                      0x05
+#define SCS_TIMEOUT                      0x06
+#define SCS_DATA_OVERRUN                 0x07
+#define SCS_DATA_UNDERRUN                0x15
+#define SCS_QUEUE_FULL                   0x1C
+#define SCS_DEVICE_UNAVAILABLE           0x28
+#define SCS_DEVICE_LOGGED_OUT            0x29
+
+       uint8_t reserved1;      /* 0C */
+
+       /* state_flags MUST be at the same location as state_flags in
+        * the Command_T3/4_Entry */
+       uint8_t state_flags;    /* 0D */
+
+       uint16_t senseDataByteCnt;      /* 0E-0F */
+       uint32_t residualByteCnt;       /* 10-13 */
+       uint32_t bidiResidualByteCnt;   /* 14-17 */
+       uint32_t expSeqNum;     /* 18-1B */
+       uint32_t maxCmdSeqNum;  /* 1C-1F */
+       uint8_t senseData[IOCB_MAX_SENSEDATA_LEN];      /* 20-3F */
+
+};
+
+struct passthru0 {
+       struct qla4_header hdr;                /* 00-03 */
+       uint32_t handle;        /* 04-07 */
+       uint16_t target;        /* 08-09 */
+       uint16_t connectionID;  /* 0A-0B */
+#define ISNS_DEFAULT_SERVER_CONN_ID    ((uint16_t)0x8000)
+
+       uint16_t controlFlags;  /* 0C-0D */
+#define PT_FLAG_ETHERNET_FRAME         0x8000
+#define PT_FLAG_ISNS_PDU               0x8000
+#define PT_FLAG_SEND_BUFFER            0x0200
+#define PT_FLAG_WAIT_4_RESPONSE                0x0100
+
+       uint16_t timeout;       /* 0E-0F */
+#define PT_DEFAULT_TIMEOUT             30 /* seconds */
+
+       struct data_seg_a64 outDataSeg64;       /* 10-1B */
+       uint32_t res1;          /* 1C-1F */
+       struct data_seg_a64 inDataSeg64;        /* 20-2B */
+       uint8_t res2[20];       /* 2C-3F */
+};
+
+struct passthru_status {
+       struct qla4_header hdr;                /* 00-03 */
+       uint32_t handle;        /* 04-07 */
+       uint16_t target;        /* 08-09 */
+       uint16_t connectionID;  /* 0A-0B */
+
+       uint8_t completionStatus;       /* 0C */
+#define PASSTHRU_STATUS_COMPLETE               0x01
+
+       uint8_t residualFlags;  /* 0D */
+
+       uint16_t timeout;       /* 0E-0F */
+       uint16_t portNumber;    /* 10-11 */
+       uint8_t res1[10];       /* 12-1B */
+       uint32_t outResidual;   /* 1C-1F */
+       uint8_t res2[12];       /* 20-2B */
+       uint32_t inResidual;    /* 2C-2F */
+       uint8_t res4[16];       /* 30-3F */
+};
+
+#endif /*  _QLA4X_FW_H */
diff --git a/drivers/scsi/qla4xxx/ql4_glbl.h b/drivers/scsi/qla4xxx/ql4_glbl.h
new file mode 100644 (file)
index 0000000..2c803ed
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * QLogic iSCSI HBA Driver
+ * Copyright (c)  2003-2006 QLogic Corporation
+ *
+ * See LICENSE.qla4xxx for copyright and licensing details.
+ */
+
+#ifndef __QLA4x_GBL_H
+#define        __QLA4x_GBL_H
+
+int qla4xxx_send_tgts(struct scsi_qla_host *ha, char *ip, uint16_t port);
+int qla4xxx_send_command_to_isp(struct scsi_qla_host *ha, struct srb * srb);
+int qla4xxx_initialize_adapter(struct scsi_qla_host * ha,
+                              uint8_t renew_ddb_list);
+int qla4xxx_soft_reset(struct scsi_qla_host *ha);
+irqreturn_t qla4xxx_intr_handler(int irq, void *dev_id);
+
+void qla4xxx_free_ddb_list(struct scsi_qla_host * ha);
+void qla4xxx_process_aen(struct scsi_qla_host * ha, uint8_t process_aen);
+
+int qla4xxx_get_dhcp_ip_address(struct scsi_qla_host * ha);
+int qla4xxx_relogin_device(struct scsi_qla_host * ha,
+                          struct ddb_entry * ddb_entry);
+int qla4xxx_reset_lun(struct scsi_qla_host * ha, struct ddb_entry * ddb_entry,
+                     int lun);
+int qla4xxx_get_flash(struct scsi_qla_host * ha, dma_addr_t dma_addr,
+                     uint32_t offset, uint32_t len);
+int qla4xxx_get_firmware_status(struct scsi_qla_host * ha);
+int qla4xxx_get_firmware_state(struct scsi_qla_host * ha);
+int qla4xxx_initialize_fw_cb(struct scsi_qla_host * ha);
+
+/* FIXME: Goodness!  this really wants a small struct to hold the
+ * parameters. On x86 the args will get passed on the stack! */
+int qla4xxx_get_fwddb_entry(struct scsi_qla_host *ha,
+                           uint16_t fw_ddb_index,
+                           struct dev_db_entry *fw_ddb_entry,
+                           dma_addr_t fw_ddb_entry_dma,
+                           uint32_t *num_valid_ddb_entries,
+                           uint32_t *next_ddb_index,
+                           uint32_t *fw_ddb_device_state,
+                           uint32_t *conn_err_detail,
+                           uint16_t *tcp_source_port_num,
+                           uint16_t *connection_id);
+
+struct ddb_entry * qla4xxx_alloc_ddb(struct scsi_qla_host * ha,
+                                    uint32_t fw_ddb_index);
+int qla4xxx_set_ddb_entry(struct scsi_qla_host * ha, uint16_t fw_ddb_index,
+                         dma_addr_t fw_ddb_entry_dma);
+
+void qla4xxx_mark_device_missing(struct scsi_qla_host *ha,
+                                struct ddb_entry *ddb_entry);
+u16 rd_nvram_word(struct scsi_qla_host * ha, int offset);
+void qla4xxx_get_crash_record(struct scsi_qla_host * ha);
+struct ddb_entry *qla4xxx_alloc_sess(struct scsi_qla_host *ha);
+int qla4xxx_add_sess(struct ddb_entry *);
+void qla4xxx_destroy_sess(struct ddb_entry *ddb_entry);
+int qla4xxx_conn_close_sess_logout(struct scsi_qla_host * ha,
+                                  uint16_t fw_ddb_index,
+                                  uint16_t connection_id,
+                                  uint16_t option);
+int qla4xxx_clear_database_entry(struct scsi_qla_host * ha,
+                                uint16_t fw_ddb_index);
+int qla4xxx_is_nvram_configuration_valid(struct scsi_qla_host * ha);
+int qla4xxx_get_fw_version(struct scsi_qla_host * ha);
+void qla4xxx_interrupt_service_routine(struct scsi_qla_host * ha,
+                                      uint32_t intr_status);
+int qla4xxx_init_rings(struct scsi_qla_host * ha);
+void qla4xxx_dump_buffer(void *b, uint32_t size);
+struct srb * qla4xxx_del_from_active_array(struct scsi_qla_host *ha, uint32_t index);
+void qla4xxx_srb_compl(struct scsi_qla_host *ha, struct srb *srb);
+int qla4xxx_reinitialize_ddb_list(struct scsi_qla_host * ha);
+int qla4xxx_process_ddb_changed(struct scsi_qla_host * ha,
+                               uint32_t fw_ddb_index, uint32_t state);
+
+extern int qla4_extended_error_logging;
+extern int ql4xdiscoverywait;
+extern int ql4xdontresethba;
+#endif                         /* _QLA4x_GBL_H */
diff --git a/drivers/scsi/qla4xxx/ql4_init.c b/drivers/scsi/qla4xxx/ql4_init.c
new file mode 100644 (file)
index 0000000..bb3a1c1
--- /dev/null
@@ -0,0 +1,1340 @@
+/*
+ * QLogic iSCSI HBA Driver
+ * Copyright (c)  2003-2006 QLogic Corporation
+ *
+ * See LICENSE.qla4xxx for copyright and licensing details.
+ */
+
+#include "ql4_def.h"
+
+/*
+ * QLogic ISP4xxx Hardware Support Function Prototypes.
+ */
+
+static void ql4xxx_set_mac_number(struct scsi_qla_host *ha)
+{
+       uint32_t value;
+       uint8_t func_number;
+       unsigned long flags;
+
+       /* Get the function number */
+       spin_lock_irqsave(&ha->hardware_lock, flags);
+       value = readw(&ha->reg->ctrl_status);
+       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
+       func_number = (uint8_t) ((value >> 4) & 0x30);
+       switch (value & ISP_CONTROL_FN_MASK) {
+       case ISP_CONTROL_FN0_SCSI:
+               ha->mac_index = 1;
+               break;
+       case ISP_CONTROL_FN1_SCSI:
+               ha->mac_index = 3;
+               break;
+       default:
+               DEBUG2(printk("scsi%ld: %s: Invalid function number, "
+                             "ispControlStatus = 0x%x\n", ha->host_no,
+                             __func__, value));
+               break;
+       }
+       DEBUG2(printk("scsi%ld: %s: mac_index %d.\n", ha->host_no, __func__,
+                     ha->mac_index));
+}
+
+/**
+ * qla4xxx_free_ddb - deallocate ddb
+ * @ha: pointer to host adapter structure.
+ * @ddb_entry: pointer to device database entry
+ *
+ * This routine deallocates and unlinks the specified ddb_entry from the
+ * adapter's
+ **/
+void qla4xxx_free_ddb(struct scsi_qla_host *ha, struct ddb_entry *ddb_entry)
+{
+       /* Remove device entry from list */
+       list_del_init(&ddb_entry->list);
+
+       /* Remove device pointer from index mapping arrays */
+       ha->fw_ddb_index_map[ddb_entry->fw_ddb_index] =
+               (struct ddb_entry *) INVALID_ENTRY;
+       ha->tot_ddbs--;
+
+       /* Free memory and scsi-ml struct for device entry */
+       qla4xxx_destroy_sess(ddb_entry);
+}
+
+/**
+ * qla4xxx_free_ddb_list - deallocate all ddbs
+ * @ha: pointer to host adapter structure.
+ *
+ * This routine deallocates and removes all devices on the sppecified adapter.
+ **/
+void qla4xxx_free_ddb_list(struct scsi_qla_host *ha)
+{
+       struct list_head *ptr;
+       struct ddb_entry *ddb_entry;
+
+       while (!list_empty(&ha->ddb_list)) {
+               ptr = ha->ddb_list.next;
+               /* Free memory for device entry and remove */
+               ddb_entry = list_entry(ptr, struct ddb_entry, list);
+               qla4xxx_free_ddb(ha, ddb_entry);
+       }
+}
+
+/**
+ * qla4xxx_init_rings - initialize hw queues
+ * @ha: pointer to host adapter structure.
+ *
+ * This routine initializes the internal queues for the specified adapter.
+ * The QLA4010 requires us to restart the queues at index 0.
+ * The QLA4000 doesn't care, so just default to QLA4010's requirement.
+ **/
+int qla4xxx_init_rings(struct scsi_qla_host *ha)
+{
+       unsigned long flags = 0;
+
+       /* Initialize request queue. */
+       spin_lock_irqsave(&ha->hardware_lock, flags);
+       ha->request_out = 0;
+       ha->request_in = 0;
+       ha->request_ptr = &ha->request_ring[ha->request_in];
+       ha->req_q_count = REQUEST_QUEUE_DEPTH;
+
+       /* Initialize response queue. */
+       ha->response_in = 0;
+       ha->response_out = 0;
+       ha->response_ptr = &ha->response_ring[ha->response_out];
+
+       /*
+        * Initialize DMA Shadow registers.  The firmware is really supposed to
+        * take care of this, but on some uniprocessor systems, the shadow
+        * registers aren't cleared-- causing the interrupt_handler to think
+        * there are responses to be processed when there aren't.
+        */
+       ha->shadow_regs->req_q_out = __constant_cpu_to_le32(0);
+       ha->shadow_regs->rsp_q_in = __constant_cpu_to_le32(0);
+       wmb();
+
+       writel(0, &ha->reg->req_q_in);
+       writel(0, &ha->reg->rsp_q_out);
+       readl(&ha->reg->rsp_q_out);
+
+       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
+       return QLA_SUCCESS;
+}
+
+/**
+ * qla4xxx_validate_mac_address - validate adapter MAC address(es)
+ * @ha: pointer to host adapter structure.
+ *
+ **/
+static int qla4xxx_validate_mac_address(struct scsi_qla_host *ha)
+{
+       struct flash_sys_info *sys_info;
+       dma_addr_t sys_info_dma;
+       int status = QLA_ERROR;
+
+       sys_info = dma_alloc_coherent(&ha->pdev->dev, sizeof(*sys_info),
+                                     &sys_info_dma, GFP_KERNEL);
+       if (sys_info == NULL) {
+               DEBUG2(printk("scsi%ld: %s: Unable to allocate dma buffer.\n",
+                             ha->host_no, __func__));
+
+               goto exit_validate_mac_no_free;
+       }
+       memset(sys_info, 0, sizeof(*sys_info));
+
+       /* Get flash sys info */
+       if (qla4xxx_get_flash(ha, sys_info_dma, FLASH_OFFSET_SYS_INFO,
+                             sizeof(*sys_info)) != QLA_SUCCESS) {
+               DEBUG2(printk("scsi%ld: %s: get_flash FLASH_OFFSET_SYS_INFO "
+                             "failed\n", ha->host_no, __func__));
+
+               goto exit_validate_mac;
+       }
+
+       /* Save M.A.C. address & serial_number */
+       memcpy(ha->my_mac, &sys_info->physAddr[0].address[0],
+              min(sizeof(ha->my_mac),
+                  sizeof(sys_info->physAddr[0].address)));
+       memcpy(ha->serial_number, &sys_info->acSerialNumber,
+              min(sizeof(ha->serial_number),
+                  sizeof(sys_info->acSerialNumber)));
+
+       status = QLA_SUCCESS;
+
+ exit_validate_mac:
+       dma_free_coherent(&ha->pdev->dev, sizeof(*sys_info), sys_info,
+                         sys_info_dma);
+
+ exit_validate_mac_no_free:
+       return status;
+}
+
+/**
+ * qla4xxx_init_local_data - initialize adapter specific local data
+ * @ha: pointer to host adapter structure.
+ *
+ **/
+static int qla4xxx_init_local_data(struct scsi_qla_host *ha)
+{
+       /* Initilize aen queue */
+       ha->aen_q_count = MAX_AEN_ENTRIES;
+
+       return qla4xxx_get_firmware_status(ha);
+}
+
+static int qla4xxx_fw_ready(struct scsi_qla_host *ha)
+{
+       uint32_t timeout_count;
+       int ready = 0;
+
+       DEBUG2(dev_info(&ha->pdev->dev, "Waiting for Firmware Ready..\n"));
+       for (timeout_count = ADAPTER_INIT_TOV; timeout_count > 0;
+            timeout_count--) {
+               if (test_and_clear_bit(DPC_GET_DHCP_IP_ADDR, &ha->dpc_flags))
+                       qla4xxx_get_dhcp_ip_address(ha);
+
+               /* Get firmware state. */
+               if (qla4xxx_get_firmware_state(ha) != QLA_SUCCESS) {
+                       DEBUG2(printk("scsi%ld: %s: unable to get firmware "
+                                     "state\n", ha->host_no, __func__));
+                       break;
+
+               }
+
+               if (ha->firmware_state & FW_STATE_ERROR) {
+                       DEBUG2(printk("scsi%ld: %s: an unrecoverable error has"
+                                     " occurred\n", ha->host_no, __func__));
+                       break;
+
+               }
+               if (ha->firmware_state & FW_STATE_CONFIG_WAIT) {
+                       /*
+                        * The firmware has not yet been issued an Initialize
+                        * Firmware command, so issue it now.
+                        */
+                       if (qla4xxx_initialize_fw_cb(ha) == QLA_ERROR)
+                               break;
+
+                       /* Go back and test for ready state - no wait. */
+                       continue;
+               }
+
+               if (ha->firmware_state == FW_STATE_READY) {
+                       DEBUG2(dev_info(&ha->pdev->dev, "Firmware Ready..\n"));
+                       /* The firmware is ready to process SCSI commands. */
+                       DEBUG2(dev_info(&ha->pdev->dev,
+                                         "scsi%ld: %s: MEDIA TYPE - %s\n",
+                                         ha->host_no,
+                                         __func__, (ha->addl_fw_state &
+                                                    FW_ADDSTATE_OPTICAL_MEDIA)
+                                         != 0 ? "OPTICAL" : "COPPER"));
+                       DEBUG2(dev_info(&ha->pdev->dev,
+                                         "scsi%ld: %s: DHCP STATE Enabled "
+                                         "%s\n",
+                                         ha->host_no, __func__,
+                                         (ha->addl_fw_state &
+                                          FW_ADDSTATE_DHCP_ENABLED) != 0 ?
+                                         "YES" : "NO"));
+                       DEBUG2(dev_info(&ha->pdev->dev,
+                                         "scsi%ld: %s: LINK %s\n",
+                                         ha->host_no, __func__,
+                                         (ha->addl_fw_state &
+                                          FW_ADDSTATE_LINK_UP) != 0 ?
+                                         "UP" : "DOWN"));
+                       DEBUG2(dev_info(&ha->pdev->dev,
+                                         "scsi%ld: %s: iSNS Service "
+                                         "Started %s\n",
+                                         ha->host_no, __func__,
+                                         (ha->addl_fw_state &
+                                          FW_ADDSTATE_ISNS_SVC_ENABLED) != 0 ?
+                                         "YES" : "NO"));
+
+                       ready = 1;
+                       break;
+               }
+               DEBUG2(printk("scsi%ld: %s: waiting on fw, state=%x:%x - "
+                             "seconds expired= %d\n", ha->host_no, __func__,
+                             ha->firmware_state, ha->addl_fw_state,
+                             timeout_count));
+               msleep(1000);
+       }                       /* end of for */
+
+       if (timeout_count <= 0)
+               DEBUG2(printk("scsi%ld: %s: FW Initialization timed out!\n",
+                             ha->host_no, __func__));
+
+       if (ha->firmware_state & FW_STATE_DHCP_IN_PROGRESS)  {
+               DEBUG2(printk("scsi%ld: %s: FW is reporting its waiting to"
+                             " grab an IP address from DHCP server\n",
+                             ha->host_no, __func__));
+               ready = 1;
+       }
+
+       return ready;
+}
+
+/**
+ * qla4xxx_init_firmware - initializes the firmware.
+ * @ha: pointer to host adapter structure.
+ *
+ **/
+static int qla4xxx_init_firmware(struct scsi_qla_host *ha)
+{
+       int status = QLA_ERROR;
+
+       dev_info(&ha->pdev->dev, "Initializing firmware..\n");
+       if (qla4xxx_initialize_fw_cb(ha) == QLA_ERROR) {
+               DEBUG2(printk("scsi%ld: %s: Failed to initialize firmware "
+                             "control block\n", ha->host_no, __func__));
+               return status;
+       }
+       if (!qla4xxx_fw_ready(ha))
+               return status;
+
+       set_bit(AF_ONLINE, &ha->flags);
+       return qla4xxx_get_firmware_status(ha);
+}
+
+static struct ddb_entry* qla4xxx_get_ddb_entry(struct scsi_qla_host *ha,
+                                              uint32_t fw_ddb_index)
+{
+       struct dev_db_entry *fw_ddb_entry = NULL;
+       dma_addr_t fw_ddb_entry_dma;
+       struct ddb_entry *ddb_entry = NULL;
+       int found = 0;
+       uint32_t device_state;
+
+       /* Make sure the dma buffer is valid */
+       fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev,
+                                         sizeof(*fw_ddb_entry),
+                                         &fw_ddb_entry_dma, GFP_KERNEL);
+       if (fw_ddb_entry == NULL) {
+               DEBUG2(printk("scsi%ld: %s: Unable to allocate dma buffer.\n",
+                             ha->host_no, __func__));
+               return NULL;
+       }
+
+       if (qla4xxx_get_fwddb_entry(ha, fw_ddb_index, fw_ddb_entry,
+                                   fw_ddb_entry_dma, NULL, NULL,
+                                   &device_state, NULL, NULL, NULL) ==
+           QLA_ERROR) {
+               DEBUG2(printk("scsi%ld: %s: failed get_ddb_entry for "
+                             "fw_ddb_index %d\n", ha->host_no, __func__,
+                             fw_ddb_index));
+               return NULL;
+       }
+
+       /* Allocate DDB if not already allocated. */
+       DEBUG2(printk("scsi%ld: %s: Looking for ddb[%d]\n", ha->host_no,
+                     __func__, fw_ddb_index));
+       list_for_each_entry(ddb_entry, &ha->ddb_list, list) {
+               if (memcmp(ddb_entry->iscsi_name, fw_ddb_entry->iscsiName,
+                          ISCSI_NAME_SIZE) == 0) {
+                       found++;
+                       break;
+               }
+       }
+
+       if (!found) {
+               DEBUG2(printk("scsi%ld: %s: ddb[%d] not found - allocating "
+                             "new ddb\n", ha->host_no, __func__,
+                             fw_ddb_index));
+               ddb_entry = qla4xxx_alloc_ddb(ha, fw_ddb_index);
+       }
+
+       /* if not found allocate new ddb */
+       dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry), fw_ddb_entry,
+                         fw_ddb_entry_dma);
+
+       return ddb_entry;
+}
+
+/**
+ * qla4xxx_update_ddb_entry - update driver's internal ddb
+ * @ha: pointer to host adapter structure.
+ * @ddb_entry: pointer to device database structure to be filled
+ * @fw_ddb_index: index of the ddb entry in fw ddb table
+ *
+ * This routine updates the driver's internal device database entry
+ * with information retrieved from the firmware's device database
+ * entry for the specified device. The ddb_entry->fw_ddb_index field
+ * must be initialized prior to        calling this routine
+ *
+ **/
+int qla4xxx_update_ddb_entry(struct scsi_qla_host *ha,
+                            struct ddb_entry *ddb_entry,
+                            uint32_t fw_ddb_index)
+{
+       struct dev_db_entry *fw_ddb_entry = NULL;
+       dma_addr_t fw_ddb_entry_dma;
+       int status = QLA_ERROR;
+
+       if (ddb_entry == NULL) {
+               DEBUG2(printk("scsi%ld: %s: ddb_entry is NULL\n", ha->host_no,
+                             __func__));
+               goto exit_update_ddb;
+       }
+
+       /* Make sure the dma buffer is valid */
+       fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev,
+                                         sizeof(*fw_ddb_entry),
+                                         &fw_ddb_entry_dma, GFP_KERNEL);
+       if (fw_ddb_entry == NULL) {
+               DEBUG2(printk("scsi%ld: %s: Unable to allocate dma buffer.\n",
+                             ha->host_no, __func__));
+
+               goto exit_update_ddb;
+       }
+
+       if (qla4xxx_get_fwddb_entry(ha, fw_ddb_index, fw_ddb_entry,
+                                   fw_ddb_entry_dma, NULL, NULL,
+                                   &ddb_entry->fw_ddb_device_state, NULL,
+                                   &ddb_entry->tcp_source_port_num,
+                                   &ddb_entry->connection_id) ==
+           QLA_ERROR) {
+               DEBUG2(printk("scsi%ld: %s: failed get_ddb_entry for "
+                             "fw_ddb_index %d\n", ha->host_no, __func__,
+                             fw_ddb_index));
+
+               goto exit_update_ddb;
+       }
+
+       status = QLA_SUCCESS;
+       ddb_entry->target_session_id = le16_to_cpu(fw_ddb_entry->TSID);
+       ddb_entry->task_mgmt_timeout =
+               le16_to_cpu(fw_ddb_entry->taskMngmntTimeout);
+       ddb_entry->CmdSn = 0;
+       ddb_entry->exe_throttle = le16_to_cpu(fw_ddb_entry->exeThrottle);
+       ddb_entry->default_relogin_timeout =
+               le16_to_cpu(fw_ddb_entry->taskMngmntTimeout);
+       ddb_entry->default_time2wait = le16_to_cpu(fw_ddb_entry->minTime2Wait);
+
+       /* Update index in case it changed */
+       ddb_entry->fw_ddb_index = fw_ddb_index;
+       ha->fw_ddb_index_map[fw_ddb_index] = ddb_entry;
+
+       ddb_entry->port = le16_to_cpu(fw_ddb_entry->portNumber);
+       ddb_entry->tpgt = le32_to_cpu(fw_ddb_entry->TargetPortalGroup);
+       memcpy(&ddb_entry->iscsi_name[0], &fw_ddb_entry->iscsiName[0],
+              min(sizeof(ddb_entry->iscsi_name),
+                  sizeof(fw_ddb_entry->iscsiName)));
+       memcpy(&ddb_entry->ip_addr[0], &fw_ddb_entry->ipAddr[0],
+              min(sizeof(ddb_entry->ip_addr), sizeof(fw_ddb_entry->ipAddr)));
+
+       DEBUG2(printk("scsi%ld: %s: ddb[%d] - State= %x status= %d.\n",
+                     ha->host_no, __func__, fw_ddb_index,
+                     ddb_entry->fw_ddb_device_state, status));
+
+ exit_update_ddb:
+       if (fw_ddb_entry)
+               dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),
+                                 fw_ddb_entry, fw_ddb_entry_dma);
+
+       return status;
+}
+
+/**
+ * qla4xxx_alloc_ddb - allocate device database entry
+ * @ha: Pointer to host adapter structure.
+ * @fw_ddb_index: Firmware's device database index
+ *
+ * This routine allocates a ddb_entry, ititializes some values, and
+ * inserts it into the ddb list.
+ **/
+struct ddb_entry * qla4xxx_alloc_ddb(struct scsi_qla_host *ha,
+                                    uint32_t fw_ddb_index)
+{
+       struct ddb_entry *ddb_entry;
+
+       DEBUG2(printk("scsi%ld: %s: fw_ddb_index [%d]\n", ha->host_no,
+                     __func__, fw_ddb_index));
+
+       ddb_entry = qla4xxx_alloc_sess(ha);
+       if (ddb_entry == NULL) {
+               DEBUG2(printk("scsi%ld: %s: Unable to allocate memory "
+                             "to add fw_ddb_index [%d]\n",
+                             ha->host_no, __func__, fw_ddb_index));
+               return ddb_entry;
+       }
+
+       ddb_entry->fw_ddb_index = fw_ddb_index;
+       atomic_set(&ddb_entry->port_down_timer, ha->port_down_retry_count);
+       atomic_set(&ddb_entry->retry_relogin_timer, INVALID_ENTRY);
+       atomic_set(&ddb_entry->relogin_timer, 0);
+       atomic_set(&ddb_entry->relogin_retry_count, 0);
+       atomic_set(&ddb_entry->state, DDB_STATE_ONLINE);
+       list_add_tail(&ddb_entry->list, &ha->ddb_list);
+       ha->fw_ddb_index_map[fw_ddb_index] = ddb_entry;
+       ha->tot_ddbs++;
+
+       return ddb_entry;
+}
+
+/**
+ * qla4xxx_configure_ddbs - builds driver ddb list
+ * @ha: Pointer to host adapter structure.
+ *
+ * This routine searches for all valid firmware ddb entries and builds
+ * an internal ddb list. Ddbs that are considered valid are those with
+ * a device state of SESSION_ACTIVE.
+ **/
+static int qla4xxx_build_ddb_list(struct scsi_qla_host *ha)
+{
+       int status = QLA_SUCCESS;
+       uint32_t fw_ddb_index = 0;
+       uint32_t next_fw_ddb_index = 0;
+       uint32_t ddb_state;
+       uint32_t conn_err, err_code;
+       struct ddb_entry *ddb_entry;
+
+       dev_info(&ha->pdev->dev, "Initializing DDBs ...\n");
+       for (fw_ddb_index = 0; fw_ddb_index < MAX_DDB_ENTRIES;
+            fw_ddb_index = next_fw_ddb_index) {
+               /* First, let's see if a device exists here */
+               if (qla4xxx_get_fwddb_entry(ha, fw_ddb_index, NULL, 0, NULL,
+                                           &next_fw_ddb_index, &ddb_state,
+                                           &conn_err, NULL, NULL) ==
+                   QLA_ERROR) {
+                       DEBUG2(printk("scsi%ld: %s: get_ddb_entry, "
+                                     "fw_ddb_index %d failed", ha->host_no,
+                                     __func__, fw_ddb_index));
+                       return QLA_ERROR;
+               }
+
+               DEBUG2(printk("scsi%ld: %s: Getting DDB[%d] ddbstate=0x%x, "
+                             "next_fw_ddb_index=%d.\n", ha->host_no, __func__,
+                             fw_ddb_index, ddb_state, next_fw_ddb_index));
+
+               /* Issue relogin, if necessary. */
+               if (ddb_state == DDB_DS_SESSION_FAILED ||
+                   ddb_state == DDB_DS_NO_CONNECTION_ACTIVE) {
+                       /* Try and login to device */
+                       DEBUG2(printk("scsi%ld: %s: Login to DDB[%d]\n",
+                                     ha->host_no, __func__, fw_ddb_index));
+                       err_code = ((conn_err & 0x00ff0000) >> 16);
+                       if (err_code == 0x1c || err_code == 0x06) {
+                               DEBUG2(printk("scsi%ld: %s send target "
+                                             "completed "
+                                             "or access denied failure\n",
+                                             ha->host_no, __func__));
+                       } else
+                               qla4xxx_set_ddb_entry(ha, fw_ddb_index, 0);
+               }
+
+               if (ddb_state != DDB_DS_SESSION_ACTIVE)
+                       goto next_one;
+               /*
+                * if fw_ddb with session active state found,
+                * add to ddb_list
+                */
+               DEBUG2(printk("scsi%ld: %s: DDB[%d] added to list\n",
+                             ha->host_no, __func__, fw_ddb_index));
+
+               /* Add DDB to internal our ddb list. */
+               ddb_entry = qla4xxx_get_ddb_entry(ha, fw_ddb_index);
+               if (ddb_entry == NULL) {
+                       DEBUG2(printk("scsi%ld: %s: Unable to allocate memory "
+                                     "for device at fw_ddb_index %d\n",
+                                     ha->host_no, __func__, fw_ddb_index));
+                       return QLA_ERROR;
+               }
+               /* Fill in the device structure */
+               if (qla4xxx_update_ddb_entry(ha, ddb_entry, fw_ddb_index) ==
+                   QLA_ERROR) {
+                       ha->fw_ddb_index_map[fw_ddb_index] =
+                               (struct ddb_entry *)INVALID_ENTRY;
+
+
+                       DEBUG2(printk("scsi%ld: %s: update_ddb_entry failed "
+                                     "for fw_ddb_index %d.\n",
+                                     ha->host_no, __func__, fw_ddb_index));
+                       return QLA_ERROR;
+               }
+
+next_one:
+               /* We know we've reached the last device when
+                * next_fw_ddb_index is 0 */
+               if (next_fw_ddb_index == 0)
+                       break;
+       }
+
+       dev_info(&ha->pdev->dev, "DDB list done..\n");
+
+       return status;
+}
+
+struct qla4_relog_scan {
+       int halt_wait;
+       uint32_t conn_err;
+       uint32_t err_code;
+       uint32_t fw_ddb_index;
+       uint32_t next_fw_ddb_index;
+       uint32_t fw_ddb_device_state;
+};
+
+static int qla4_test_rdy(struct scsi_qla_host *ha, struct qla4_relog_scan *rs)
+{
+       struct ddb_entry *ddb_entry;
+
+       /*
+        * Don't want to do a relogin if connection
+        * error is 0x1c.
+        */
+       rs->err_code = ((rs->conn_err & 0x00ff0000) >> 16);
+       if (rs->err_code == 0x1c || rs->err_code == 0x06) {
+               DEBUG2(printk(
+                              "scsi%ld: %s send target"
+                              " completed or "
+                              "access denied failure\n",
+                              ha->host_no, __func__));
+       } else {
+               /* We either have a device that is in
+                * the process of relogging in or a
+                * device that is waiting to be
+                * relogged in */
+               rs->halt_wait = 0;
+
+               ddb_entry = qla4xxx_lookup_ddb_by_fw_index(ha,
+                                                          rs->fw_ddb_index);
+               if (ddb_entry == NULL)
+                       return QLA_ERROR;
+
+               if (ddb_entry->dev_scan_wait_to_start_relogin != 0
+                   && time_after_eq(jiffies,
+                                    ddb_entry->
+                                    dev_scan_wait_to_start_relogin))
+               {
+                       ddb_entry->dev_scan_wait_to_start_relogin = 0;
+                       qla4xxx_set_ddb_entry(ha, rs->fw_ddb_index, 0);
+               }
+       }
+       return QLA_SUCCESS;
+}
+
+static int qla4_scan_for_relogin(struct scsi_qla_host *ha,
+                                struct qla4_relog_scan *rs)
+{
+       int error;
+
+       /* scan for relogins
+        * ----------------- */
+       for (rs->fw_ddb_index = 0; rs->fw_ddb_index < MAX_DDB_ENTRIES;
+            rs->fw_ddb_index = rs->next_fw_ddb_index) {
+               if (qla4xxx_get_fwddb_entry(ha, rs->fw_ddb_index, NULL, 0,
+                                           NULL, &rs->next_fw_ddb_index,
+                                           &rs->fw_ddb_device_state,
+                                           &rs->conn_err, NULL, NULL)
+                   == QLA_ERROR)
+                       return QLA_ERROR;
+
+               if (rs->fw_ddb_device_state == DDB_DS_LOGIN_IN_PROCESS)
+                       rs->halt_wait = 0;
+
+               if (rs->fw_ddb_device_state == DDB_DS_SESSION_FAILED ||
+                   rs->fw_ddb_device_state == DDB_DS_NO_CONNECTION_ACTIVE) {
+                       error = qla4_test_rdy(ha, rs);
+                       if (error)
+                               return error;
+               }
+
+               /* We know we've reached the last device when
+                * next_fw_ddb_index is 0 */
+               if (rs->next_fw_ddb_index == 0)
+                       break;
+       }
+       return QLA_SUCCESS;
+}
+
+/**
+ * qla4xxx_devices_ready - wait for target devices to be logged in
+ * @ha: pointer to adapter structure
+ *
+ * This routine waits up to ql4xdiscoverywait seconds
+ * F/W database during driver load time.
+ **/
+static int qla4xxx_devices_ready(struct scsi_qla_host *ha)
+{
+       int error;
+       unsigned long discovery_wtime;
+       struct qla4_relog_scan rs;
+
+       discovery_wtime = jiffies + (ql4xdiscoverywait * HZ);
+
+       DEBUG(printk("Waiting (%d) for devices ...\n", ql4xdiscoverywait));
+       do {
+               /* poll for AEN. */
+               qla4xxx_get_firmware_state(ha);
+               if (test_and_clear_bit(DPC_AEN, &ha->dpc_flags)) {
+                       /* Set time-between-relogin timer */
+                       qla4xxx_process_aen(ha, RELOGIN_DDB_CHANGED_AENS);
+               }
+
+               /* if no relogins active or needed, halt discvery wait */
+               rs.halt_wait = 1;
+
+               error = qla4_scan_for_relogin(ha, &rs);
+
+               if (rs.halt_wait) {
+                       DEBUG2(printk("scsi%ld: %s: Delay halted.  Devices "
+                                     "Ready.\n", ha->host_no, __func__));
+                       return QLA_SUCCESS;
+               }
+
+               msleep(2000);
+       } while (!time_after_eq(jiffies, discovery_wtime));
+
+       DEBUG3(qla4xxx_get_conn_event_log(ha));
+
+       return QLA_SUCCESS;
+}
+
+static void qla4xxx_flush_AENS(struct scsi_qla_host *ha)
+{
+       unsigned long wtime;
+
+       /* Flush the 0x8014 AEN from the firmware as a result of
+        * Auto connect. We are basically doing get_firmware_ddb()
+        * to determine whether we need to log back in or not.
+        *  Trying to do a set ddb before we have processed 0x8014
+        *  will result in another set_ddb() for the same ddb. In other
+        *  words there will be stale entries in the aen_q.
+        */
+       wtime = jiffies + (2 * HZ);
+       do {
+               if (qla4xxx_get_firmware_state(ha) == QLA_SUCCESS)
+                       if (ha->firmware_state & (BIT_2 | BIT_0))
+                               return;
+
+               if (test_and_clear_bit(DPC_AEN, &ha->dpc_flags))
+                       qla4xxx_process_aen(ha, FLUSH_DDB_CHANGED_AENS);
+
+               msleep(1000);
+       } while (!time_after_eq(jiffies, wtime));
+
+}
+
+static int qla4xxx_initialize_ddb_list(struct scsi_qla_host *ha)
+{
+       uint16_t fw_ddb_index;
+       int status = QLA_SUCCESS;
+
+       /* free the ddb list if is not empty */
+       if (!list_empty(&ha->ddb_list))
+               qla4xxx_free_ddb_list(ha);
+
+       for (fw_ddb_index = 0; fw_ddb_index < MAX_DDB_ENTRIES; fw_ddb_index++)
+               ha->fw_ddb_index_map[fw_ddb_index] =
+                       (struct ddb_entry *)INVALID_ENTRY;
+
+       ha->tot_ddbs = 0;
+
+       qla4xxx_flush_AENS(ha);
+
+       /*
+        * First perform device discovery for active
+        * fw ddb indexes and build
+        * ddb list.
+        */
+       if ((status = qla4xxx_build_ddb_list(ha)) == QLA_ERROR)
+               return status;
+
+       /* Wait for an AEN */
+       qla4xxx_devices_ready(ha);
+
+       /*
+        * Targets can come online after the inital discovery, so processing
+        * the aens here will catch them.
+        */
+       if (test_and_clear_bit(DPC_AEN, &ha->dpc_flags))
+               qla4xxx_process_aen(ha, PROCESS_ALL_AENS);
+
+       return status;
+}
+
+/**
+ * qla4xxx_update_ddb_list - update the driver ddb list
+ * @ha: pointer to host adapter structure.
+ *
+ * This routine obtains device information from the F/W database after
+ * firmware or adapter resets.  The device table is preserved.
+ **/
+int qla4xxx_reinitialize_ddb_list(struct scsi_qla_host *ha)
+{
+       int status = QLA_SUCCESS;
+       struct ddb_entry *ddb_entry, *detemp;
+
+       /* Update the device information for all devices. */
+       list_for_each_entry_safe(ddb_entry, detemp, &ha->ddb_list, list) {
+               qla4xxx_update_ddb_entry(ha, ddb_entry,
+                                        ddb_entry->fw_ddb_index);
+               if (ddb_entry->fw_ddb_device_state == DDB_DS_SESSION_ACTIVE) {
+                       atomic_set(&ddb_entry->state, DDB_STATE_ONLINE);
+                       DEBUG2(printk ("scsi%ld: %s: ddb index [%d] marked "
+                                      "ONLINE\n", ha->host_no, __func__,
+                                      ddb_entry->fw_ddb_index));
+               } else if (atomic_read(&ddb_entry->state) == DDB_STATE_ONLINE)
+                       qla4xxx_mark_device_missing(ha, ddb_entry);
+       }
+       return status;
+}
+
+/**
+ * qla4xxx_relogin_device - re-establish session
+ * @ha: Pointer to host adapter structure.
+ * @ddb_entry: Pointer to device database entry
+ *
+ * This routine does a session relogin with the specified device.
+ * The ddb entry must be assigned prior to making this call.
+ **/
+int qla4xxx_relogin_device(struct scsi_qla_host *ha,
+                          struct ddb_entry * ddb_entry)
+{
+       uint16_t relogin_timer;
+
+       relogin_timer = max(ddb_entry->default_relogin_timeout,
+                           (uint16_t)RELOGIN_TOV);
+       atomic_set(&ddb_entry->relogin_timer, relogin_timer);
+
+       DEBUG2(printk("scsi%ld: Relogin index [%d]. TOV=%d\n", ha->host_no,
+                     ddb_entry->fw_ddb_index, relogin_timer));
+
+       qla4xxx_set_ddb_entry(ha, ddb_entry->fw_ddb_index, 0);
+
+       return QLA_SUCCESS;
+}
+
+/**
+ * qla4010_get_topcat_presence - check if it is QLA4040 TopCat Chip
+ * @ha: Pointer to host adapter structure.
+ *
+ **/
+static int qla4010_get_topcat_presence(struct scsi_qla_host *ha)
+{
+       unsigned long flags;
+       uint16_t topcat;
+
+       if (ql4xxx_lock_nvram(ha) != QLA_SUCCESS)
+               return QLA_ERROR;
+       spin_lock_irqsave(&ha->hardware_lock, flags);
+       topcat = rd_nvram_word(ha, offsetof(struct eeprom_data,
+                                           isp4010.topcat));
+       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
+       if ((topcat & TOPCAT_MASK) == TOPCAT_PRESENT)
+               set_bit(AF_TOPCAT_CHIP_PRESENT, &ha->flags);
+       else
+               clear_bit(AF_TOPCAT_CHIP_PRESENT, &ha->flags);
+       ql4xxx_unlock_nvram(ha);
+       return QLA_SUCCESS;
+}
+
+
+static int qla4xxx_config_nvram(struct scsi_qla_host *ha)
+{
+       unsigned long flags;
+       union external_hw_config_reg extHwConfig;
+
+       DEBUG2(printk("scsi%ld: %s: Get EEProm parameters \n", ha->host_no,
+                     __func__));
+       if (ql4xxx_lock_flash(ha) != QLA_SUCCESS)
+               return (QLA_ERROR);
+       if (ql4xxx_lock_nvram(ha) != QLA_SUCCESS) {
+               ql4xxx_unlock_flash(ha);
+               return (QLA_ERROR);
+       }
+
+       /* Get EEPRom Parameters from NVRAM and validate */
+       dev_info(&ha->pdev->dev, "Configuring NVRAM ...\n");
+       if (qla4xxx_is_nvram_configuration_valid(ha) == QLA_SUCCESS) {
+               spin_lock_irqsave(&ha->hardware_lock, flags);
+               extHwConfig.Asuint32_t =
+                       rd_nvram_word(ha, eeprom_ext_hw_conf_offset(ha));
+               spin_unlock_irqrestore(&ha->hardware_lock, flags);
+       } else {
+               /*
+                * QLogic adapters should always have a valid NVRAM.
+                * If not valid, do not load.
+                */
+               dev_warn(&ha->pdev->dev,
+                          "scsi%ld: %s: EEProm checksum invalid.  "
+                          "Please update your EEPROM\n", ha->host_no,
+                          __func__);
+
+               /* set defaults */
+               if (is_qla4010(ha))
+                       extHwConfig.Asuint32_t = 0x1912;
+               else if (is_qla4022(ha))
+                       extHwConfig.Asuint32_t = 0x0023;
+       }
+       DEBUG(printk("scsi%ld: %s: Setting extHwConfig to 0xFFFF%04x\n",
+                    ha->host_no, __func__, extHwConfig.Asuint32_t));
+
+       spin_lock_irqsave(&ha->hardware_lock, flags);
+       writel((0xFFFF << 16) | extHwConfig.Asuint32_t, isp_ext_hw_conf(ha));
+       readl(isp_ext_hw_conf(ha));
+       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
+       ql4xxx_unlock_nvram(ha);
+       ql4xxx_unlock_flash(ha);
+
+       return (QLA_SUCCESS);
+}
+
+static void qla4x00_pci_config(struct scsi_qla_host *ha)
+{
+       uint16_t w, mwi;
+
+       dev_info(&ha->pdev->dev, "Configuring PCI space...\n");
+
+       pci_set_master(ha->pdev);
+       mwi = 0;
+       if (pci_set_mwi(ha->pdev))
+               mwi = PCI_COMMAND_INVALIDATE;
+       /*
+        * We want to respect framework's setting of PCI configuration space
+        * command register and also want to make sure that all bits of
+        * interest to us are properly set in command register.
+        */
+       pci_read_config_word(ha->pdev, PCI_COMMAND, &w);
+       w |= mwi | (PCI_COMMAND_PARITY | PCI_COMMAND_SERR);
+       w &= ~PCI_COMMAND_INTX_DISABLE;
+       pci_write_config_word(ha->pdev, PCI_COMMAND, w);
+}
+
+static int qla4xxx_start_firmware_from_flash(struct scsi_qla_host *ha)
+{
+       int status = QLA_ERROR;
+       uint32_t max_wait_time;
+       unsigned long flags;
+       uint32_t mbox_status;
+
+       dev_info(&ha->pdev->dev, "Starting firmware ...\n");
+
+       /*
+        * Start firmware from flash ROM
+        *
+        * WORKAROUND: Stuff a non-constant value that the firmware can
+        * use as a seed for a random number generator in MB7 prior to
+        * setting BOOT_ENABLE.  Fixes problem where the TCP
+        * connections use the same TCP ports after each reboot,
+        * causing some connections to not get re-established.
+        */
+       DEBUG(printk("scsi%d: %s: Start firmware from flash ROM\n",
+                    ha->host_no, __func__));
+
+       spin_lock_irqsave(&ha->hardware_lock, flags);
+       writel(jiffies, &ha->reg->mailbox[7]);
+       if (is_qla4022(ha))
+               writel(set_rmask(NVR_WRITE_ENABLE),
+                      &ha->reg->u1.isp4022.nvram);
+
+       writel(set_rmask(CSR_BOOT_ENABLE), &ha->reg->ctrl_status);
+       readl(&ha->reg->ctrl_status);
+       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
+       /* Wait for firmware to come UP. */
+       max_wait_time = FIRMWARE_UP_TOV * 4;
+       do {
+               uint32_t ctrl_status;
+
+               spin_lock_irqsave(&ha->hardware_lock, flags);
+               ctrl_status = readw(&ha->reg->ctrl_status);
+               mbox_status = readw(&ha->reg->mailbox[0]);
+               spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
+               if (ctrl_status & set_rmask(CSR_SCSI_PROCESSOR_INTR))
+                       break;
+               if (mbox_status == MBOX_STS_COMMAND_COMPLETE)
+                       break;
+
+               DEBUG2(printk("scsi%ld: %s: Waiting for boot firmware to "
+                             "complete... ctrl_sts=0x%x, remaining=%d\n",
+                             ha->host_no, __func__, ctrl_status,
+                             max_wait_time));
+
+               msleep(250);
+       } while ((max_wait_time--));
+
+       if (mbox_status == MBOX_STS_COMMAND_COMPLETE) {
+               DEBUG(printk("scsi%ld: %s: Firmware has started\n",
+                            ha->host_no, __func__));
+
+               spin_lock_irqsave(&ha->hardware_lock, flags);
+               writel(set_rmask(CSR_SCSI_PROCESSOR_INTR),
+                      &ha->reg->ctrl_status);
+               readl(&ha->reg->ctrl_status);
+               spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
+               status = QLA_SUCCESS;
+       } else {
+               printk(KERN_INFO "scsi%ld: %s: Boot firmware failed "
+                      "-  mbox status 0x%x\n", ha->host_no, __func__,
+                      mbox_status);
+               status = QLA_ERROR;
+       }
+       return status;
+}
+
+static int ql4xxx_lock_drvr_wait(struct scsi_qla_host *a)
+{
+#define QL4_LOCK_DRVR_WAIT     300
+#define QL4_LOCK_DRVR_SLEEP    100
+
+       int drvr_wait = QL4_LOCK_DRVR_WAIT;
+       while (drvr_wait) {
+               if (ql4xxx_lock_drvr(a) == 0) {
+                       msleep(QL4_LOCK_DRVR_SLEEP);
+                       if (drvr_wait) {
+                               DEBUG2(printk("scsi%ld: %s: Waiting for "
+                                             "Global Init Semaphore...n",
+                                             a->host_no,
+                                             __func__));
+                       }
+                       drvr_wait -= QL4_LOCK_DRVR_SLEEP;
+               } else {
+                       DEBUG2(printk("scsi%ld: %s: Global Init Semaphore "
+                                     "acquired.n", a->host_no, __func__));
+                       return QLA_SUCCESS;
+               }
+       }
+       return QLA_ERROR;
+}
+
+/**
+ * qla4xxx_start_firmware - starts qla4xxx firmware
+ * @ha: Pointer to host adapter structure.
+ *
+ * This routine performs the neccessary steps to start the firmware for
+ * the QLA4010 adapter.
+ **/
+static int qla4xxx_start_firmware(struct scsi_qla_host *ha)
+{
+       unsigned long flags = 0;
+       uint32_t mbox_status;
+       int status = QLA_ERROR;
+       int soft_reset = 1;
+       int config_chip = 0;
+
+       if (is_qla4010(ha)){
+               if (qla4010_get_topcat_presence(ha) != QLA_SUCCESS)
+                       return QLA_ERROR;
+       }
+
+       if (is_qla4022(ha))
+               ql4xxx_set_mac_number(ha);
+
+       if (ql4xxx_lock_drvr_wait(ha) != QLA_SUCCESS)
+               return QLA_ERROR;
+
+       spin_lock_irqsave(&ha->hardware_lock, flags);
+
+       DEBUG2(printk("scsi%ld: %s: port_ctrl   = 0x%08X\n", ha->host_no,
+                     __func__, readw(isp_port_ctrl(ha))));
+       DEBUG(printk("scsi%ld: %s: port_status = 0x%08X\n", ha->host_no,
+                    __func__, readw(isp_port_status(ha))));
+
+       /* Is Hardware already initialized? */
+       if ((readw(isp_port_ctrl(ha)) & 0x8000) != 0) {
+               DEBUG(printk("scsi%ld: %s: Hardware has already been "
+                            "initialized\n", ha->host_no, __func__));
+
+               /* Receive firmware boot acknowledgement */
+               mbox_status = readw(&ha->reg->mailbox[0]);
+
+               DEBUG2(printk("scsi%ld: %s: H/W Config complete - mbox[0]= "
+                             "0x%x\n", ha->host_no, __func__, mbox_status));
+
+               /* Is firmware already booted? */
+               if (mbox_status == 0) {
+                       /* F/W not running, must be config by net driver */
+                       config_chip = 1;
+                       soft_reset = 0;
+               } else {
+                       writel(set_rmask(CSR_SCSI_PROCESSOR_INTR),
+                              &ha->reg->ctrl_status);
+                       readl(&ha->reg->ctrl_status);
+                       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+                       if (qla4xxx_get_firmware_state(ha) == QLA_SUCCESS) {
+                               DEBUG2(printk("scsi%ld: %s: Get firmware "
+                                             "state -- state = 0x%x\n",
+                                             ha->host_no,
+                                             __func__, ha->firmware_state));
+                               /* F/W is running */
+                               if (ha->firmware_state &
+                                   FW_STATE_CONFIG_WAIT) {
+                                       DEBUG2(printk("scsi%ld: %s: Firmware "
+                                                     "in known state -- "
+                                                     "config and "
+                                                     "boot, state = 0x%x\n",
+                                                     ha->host_no, __func__,
+                                                     ha->firmware_state));
+                                       config_chip = 1;
+                                       soft_reset = 0;
+                               }
+                       } else {
+                               DEBUG2(printk("scsi%ld: %s: Firmware in "
+                                             "unknown state -- resetting,"
+                                             " state = "
+                                             "0x%x\n", ha->host_no, __func__,
+                                             ha->firmware_state));
+                       }
+                       spin_lock_irqsave(&ha->hardware_lock, flags);
+               }
+       } else {
+               DEBUG(printk("scsi%ld: %s: H/W initialization hasn't been "
+                            "started - resetting\n", ha->host_no, __func__));
+       }
+       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
+       DEBUG(printk("scsi%ld: %s: Flags soft_rest=%d, config= %d\n ",
+                    ha->host_no, __func__, soft_reset, config_chip));
+       if (soft_reset) {
+               DEBUG(printk("scsi%ld: %s: Issue Soft Reset\n", ha->host_no,
+                            __func__));
+               status = qla4xxx_soft_reset(ha);
+               if (status == QLA_ERROR) {
+                       DEBUG(printk("scsi%d: %s: Soft Reset failed!\n",
+                                    ha->host_no, __func__));
+                       ql4xxx_unlock_drvr(ha);
+                       return QLA_ERROR;
+               }
+               config_chip = 1;
+
+               /* Reset clears the semaphore, so aquire again */
+               if (ql4xxx_lock_drvr_wait(ha) != QLA_SUCCESS)
+                       return QLA_ERROR;
+       }
+
+       if (config_chip) {
+               if ((status = qla4xxx_config_nvram(ha)) == QLA_SUCCESS)
+                       status = qla4xxx_start_firmware_from_flash(ha);
+       }
+
+       ql4xxx_unlock_drvr(ha);
+       if (status == QLA_SUCCESS) {
+               qla4xxx_get_fw_version(ha);
+               if (test_and_clear_bit(AF_GET_CRASH_RECORD, &ha->flags))
+                       qla4xxx_get_crash_record(ha);
+       } else {
+               DEBUG(printk("scsi%ld: %s: Firmware has NOT started\n",
+                            ha->host_no, __func__));
+       }
+       return status;
+}
+
+
+/**
+ * qla4xxx_initialize_adapter - initiailizes hba
+ * @ha: Pointer to host adapter structure.
+ * @renew_ddb_list: Indicates what to do with the adapter's ddb list
+ *     after adapter recovery has completed.
+ *     0=preserve ddb list, 1=destroy and rebuild ddb list
+ *
+ * This routine parforms all of the steps necessary to initialize the adapter.
+ *
+ **/
+int qla4xxx_initialize_adapter(struct scsi_qla_host *ha,
+                              uint8_t renew_ddb_list)
+{
+       int status = QLA_ERROR;
+       int8_t ip_address[IP_ADDR_LEN] = {0} ;
+
+       ha->eeprom_cmd_data = 0;
+
+       qla4x00_pci_config(ha);
+
+       qla4xxx_disable_intrs(ha);
+
+       /* Initialize the Host adapter request/response queues and firmware */
+       if (qla4xxx_start_firmware(ha) == QLA_ERROR)
+               return status;
+
+       if (qla4xxx_validate_mac_address(ha) == QLA_ERROR)
+               return status;
+
+       if (qla4xxx_init_local_data(ha) == QLA_ERROR)
+               return status;
+
+       status = qla4xxx_init_firmware(ha);
+       if (status == QLA_ERROR)
+               return status;
+
+       /*
+        * FW is waiting to get an IP address from DHCP server: Skip building
+        * the ddb_list and wait for DHCP lease acquired aen to come in
+        * followed by 0x8014 aen" to trigger the tgt discovery process.
+        */
+       if (ha->firmware_state & FW_STATE_DHCP_IN_PROGRESS)
+               return status;
+
+       /* Skip device discovery if ip and subnet is zero */
+       if (memcmp(ha->ip_address, ip_address, IP_ADDR_LEN) == 0 ||
+           memcmp(ha->subnet_mask, ip_address, IP_ADDR_LEN) == 0)
+               return status;
+
+       if (renew_ddb_list == PRESERVE_DDB_LIST) {
+               /*
+                * We want to preserve lun states (i.e. suspended, etc.)
+                * for recovery initiated by the driver.  So just update
+                * the device states for the existing ddb_list.
+                */
+               qla4xxx_reinitialize_ddb_list(ha);
+       } else if (renew_ddb_list == REBUILD_DDB_LIST) {
+               /*
+                * We want to build the ddb_list from scratch during
+                * driver initialization and recovery initiated by the
+                * INT_HBA_RESET IOCTL.
+                */
+               status = qla4xxx_initialize_ddb_list(ha);
+               if (status == QLA_ERROR) {
+                       DEBUG2(printk("%s(%ld) Error occurred during build"
+                                     "ddb list\n", __func__, ha->host_no));
+                       goto exit_init_hba;
+               }
+
+       }
+       if (!ha->tot_ddbs) {
+               DEBUG2(printk("scsi%ld: Failed to initialize devices or none "
+                             "present in Firmware device database\n",
+                             ha->host_no));
+       }
+
+ exit_init_hba:
+       return status;
+
+}
+
+/**
+ * qla4xxx_add_device_dynamically - ddb addition due to an AEN
+ * @ha:  Pointer to host adapter structure.
+ * @fw_ddb_index:  Firmware's device database index
+ *
+ * This routine processes adds a device as a result of an 8014h AEN.
+ **/
+static void qla4xxx_add_device_dynamically(struct scsi_qla_host *ha,
+                                          uint32_t fw_ddb_index)
+{
+       struct ddb_entry * ddb_entry;
+
+       /* First allocate a device structure */
+       ddb_entry = qla4xxx_get_ddb_entry(ha, fw_ddb_index);
+       if (ddb_entry == NULL) {
+               DEBUG2(printk(KERN_WARNING
+                             "scsi%ld: Unable to allocate memory to add "
+                             "fw_ddb_index %d\n", ha->host_no, fw_ddb_index));
+               return;
+       }
+
+       if (qla4xxx_update_ddb_entry(ha, ddb_entry, fw_ddb_index) ==
+                                   QLA_ERROR) {
+               ha->fw_ddb_index_map[fw_ddb_index] =
+                                       (struct ddb_entry *)INVALID_ENTRY;
+               DEBUG2(printk(KERN_WARNING
+                             "scsi%ld: failed to add new device at index "
+                             "[%d]\n Unable to retrieve fw ddb entry\n",
+                             ha->host_no, fw_ddb_index));
+               qla4xxx_free_ddb(ha, ddb_entry);
+               return;
+       }
+
+       if (qla4xxx_add_sess(ddb_entry)) {
+               DEBUG2(printk(KERN_WARNING
+                             "scsi%ld: failed to add new device at index "
+                             "[%d]\n Unable to add connection and session\n",
+                             ha->host_no, fw_ddb_index));
+               qla4xxx_free_ddb(ha, ddb_entry);
+       }
+}
+
+/**
+ * qla4xxx_process_ddb_changed - process ddb state change
+ * @ha - Pointer to host adapter structure.
+ * @fw_ddb_index - Firmware's device database index
+ * @state - Device state
+ *
+ * This routine processes a Decive Database Changed AEN Event.
+ **/
+int qla4xxx_process_ddb_changed(struct scsi_qla_host *ha,
+                               uint32_t fw_ddb_index, uint32_t state)
+{
+       struct ddb_entry * ddb_entry;
+       uint32_t old_fw_ddb_device_state;
+
+       /* check for out of range index */
+       if (fw_ddb_index >= MAX_DDB_ENTRIES)
+               return QLA_ERROR;
+
+       /* Get the corresponging ddb entry */
+       ddb_entry = qla4xxx_lookup_ddb_by_fw_index(ha, fw_ddb_index);
+       /* Device does not currently exist in our database. */
+       if (ddb_entry == NULL) {
+               if (state == DDB_DS_SESSION_ACTIVE)
+                       qla4xxx_add_device_dynamically(ha, fw_ddb_index);
+               return QLA_SUCCESS;
+       }
+
+       /* Device already exists in our database. */
+       old_fw_ddb_device_state = ddb_entry->fw_ddb_device_state;
+       DEBUG2(printk("scsi%ld: %s DDB - old state= 0x%x, new state=0x%x for "
+                     "index [%d]\n", ha->host_no, __func__,
+                     ddb_entry->fw_ddb_device_state, state, fw_ddb_index));
+       if (old_fw_ddb_device_state == state &&
+           state == DDB_DS_SESSION_ACTIVE) {
+               /* Do nothing, state not changed. */
+               return QLA_SUCCESS;
+       }
+
+       ddb_entry->fw_ddb_device_state = state;
+       /* Device is back online. */
+       if (ddb_entry->fw_ddb_device_state == DDB_DS_SESSION_ACTIVE) {
+               atomic_set(&ddb_entry->port_down_timer,
+                          ha->port_down_retry_count);
+               atomic_set(&ddb_entry->state, DDB_STATE_ONLINE);
+               atomic_set(&ddb_entry->relogin_retry_count, 0);
+               atomic_set(&ddb_entry->relogin_timer, 0);
+               clear_bit(DF_RELOGIN, &ddb_entry->flags);
+               clear_bit(DF_NO_RELOGIN, &ddb_entry->flags);
+               iscsi_if_create_session_done(ddb_entry->conn);
+               /*
+                * Change the lun state to READY in case the lun TIMEOUT before
+                * the device came back.
+                */
+       } else {
+               /* Device went away, try to relogin. */
+               /* Mark device missing */
+               if (atomic_read(&ddb_entry->state) == DDB_STATE_ONLINE)
+                       qla4xxx_mark_device_missing(ha, ddb_entry);
+               /*
+                * Relogin if device state changed to a not active state.
+                * However, do not relogin if this aen is a result of an IOCTL
+                * logout (DF_NO_RELOGIN) or if this is a discovered device.
+                */
+               if (ddb_entry->fw_ddb_device_state == DDB_DS_SESSION_FAILED &&
+                   !test_bit(DF_RELOGIN, &ddb_entry->flags) &&
+                   !test_bit(DF_NO_RELOGIN, &ddb_entry->flags) &&
+                   !test_bit(DF_ISNS_DISCOVERED, &ddb_entry->flags)) {
+                       /*
+                        * This triggers a relogin.  After the relogin_timer
+                        * expires, the relogin gets scheduled.  We must wait a
+                        * minimum amount of time since receiving an 0x8014 AEN
+                        * with failed device_state or a logout response before
+                        * we can issue another relogin.
+                        */
+                       /* Firmware padds this timeout: (time2wait +1).
+                        * Driver retry to login should be longer than F/W.
+                        * Otherwise F/W will fail
+                        * set_ddb() mbx cmd with 0x4005 since it still
+                        * counting down its time2wait.
+                        */
+                       atomic_set(&ddb_entry->relogin_timer, 0);
+                       atomic_set(&ddb_entry->retry_relogin_timer,
+                                  ddb_entry->default_time2wait + 4);
+               }
+       }
+
+       return QLA_SUCCESS;
+}
+
diff --git a/drivers/scsi/qla4xxx/ql4_inline.h b/drivers/scsi/qla4xxx/ql4_inline.h
new file mode 100644 (file)
index 0000000..0d61797
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * QLogic iSCSI HBA Driver
+ * Copyright (c)  2003-2006 QLogic Corporation
+ *
+ * See LICENSE.qla4xxx for copyright and licensing details.
+ */
+
+/*
+ *
+ * qla4xxx_lookup_ddb_by_fw_index
+ *     This routine locates a device handle given the firmware device
+ *     database index.  If device doesn't exist, returns NULL.
+ *
+ * Input:
+ *     ha - Pointer to host adapter structure.
+ *     fw_ddb_index - Firmware's device database index
+ *
+ * Returns:
+ *     Pointer to the corresponding internal device database structure
+ */
+static inline struct ddb_entry *
+qla4xxx_lookup_ddb_by_fw_index(struct scsi_qla_host *ha, uint32_t fw_ddb_index)
+{
+       struct ddb_entry *ddb_entry = NULL;
+
+       if ((fw_ddb_index < MAX_DDB_ENTRIES) &&
+           (ha->fw_ddb_index_map[fw_ddb_index] !=
+               (struct ddb_entry *) INVALID_ENTRY)) {
+               ddb_entry = ha->fw_ddb_index_map[fw_ddb_index];
+       }
+
+       DEBUG3(printk("scsi%d: %s: index [%d], ddb_entry = %p\n",
+           ha->host_no, __func__, fw_ddb_index, ddb_entry));
+
+       return ddb_entry;
+}
+
+static inline void
+__qla4xxx_enable_intrs(struct scsi_qla_host *ha)
+{
+       if (is_qla4022(ha)) {
+               writel(set_rmask(IMR_SCSI_INTR_ENABLE),
+                      &ha->reg->u1.isp4022.intr_mask);
+               readl(&ha->reg->u1.isp4022.intr_mask);
+       } else {
+               writel(set_rmask(CSR_SCSI_INTR_ENABLE), &ha->reg->ctrl_status);
+               readl(&ha->reg->ctrl_status);
+       }
+       set_bit(AF_INTERRUPTS_ON, &ha->flags);
+}
+
+static inline void
+__qla4xxx_disable_intrs(struct scsi_qla_host *ha)
+{
+       if (is_qla4022(ha)) {
+               writel(clr_rmask(IMR_SCSI_INTR_ENABLE),
+                      &ha->reg->u1.isp4022.intr_mask);
+               readl(&ha->reg->u1.isp4022.intr_mask);
+       } else {
+               writel(clr_rmask(CSR_SCSI_INTR_ENABLE), &ha->reg->ctrl_status);
+               readl(&ha->reg->ctrl_status);
+       }
+       clear_bit(AF_INTERRUPTS_ON, &ha->flags);
+}
+
+static inline void
+qla4xxx_enable_intrs(struct scsi_qla_host *ha)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&ha->hardware_lock, flags);
+       __qla4xxx_enable_intrs(ha);
+       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+}
+
+static inline void
+qla4xxx_disable_intrs(struct scsi_qla_host *ha)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&ha->hardware_lock, flags);
+       __qla4xxx_disable_intrs(ha);
+       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+}
diff --git a/drivers/scsi/qla4xxx/ql4_iocb.c b/drivers/scsi/qla4xxx/ql4_iocb.c
new file mode 100644 (file)
index 0000000..c0a254b
--- /dev/null
@@ -0,0 +1,368 @@
+/*
+ * QLogic iSCSI HBA Driver
+ * Copyright (c)  2003-2006 QLogic Corporation
+ *
+ * See LICENSE.qla4xxx for copyright and licensing details.
+ */
+
+#include "ql4_def.h"
+
+#include <scsi/scsi_tcq.h>
+
+/**
+ * qla4xxx_get_req_pkt - returns a valid entry in request queue.
+ * @ha: Pointer to host adapter structure.
+ * @queue_entry: Pointer to pointer to queue entry structure
+ *
+ * This routine performs the following tasks:
+ *     - returns the current request_in pointer (if queue not full)
+ *     - advances the request_in pointer
+ *     - checks for queue full
+ **/
+int qla4xxx_get_req_pkt(struct scsi_qla_host *ha,
+                       struct queue_entry **queue_entry)
+{
+       uint16_t request_in;
+       uint8_t status = QLA_SUCCESS;
+
+       *queue_entry = ha->request_ptr;
+
+       /* get the latest request_in and request_out index */
+       request_in = ha->request_in;
+       ha->request_out = (uint16_t) le32_to_cpu(ha->shadow_regs->req_q_out);
+
+       /* Advance request queue pointer and check for queue full */
+       if (request_in == (REQUEST_QUEUE_DEPTH - 1)) {
+               request_in = 0;
+               ha->request_ptr = ha->request_ring;
+       } else {
+               request_in++;
+               ha->request_ptr++;
+       }
+
+       /* request queue is full, try again later */
+       if ((ha->iocb_cnt + 1) >= ha->iocb_hiwat) {
+               /* restore request pointer */
+               ha->request_ptr = *queue_entry;
+               status = QLA_ERROR;
+       } else {
+               ha->request_in = request_in;
+               memset(*queue_entry, 0, sizeof(**queue_entry));
+       }
+
+       return status;
+}
+
+/**
+ * qla4xxx_send_marker_iocb - issues marker iocb to HBA
+ * @ha: Pointer to host adapter structure.
+ * @ddb_entry: Pointer to device database entry
+ * @lun: SCSI LUN
+ * @marker_type: marker identifier
+ *
+ * This routine issues a marker IOCB.
+ **/
+int qla4xxx_send_marker_iocb(struct scsi_qla_host *ha,
+                            struct ddb_entry *ddb_entry, int lun)
+{
+       struct marker_entry *marker_entry;
+       unsigned long flags = 0;
+       uint8_t status = QLA_SUCCESS;
+
+       /* Acquire hardware specific lock */
+       spin_lock_irqsave(&ha->hardware_lock, flags);
+
+       /* Get pointer to the queue entry for the marker */
+       if (qla4xxx_get_req_pkt(ha, (struct queue_entry **) &marker_entry) !=
+           QLA_SUCCESS) {
+               status = QLA_ERROR;
+               goto exit_send_marker;
+       }
+
+       /* Put the marker in the request queue */
+       marker_entry->hdr.entryType = ET_MARKER;
+       marker_entry->hdr.entryCount = 1;
+       marker_entry->target = cpu_to_le16(ddb_entry->fw_ddb_index);
+       marker_entry->modifier = cpu_to_le16(MM_LUN_RESET);
+       int_to_scsilun(lun, &marker_entry->lun);
+       wmb();
+
+       /* Tell ISP it's got a new I/O request */
+       writel(ha->request_in, &ha->reg->req_q_in);
+       readl(&ha->reg->req_q_in);
+
+exit_send_marker:
+       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+       return status;
+}
+
+struct continuation_t1_entry* qla4xxx_alloc_cont_entry(
+       struct scsi_qla_host *ha)
+{
+       struct continuation_t1_entry *cont_entry;
+
+       cont_entry = (struct continuation_t1_entry *)ha->request_ptr;
+
+       /* Advance request queue pointer */
+       if (ha->request_in == (REQUEST_QUEUE_DEPTH - 1)) {
+               ha->request_in = 0;
+               ha->request_ptr = ha->request_ring;
+       } else {
+               ha->request_in++;
+               ha->request_ptr++;
+       }
+
+       /* Load packet defaults */
+       cont_entry->hdr.entryType = ET_CONTINUE;
+       cont_entry->hdr.entryCount = 1;
+       cont_entry->hdr.systemDefined = (uint8_t) cpu_to_le16(ha->request_in);
+
+       return cont_entry;
+}
+
+uint16_t qla4xxx_calc_request_entries(uint16_t dsds)
+{
+       uint16_t iocbs;
+
+       iocbs = 1;
+       if (dsds > COMMAND_SEG) {
+               iocbs += (dsds - COMMAND_SEG) / CONTINUE_SEG;
+               if ((dsds - COMMAND_SEG) % CONTINUE_SEG)
+                       iocbs++;
+       }
+       return iocbs;
+}
+
+void qla4xxx_build_scsi_iocbs(struct srb *srb,
+                             struct command_t3_entry *cmd_entry,
+                             uint16_t tot_dsds)
+{
+       struct scsi_qla_host *ha;
+       uint16_t avail_dsds;
+       struct data_seg_a64 *cur_dsd;
+       struct scsi_cmnd *cmd;
+
+       cmd = srb->cmd;
+       ha = srb->ha;
+
+       if (cmd->request_bufflen == 0 || cmd->sc_data_direction == DMA_NONE) {
+               /* No data being transferred */
+               cmd_entry->ttlByteCnt = __constant_cpu_to_le32(0);
+               return;
+       }
+
+       avail_dsds = COMMAND_SEG;
+       cur_dsd = (struct data_seg_a64 *) & (cmd_entry->dataseg[0]);
+
+       /* Load data segments */
+       if (cmd->use_sg) {
+               struct scatterlist *cur_seg;
+               struct scatterlist *end_seg;
+
+               cur_seg = (struct scatterlist *)cmd->request_buffer;
+               end_seg = cur_seg + tot_dsds;
+               while (cur_seg < end_seg) {
+                       dma_addr_t sle_dma;
+
+                       /* Allocate additional continuation packets? */
+                       if (avail_dsds == 0) {
+                               struct continuation_t1_entry *cont_entry;
+
+                               cont_entry = qla4xxx_alloc_cont_entry(ha);
+                               cur_dsd =
+                                       (struct data_seg_a64 *)
+                                       &cont_entry->dataseg[0];
+                               avail_dsds = CONTINUE_SEG;
+                       }
+
+                       sle_dma = sg_dma_address(cur_seg);
+                       cur_dsd->base.addrLow = cpu_to_le32(LSDW(sle_dma));
+                       cur_dsd->base.addrHigh = cpu_to_le32(MSDW(sle_dma));
+                       cur_dsd->count = cpu_to_le32(sg_dma_len(cur_seg));
+                       avail_dsds--;
+
+                       cur_dsd++;
+                       cur_seg++;
+               }
+       } else {
+               cur_dsd->base.addrLow = cpu_to_le32(LSDW(srb->dma_handle));
+               cur_dsd->base.addrHigh = cpu_to_le32(MSDW(srb->dma_handle));
+               cur_dsd->count = cpu_to_le32(cmd->request_bufflen);
+       }
+}
+
+/**
+ * qla4xxx_send_command_to_isp - issues command to HBA
+ * @ha: pointer to host adapter structure.
+ * @srb: pointer to SCSI Request Block to be sent to ISP
+ *
+ * This routine is called by qla4xxx_queuecommand to build an ISP
+ * command and pass it to the ISP for execution.
+ **/
+int qla4xxx_send_command_to_isp(struct scsi_qla_host *ha, struct srb * srb)
+{
+       struct scsi_cmnd *cmd = srb->cmd;
+       struct ddb_entry *ddb_entry;
+       struct command_t3_entry *cmd_entry;
+       struct scatterlist *sg = NULL;
+
+       uint16_t tot_dsds;
+       uint16_t req_cnt;
+
+       unsigned long flags;
+       uint16_t cnt;
+       uint32_t index;
+       char tag[2];
+
+       /* Get real lun and adapter */
+       ddb_entry = srb->ddb;
+
+       /* Send marker(s) if needed. */
+       if (ha->marker_needed == 1) {
+               if (qla4xxx_send_marker_iocb(ha, ddb_entry,
+                                            cmd->device->lun) != QLA_SUCCESS)
+                       return QLA_ERROR;
+
+               ha->marker_needed = 0;
+       }
+       tot_dsds = 0;
+
+       /* Acquire hardware specific lock */
+       spin_lock_irqsave(&ha->hardware_lock, flags);
+
+       index = (uint32_t)cmd->request->tag;
+
+       /* Calculate the number of request entries needed. */
+       if (cmd->use_sg) {
+               sg = (struct scatterlist *)cmd->request_buffer;
+               tot_dsds = pci_map_sg(ha->pdev, sg, cmd->use_sg,
+                                     cmd->sc_data_direction);
+               if (tot_dsds == 0)
+                       goto queuing_error;
+       } else if (cmd->request_bufflen) {
+               dma_addr_t      req_dma;
+
+               req_dma = pci_map_single(ha->pdev, cmd->request_buffer,
+                                        cmd->request_bufflen,
+                                        cmd->sc_data_direction);
+               if (dma_mapping_error(req_dma))
+                       goto queuing_error;
+
+               srb->dma_handle = req_dma;
+               tot_dsds = 1;
+       }
+       req_cnt = qla4xxx_calc_request_entries(tot_dsds);
+
+       if (ha->req_q_count < (req_cnt + 2)) {
+               cnt = (uint16_t) le32_to_cpu(ha->shadow_regs->req_q_out);
+               if (ha->request_in < cnt)
+                       ha->req_q_count = cnt - ha->request_in;
+               else
+                       ha->req_q_count = REQUEST_QUEUE_DEPTH -
+                               (ha->request_in - cnt);
+       }
+
+       if (ha->req_q_count < (req_cnt + 2))
+               goto queuing_error;
+
+       /* total iocbs active */
+       if ((ha->iocb_cnt + req_cnt) >= REQUEST_QUEUE_DEPTH)
+               goto queuing_error;
+
+       /* Build command packet */
+       cmd_entry = (struct command_t3_entry *) ha->request_ptr;
+       memset(cmd_entry, 0, sizeof(struct command_t3_entry));
+       cmd_entry->hdr.entryType = ET_COMMAND;
+       cmd_entry->handle = cpu_to_le32(index);
+       cmd_entry->target = cpu_to_le16(ddb_entry->fw_ddb_index);
+       cmd_entry->connection_id = cpu_to_le16(ddb_entry->connection_id);
+
+       int_to_scsilun(cmd->device->lun, &cmd_entry->lun);
+       cmd_entry->cmdSeqNum = cpu_to_le32(ddb_entry->CmdSn);
+       cmd_entry->ttlByteCnt = cpu_to_le32(cmd->request_bufflen);
+       memcpy(cmd_entry->cdb, cmd->cmnd, cmd->cmd_len);
+       cmd_entry->dataSegCnt = cpu_to_le16(tot_dsds);
+       cmd_entry->hdr.entryCount = req_cnt;
+
+       /* Set data transfer direction control flags
+        * NOTE: Look at data_direction bits iff there is data to be
+        *       transferred, as the data direction bit is sometimed filled
+        *       in when there is no data to be transferred */
+       cmd_entry->control_flags = CF_NO_DATA;
+       if (cmd->request_bufflen) {
+               if (cmd->sc_data_direction == DMA_TO_DEVICE)
+                       cmd_entry->control_flags = CF_WRITE;
+               else if (cmd->sc_data_direction == DMA_FROM_DEVICE)
+                       cmd_entry->control_flags = CF_READ;
+       }
+
+       /* Set tagged queueing control flags */
+       cmd_entry->control_flags |= CF_SIMPLE_TAG;
+       if (scsi_populate_tag_msg(cmd, tag))
+               switch (tag[0]) {
+               case MSG_HEAD_TAG:
+                       cmd_entry->control_flags |= CF_HEAD_TAG;
+                       break;
+               case MSG_ORDERED_TAG:
+                       cmd_entry->control_flags |= CF_ORDERED_TAG;
+                       break;
+               }
+
+
+       /* Advance request queue pointer */
+       ha->request_in++;
+       if (ha->request_in == REQUEST_QUEUE_DEPTH) {
+               ha->request_in = 0;
+               ha->request_ptr = ha->request_ring;
+       } else
+               ha->request_ptr++;
+
+
+       qla4xxx_build_scsi_iocbs(srb, cmd_entry, tot_dsds);
+       wmb();
+
+       /*
+        * Check to see if adapter is online before placing request on
+        * request queue.  If a reset occurs and a request is in the queue,
+        * the firmware will still attempt to process the request, retrieving
+        * garbage for pointers.
+        */
+       if (!test_bit(AF_ONLINE, &ha->flags)) {
+               DEBUG2(printk("scsi%ld: %s: Adapter OFFLINE! "
+                             "Do not issue command.\n",
+                             ha->host_no, __func__));
+               goto queuing_error;
+       }
+
+       srb->cmd->host_scribble = (unsigned char *)srb;
+
+       /* update counters */
+       srb->state = SRB_ACTIVE_STATE;
+       srb->flags |= SRB_DMA_VALID;
+
+       /* Track IOCB used */
+       ha->iocb_cnt += req_cnt;
+       srb->iocb_cnt = req_cnt;
+       ha->req_q_count -= req_cnt;
+
+       /* Debug print statements */
+       writel(ha->request_in, &ha->reg->req_q_in);
+       readl(&ha->reg->req_q_in);
+       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
+       return QLA_SUCCESS;
+
+queuing_error:
+
+       if (cmd->use_sg && tot_dsds) {
+               sg = (struct scatterlist *) cmd->request_buffer;
+               pci_unmap_sg(ha->pdev, sg, cmd->use_sg,
+                            cmd->sc_data_direction);
+       } else if (tot_dsds)
+               pci_unmap_single(ha->pdev, srb->dma_handle,
+                                cmd->request_bufflen, cmd->sc_data_direction);
+       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
+       return QLA_ERROR;
+}
+
diff --git a/drivers/scsi/qla4xxx/ql4_isr.c b/drivers/scsi/qla4xxx/ql4_isr.c
new file mode 100644 (file)
index 0000000..1e28332
--- /dev/null
@@ -0,0 +1,796 @@
+/*
+ * QLogic iSCSI HBA Driver
+ * Copyright (c)  2003-2006 QLogic Corporation
+ *
+ * See LICENSE.qla4xxx for copyright and licensing details.
+ */
+
+#include "ql4_def.h"
+
+/**
+ * qla2x00_process_completed_request() - Process a Fast Post response.
+ * @ha: SCSI driver HA context
+ * @index: SRB index
+ **/
+static void qla4xxx_process_completed_request(struct scsi_qla_host *ha,
+                                             uint32_t index)
+{
+       struct srb *srb;
+
+       srb = qla4xxx_del_from_active_array(ha, index);
+       if (srb) {
+               /* Save ISP completion status */
+               srb->cmd->result = DID_OK << 16;
+               qla4xxx_srb_compl(ha, srb);
+       } else {
+               DEBUG2(printk("scsi%ld: Invalid ISP SCSI completion handle = "
+                             "%d\n", ha->host_no, index));
+               set_bit(DPC_RESET_HA, &ha->dpc_flags);
+       }
+}
+
+/**
+ * qla4xxx_status_entry - processes status IOCBs
+ * @ha: Pointer to host adapter structure.
+ * @sts_entry: Pointer to status entry structure.
+ **/
+static void qla4xxx_status_entry(struct scsi_qla_host *ha,
+                                struct status_entry *sts_entry)
+{
+       uint8_t scsi_status;
+       struct scsi_cmnd *cmd;
+       struct srb *srb;
+       struct ddb_entry *ddb_entry;
+       uint32_t residual;
+       uint16_t sensebytecnt;
+
+       if (sts_entry->completionStatus == SCS_COMPLETE &&
+           sts_entry->scsiStatus == 0) {
+               qla4xxx_process_completed_request(ha,
+                                                 le32_to_cpu(sts_entry->
+                                                             handle));
+               return;
+       }
+
+       srb = qla4xxx_del_from_active_array(ha, le32_to_cpu(sts_entry->handle));
+       if (!srb) {
+               /* FIXMEdg: Don't we need to reset ISP in this case??? */
+               DEBUG2(printk(KERN_WARNING "scsi%ld: %s: Status Entry invalid "
+                             "handle 0x%x, sp=%p. This cmd may have already "
+                             "been completed.\n", ha->host_no, __func__,
+                             le32_to_cpu(sts_entry->handle), srb));
+               return;
+       }
+
+       cmd = srb->cmd;
+       if (cmd == NULL) {
+               DEBUG2(printk("scsi%ld: %s: Command already returned back to "
+                             "OS pkt->handle=%d srb=%p srb->state:%d\n",
+                             ha->host_no, __func__, sts_entry->handle,
+                             srb, srb->state));
+               dev_warn(&ha->pdev->dev, "Command is NULL:"
+                       " already returned to OS (srb=%p)\n", srb);
+               return;
+       }
+
+       ddb_entry = srb->ddb;
+       if (ddb_entry == NULL) {
+               cmd->result = DID_NO_CONNECT << 16;
+               goto status_entry_exit;
+       }
+
+       residual = le32_to_cpu(sts_entry->residualByteCnt);
+
+       /* Translate ISP error to a Linux SCSI error. */
+       scsi_status = sts_entry->scsiStatus;
+       switch (sts_entry->completionStatus) {
+       case SCS_COMPLETE:
+               if (scsi_status == 0) {
+                       cmd->result = DID_OK << 16;
+                       break;
+               }
+
+               if (sts_entry->iscsiFlags &
+                   (ISCSI_FLAG_RESIDUAL_OVER|ISCSI_FLAG_RESIDUAL_UNDER))
+                       cmd->resid = residual;
+
+               cmd->result = DID_OK << 16 | scsi_status;
+
+               if (scsi_status != SCSI_CHECK_CONDITION)
+                       break;
+
+               /* Copy Sense Data into sense buffer. */
+               memset(cmd->sense_buffer, 0, sizeof(cmd->sense_buffer));
+
+               sensebytecnt = le16_to_cpu(sts_entry->senseDataByteCnt);
+               if (sensebytecnt == 0)
+                       break;
+
+               memcpy(cmd->sense_buffer, sts_entry->senseData,
+                      min(sensebytecnt,
+                          (uint16_t) sizeof(cmd->sense_buffer)));
+
+               DEBUG2(printk("scsi%ld:%d:%d:%d: %s: sense key = %x, "
+                             "ASC/ASCQ = %02x/%02x\n", ha->host_no,
+                             cmd->device->channel, cmd->device->id,
+                             cmd->device->lun, __func__,
+                             sts_entry->senseData[2] & 0x0f,
+                             sts_entry->senseData[12],
+                             sts_entry->senseData[13]));
+
+               srb->flags |= SRB_GOT_SENSE;
+               break;
+
+       case SCS_INCOMPLETE:
+               /* Always set the status to DID_ERROR, since
+                * all conditions result in that status anyway */
+               cmd->result = DID_ERROR << 16;
+               break;
+
+       case SCS_RESET_OCCURRED:
+               DEBUG2(printk("scsi%ld:%d:%d:%d: %s: Device RESET occurred\n",
+                             ha->host_no, cmd->device->channel,
+                             cmd->device->id, cmd->device->lun, __func__));
+
+               cmd->result = DID_RESET << 16;
+               break;
+
+       case SCS_ABORTED:
+               DEBUG2(printk("scsi%ld:%d:%d:%d: %s: Abort occurred\n",
+                             ha->host_no, cmd->device->channel,
+                             cmd->device->id, cmd->device->lun, __func__));
+
+               cmd->result = DID_RESET << 16;
+               break;
+
+       case SCS_TIMEOUT:
+               DEBUG2(printk(KERN_INFO "scsi%ld:%d:%d:%d: Timeout\n",
+                             ha->host_no, cmd->device->channel,
+                             cmd->device->id, cmd->device->lun));
+
+               cmd->result = DID_BUS_BUSY << 16;
+
+               /*
+                * Mark device missing so that we won't continue to send
+                * I/O to this device.  We should get a ddb state change
+                * AEN soon.
+                */
+               if (atomic_read(&ddb_entry->state) == DDB_STATE_ONLINE)
+                       qla4xxx_mark_device_missing(ha, ddb_entry);
+               break;
+
+       case SCS_DATA_UNDERRUN:
+       case SCS_DATA_OVERRUN:
+               if (sts_entry->iscsiFlags & ISCSI_FLAG_RESIDUAL_OVER) {
+                       DEBUG2(printk("scsi%ld:%d:%d:%d: %s: " "Data overrun, "
+                                     "residual = 0x%x\n", ha->host_no,
+                                     cmd->device->channel, cmd->device->id,
+                                     cmd->device->lun, __func__, residual));
+
+                       cmd->result = DID_ERROR << 16;
+                       break;
+               }
+
+               if ((sts_entry->iscsiFlags & ISCSI_FLAG_RESIDUAL_UNDER) == 0) {
+                       /*
+                        * Firmware detected a SCSI transport underrun
+                        * condition
+                        */
+                       cmd->resid = residual;
+                       DEBUG2(printk("scsi%ld:%d:%d:%d: %s: UNDERRUN status "
+                                     "detected, xferlen = 0x%x, residual = "
+                                     "0x%x\n",
+                                     ha->host_no, cmd->device->channel,
+                                     cmd->device->id,
+                                     cmd->device->lun, __func__,
+                                     cmd->request_bufflen,
+                                     residual));
+               }
+
+               /*
+                * If there is scsi_status, it takes precedense over
+                * underflow condition.
+                */
+               if (scsi_status != 0) {
+                       cmd->result = DID_OK << 16 | scsi_status;
+
+                       if (scsi_status != SCSI_CHECK_CONDITION)
+                               break;
+
+                       /* Copy Sense Data into sense buffer. */
+                       memset(cmd->sense_buffer, 0,
+                              sizeof(cmd->sense_buffer));
+
+                       sensebytecnt =
+                               le16_to_cpu(sts_entry->senseDataByteCnt);
+                       if (sensebytecnt == 0)
+                               break;
+
+                       memcpy(cmd->sense_buffer, sts_entry->senseData,
+                              min(sensebytecnt,
+                                  (uint16_t) sizeof(cmd->sense_buffer)));
+
+                       DEBUG2(printk("scsi%ld:%d:%d:%d: %s: sense key = %x, "
+                                     "ASC/ASCQ = %02x/%02x\n", ha->host_no,
+                                     cmd->device->channel, cmd->device->id,
+                                     cmd->device->lun, __func__,
+                                     sts_entry->senseData[2] & 0x0f,
+                                     sts_entry->senseData[12],
+                                     sts_entry->senseData[13]));
+               } else {
+                       /*
+                        * If RISC reports underrun and target does not
+                        * report it then we must have a lost frame, so
+                        * tell upper layer to retry it by reporting a
+                        * bus busy.
+                        */
+                       if ((sts_entry->iscsiFlags &
+                            ISCSI_FLAG_RESIDUAL_UNDER) == 0) {
+                               cmd->result = DID_BUS_BUSY << 16;
+                       } else if ((cmd->request_bufflen - residual) <
+                                  cmd->underflow) {
+                               /*
+                                * Handle mid-layer underflow???
+                                *
+                                * For kernels less than 2.4, the driver must
+                                * return an error if an underflow is detected.
+                                * For kernels equal-to and above 2.4, the
+                                * mid-layer will appearantly handle the
+                                * underflow by detecting the residual count --
+                                * unfortunately, we do not see where this is
+                                * actually being done.  In the interim, we
+                                * will return DID_ERROR.
+                                */
+                               DEBUG2(printk("scsi%ld:%d:%d:%d: %s: "
+                                             "Mid-layer Data underrun, "
+                                             "xferlen = 0x%x, "
+                                             "residual = 0x%x\n", ha->host_no,
+                                             cmd->device->channel,
+                                             cmd->device->id,
+                                             cmd->device->lun, __func__,
+                                             cmd->request_bufflen, residual));
+
+                               cmd->result = DID_ERROR << 16;
+                       } else {
+                               cmd->result = DID_OK << 16;
+                       }
+               }
+               break;
+
+       case SCS_DEVICE_LOGGED_OUT:
+       case SCS_DEVICE_UNAVAILABLE:
+               /*
+                * Mark device missing so that we won't continue to
+                * send I/O to this device.  We should get a ddb
+                * state change AEN soon.
+                */
+               if (atomic_read(&ddb_entry->state) == DDB_STATE_ONLINE)
+                       qla4xxx_mark_device_missing(ha, ddb_entry);
+
+               cmd->result = DID_BUS_BUSY << 16;
+               break;
+
+       case SCS_QUEUE_FULL:
+               /*
+                * SCSI Mid-Layer handles device queue full
+                */
+               cmd->result = DID_OK << 16 | sts_entry->scsiStatus;
+               DEBUG2(printk("scsi%ld:%d:%d: %s: QUEUE FULL detected "
+                             "compl=%02x, scsi=%02x, state=%02x, iFlags=%02x,"
+                             " iResp=%02x\n", ha->host_no, cmd->device->id,
+                             cmd->device->lun, __func__,
+                             sts_entry->completionStatus,
+                             sts_entry->scsiStatus, sts_entry->state_flags,
+                             sts_entry->iscsiFlags,
+                             sts_entry->iscsiResponse));
+               break;
+
+       default:
+               cmd->result = DID_ERROR << 16;
+               break;
+       }
+
+status_entry_exit:
+
+       /* complete the request */
+       srb->cc_stat = sts_entry->completionStatus;
+       qla4xxx_srb_compl(ha, srb);
+}
+
+/**
+ * qla4xxx_process_response_queue - process response queue completions
+ * @ha: Pointer to host adapter structure.
+ *
+ * This routine process response queue completions in interrupt context.
+ * Hardware_lock locked upon entry
+ **/
+static void qla4xxx_process_response_queue(struct scsi_qla_host * ha)
+{
+       uint32_t count = 0;
+       struct srb *srb = NULL;
+       struct status_entry *sts_entry;
+
+       /* Process all responses from response queue */
+       while ((ha->response_in =
+               (uint16_t)le32_to_cpu(ha->shadow_regs->rsp_q_in)) !=
+              ha->response_out) {
+               sts_entry = (struct status_entry *) ha->response_ptr;
+               count++;
+
+               /* Advance pointers for next entry */
+               if (ha->response_out == (RESPONSE_QUEUE_DEPTH - 1)) {
+                       ha->response_out = 0;
+                       ha->response_ptr = ha->response_ring;
+               } else {
+                       ha->response_out++;
+                       ha->response_ptr++;
+               }
+
+               /* process entry */
+               switch (sts_entry->hdr.entryType) {
+               case ET_STATUS:
+                       /*
+                        * Common status - Single completion posted in single
+                        * IOSB.
+                        */
+                       qla4xxx_status_entry(ha, sts_entry);
+                       break;
+
+               case ET_PASSTHRU_STATUS:
+                       break;
+
+               case ET_STATUS_CONTINUATION:
+                       /* Just throw away the status continuation entries */
+                       DEBUG2(printk("scsi%ld: %s: Status Continuation entry "
+                                     "- ignoring\n", ha->host_no, __func__));
+                       break;
+
+               case ET_COMMAND:
+                       /* ISP device queue is full. Command not
+                        * accepted by ISP.  Queue command for
+                        * later */
+
+                       srb = qla4xxx_del_from_active_array(ha,
+                                                   le32_to_cpu(sts_entry->
+                                                               handle));
+                       if (srb == NULL)
+                               goto exit_prq_invalid_handle;
+
+                       DEBUG2(printk("scsi%ld: %s: FW device queue full, "
+                                     "srb %p\n", ha->host_no, __func__, srb));
+
+                       /* ETRY normally by sending it back with
+                        * DID_BUS_BUSY */
+                       srb->cmd->result = DID_BUS_BUSY << 16;
+                       qla4xxx_srb_compl(ha, srb);
+                       break;
+
+               case ET_CONTINUE:
+                       /* Just throw away the continuation entries */
+                       DEBUG2(printk("scsi%ld: %s: Continuation entry - "
+                                     "ignoring\n", ha->host_no, __func__));
+                       break;
+
+               default:
+                       /*
+                        * Invalid entry in response queue, reset RISC
+                        * firmware.
+                        */
+                       DEBUG2(printk("scsi%ld: %s: Invalid entry %x in "
+                                     "response queue \n", ha->host_no,
+                                     __func__,
+                                     sts_entry->hdr.entryType));
+                       goto exit_prq_error;
+               }
+       }
+
+       /*
+        * Done with responses, update the ISP For QLA4010, this also clears
+        * the interrupt.
+        */
+       writel(ha->response_out, &ha->reg->rsp_q_out);
+       readl(&ha->reg->rsp_q_out);
+
+       return;
+
+exit_prq_invalid_handle:
+       DEBUG2(printk("scsi%ld: %s: Invalid handle(srb)=%p type=%x IOCS=%x\n",
+                     ha->host_no, __func__, srb, sts_entry->hdr.entryType,
+                     sts_entry->completionStatus));
+
+exit_prq_error:
+       writel(ha->response_out, &ha->reg->rsp_q_out);
+       readl(&ha->reg->rsp_q_out);
+
+       set_bit(DPC_RESET_HA, &ha->dpc_flags);
+}
+
+/**
+ * qla4xxx_isr_decode_mailbox - decodes mailbox status
+ * @ha: Pointer to host adapter structure.
+ * @mailbox_status: Mailbox status.
+ *
+ * This routine decodes the mailbox status during the ISR.
+ * Hardware_lock locked upon entry. runs in interrupt context.
+ **/
+static void qla4xxx_isr_decode_mailbox(struct scsi_qla_host * ha,
+                                      uint32_t mbox_status)
+{
+       int i;
+
+       if ((mbox_status == MBOX_STS_BUSY) ||
+           (mbox_status == MBOX_STS_INTERMEDIATE_COMPLETION) ||
+           (mbox_status >> 12 == MBOX_COMPLETION_STATUS)) {
+               ha->mbox_status[0] = mbox_status;
+
+               if (test_bit(AF_MBOX_COMMAND, &ha->flags)) {
+                       /*
+                        * Copy all mailbox registers to a temporary
+                        * location and set mailbox command done flag
+                        */
+                       for (i = 1; i < ha->mbox_status_count; i++)
+                               ha->mbox_status[i] =
+                                       readl(&ha->reg->mailbox[i]);
+
+                       set_bit(AF_MBOX_COMMAND_DONE, &ha->flags);
+                       wake_up(&ha->mailbox_wait_queue);
+               }
+       } else if (mbox_status >> 12 == MBOX_ASYNC_EVENT_STATUS) {
+               /* Immediately process the AENs that don't require much work.
+                * Only queue the database_changed AENs */
+               switch (mbox_status) {
+               case MBOX_ASTS_SYSTEM_ERROR:
+                       /* Log Mailbox registers */
+                       if (ql4xdontresethba) {
+                               DEBUG2(printk("%s:Dont Reset HBA\n",
+                                             __func__));
+                       } else {
+                               set_bit(AF_GET_CRASH_RECORD, &ha->flags);
+                               set_bit(DPC_RESET_HA, &ha->dpc_flags);
+                       }
+                       break;
+
+               case MBOX_ASTS_REQUEST_TRANSFER_ERROR:
+               case MBOX_ASTS_RESPONSE_TRANSFER_ERROR:
+               case MBOX_ASTS_NVRAM_INVALID:
+               case MBOX_ASTS_IP_ADDRESS_CHANGED:
+               case MBOX_ASTS_DHCP_LEASE_EXPIRED:
+                       DEBUG2(printk("scsi%ld: AEN %04x, ERROR Status, "
+                                     "Reset HA\n", ha->host_no, mbox_status));
+                       set_bit(DPC_RESET_HA, &ha->dpc_flags);
+                       break;
+
+               case MBOX_ASTS_LINK_UP:
+                       DEBUG2(printk("scsi%ld: AEN %04x Adapter LINK UP\n",
+                                     ha->host_no, mbox_status));
+                       set_bit(AF_LINK_UP, &ha->flags);
+                       break;
+
+               case MBOX_ASTS_LINK_DOWN:
+                       DEBUG2(printk("scsi%ld: AEN %04x Adapter LINK DOWN\n",
+                                     ha->host_no, mbox_status));
+                       clear_bit(AF_LINK_UP, &ha->flags);
+                       break;
+
+               case MBOX_ASTS_HEARTBEAT:
+                       ha->seconds_since_last_heartbeat = 0;
+                       break;
+
+               case MBOX_ASTS_DHCP_LEASE_ACQUIRED:
+                       DEBUG2(printk("scsi%ld: AEN %04x DHCP LEASE "
+                                     "ACQUIRED\n", ha->host_no, mbox_status));
+                       set_bit(DPC_GET_DHCP_IP_ADDR, &ha->dpc_flags);
+                       break;
+
+               case MBOX_ASTS_PROTOCOL_STATISTIC_ALARM:
+               case MBOX_ASTS_SCSI_COMMAND_PDU_REJECTED: /* Target
+                                                          * mode
+                                                          * only */
+               case MBOX_ASTS_UNSOLICITED_PDU_RECEIVED:  /* Connection mode */
+               case MBOX_ASTS_IPSEC_SYSTEM_FATAL_ERROR:
+               case MBOX_ASTS_SUBNET_STATE_CHANGE:
+                       /* No action */
+                       DEBUG2(printk("scsi%ld: AEN %04x\n", ha->host_no,
+                                     mbox_status));
+                       break;
+
+               case MBOX_ASTS_MAC_ADDRESS_CHANGED:
+               case MBOX_ASTS_DNS:
+                       /* No action */
+                       DEBUG2(printk(KERN_INFO "scsi%ld: AEN %04x, "
+                                     "mbox_sts[1]=%04x, mbox_sts[2]=%04x\n",
+                                     ha->host_no, mbox_status,
+                                     readl(&ha->reg->mailbox[1]),
+                                     readl(&ha->reg->mailbox[2])));
+                       break;
+
+               case MBOX_ASTS_SELF_TEST_FAILED:
+               case MBOX_ASTS_LOGIN_FAILED:
+                       /* No action */
+                       DEBUG2(printk("scsi%ld: AEN %04x, mbox_sts[1]=%04x, "
+                                     "mbox_sts[2]=%04x, mbox_sts[3]=%04x\n",
+                                     ha->host_no, mbox_status,
+                                     readl(&ha->reg->mailbox[1]),
+                                     readl(&ha->reg->mailbox[2]),
+                                     readl(&ha->reg->mailbox[3])));
+                       break;
+
+               case MBOX_ASTS_DATABASE_CHANGED:
+                       /* Queue AEN information and process it in the DPC
+                        * routine */
+                       if (ha->aen_q_count > 0) {
+                               /* advance pointer */
+                               if (ha->aen_in == (MAX_AEN_ENTRIES - 1))
+                                       ha->aen_in = 0;
+                               else
+                                       ha->aen_in++;
+
+                               /* decrement available counter */
+                               ha->aen_q_count--;
+
+                               for (i = 1; i < MBOX_AEN_REG_COUNT; i++)
+                                       ha->aen_q[ha->aen_in].mbox_sts[i] =
+                                               readl(&ha->reg->mailbox[i]);
+
+                               ha->aen_q[ha->aen_in].mbox_sts[0] = mbox_status;
+
+                               /* print debug message */
+                               DEBUG2(printk("scsi%ld: AEN[%d] %04x queued"
+                                             " mb1:0x%x mb2:0x%x mb3:0x%x mb4:0x%x\n",
+                                             ha->host_no, ha->aen_in,
+                                             mbox_status,
+                                             ha->aen_q[ha->aen_in].mbox_sts[1],
+                                             ha->aen_q[ha->aen_in].mbox_sts[2],
+                                             ha->aen_q[ha->aen_in].mbox_sts[3],
+                                             ha->aen_q[ha->aen_in].  mbox_sts[4]));
+
+                               /* The DPC routine will process the aen */
+                               set_bit(DPC_AEN, &ha->dpc_flags);
+                       } else {
+                               DEBUG2(printk("scsi%ld: %s: aen %04x, queue "
+                                             "overflowed!  AEN LOST!!\n",
+                                             ha->host_no, __func__,
+                                             mbox_status));
+
+                               DEBUG2(printk("scsi%ld: DUMP AEN QUEUE\n",
+                                             ha->host_no));
+
+                               for (i = 0; i < MAX_AEN_ENTRIES; i++) {
+                                       DEBUG2(printk("AEN[%d] %04x %04x %04x "
+                                                     "%04x\n", i,
+                                                     ha->aen_q[i].mbox_sts[0],
+                                                     ha->aen_q[i].mbox_sts[1],
+                                                     ha->aen_q[i].mbox_sts[2],
+                                                     ha->aen_q[i].mbox_sts[3]));
+                               }
+                       }
+                       break;
+
+               default:
+                       DEBUG2(printk(KERN_WARNING
+                                     "scsi%ld: AEN %04x UNKNOWN\n",
+                                     ha->host_no, mbox_status));
+                       break;
+               }
+       } else {
+               DEBUG2(printk("scsi%ld: Unknown mailbox status %08X\n",
+                             ha->host_no, mbox_status));
+
+               ha->mbox_status[0] = mbox_status;
+       }
+}
+
+/**
+ * qla4xxx_interrupt_service_routine - isr
+ * @ha: pointer to host adapter structure.
+ *
+ * This is the main interrupt service routine.
+ * hardware_lock locked upon entry. runs in interrupt context.
+ **/
+void qla4xxx_interrupt_service_routine(struct scsi_qla_host * ha,
+                                      uint32_t intr_status)
+{
+       /* Process response queue interrupt. */
+       if (intr_status & CSR_SCSI_COMPLETION_INTR)
+               qla4xxx_process_response_queue(ha);
+
+       /* Process mailbox/asynch event  interrupt.*/
+       if (intr_status & CSR_SCSI_PROCESSOR_INTR) {
+               qla4xxx_isr_decode_mailbox(ha,
+                                          readl(&ha->reg->mailbox[0]));
+
+               /* Clear Mailbox Interrupt */
+               writel(set_rmask(CSR_SCSI_PROCESSOR_INTR),
+                      &ha->reg->ctrl_status);
+               readl(&ha->reg->ctrl_status);
+       }
+}
+
+/**
+ * qla4xxx_intr_handler - hardware interrupt handler.
+ * @irq: Unused
+ * @dev_id: Pointer to host adapter structure
+ **/
+irqreturn_t qla4xxx_intr_handler(int irq, void *dev_id)
+{
+       struct scsi_qla_host *ha;
+       uint32_t intr_status;
+       unsigned long flags = 0;
+       uint8_t reqs_count = 0;
+
+       ha = (struct scsi_qla_host *) dev_id;
+       if (!ha) {
+               DEBUG2(printk(KERN_INFO
+                             "qla4xxx: Interrupt with NULL host ptr\n"));
+               return IRQ_NONE;
+       }
+
+       spin_lock_irqsave(&ha->hardware_lock, flags);
+
+       /*
+        * Repeatedly service interrupts up to a maximum of
+        * MAX_REQS_SERVICED_PER_INTR
+        */
+       while (1) {
+               /*
+                * Read interrupt status
+                */
+               if (le32_to_cpu(ha->shadow_regs->rsp_q_in) !=
+                   ha->response_out)
+                       intr_status = CSR_SCSI_COMPLETION_INTR;
+               else
+                       intr_status = readl(&ha->reg->ctrl_status);
+
+               if ((intr_status &
+                    (CSR_SCSI_RESET_INTR|CSR_FATAL_ERROR|INTR_PENDING)) ==
+                   0) {
+                       if (reqs_count == 0)
+                               ha->spurious_int_count++;
+                       break;
+               }
+
+               if (intr_status & CSR_FATAL_ERROR) {
+                       DEBUG2(printk(KERN_INFO "scsi%ld: Fatal Error, "
+                                     "Status 0x%04x\n", ha->host_no,
+                                     readl(isp_port_error_status (ha))));
+
+                       /* Issue Soft Reset to clear this error condition.
+                        * This will prevent the RISC from repeatedly
+                        * interrupting the driver; thus, allowing the DPC to
+                        * get scheduled to continue error recovery.
+                        * NOTE: Disabling RISC interrupts does not work in
+                        * this case, as CSR_FATAL_ERROR overrides
+                        * CSR_SCSI_INTR_ENABLE */
+                       if ((readl(&ha->reg->ctrl_status) &
+                            CSR_SCSI_RESET_INTR) == 0) {
+                               writel(set_rmask(CSR_SOFT_RESET),
+                                      &ha->reg->ctrl_status);
+                               readl(&ha->reg->ctrl_status);
+                       }
+
+                       writel(set_rmask(CSR_FATAL_ERROR),
+                              &ha->reg->ctrl_status);
+                       readl(&ha->reg->ctrl_status);
+
+                       __qla4xxx_disable_intrs(ha);
+
+                       set_bit(DPC_RESET_HA, &ha->dpc_flags);
+
+                       break;
+               } else if (intr_status & CSR_SCSI_RESET_INTR) {
+                       clear_bit(AF_ONLINE, &ha->flags);
+                       __qla4xxx_disable_intrs(ha);
+
+                       writel(set_rmask(CSR_SCSI_RESET_INTR),
+                              &ha->reg->ctrl_status);
+                       readl(&ha->reg->ctrl_status);
+
+                       set_bit(DPC_RESET_HA_INTR, &ha->dpc_flags);
+
+                       break;
+               } else if (intr_status & INTR_PENDING) {
+                       qla4xxx_interrupt_service_routine(ha, intr_status);
+                       ha->total_io_count++;
+                       if (++reqs_count == MAX_REQS_SERVICED_PER_INTR)
+                               break;
+
+                       intr_status = 0;
+               }
+       }
+
+       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
+       return IRQ_HANDLED;
+}
+
+/**
+ * qla4xxx_process_aen - processes AENs generated by firmware
+ * @ha: pointer to host adapter structure.
+ * @process_aen: type of AENs to process
+ *
+ * Processes specific types of Asynchronous Events generated by firmware.
+ * The type of AENs to process is specified by process_aen and can be
+ *     PROCESS_ALL_AENS         0
+ *     FLUSH_DDB_CHANGED_AENS   1
+ *     RELOGIN_DDB_CHANGED_AENS 2
+ **/
+void qla4xxx_process_aen(struct scsi_qla_host * ha, uint8_t process_aen)
+{
+       uint32_t mbox_sts[MBOX_AEN_REG_COUNT];
+       struct aen *aen;
+       int i;
+       unsigned long flags;
+
+       spin_lock_irqsave(&ha->hardware_lock, flags);
+       while (ha->aen_out != ha->aen_in) {
+               /* Advance pointers for next entry */
+               if (ha->aen_out == (MAX_AEN_ENTRIES - 1))
+                       ha->aen_out = 0;
+               else
+                       ha->aen_out++;
+
+               ha->aen_q_count++;
+               aen = &ha->aen_q[ha->aen_out];
+
+               /* copy aen information to local structure */
+               for (i = 0; i < MBOX_AEN_REG_COUNT; i++)
+                       mbox_sts[i] = aen->mbox_sts[i];
+
+               spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
+               DEBUG(printk("scsi%ld: AEN[%d] %04x, index [%d] state=%04x "
+                            "mod=%x conerr=%08x \n", ha->host_no, ha->aen_out,
+                            mbox_sts[0], mbox_sts[2], mbox_sts[3],
+                            mbox_sts[1], mbox_sts[4]));
+
+               switch (mbox_sts[0]) {
+               case MBOX_ASTS_DATABASE_CHANGED:
+                       if (process_aen == FLUSH_DDB_CHANGED_AENS) {
+                               DEBUG2(printk("scsi%ld: AEN[%d] %04x, index "
+                                             "[%d] state=%04x FLUSHED!\n",
+                                             ha->host_no, ha->aen_out,
+                                             mbox_sts[0], mbox_sts[2],
+                                             mbox_sts[3]));
+                               break;
+                       } else if (process_aen == RELOGIN_DDB_CHANGED_AENS) {
+                               /* for use during init time, we only want to
+                                * relogin non-active ddbs */
+                               struct ddb_entry *ddb_entry;
+
+                               ddb_entry =
+                                       /* FIXME: name length? */
+                                       qla4xxx_lookup_ddb_by_fw_index(ha,
+                                                                      mbox_sts[2]);
+                               if (!ddb_entry)
+                                       break;
+
+                               ddb_entry->dev_scan_wait_to_complete_relogin =
+                                       0;
+                               ddb_entry->dev_scan_wait_to_start_relogin =
+                                       jiffies +
+                                       ((ddb_entry->default_time2wait +
+                                         4) * HZ);
+
+                               DEBUG2(printk("scsi%ld: ddb index [%d] initate"
+                                             " RELOGIN after %d seconds\n",
+                                             ha->host_no,
+                                             ddb_entry->fw_ddb_index,
+                                             ddb_entry->default_time2wait +
+                                             4));
+                               break;
+                       }
+
+                       if (mbox_sts[1] == 0) { /* Global DB change. */
+                               qla4xxx_reinitialize_ddb_list(ha);
+                       } else if (mbox_sts[1] == 1) {  /* Specific device. */
+                               qla4xxx_process_ddb_changed(ha, mbox_sts[2],
+                                                           mbox_sts[3]);
+                       }
+                       break;
+               }
+               spin_lock_irqsave(&ha->hardware_lock, flags);
+       }
+       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
+}
+
diff --git a/drivers/scsi/qla4xxx/ql4_mbx.c b/drivers/scsi/qla4xxx/ql4_mbx.c
new file mode 100644 (file)
index 0000000..ef82399
--- /dev/null
@@ -0,0 +1,930 @@
+/*
+ * QLogic iSCSI HBA Driver
+ * Copyright (c)  2003-2006 QLogic Corporation
+ *
+ * See LICENSE.qla4xxx for copyright and licensing details.
+ */
+
+#include "ql4_def.h"
+
+
+/**
+ * qla4xxx_mailbox_command - issues mailbox commands
+ * @ha: Pointer to host adapter structure.
+ * @inCount: number of mailbox registers to load.
+ * @outCount: number of mailbox registers to return.
+ * @mbx_cmd: data pointer for mailbox in registers.
+ * @mbx_sts: data pointer for mailbox out registers.
+ *
+ * This routine sssue mailbox commands and waits for completion.
+ * If outCount is 0, this routine completes successfully WITHOUT waiting
+ * for the mailbox command to complete.
+ **/
+int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount,
+                           uint8_t outCount, uint32_t *mbx_cmd,
+                           uint32_t *mbx_sts)
+{
+       int status = QLA_ERROR;
+       uint8_t i;
+       u_long wait_count;
+       uint32_t intr_status;
+       unsigned long flags = 0;
+       DECLARE_WAITQUEUE(wait, current);
+
+       mutex_lock(&ha->mbox_sem);
+
+       /* Mailbox code active */
+       set_bit(AF_MBOX_COMMAND, &ha->flags);
+
+       /* Make sure that pointers are valid */
+       if (!mbx_cmd || !mbx_sts) {
+               DEBUG2(printk("scsi%ld: %s: Invalid mbx_cmd or mbx_sts "
+                             "pointer\n", ha->host_no, __func__));
+               goto mbox_exit;
+       }
+
+       /* To prevent overwriting mailbox registers for a command that has
+        * not yet been serviced, check to see if a previously issued
+        * mailbox command is interrupting.
+        * -----------------------------------------------------------------
+        */
+       spin_lock_irqsave(&ha->hardware_lock, flags);
+       intr_status = readl(&ha->reg->ctrl_status);
+       if (intr_status & CSR_SCSI_PROCESSOR_INTR) {
+               /* Service existing interrupt */
+               qla4xxx_interrupt_service_routine(ha, intr_status);
+               clear_bit(AF_MBOX_COMMAND_DONE, &ha->flags);
+       }
+
+       /* Send the mailbox command to the firmware */
+       ha->mbox_status_count = outCount;
+       for (i = 0; i < outCount; i++)
+               ha->mbox_status[i] = 0;
+
+       /* Load all mailbox registers, except mailbox 0. */
+       for (i = 1; i < inCount; i++)
+               writel(mbx_cmd[i], &ha->reg->mailbox[i]);
+
+       /* Wakeup firmware  */
+       writel(mbx_cmd[0], &ha->reg->mailbox[0]);
+       readl(&ha->reg->mailbox[0]);
+       writel(set_rmask(CSR_INTR_RISC), &ha->reg->ctrl_status);
+       readl(&ha->reg->ctrl_status);
+       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
+       /* Wait for completion */
+       set_current_state(TASK_UNINTERRUPTIBLE);
+       add_wait_queue(&ha->mailbox_wait_queue, &wait);
+
+       /*
+        * If we don't want status, don't wait for the mailbox command to
+        * complete.  For example, MBOX_CMD_RESET_FW doesn't return status,
+        * you must poll the inbound Interrupt Mask for completion.
+        */
+       if (outCount == 0) {
+               status = QLA_SUCCESS;
+               set_current_state(TASK_RUNNING);
+               remove_wait_queue(&ha->mailbox_wait_queue, &wait);
+               goto mbox_exit;
+       }
+       /* Wait for command to complete */
+       wait_count = jiffies + MBOX_TOV * HZ;
+       while (test_bit(AF_MBOX_COMMAND_DONE, &ha->flags) == 0) {
+               if (time_after_eq(jiffies, wait_count))
+                       break;
+
+               spin_lock_irqsave(&ha->hardware_lock, flags);
+               intr_status = readl(&ha->reg->ctrl_status);
+               if (intr_status & INTR_PENDING) {
+                       /*
+                        * Service the interrupt.
+                        * The ISR will save the mailbox status registers
+                        * to a temporary storage location in the adapter
+                        * structure.
+                        */
+                       ha->mbox_status_count = outCount;
+                       qla4xxx_interrupt_service_routine(ha, intr_status);
+               }
+               spin_unlock_irqrestore(&ha->hardware_lock, flags);
+               msleep(10);
+       }
+       set_current_state(TASK_RUNNING);
+       remove_wait_queue(&ha->mailbox_wait_queue, &wait);
+
+       /* Check for mailbox timeout. */
+       if (!test_bit(AF_MBOX_COMMAND_DONE, &ha->flags)) {
+               DEBUG2(printk("scsi%ld: Mailbox Cmd 0x%08X timed out ...,"
+                             " Scheduling Adapter Reset\n", ha->host_no,
+                             mbx_cmd[0]));
+               ha->mailbox_timeout_count++;
+               mbx_sts[0] = (-1);
+               set_bit(DPC_RESET_HA, &ha->dpc_flags);
+               goto mbox_exit;
+       }
+
+       /*
+        * Copy the mailbox out registers to the caller's mailbox in/out
+        * structure.
+        */
+       spin_lock_irqsave(&ha->hardware_lock, flags);
+       for (i = 0; i < outCount; i++)
+               mbx_sts[i] = ha->mbox_status[i];
+
+       /* Set return status and error flags (if applicable). */
+       switch (ha->mbox_status[0]) {
+       case MBOX_STS_COMMAND_COMPLETE:
+               status = QLA_SUCCESS;
+               break;
+
+       case MBOX_STS_INTERMEDIATE_COMPLETION:
+               status = QLA_SUCCESS;
+               break;
+
+       case MBOX_STS_BUSY:
+               DEBUG2( printk("scsi%ld: %s: Cmd = %08X, ISP BUSY\n",
+                              ha->host_no, __func__, mbx_cmd[0]));
+               ha->mailbox_timeout_count++;
+               break;
+
+       default:
+               DEBUG2(printk("scsi%ld: %s: **** FAILED, cmd = %08X, "
+                             "sts = %08X ****\n", ha->host_no, __func__,
+                             mbx_cmd[0], mbx_sts[0]));
+               break;
+       }
+       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
+mbox_exit:
+       clear_bit(AF_MBOX_COMMAND, &ha->flags);
+       clear_bit(AF_MBOX_COMMAND_DONE, &ha->flags);
+       mutex_unlock(&ha->mbox_sem);
+
+       return status;
+}
+
+
+/**
+ * qla4xxx_issue_iocb - issue mailbox iocb command
+ * @ha: adapter state pointer.
+ * @buffer: buffer pointer.
+ * @phys_addr: physical address of buffer.
+ * @size: size of buffer.
+ *
+ * Issues iocbs via mailbox commands.
+ * TARGET_QUEUE_LOCK must be released.
+ * ADAPTER_STATE_LOCK must be released.
+ **/
+int
+qla4xxx_issue_iocb(struct scsi_qla_host * ha, void *buffer,
+                  dma_addr_t phys_addr, size_t size)
+{
+       uint32_t mbox_cmd[MBOX_REG_COUNT];
+       uint32_t mbox_sts[MBOX_REG_COUNT];
+       int status;
+
+       memset(&mbox_cmd, 0, sizeof(mbox_cmd));
+       memset(&mbox_sts, 0, sizeof(mbox_sts));
+       mbox_cmd[0] = MBOX_CMD_EXECUTE_IOCB_A64;
+       mbox_cmd[1] = 0;
+       mbox_cmd[2] = LSDW(phys_addr);
+       mbox_cmd[3] = MSDW(phys_addr);
+       status = qla4xxx_mailbox_command(ha, 4, 1, &mbox_cmd[0], &mbox_sts[0]);
+       return status;
+}
+
+int qla4xxx_conn_close_sess_logout(struct scsi_qla_host * ha,
+                                  uint16_t fw_ddb_index,
+                                  uint16_t connection_id,
+                                  uint16_t option)
+{
+       uint32_t mbox_cmd[MBOX_REG_COUNT];
+       uint32_t mbox_sts[MBOX_REG_COUNT];
+
+       memset(&mbox_cmd, 0, sizeof(mbox_cmd));
+       memset(&mbox_sts, 0, sizeof(mbox_sts));
+       mbox_cmd[0] = MBOX_CMD_CONN_CLOSE_SESS_LOGOUT;
+       mbox_cmd[1] = fw_ddb_index;
+       mbox_cmd[2] = connection_id;
+       mbox_cmd[3] = LOGOUT_OPTION_RELOGIN;
+       if (qla4xxx_mailbox_command(ha, 4, 2, &mbox_cmd[0], &mbox_sts[0]) !=
+           QLA_SUCCESS) {
+               DEBUG2(printk("scsi%ld: %s: MBOX_CMD_CONN_CLOSE_SESS_LOGOUT "
+                             "option %04x failed sts %04X %04X",
+                             ha->host_no, __func__,
+                             option, mbox_sts[0], mbox_sts[1]));
+               if (mbox_sts[0] == 0x4005)
+                       DEBUG2(printk("%s reason %04X\n", __func__,
+                                     mbox_sts[1]));
+       }
+       return QLA_SUCCESS;
+}
+
+int qla4xxx_clear_database_entry(struct scsi_qla_host * ha,
+                                uint16_t fw_ddb_index)
+{
+       uint32_t mbox_cmd[MBOX_REG_COUNT];
+       uint32_t mbox_sts[MBOX_REG_COUNT];
+
+       memset(&mbox_cmd, 0, sizeof(mbox_cmd));
+       memset(&mbox_sts, 0, sizeof(mbox_sts));
+       mbox_cmd[0] = MBOX_CMD_CLEAR_DATABASE_ENTRY;
+       mbox_cmd[1] = fw_ddb_index;
+       if (qla4xxx_mailbox_command(ha, 2, 5, &mbox_cmd[0], &mbox_sts[0]) !=
+           QLA_SUCCESS)
+               return QLA_ERROR;
+
+       return QLA_SUCCESS;
+}
+
+/**
+ * qla4xxx_initialize_fw_cb - initializes firmware control block.
+ * @ha: Pointer to host adapter structure.
+ **/
+int qla4xxx_initialize_fw_cb(struct scsi_qla_host * ha)
+{
+       struct init_fw_ctrl_blk *init_fw_cb;
+       dma_addr_t init_fw_cb_dma;
+       uint32_t mbox_cmd[MBOX_REG_COUNT];
+       uint32_t mbox_sts[MBOX_REG_COUNT];
+       int status = QLA_ERROR;
+
+       init_fw_cb = dma_alloc_coherent(&ha->pdev->dev,
+                                       sizeof(struct init_fw_ctrl_blk),
+                                       &init_fw_cb_dma, GFP_KERNEL);
+       if (init_fw_cb == NULL) {
+               DEBUG2(printk("scsi%ld: %s: Unable to alloc init_cb\n",
+                             ha->host_no, __func__));
+               return 10;
+       }
+       memset(init_fw_cb, 0, sizeof(struct init_fw_ctrl_blk));
+
+       /* Get Initialize Firmware Control Block. */
+       memset(&mbox_cmd, 0, sizeof(mbox_cmd));
+       memset(&mbox_sts, 0, sizeof(mbox_sts));
+       mbox_cmd[0] = MBOX_CMD_GET_INIT_FW_CTRL_BLOCK;
+       mbox_cmd[2] = LSDW(init_fw_cb_dma);
+       mbox_cmd[3] = MSDW(init_fw_cb_dma);
+       if (qla4xxx_mailbox_command(ha, 4, 1, &mbox_cmd[0], &mbox_sts[0]) !=
+           QLA_SUCCESS) {
+               dma_free_coherent(&ha->pdev->dev,
+                                 sizeof(struct init_fw_ctrl_blk),
+                                 init_fw_cb, init_fw_cb_dma);
+               return status;
+       }
+
+       /* Initialize request and response queues. */
+       qla4xxx_init_rings(ha);
+
+       /* Fill in the request and response queue information. */
+       init_fw_cb->ReqQConsumerIndex = cpu_to_le16(ha->request_out);
+       init_fw_cb->ComplQProducerIndex = cpu_to_le16(ha->response_in);
+       init_fw_cb->ReqQLen = __constant_cpu_to_le16(REQUEST_QUEUE_DEPTH);
+       init_fw_cb->ComplQLen = __constant_cpu_to_le16(RESPONSE_QUEUE_DEPTH);
+       init_fw_cb->ReqQAddrLo = cpu_to_le32(LSDW(ha->request_dma));
+       init_fw_cb->ReqQAddrHi = cpu_to_le32(MSDW(ha->request_dma));
+       init_fw_cb->ComplQAddrLo = cpu_to_le32(LSDW(ha->response_dma));
+       init_fw_cb->ComplQAddrHi = cpu_to_le32(MSDW(ha->response_dma));
+       init_fw_cb->ShadowRegBufAddrLo =
+               cpu_to_le32(LSDW(ha->shadow_regs_dma));
+       init_fw_cb->ShadowRegBufAddrHi =
+               cpu_to_le32(MSDW(ha->shadow_regs_dma));
+
+       /* Set up required options. */
+       init_fw_cb->FwOptions |=
+               __constant_cpu_to_le16(FWOPT_SESSION_MODE |
+                                      FWOPT_INITIATOR_MODE);
+       init_fw_cb->FwOptions &= __constant_cpu_to_le16(~FWOPT_TARGET_MODE);
+
+       /* Save some info in adapter structure. */
+       ha->firmware_options = le16_to_cpu(init_fw_cb->FwOptions);
+       ha->tcp_options = le16_to_cpu(init_fw_cb->TCPOptions);
+       ha->heartbeat_interval = init_fw_cb->HeartbeatInterval;
+       memcpy(ha->ip_address, init_fw_cb->IPAddr,
+              min(sizeof(ha->ip_address), sizeof(init_fw_cb->IPAddr)));
+       memcpy(ha->subnet_mask, init_fw_cb->SubnetMask,
+              min(sizeof(ha->subnet_mask), sizeof(init_fw_cb->SubnetMask)));
+       memcpy(ha->gateway, init_fw_cb->GatewayIPAddr,
+              min(sizeof(ha->gateway), sizeof(init_fw_cb->GatewayIPAddr)));
+       memcpy(ha->name_string, init_fw_cb->iSCSINameString,
+              min(sizeof(ha->name_string),
+                  sizeof(init_fw_cb->iSCSINameString)));
+       memcpy(ha->alias, init_fw_cb->Alias,
+              min(sizeof(ha->alias), sizeof(init_fw_cb->Alias)));
+
+       /* Save Command Line Paramater info */
+       ha->port_down_retry_count = le16_to_cpu(init_fw_cb->KeepAliveTimeout);
+       ha->discovery_wait = ql4xdiscoverywait;
+
+       /* Send Initialize Firmware Control Block. */
+       mbox_cmd[0] = MBOX_CMD_INITIALIZE_FIRMWARE;
+       mbox_cmd[1] = 0;
+       mbox_cmd[2] = LSDW(init_fw_cb_dma);
+       mbox_cmd[3] = MSDW(init_fw_cb_dma);
+       if (qla4xxx_mailbox_command(ha, 4, 1, &mbox_cmd[0], &mbox_sts[0]) ==
+           QLA_SUCCESS)
+               status = QLA_SUCCESS;
+        else {
+               DEBUG2(printk("scsi%ld: %s: MBOX_CMD_INITIALIZE_FIRMWARE "
+                             "failed w/ status %04X\n", ha->host_no, __func__,
+                             mbox_sts[0]));
+       }
+       dma_free_coherent(&ha->pdev->dev, sizeof(struct init_fw_ctrl_blk),
+                         init_fw_cb, init_fw_cb_dma);
+
+       return status;
+}
+
+/**
+ * qla4xxx_get_dhcp_ip_address - gets HBA ip address via DHCP
+ * @ha: Pointer to host adapter structure.
+ **/
+int qla4xxx_get_dhcp_ip_address(struct scsi_qla_host * ha)
+{
+       struct init_fw_ctrl_blk *init_fw_cb;
+       dma_addr_t init_fw_cb_dma;
+       uint32_t mbox_cmd[MBOX_REG_COUNT];
+       uint32_t mbox_sts[MBOX_REG_COUNT];
+
+       init_fw_cb = dma_alloc_coherent(&ha->pdev->dev,
+                                       sizeof(struct init_fw_ctrl_blk),
+                                       &init_fw_cb_dma, GFP_KERNEL);
+       if (init_fw_cb == NULL) {
+               printk("scsi%ld: %s: Unable to alloc init_cb\n", ha->host_no,
+                      __func__);
+               return 10;
+       }
+
+       /* Get Initialize Firmware Control Block. */
+       memset(&mbox_cmd, 0, sizeof(mbox_cmd));
+       memset(&mbox_sts, 0, sizeof(mbox_sts));
+       memset(init_fw_cb, 0, sizeof(struct init_fw_ctrl_blk));
+       mbox_cmd[0] = MBOX_CMD_GET_INIT_FW_CTRL_BLOCK;
+       mbox_cmd[2] = LSDW(init_fw_cb_dma);
+       mbox_cmd[3] = MSDW(init_fw_cb_dma);
+
+       if (qla4xxx_mailbox_command(ha, 4, 1, &mbox_cmd[0], &mbox_sts[0]) !=
+           QLA_SUCCESS) {
+               DEBUG2(printk("scsi%ld: %s: Failed to get init_fw_ctrl_blk\n",
+                             ha->host_no, __func__));
+               dma_free_coherent(&ha->pdev->dev,
+                                 sizeof(struct init_fw_ctrl_blk),
+                                 init_fw_cb, init_fw_cb_dma);
+               return QLA_ERROR;
+       }
+
+       /* Save IP Address. */
+       memcpy(ha->ip_address, init_fw_cb->IPAddr,
+              min(sizeof(ha->ip_address), sizeof(init_fw_cb->IPAddr)));
+       memcpy(ha->subnet_mask, init_fw_cb->SubnetMask,
+              min(sizeof(ha->subnet_mask), sizeof(init_fw_cb->SubnetMask)));
+       memcpy(ha->gateway, init_fw_cb->GatewayIPAddr,
+              min(sizeof(ha->gateway), sizeof(init_fw_cb->GatewayIPAddr)));
+
+       dma_free_coherent(&ha->pdev->dev, sizeof(struct init_fw_ctrl_blk),
+                         init_fw_cb, init_fw_cb_dma);
+
+       return QLA_SUCCESS;
+}
+
+/**
+ * qla4xxx_get_firmware_state - gets firmware state of HBA
+ * @ha: Pointer to host adapter structure.
+ **/
+int qla4xxx_get_firmware_state(struct scsi_qla_host * ha)
+{
+       uint32_t mbox_cmd[MBOX_REG_COUNT];
+       uint32_t mbox_sts[MBOX_REG_COUNT];
+
+       /* Get firmware version */
+       memset(&mbox_cmd, 0, sizeof(mbox_cmd));
+       memset(&mbox_sts, 0, sizeof(mbox_sts));
+       mbox_cmd[0] = MBOX_CMD_GET_FW_STATE;
+       if (qla4xxx_mailbox_command(ha, 1, 4, &mbox_cmd[0], &mbox_sts[0]) !=
+           QLA_SUCCESS) {
+               DEBUG2(printk("scsi%ld: %s: MBOX_CMD_GET_FW_STATE failed w/ "
+                             "status %04X\n", ha->host_no, __func__,
+                             mbox_sts[0]));
+               return QLA_ERROR;
+       }
+       ha->firmware_state = mbox_sts[1];
+       ha->board_id = mbox_sts[2];
+       ha->addl_fw_state = mbox_sts[3];
+       DEBUG2(printk("scsi%ld: %s firmware_state=0x%x\n",
+                     ha->host_no, __func__, ha->firmware_state);)
+
+               return QLA_SUCCESS;
+}
+
+/**
+ * qla4xxx_get_firmware_status - retrieves firmware status
+ * @ha: Pointer to host adapter structure.
+ **/
+int qla4xxx_get_firmware_status(struct scsi_qla_host * ha)
+{
+       uint32_t mbox_cmd[MBOX_REG_COUNT];
+       uint32_t mbox_sts[MBOX_REG_COUNT];
+
+       /* Get firmware version */
+       memset(&mbox_cmd, 0, sizeof(mbox_cmd));
+       memset(&mbox_sts, 0, sizeof(mbox_sts));
+       mbox_cmd[0] = MBOX_CMD_GET_FW_STATUS;
+       if (qla4xxx_mailbox_command(ha, 1, 3, &mbox_cmd[0], &mbox_sts[0]) !=
+           QLA_SUCCESS) {
+               DEBUG2(printk("scsi%ld: %s: MBOX_CMD_GET_FW_STATUS failed w/ "
+                             "status %04X\n", ha->host_no, __func__,
+                             mbox_sts[0]));
+               return QLA_ERROR;
+       }
+
+       /* High-water mark of IOCBs */
+       ha->iocb_hiwat = mbox_sts[2];
+       if (ha->iocb_hiwat > IOCB_HIWAT_CUSHION)
+               ha->iocb_hiwat -= IOCB_HIWAT_CUSHION;
+       else
+               dev_info(&ha->pdev->dev, "WARNING!!!  You have less than %d "
+                          "firmare IOCBs available (%d).\n",
+                          IOCB_HIWAT_CUSHION, ha->iocb_hiwat);
+
+       return QLA_SUCCESS;
+}
+
+/**
+ * qla4xxx_get_fwddb_entry - retrieves firmware ddb entry
+ * @ha: Pointer to host adapter structure.
+ * @fw_ddb_index: Firmware's device database index
+ * @fw_ddb_entry: Pointer to firmware's device database entry structure
+ * @num_valid_ddb_entries: Pointer to number of valid ddb entries
+ * @next_ddb_index: Pointer to next valid device database index
+ * @fw_ddb_device_state: Pointer to device state
+ **/
+int qla4xxx_get_fwddb_entry(struct scsi_qla_host *ha,
+                           uint16_t fw_ddb_index,
+                           struct dev_db_entry *fw_ddb_entry,
+                           dma_addr_t fw_ddb_entry_dma,
+                           uint32_t *num_valid_ddb_entries,
+                           uint32_t *next_ddb_index,
+                           uint32_t *fw_ddb_device_state,
+                           uint32_t *conn_err_detail,
+                           uint16_t *tcp_source_port_num,
+                           uint16_t *connection_id)
+{
+       int status = QLA_ERROR;
+       uint32_t mbox_cmd[MBOX_REG_COUNT];
+       uint32_t mbox_sts[MBOX_REG_COUNT];
+
+       /* Make sure the device index is valid */
+       if (fw_ddb_index >= MAX_DDB_ENTRIES) {
+               DEBUG2(printk("scsi%ld: %s: index [%d] out of range.\n",
+                             ha->host_no, __func__, fw_ddb_index));
+               goto exit_get_fwddb;
+       }
+       memset(&mbox_cmd, 0, sizeof(mbox_cmd));
+       memset(&mbox_sts, 0, sizeof(mbox_sts));
+       mbox_cmd[0] = MBOX_CMD_GET_DATABASE_ENTRY;
+       mbox_cmd[1] = (uint32_t) fw_ddb_index;
+       mbox_cmd[2] = LSDW(fw_ddb_entry_dma);
+       mbox_cmd[3] = MSDW(fw_ddb_entry_dma);
+       if (qla4xxx_mailbox_command(ha, 4, 7, &mbox_cmd[0], &mbox_sts[0]) ==
+           QLA_ERROR) {
+               DEBUG2(printk("scsi%ld: %s: MBOX_CMD_GET_DATABASE_ENTRY failed"
+                             " with status 0x%04X\n", ha->host_no, __func__,
+                             mbox_sts[0]));
+               goto exit_get_fwddb;
+       }
+       if (fw_ddb_index != mbox_sts[1]) {
+               DEBUG2(printk("scsi%ld: %s: index mismatch [%d] != [%d].\n",
+                             ha->host_no, __func__, fw_ddb_index,
+                             mbox_sts[1]));
+               goto exit_get_fwddb;
+       }
+       if (fw_ddb_entry) {
+               dev_info(&ha->pdev->dev, "DDB[%d] MB0 %04x Tot %d Next %d "
+                          "State %04x ConnErr %08x %d.%d.%d.%d:%04d \"%s\"\n",
+                          fw_ddb_index, mbox_sts[0], mbox_sts[2], mbox_sts[3],
+                          mbox_sts[4], mbox_sts[5], fw_ddb_entry->ipAddr[0],
+                          fw_ddb_entry->ipAddr[1], fw_ddb_entry->ipAddr[2],
+                          fw_ddb_entry->ipAddr[3],
+                          le16_to_cpu(fw_ddb_entry->portNumber),
+                          fw_ddb_entry->iscsiName);
+       }
+       if (num_valid_ddb_entries)
+               *num_valid_ddb_entries = mbox_sts[2];
+       if (next_ddb_index)
+               *next_ddb_index = mbox_sts[3];
+       if (fw_ddb_device_state)
+               *fw_ddb_device_state = mbox_sts[4];
+
+       /*
+        * RA: This mailbox has been changed to pass connection error and
+        * details.  Its true for ISP4010 as per Version E - Not sure when it
+        * was changed.  Get the time2wait from the fw_dd_entry field :
+        * default_time2wait which we call it as minTime2Wait DEV_DB_ENTRY
+        * struct.
+        */
+       if (conn_err_detail)
+               *conn_err_detail = mbox_sts[5];
+       if (tcp_source_port_num)
+               *tcp_source_port_num = (uint16_t) mbox_sts[6] >> 16;
+       if (connection_id)
+               *connection_id = (uint16_t) mbox_sts[6] & 0x00FF;
+       status = QLA_SUCCESS;
+
+exit_get_fwddb:
+       return status;
+}
+
+/**
+ * qla4xxx_set_fwddb_entry - sets a ddb entry.
+ * @ha: Pointer to host adapter structure.
+ * @fw_ddb_index: Firmware's device database index
+ * @fw_ddb_entry: Pointer to firmware's ddb entry structure, or NULL.
+ *
+ * This routine initializes or updates the adapter's device database
+ * entry for the specified device. It also triggers a login for the
+ * specified device. Therefore, it may also be used as a secondary
+ * login routine when a NULL pointer is specified for the fw_ddb_entry.
+ **/
+int qla4xxx_set_ddb_entry(struct scsi_qla_host * ha, uint16_t fw_ddb_index,
+                         dma_addr_t fw_ddb_entry_dma)
+{
+       uint32_t mbox_cmd[MBOX_REG_COUNT];
+       uint32_t mbox_sts[MBOX_REG_COUNT];
+
+       /* Do not wait for completion. The firmware will send us an
+        * ASTS_DATABASE_CHANGED (0x8014) to notify us of the login status.
+        */
+       memset(&mbox_cmd, 0, sizeof(mbox_cmd));
+       memset(&mbox_sts, 0, sizeof(mbox_sts));
+
+       mbox_cmd[0] = MBOX_CMD_SET_DATABASE_ENTRY;
+       mbox_cmd[1] = (uint32_t) fw_ddb_index;
+       mbox_cmd[2] = LSDW(fw_ddb_entry_dma);
+       mbox_cmd[3] = MSDW(fw_ddb_entry_dma);
+       return qla4xxx_mailbox_command(ha, 4, 1, &mbox_cmd[0], &mbox_sts[0]);
+}
+
+int qla4xxx_conn_open_session_login(struct scsi_qla_host * ha,
+                                   uint16_t fw_ddb_index)
+{
+       int status = QLA_ERROR;
+       uint32_t mbox_cmd[MBOX_REG_COUNT];
+       uint32_t mbox_sts[MBOX_REG_COUNT];
+
+       /* Do not wait for completion. The firmware will send us an
+        * ASTS_DATABASE_CHANGED (0x8014) to notify us of the login status.
+        */
+       memset(&mbox_cmd, 0, sizeof(mbox_cmd));
+       memset(&mbox_sts, 0, sizeof(mbox_sts));
+       mbox_cmd[0] = MBOX_CMD_CONN_OPEN_SESS_LOGIN;
+       mbox_cmd[1] = (uint32_t) fw_ddb_index;
+       mbox_cmd[2] = 0;
+       mbox_cmd[3] = 0;
+       mbox_cmd[4] = 0;
+       status = qla4xxx_mailbox_command(ha, 4, 0, &mbox_cmd[0], &mbox_sts[0]);
+       DEBUG2(printk("%s fw_ddb_index=%d status=%d mbx0_1=0x%x :0x%x\n",
+                     __func__, fw_ddb_index, status, mbox_sts[0],
+                     mbox_sts[1]);)
+
+               return status;
+}
+
+/**
+ * qla4xxx_get_crash_record - retrieves crash record.
+ * @ha: Pointer to host adapter structure.
+ *
+ * This routine retrieves a crash record from the QLA4010 after an 8002h aen.
+ **/
+void qla4xxx_get_crash_record(struct scsi_qla_host * ha)
+{
+       uint32_t mbox_cmd[MBOX_REG_COUNT];
+       uint32_t mbox_sts[MBOX_REG_COUNT];
+       struct crash_record *crash_record = NULL;
+       dma_addr_t crash_record_dma = 0;
+       uint32_t crash_record_size = 0;
+       memset(&mbox_cmd, 0, sizeof(mbox_cmd));
+       memset(&mbox_sts, 0, sizeof(mbox_cmd));
+
+       /* Get size of crash record. */
+       mbox_cmd[0] = MBOX_CMD_GET_CRASH_RECORD;
+       if (qla4xxx_mailbox_command(ha, 5, 5, &mbox_cmd[0], &mbox_sts[0]) !=
+           QLA_SUCCESS) {
+               DEBUG2(printk("scsi%ld: %s: ERROR: Unable to retrieve size!\n",
+                             ha->host_no, __func__));
+               goto exit_get_crash_record;
+       }
+       crash_record_size = mbox_sts[4];
+       if (crash_record_size == 0) {
+               DEBUG2(printk("scsi%ld: %s: ERROR: Crash record size is 0!\n",
+                             ha->host_no, __func__));
+               goto exit_get_crash_record;
+       }
+
+       /* Alloc Memory for Crash Record. */
+       crash_record = dma_alloc_coherent(&ha->pdev->dev, crash_record_size,
+                                         &crash_record_dma, GFP_KERNEL);
+       if (crash_record == NULL)
+               goto exit_get_crash_record;
+
+       /* Get Crash Record. */
+       mbox_cmd[0] = MBOX_CMD_GET_CRASH_RECORD;
+       mbox_cmd[2] = LSDW(crash_record_dma);
+       mbox_cmd[3] = MSDW(crash_record_dma);
+       mbox_cmd[4] = crash_record_size;
+       if (qla4xxx_mailbox_command(ha, 5, 5, &mbox_cmd[0], &mbox_sts[0]) !=
+           QLA_SUCCESS)
+               goto exit_get_crash_record;
+
+       /* Dump Crash Record. */
+
+exit_get_crash_record:
+       if (crash_record)
+               dma_free_coherent(&ha->pdev->dev, crash_record_size,
+                                 crash_record, crash_record_dma);
+}
+
+/**
+ * qla4xxx_get_conn_event_log - retrieves connection event log
+ * @ha: Pointer to host adapter structure.
+ **/
+void qla4xxx_get_conn_event_log(struct scsi_qla_host * ha)
+{
+       uint32_t mbox_cmd[MBOX_REG_COUNT];
+       uint32_t mbox_sts[MBOX_REG_COUNT];
+       struct conn_event_log_entry *event_log = NULL;
+       dma_addr_t event_log_dma = 0;
+       uint32_t event_log_size = 0;
+       uint32_t num_valid_entries;
+       uint32_t      oldest_entry = 0;
+       uint32_t        max_event_log_entries;
+       uint8_t         i;
+
+
+       memset(&mbox_cmd, 0, sizeof(mbox_cmd));
+       memset(&mbox_sts, 0, sizeof(mbox_cmd));
+
+       /* Get size of crash record. */
+       mbox_cmd[0] = MBOX_CMD_GET_CONN_EVENT_LOG;
+       if (qla4xxx_mailbox_command(ha, 4, 5, &mbox_cmd[0], &mbox_sts[0]) !=
+           QLA_SUCCESS)
+               goto exit_get_event_log;
+
+       event_log_size = mbox_sts[4];
+       if (event_log_size == 0)
+               goto exit_get_event_log;
+
+       /* Alloc Memory for Crash Record. */
+       event_log = dma_alloc_coherent(&ha->pdev->dev, event_log_size,
+                                      &event_log_dma, GFP_KERNEL);
+       if (event_log == NULL)
+               goto exit_get_event_log;
+
+       /* Get Crash Record. */
+       mbox_cmd[0] = MBOX_CMD_GET_CONN_EVENT_LOG;
+       mbox_cmd[2] = LSDW(event_log_dma);
+       mbox_cmd[3] = MSDW(event_log_dma);
+       if (qla4xxx_mailbox_command(ha, 4, 5, &mbox_cmd[0], &mbox_sts[0]) !=
+           QLA_SUCCESS) {
+               DEBUG2(printk("scsi%ld: %s: ERROR: Unable to retrieve event "
+                             "log!\n", ha->host_no, __func__));
+               goto exit_get_event_log;
+       }
+
+       /* Dump Event Log. */
+       num_valid_entries = mbox_sts[1];
+
+       max_event_log_entries = event_log_size /
+               sizeof(struct conn_event_log_entry);
+
+       if (num_valid_entries > max_event_log_entries)
+               oldest_entry = num_valid_entries % max_event_log_entries;
+
+       DEBUG3(printk("scsi%ld: Connection Event Log Dump (%d entries):\n",
+                     ha->host_no, num_valid_entries));
+
+       if (qla4_extended_error_logging == 3) {
+               if (oldest_entry == 0) {
+                       /* Circular Buffer has not wrapped around */
+                       for (i=0; i < num_valid_entries; i++) {
+                               qla4xxx_dump_buffer((uint8_t *)event_log+
+                                                   (i*sizeof(*event_log)),
+                                                   sizeof(*event_log));
+                       }
+               }
+               else {
+                       /* Circular Buffer has wrapped around -
+                        * display accordingly*/
+                       for (i=oldest_entry; i < max_event_log_entries; i++) {
+                               qla4xxx_dump_buffer((uint8_t *)event_log+
+                                                   (i*sizeof(*event_log)),
+                                                   sizeof(*event_log));
+                       }
+                       for (i=0; i < oldest_entry; i++) {
+                               qla4xxx_dump_buffer((uint8_t *)event_log+
+                                                   (i*sizeof(*event_log)),
+                                                   sizeof(*event_log));
+                       }
+               }
+       }
+
+exit_get_event_log:
+       if (event_log)
+               dma_free_coherent(&ha->pdev->dev, event_log_size, event_log,
+                                 event_log_dma);
+}
+
+/**
+ * qla4xxx_reset_lun - issues LUN Reset
+ * @ha: Pointer to host adapter structure.
+ * @db_entry: Pointer to device database entry
+ * @un_entry: Pointer to lun entry structure
+ *
+ * This routine performs a LUN RESET on the specified target/lun.
+ * The caller must ensure that the ddb_entry and lun_entry pointers
+ * are valid before calling this routine.
+ **/
+int qla4xxx_reset_lun(struct scsi_qla_host * ha, struct ddb_entry * ddb_entry,
+                     int lun)
+{
+       uint32_t mbox_cmd[MBOX_REG_COUNT];
+       uint32_t mbox_sts[MBOX_REG_COUNT];
+       int status = QLA_SUCCESS;
+
+       DEBUG2(printk("scsi%ld:%d:%d: lun reset issued\n", ha->host_no,
+                     ddb_entry->os_target_id, lun));
+
+       /*
+        * Send lun reset command to ISP, so that the ISP will return all
+        * outstanding requests with RESET status
+        */
+       memset(&mbox_cmd, 0, sizeof(mbox_cmd));
+       memset(&mbox_sts, 0, sizeof(mbox_sts));
+       mbox_cmd[0] = MBOX_CMD_LUN_RESET;
+       mbox_cmd[1] = ddb_entry->fw_ddb_index;
+       mbox_cmd[2] = lun << 8;
+       mbox_cmd[5] = 0x01;     /* Immediate Command Enable */
+       qla4xxx_mailbox_command(ha, 6, 1, &mbox_cmd[0], &mbox_sts[0]);
+       if (mbox_sts[0] != MBOX_STS_COMMAND_COMPLETE &&
+           mbox_sts[0] != MBOX_STS_COMMAND_ERROR)
+               status = QLA_ERROR;
+
+       return status;
+}
+
+
+int qla4xxx_get_flash(struct scsi_qla_host * ha, dma_addr_t dma_addr,
+                     uint32_t offset, uint32_t len)
+{
+       uint32_t mbox_cmd[MBOX_REG_COUNT];
+       uint32_t mbox_sts[MBOX_REG_COUNT];
+
+       memset(&mbox_cmd, 0, sizeof(mbox_cmd));
+       memset(&mbox_sts, 0, sizeof(mbox_sts));
+       mbox_cmd[0] = MBOX_CMD_READ_FLASH;
+       mbox_cmd[1] = LSDW(dma_addr);
+       mbox_cmd[2] = MSDW(dma_addr);
+       mbox_cmd[3] = offset;
+       mbox_cmd[4] = len;
+       if (qla4xxx_mailbox_command(ha, 5, 2, &mbox_cmd[0], &mbox_sts[0]) !=
+           QLA_SUCCESS) {
+               DEBUG2(printk("scsi%ld: %s: MBOX_CMD_READ_FLASH, failed w/ "
+                   "status %04X %04X, offset %08x, len %08x\n", ha->host_no,
+                   __func__, mbox_sts[0], mbox_sts[1], offset, len));
+               return QLA_ERROR;
+       }
+       return QLA_SUCCESS;
+}
+
+/**
+ * qla4xxx_get_fw_version - gets firmware version
+ * @ha: Pointer to host adapter structure.
+ *
+ * Retrieves the firmware version on HBA. In QLA4010, mailboxes 2 & 3 may
+ * hold an address for data.  Make sure that we write 0 to those mailboxes,
+ * if unused.
+ **/
+int qla4xxx_get_fw_version(struct scsi_qla_host * ha)
+{
+       uint32_t mbox_cmd[MBOX_REG_COUNT];
+       uint32_t mbox_sts[MBOX_REG_COUNT];
+
+       /* Get firmware version. */
+       memset(&mbox_cmd, 0, sizeof(mbox_cmd));
+       memset(&mbox_sts, 0, sizeof(mbox_sts));
+       mbox_cmd[0] = MBOX_CMD_ABOUT_FW;
+       if (qla4xxx_mailbox_command(ha, 4, 5, &mbox_cmd[0], &mbox_sts[0]) !=
+           QLA_SUCCESS) {
+               DEBUG2(printk("scsi%ld: %s: MBOX_CMD_ABOUT_FW failed w/ "
+                   "status %04X\n", ha->host_no, __func__, mbox_sts[0]));
+               return QLA_ERROR;
+       }
+
+       /* Save firmware version information. */
+       ha->firmware_version[0] = mbox_sts[1];
+       ha->firmware_version[1] = mbox_sts[2];
+       ha->patch_number = mbox_sts[3];
+       ha->build_number = mbox_sts[4];
+
+       return QLA_SUCCESS;
+}
+
+int qla4xxx_get_default_ddb(struct scsi_qla_host *ha, dma_addr_t dma_addr)
+{
+       uint32_t mbox_cmd[MBOX_REG_COUNT];
+       uint32_t mbox_sts[MBOX_REG_COUNT];
+
+       memset(&mbox_cmd, 0, sizeof(mbox_cmd));
+       memset(&mbox_sts, 0, sizeof(mbox_sts));
+
+       mbox_cmd[0] = MBOX_CMD_GET_DATABASE_ENTRY_DEFAULTS;
+       mbox_cmd[2] = LSDW(dma_addr);
+       mbox_cmd[3] = MSDW(dma_addr);
+
+       if (qla4xxx_mailbox_command(ha, 4, 1, &mbox_cmd[0], &mbox_sts[0]) !=
+           QLA_SUCCESS) {
+               DEBUG2(printk("scsi%ld: %s: failed status %04X\n",
+                    ha->host_no, __func__, mbox_sts[0]));
+               return QLA_ERROR;
+       }
+       return QLA_SUCCESS;
+}
+
+int qla4xxx_req_ddb_entry(struct scsi_qla_host *ha, uint32_t *ddb_index)
+{
+       uint32_t mbox_cmd[MBOX_REG_COUNT];
+       uint32_t mbox_sts[MBOX_REG_COUNT];
+
+       memset(&mbox_cmd, 0, sizeof(mbox_cmd));
+       memset(&mbox_sts, 0, sizeof(mbox_sts));
+
+       mbox_cmd[0] = MBOX_CMD_REQUEST_DATABASE_ENTRY;
+       mbox_cmd[1] = MAX_PRST_DEV_DB_ENTRIES;
+
+       if (qla4xxx_mailbox_command(ha, 2, 3, &mbox_cmd[0], &mbox_sts[0]) !=
+           QLA_SUCCESS) {
+               if (mbox_sts[0] == MBOX_STS_COMMAND_ERROR) {
+                       *ddb_index = mbox_sts[2];
+               } else {
+                       DEBUG2(printk("scsi%ld: %s: failed status %04X\n",
+                            ha->host_no, __func__, mbox_sts[0]));
+                       return QLA_ERROR;
+               }
+       } else {
+               *ddb_index = MAX_PRST_DEV_DB_ENTRIES;
+       }
+
+       return QLA_SUCCESS;
+}
+
+
+int qla4xxx_send_tgts(struct scsi_qla_host *ha, char *ip, uint16_t port)
+{
+       struct dev_db_entry *fw_ddb_entry;
+       dma_addr_t fw_ddb_entry_dma;
+       uint32_t ddb_index;
+       int ret_val = QLA_SUCCESS;
+
+
+       fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev,
+                                         sizeof(*fw_ddb_entry),
+                                         &fw_ddb_entry_dma, GFP_KERNEL);
+       if (!fw_ddb_entry) {
+               DEBUG2(printk("scsi%ld: %s: Unable to allocate dma buffer.\n",
+                             ha->host_no, __func__));
+               ret_val = QLA_ERROR;
+               goto qla4xxx_send_tgts_exit;
+       }
+
+       ret_val = qla4xxx_get_default_ddb(ha, fw_ddb_entry_dma);
+       if (ret_val != QLA_SUCCESS)
+               goto qla4xxx_send_tgts_exit;
+
+       ret_val = qla4xxx_req_ddb_entry(ha, &ddb_index);
+       if (ret_val != QLA_SUCCESS)
+               goto qla4xxx_send_tgts_exit;
+
+       memset((void *)fw_ddb_entry->iSCSIAlias, 0,
+              sizeof(fw_ddb_entry->iSCSIAlias));
+
+       memset((void *)fw_ddb_entry->iscsiName, 0,
+              sizeof(fw_ddb_entry->iscsiName));
+
+       memset((void *)fw_ddb_entry->ipAddr, 0, sizeof(fw_ddb_entry->ipAddr));
+       memset((void *)fw_ddb_entry->targetAddr, 0,
+              sizeof(fw_ddb_entry->targetAddr));
+
+       fw_ddb_entry->options = (DDB_OPT_DISC_SESSION | DDB_OPT_TARGET);
+       fw_ddb_entry->portNumber = cpu_to_le16(ntohs(port));
+
+       fw_ddb_entry->ipAddr[0] = *ip;
+       fw_ddb_entry->ipAddr[1] = *(ip + 1);
+       fw_ddb_entry->ipAddr[2] = *(ip + 2);
+       fw_ddb_entry->ipAddr[3] = *(ip + 3);
+
+       ret_val = qla4xxx_set_ddb_entry(ha, ddb_index, fw_ddb_entry_dma);
+
+qla4xxx_send_tgts_exit:
+       dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),
+                         fw_ddb_entry, fw_ddb_entry_dma);
+       return ret_val;
+}
+
diff --git a/drivers/scsi/qla4xxx/ql4_nvram.c b/drivers/scsi/qla4xxx/ql4_nvram.c
new file mode 100644 (file)
index 0000000..e3957ca
--- /dev/null
@@ -0,0 +1,224 @@
+/*
+ * QLogic iSCSI HBA Driver
+ * Copyright (c)  2003-2006 QLogic Corporation
+ *
+ * See LICENSE.qla4xxx for copyright and licensing details.
+ */
+
+#include "ql4_def.h"
+
+static inline int eeprom_size(struct scsi_qla_host *ha)
+{
+       return is_qla4022(ha) ? FM93C86A_SIZE_16 : FM93C66A_SIZE_16;
+}
+
+static inline int eeprom_no_addr_bits(struct scsi_qla_host *ha)
+{
+       return is_qla4022(ha) ? FM93C86A_NO_ADDR_BITS_16 :
+               FM93C56A_NO_ADDR_BITS_16;
+}
+
+static inline int eeprom_no_data_bits(struct scsi_qla_host *ha)
+{
+       return FM93C56A_DATA_BITS_16;
+}
+
+static int fm93c56a_select(struct scsi_qla_host * ha)
+{
+       DEBUG5(printk(KERN_ERR "fm93c56a_select:\n"));
+
+       ha->eeprom_cmd_data = AUBURN_EEPROM_CS_1 | 0x000f0000;
+       writel(ha->eeprom_cmd_data, isp_nvram(ha));
+       readl(isp_nvram(ha));
+       return 1;
+}
+
+static int fm93c56a_cmd(struct scsi_qla_host * ha, int cmd, int addr)
+{
+       int i;
+       int mask;
+       int dataBit;
+       int previousBit;
+
+       /* Clock in a zero, then do the start bit. */
+       writel(ha->eeprom_cmd_data | AUBURN_EEPROM_DO_1, isp_nvram(ha));
+       writel(ha->eeprom_cmd_data | AUBURN_EEPROM_DO_1 |
+              AUBURN_EEPROM_CLK_RISE, isp_nvram(ha));
+       writel(ha->eeprom_cmd_data | AUBURN_EEPROM_DO_1 |
+              AUBURN_EEPROM_CLK_FALL, isp_nvram(ha));
+       readl(isp_nvram(ha));
+       mask = 1 << (FM93C56A_CMD_BITS - 1);
+
+       /* Force the previous data bit to be different. */
+       previousBit = 0xffff;
+       for (i = 0; i < FM93C56A_CMD_BITS; i++) {
+               dataBit =
+                       (cmd & mask) ? AUBURN_EEPROM_DO_1 : AUBURN_EEPROM_DO_0;
+               if (previousBit != dataBit) {
+
+                       /*
+                        * If the bit changed, then change the DO state to
+                        * match.
+                        */
+                       writel(ha->eeprom_cmd_data | dataBit, isp_nvram(ha));
+                       previousBit = dataBit;
+               }
+               writel(ha->eeprom_cmd_data | dataBit |
+                      AUBURN_EEPROM_CLK_RISE, isp_nvram(ha));
+               writel(ha->eeprom_cmd_data | dataBit |
+                      AUBURN_EEPROM_CLK_FALL, isp_nvram(ha));
+               readl(isp_nvram(ha));
+               cmd = cmd << 1;
+       }
+       mask = 1 << (eeprom_no_addr_bits(ha) - 1);
+
+       /* Force the previous data bit to be different. */
+       previousBit = 0xffff;
+       for (i = 0; i < eeprom_no_addr_bits(ha); i++) {
+               dataBit = addr & mask ? AUBURN_EEPROM_DO_1 :
+                       AUBURN_EEPROM_DO_0;
+               if (previousBit != dataBit) {
+                       /*
+                        * If the bit changed, then change the DO state to
+                        * match.
+                        */
+                       writel(ha->eeprom_cmd_data | dataBit, isp_nvram(ha));
+                       previousBit = dataBit;
+               }
+               writel(ha->eeprom_cmd_data | dataBit |
+                      AUBURN_EEPROM_CLK_RISE, isp_nvram(ha));
+               writel(ha->eeprom_cmd_data | dataBit |
+                      AUBURN_EEPROM_CLK_FALL, isp_nvram(ha));
+               readl(isp_nvram(ha));
+               addr = addr << 1;
+       }
+       return 1;
+}
+
+static int fm93c56a_deselect(struct scsi_qla_host * ha)
+{
+       ha->eeprom_cmd_data = AUBURN_EEPROM_CS_0 | 0x000f0000;
+       writel(ha->eeprom_cmd_data, isp_nvram(ha));
+       readl(isp_nvram(ha));
+       return 1;
+}
+
+static int fm93c56a_datain(struct scsi_qla_host * ha, unsigned short *value)
+{
+       int i;
+       int data = 0;
+       int dataBit;
+
+       /* Read the data bits
+        * The first bit is a dummy.  Clock right over it. */
+       for (i = 0; i < eeprom_no_data_bits(ha); i++) {
+               writel(ha->eeprom_cmd_data |
+                      AUBURN_EEPROM_CLK_RISE, isp_nvram(ha));
+               writel(ha->eeprom_cmd_data |
+                      AUBURN_EEPROM_CLK_FALL, isp_nvram(ha));
+               dataBit =
+                       (readw(isp_nvram(ha)) & AUBURN_EEPROM_DI_1) ? 1 : 0;
+               data = (data << 1) | dataBit;
+       }
+
+       *value = data;
+       return 1;
+}
+
+static int eeprom_readword(int eepromAddr, u16 * value,
+                          struct scsi_qla_host * ha)
+{
+       fm93c56a_select(ha);
+       fm93c56a_cmd(ha, FM93C56A_READ, eepromAddr);
+       fm93c56a_datain(ha, value);
+       fm93c56a_deselect(ha);
+       return 1;
+}
+
+/* Hardware_lock must be set before calling */
+u16 rd_nvram_word(struct scsi_qla_host * ha, int offset)
+{
+       u16 val;
+
+       /* NOTE: NVRAM uses half-word addresses */
+       eeprom_readword(offset, &val, ha);
+       return val;
+}
+
+int qla4xxx_is_nvram_configuration_valid(struct scsi_qla_host * ha)
+{
+       int status = QLA_ERROR;
+       uint16_t checksum = 0;
+       uint32_t index;
+       unsigned long flags;
+
+       spin_lock_irqsave(&ha->hardware_lock, flags);
+       for (index = 0; index < eeprom_size(ha); index++)
+               checksum += rd_nvram_word(ha, index);
+       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
+       if (checksum == 0)
+               status = QLA_SUCCESS;
+
+       return status;
+}
+
+/*************************************************************************
+ *
+ *                     Hardware Semaphore routines
+ *
+ *************************************************************************/
+int ql4xxx_sem_spinlock(struct scsi_qla_host * ha, u32 sem_mask, u32 sem_bits)
+{
+       uint32_t value;
+       unsigned long flags;
+       unsigned int seconds = 30;
+
+       DEBUG2(printk("scsi%ld : Trying to get SEM lock - mask= 0x%x, code = "
+                     "0x%x\n", ha->host_no, sem_mask, sem_bits));
+       do {
+               spin_lock_irqsave(&ha->hardware_lock, flags);
+               writel((sem_mask | sem_bits), isp_semaphore(ha));
+               value = readw(isp_semaphore(ha));
+               spin_unlock_irqrestore(&ha->hardware_lock, flags);
+               if ((value & (sem_mask >> 16)) == sem_bits) {
+                       DEBUG2(printk("scsi%ld : Got SEM LOCK - mask= 0x%x, "
+                                     "code = 0x%x\n", ha->host_no,
+                                     sem_mask, sem_bits));
+                       return QLA_SUCCESS;
+               }
+               ssleep(1);
+       } while (--seconds);
+       return QLA_ERROR;
+}
+
+void ql4xxx_sem_unlock(struct scsi_qla_host * ha, u32 sem_mask)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&ha->hardware_lock, flags);
+       writel(sem_mask, isp_semaphore(ha));
+       readl(isp_semaphore(ha));
+       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
+       DEBUG2(printk("scsi%ld : UNLOCK SEM - mask= 0x%x\n", ha->host_no,
+                     sem_mask));
+}
+
+int ql4xxx_sem_lock(struct scsi_qla_host * ha, u32 sem_mask, u32 sem_bits)
+{
+       uint32_t value;
+       unsigned long flags;
+
+       spin_lock_irqsave(&ha->hardware_lock, flags);
+       writel((sem_mask | sem_bits), isp_semaphore(ha));
+       value = readw(isp_semaphore(ha));
+       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+       if ((value & (sem_mask >> 16)) == sem_bits) {
+               DEBUG2(printk("scsi%ld : Got SEM LOCK - mask= 0x%x, code = "
+                             "0x%x, sema code=0x%x\n", ha->host_no,
+                             sem_mask, sem_bits, value));
+               return 1;
+       }
+       return 0;
+}
diff --git a/drivers/scsi/qla4xxx/ql4_nvram.h b/drivers/scsi/qla4xxx/ql4_nvram.h
new file mode 100644 (file)
index 0000000..08e2aed
--- /dev/null
@@ -0,0 +1,256 @@
+/*
+ * QLogic iSCSI HBA Driver
+ * Copyright (c)  2003-2006 QLogic Corporation
+ *
+ * See LICENSE.qla4xxx for copyright and licensing details.
+ */
+
+#ifndef _QL4XNVRM_H_
+#define _QL4XNVRM_H_
+
+/*
+ * AM29LV Flash definitions
+ */
+#define FM93C56A_SIZE_8         0x100
+#define FM93C56A_SIZE_16 0x80
+#define FM93C66A_SIZE_8         0x200
+#define FM93C66A_SIZE_16 0x100/* 4010 */
+#define FM93C86A_SIZE_16 0x400/* 4022 */
+
+#define         FM93C56A_START       0x1
+
+// Commands
+#define         FM93C56A_READ        0x2
+#define         FM93C56A_WEN         0x0
+#define         FM93C56A_WRITE       0x1
+#define         FM93C56A_WRITE_ALL   0x0
+#define         FM93C56A_WDS         0x0
+#define         FM93C56A_ERASE       0x3
+#define         FM93C56A_ERASE_ALL   0x0
+
+/* Command Extentions */
+#define         FM93C56A_WEN_EXT        0x3
+#define         FM93C56A_WRITE_ALL_EXT  0x1
+#define         FM93C56A_WDS_EXT        0x0
+#define         FM93C56A_ERASE_ALL_EXT  0x2
+
+/* Address Bits */
+#define         FM93C56A_NO_ADDR_BITS_16   8   /* 4010 */
+#define         FM93C56A_NO_ADDR_BITS_8    9   /* 4010 */
+#define         FM93C86A_NO_ADDR_BITS_16   10  /* 4022 */
+
+/* Data Bits */
+#define         FM93C56A_DATA_BITS_16   16
+#define         FM93C56A_DATA_BITS_8    8
+
+/* Special Bits */
+#define         FM93C56A_READ_DUMMY_BITS   1
+#define         FM93C56A_READY             0
+#define         FM93C56A_BUSY              1
+#define         FM93C56A_CMD_BITS          2
+
+/* Auburn Bits */
+#define         AUBURN_EEPROM_DI           0x8
+#define         AUBURN_EEPROM_DI_0         0x0
+#define         AUBURN_EEPROM_DI_1         0x8
+#define         AUBURN_EEPROM_DO           0x4
+#define         AUBURN_EEPROM_DO_0         0x0
+#define         AUBURN_EEPROM_DO_1         0x4
+#define         AUBURN_EEPROM_CS           0x2
+#define         AUBURN_EEPROM_CS_0         0x0
+#define         AUBURN_EEPROM_CS_1         0x2
+#define         AUBURN_EEPROM_CLK_RISE     0x1
+#define         AUBURN_EEPROM_CLK_FALL     0x0
+
+/* */
+/* EEPROM format */
+/* */
+struct bios_params {
+       uint16_t SpinUpDelay:1;
+       uint16_t BIOSDisable:1;
+       uint16_t MMAPEnable:1;
+       uint16_t BootEnable:1;
+       uint16_t Reserved0:12;
+       uint8_t bootID0:7;
+       uint8_t bootID0Valid:1;
+       uint8_t bootLUN0[8];
+       uint8_t bootID1:7;
+       uint8_t bootID1Valid:1;
+       uint8_t bootLUN1[8];
+       uint16_t MaxLunsPerTarget;
+       uint8_t Reserved1[10];
+};
+
+struct eeprom_port_cfg {
+
+       /* MTU MAC 0 */
+       u16 etherMtu_mac;
+
+       /* Flow Control MAC 0 */
+       u16 pauseThreshold_mac;
+       u16 resumeThreshold_mac;
+       u16 reserved[13];
+};
+
+struct eeprom_function_cfg {
+       u8 reserved[30];
+
+       /* MAC ADDR */
+       u8 macAddress[6];
+       u8 macAddressSecondary[6];
+       u16 subsysVendorId;
+       u16 subsysDeviceId;
+};
+
+struct eeprom_data {
+       union {
+               struct {        /* isp4010 */
+                       u8 asic_id[4]; /* x00 */
+                       u8 version;     /* x04 */
+                       u8 reserved;    /* x05 */
+                       u16 board_id;   /* x06 */
+#define          EEPROM_BOARDID_ELDORADO    1
+#define          EEPROM_BOARDID_PLACER      2
+
+#define EEPROM_SERIAL_NUM_SIZE      16
+                       u8 serial_number[EEPROM_SERIAL_NUM_SIZE]; /* x08 */
+
+                       /* ExtHwConfig: */
+                       /* Offset = 24bytes
+                        *
+                        * | SSRAM Size|     |ST|PD|SDRAM SZ| W| B| SP  |  |
+                        * |15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+                        * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+                        */
+                       u16 ext_hw_conf; /* x18 */
+                       u8 mac0[6];     /* x1A */
+                       u8 mac1[6];     /* x20 */
+                       u8 mac2[6];     /* x26 */
+                       u8 mac3[6];     /* x2C */
+                       u16 etherMtu;   /* x32 */
+                       u16 macConfig;  /* x34 */
+#define         MAC_CONFIG_ENABLE_ANEG     0x0001
+#define         MAC_CONFIG_ENABLE_PAUSE    0x0002
+                       u16 phyConfig;  /* x36 */
+#define         PHY_CONFIG_PHY_ADDR_MASK             0x1f
+#define         PHY_CONFIG_ENABLE_FW_MANAGEMENT_MASK 0x20
+                       u16 topcat;     /* x38 */
+#define TOPCAT_PRESENT         0x0100
+#define TOPCAT_MASK            0xFF00
+
+#define EEPROM_UNUSED_1_SIZE   2
+                       u8 unused_1[EEPROM_UNUSED_1_SIZE]; /* x3A */
+                       u16 bufletSize; /* x3C */
+                       u16 bufletCount;        /* x3E */
+                       u16 bufletPauseThreshold; /* x40 */
+                       u16 tcpWindowThreshold50; /* x42 */
+                       u16 tcpWindowThreshold25; /* x44 */
+                       u16 tcpWindowThreshold0; /* x46 */
+                       u16 ipHashTableBaseHi;  /* x48 */
+                       u16 ipHashTableBaseLo;  /* x4A */
+                       u16 ipHashTableSize;    /* x4C */
+                       u16 tcpHashTableBaseHi; /* x4E */
+                       u16 tcpHashTableBaseLo; /* x50 */
+                       u16 tcpHashTableSize;   /* x52 */
+                       u16 ncbTableBaseHi;     /* x54 */
+                       u16 ncbTableBaseLo;     /* x56 */
+                       u16 ncbTableSize;       /* x58 */
+                       u16 drbTableBaseHi;     /* x5A */
+                       u16 drbTableBaseLo;     /* x5C */
+                       u16 drbTableSize;       /* x5E */
+
+#define EEPROM_UNUSED_2_SIZE   4
+                       u8 unused_2[EEPROM_UNUSED_2_SIZE]; /* x60 */
+                       u16 ipReassemblyTimeout; /* x64 */
+                       u16 tcpMaxWindowSizeHi; /* x66 */
+                       u16 tcpMaxWindowSizeLo; /* x68 */
+                       u32 net_ip_addr0;       /* x6A Added for TOE
+                                                * functionality. */
+                       u32 net_ip_addr1;       /* x6E */
+                       u32 scsi_ip_addr0;      /* x72 */
+                       u32 scsi_ip_addr1;      /* x76 */
+#define EEPROM_UNUSED_3_SIZE   128     /* changed from 144 to account
+                                        * for ip addresses */
+                       u8 unused_3[EEPROM_UNUSED_3_SIZE]; /* x7A */
+                       u16 subsysVendorId_f0;  /* xFA */
+                       u16 subsysDeviceId_f0;  /* xFC */
+
+                       /* Address = 0x7F */
+#define FM93C56A_SIGNATURE  0x9356
+#define FM93C66A_SIGNATURE  0x9366
+                       u16 signature;  /* xFE */
+
+#define EEPROM_UNUSED_4_SIZE   250
+                       u8 unused_4[EEPROM_UNUSED_4_SIZE]; /* x100 */
+                       u16 subsysVendorId_f1;  /* x1FA */
+                       u16 subsysDeviceId_f1;  /* x1FC */
+                       u16 checksum;   /* x1FE */
+               } __attribute__ ((packed)) isp4010;
+               struct {        /* isp4022 */
+                       u8 asicId[4];   /* x00 */
+                       u8 version;     /* x04 */
+                       u8 reserved_5;  /* x05 */
+                       u16 boardId;    /* x06 */
+                       u8 boardIdStr[16];      /* x08 */
+                       u8 serialNumber[16];    /* x18 */
+
+                       /* External Hardware Configuration */
+                       u16 ext_hw_conf;        /* x28 */
+
+                       /* MAC 0 CONFIGURATION */
+                       struct eeprom_port_cfg macCfg_port0; /* x2A */
+
+                       /* MAC 1 CONFIGURATION */
+                       struct eeprom_port_cfg macCfg_port1; /* x4A */
+
+                       /* DDR SDRAM Configuration */
+                       u16 bufletSize; /* x6A */
+                       u16 bufletCount;        /* x6C */
+                       u16 tcpWindowThreshold50; /* x6E */
+                       u16 tcpWindowThreshold25; /* x70 */
+                       u16 tcpWindowThreshold0; /* x72 */
+                       u16 ipHashTableBaseHi;  /* x74 */
+                       u16 ipHashTableBaseLo;  /* x76 */
+                       u16 ipHashTableSize;    /* x78 */
+                       u16 tcpHashTableBaseHi; /* x7A */
+                       u16 tcpHashTableBaseLo; /* x7C */
+                       u16 tcpHashTableSize;   /* x7E */
+                       u16 ncbTableBaseHi;     /* x80 */
+                       u16 ncbTableBaseLo;     /* x82 */
+                       u16 ncbTableSize;       /* x84 */
+                       u16 drbTableBaseHi;     /* x86 */
+                       u16 drbTableBaseLo;     /* x88 */
+                       u16 drbTableSize;       /* x8A */
+                       u16 reserved_142[4];    /* x8C */
+
+                       /* TCP/IP Parameters */
+                       u16 ipReassemblyTimeout; /* x94 */
+                       u16 tcpMaxWindowSize;   /* x96 */
+                       u16 ipSecurity; /* x98 */
+                       u8 reserved_156[294]; /* x9A */
+                       u16 qDebug[8];  /* QLOGIC USE ONLY   x1C0 */
+                       struct eeprom_function_cfg funcCfg_fn0; /* x1D0 */
+                       u16 reserved_510; /* x1FE */
+
+                       /* Address = 512 */
+                       u8 oemSpace[432]; /* x200 */
+                       struct bios_params sBIOSParams_fn1; /* x3B0 */
+                       struct eeprom_function_cfg funcCfg_fn1; /* x3D0 */
+                       u16 reserved_1022; /* x3FE */
+
+                       /* Address = 1024 */
+                       u8 reserved_1024[464];  /* x400 */
+                       struct eeprom_function_cfg funcCfg_fn2; /* x5D0 */
+                       u16 reserved_1534; /* x5FE */
+
+                       /* Address = 1536 */
+                       u8 reserved_1536[432];  /* x600 */
+                       struct bios_params sBIOSParams_fn3; /* x7B0 */
+                       struct eeprom_function_cfg funcCfg_fn3; /* x7D0 */
+                       u16 checksum;   /* x7FE */
+               } __attribute__ ((packed)) isp4022;
+       };
+};
+
+
+#endif /* _QL4XNVRM_H_ */
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
new file mode 100644 (file)
index 0000000..178fcdd
--- /dev/null
@@ -0,0 +1,1755 @@
+/*
+ * QLogic iSCSI HBA Driver
+ * Copyright (c)  2003-2006 QLogic Corporation
+ *
+ * See LICENSE.qla4xxx for copyright and licensing details.
+ */
+#include <linux/moduleparam.h>
+
+#include <scsi/scsi_tcq.h>
+#include <scsi/scsicam.h>
+
+#include "ql4_def.h"
+
+/*
+ * Driver version
+ */
+char qla4xxx_version_str[40];
+
+/*
+ * SRB allocation cache
+ */
+static kmem_cache_t *srb_cachep;
+
+/*
+ * Module parameter information and variables
+ */
+int ql4xdiscoverywait = 60;
+module_param(ql4xdiscoverywait, int, S_IRUGO | S_IRUSR);
+MODULE_PARM_DESC(ql4xdiscoverywait, "Discovery wait time");
+int ql4xdontresethba = 0;
+module_param(ql4xdontresethba, int, S_IRUGO | S_IRUSR);
+MODULE_PARM_DESC(ql4xdontresethba,
+                "Dont reset the HBA when the driver gets 0x8002 AEN "
+                " default it will reset hba :0"
+                " set to 1 to avoid resetting HBA");
+
+int qla4_extended_error_logging = 0; /* 0 = off, 1 = log errors */
+module_param(qla4_extended_error_logging, int, S_IRUGO | S_IRUSR);
+MODULE_PARM_DESC(qla4_extended_error_logging,
+                "Option to enable extended error logging, "
+                "Default is 0 - no logging, 1 - debug logging");
+
+/*
+ * SCSI host template entry points
+ */
+
+void qla4xxx_config_dma_addressing(struct scsi_qla_host *ha);
+
+/*
+ * iSCSI template entry points
+ */
+static int qla4xxx_tgt_dscvr(enum iscsi_tgt_dscvr type, uint32_t host_no,
+                            uint32_t enable, struct sockaddr *dst_addr);
+static int qla4xxx_conn_get_param(struct iscsi_cls_conn *conn,
+                                 enum iscsi_param param, char *buf);
+static int qla4xxx_sess_get_param(struct iscsi_cls_session *sess,
+                                 enum iscsi_param param, char *buf);
+static void qla4xxx_conn_stop(struct iscsi_cls_conn *conn, int flag);
+static int qla4xxx_conn_start(struct iscsi_cls_conn *conn);
+static void qla4xxx_recovery_timedout(struct iscsi_cls_session *session);
+
+/*
+ * SCSI host template entry points
+ */
+static int qla4xxx_queuecommand(struct scsi_cmnd *cmd,
+                               void (*done) (struct scsi_cmnd *));
+static int qla4xxx_eh_device_reset(struct scsi_cmnd *cmd);
+static int qla4xxx_eh_host_reset(struct scsi_cmnd *cmd);
+static int qla4xxx_slave_alloc(struct scsi_device *device);
+static int qla4xxx_slave_configure(struct scsi_device *device);
+static void qla4xxx_slave_destroy(struct scsi_device *sdev);
+
+static struct scsi_host_template qla4xxx_driver_template = {
+       .module                 = THIS_MODULE,
+       .name                   = DRIVER_NAME,
+       .proc_name              = DRIVER_NAME,
+       .queuecommand           = qla4xxx_queuecommand,
+
+       .eh_device_reset_handler = qla4xxx_eh_device_reset,
+       .eh_host_reset_handler  = qla4xxx_eh_host_reset,
+
+       .slave_configure        = qla4xxx_slave_configure,
+       .slave_alloc            = qla4xxx_slave_alloc,
+       .slave_destroy          = qla4xxx_slave_destroy,
+
+       .this_id                = -1,
+       .cmd_per_lun            = 3,
+       .use_clustering         = ENABLE_CLUSTERING,
+       .sg_tablesize           = SG_ALL,
+
+       .max_sectors            = 0xFFFF,
+};
+
+static struct iscsi_transport qla4xxx_iscsi_transport = {
+       .owner                  = THIS_MODULE,
+       .name                   = DRIVER_NAME,
+       .param_mask             = ISCSI_CONN_PORT |
+                                 ISCSI_CONN_ADDRESS |
+                                 ISCSI_TARGET_NAME |
+                                 ISCSI_TPGT,
+       .sessiondata_size       = sizeof(struct ddb_entry),
+       .host_template          = &qla4xxx_driver_template,
+
+       .tgt_dscvr              = qla4xxx_tgt_dscvr,
+       .get_conn_param         = qla4xxx_conn_get_param,
+       .get_session_param      = qla4xxx_sess_get_param,
+       .start_conn             = qla4xxx_conn_start,
+       .stop_conn              = qla4xxx_conn_stop,
+       .session_recovery_timedout = qla4xxx_recovery_timedout,
+};
+
+static struct scsi_transport_template *qla4xxx_scsi_transport;
+
+static void qla4xxx_recovery_timedout(struct iscsi_cls_session *session)
+{
+       struct ddb_entry *ddb_entry = session->dd_data;
+       struct scsi_qla_host *ha = ddb_entry->ha;
+
+       DEBUG2(printk("scsi%ld: %s: index [%d] port down retry count of (%d) "
+                     "secs exhausted, marking device DEAD.\n", ha->host_no,
+                     __func__, ddb_entry->fw_ddb_index,
+                     ha->port_down_retry_count));
+
+       atomic_set(&ddb_entry->state, DDB_STATE_DEAD);
+
+       DEBUG2(printk("scsi%ld: %s: scheduling dpc routine - dpc flags = "
+                     "0x%lx\n", ha->host_no, __func__, ha->dpc_flags));
+       queue_work(ha->dpc_thread, &ha->dpc_work);
+}
+
+static int qla4xxx_conn_start(struct iscsi_cls_conn *conn)
+{
+       struct iscsi_cls_session *session;
+       struct ddb_entry *ddb_entry;
+
+       session = iscsi_dev_to_session(conn->dev.parent);
+       ddb_entry = session->dd_data;
+
+       DEBUG2(printk("scsi%ld: %s: index [%d] starting conn\n",
+                     ddb_entry->ha->host_no, __func__,
+                     ddb_entry->fw_ddb_index));
+       iscsi_unblock_session(session);
+       return 0;
+}
+
+static void qla4xxx_conn_stop(struct iscsi_cls_conn *conn, int flag)
+{
+       struct iscsi_cls_session *session;
+       struct ddb_entry *ddb_entry;
+
+       session = iscsi_dev_to_session(conn->dev.parent);
+       ddb_entry = session->dd_data;
+
+       DEBUG2(printk("scsi%ld: %s: index [%d] stopping conn\n",
+                     ddb_entry->ha->host_no, __func__,
+                     ddb_entry->fw_ddb_index));
+       if (flag == STOP_CONN_RECOVER)
+               iscsi_block_session(session);
+       else
+               printk(KERN_ERR "iscsi: invalid stop flag %d\n", flag);
+}
+
+static int qla4xxx_sess_get_param(struct iscsi_cls_session *sess,
+                                 enum iscsi_param param, char *buf)
+{
+       struct ddb_entry *ddb_entry = sess->dd_data;
+       int len;
+
+       switch (param) {
+       case ISCSI_PARAM_TARGET_NAME:
+               len = snprintf(buf, PAGE_SIZE - 1, "%s\n",
+                              ddb_entry->iscsi_name);
+               break;
+       case ISCSI_PARAM_TPGT:
+               len = sprintf(buf, "%u\n", ddb_entry->tpgt);
+               break;
+       default:
+               return -ENOSYS;
+       }
+
+       return len;
+}
+
+static int qla4xxx_conn_get_param(struct iscsi_cls_conn *conn,
+                                 enum iscsi_param param, char *buf)
+{
+       struct iscsi_cls_session *session;
+       struct ddb_entry *ddb_entry;
+       int len;
+
+       session = iscsi_dev_to_session(conn->dev.parent);
+       ddb_entry = session->dd_data;
+
+       switch (param) {
+       case ISCSI_PARAM_CONN_PORT:
+               len = sprintf(buf, "%hu\n", ddb_entry->port);
+               break;
+       case ISCSI_PARAM_CONN_ADDRESS:
+               /* TODO: what are the ipv6 bits */
+               len = sprintf(buf, "%u.%u.%u.%u\n",
+                             NIPQUAD(ddb_entry->ip_addr));
+               break;
+       default:
+               return -ENOSYS;
+       }
+
+       return len;
+}
+
+static int qla4xxx_tgt_dscvr(enum iscsi_tgt_dscvr type, uint32_t host_no,
+                            uint32_t enable, struct sockaddr *dst_addr)
+{
+       struct scsi_qla_host *ha;
+       struct Scsi_Host *shost;
+       struct sockaddr_in *addr;
+       struct sockaddr_in6 *addr6;
+       int ret = 0;
+
+       shost = scsi_host_lookup(host_no);
+       if (IS_ERR(shost)) {
+               printk(KERN_ERR "Could not find host no %u\n", host_no);
+               return -ENODEV;
+       }
+
+       ha = (struct scsi_qla_host *) shost->hostdata;
+
+       switch (type) {
+       case ISCSI_TGT_DSCVR_SEND_TARGETS:
+               if (dst_addr->sa_family == AF_INET) {
+                       addr = (struct sockaddr_in *)dst_addr;
+                       if (qla4xxx_send_tgts(ha, (char *)&addr->sin_addr,
+                                             addr->sin_port) != QLA_SUCCESS)
+                               ret = -EIO;
+               } else if (dst_addr->sa_family == AF_INET6) {
+                       /*
+                        * TODO: fix qla4xxx_send_tgts
+                        */
+                       addr6 = (struct sockaddr_in6 *)dst_addr;
+                       if (qla4xxx_send_tgts(ha, (char *)&addr6->sin6_addr,
+                                             addr6->sin6_port) != QLA_SUCCESS)
+                               ret = -EIO;
+               } else
+                       ret = -ENOSYS;
+               break;
+       default:
+               ret = -ENOSYS;
+       }
+
+       scsi_host_put(shost);
+       return ret;
+}
+
+void qla4xxx_destroy_sess(struct ddb_entry *ddb_entry)
+{
+       if (!ddb_entry->sess)
+               return;
+
+       if (ddb_entry->conn) {
+               iscsi_if_destroy_session_done(ddb_entry->conn);
+               iscsi_destroy_conn(ddb_entry->conn);
+               iscsi_remove_session(ddb_entry->sess);
+       }
+       iscsi_free_session(ddb_entry->sess);
+}
+
+int qla4xxx_add_sess(struct ddb_entry *ddb_entry)
+{
+       int err;
+
+       err = iscsi_add_session(ddb_entry->sess, ddb_entry->fw_ddb_index);
+       if (err) {
+               DEBUG2(printk(KERN_ERR "Could not add session.\n"));
+               return err;
+       }
+
+       ddb_entry->conn = iscsi_create_conn(ddb_entry->sess, 0);
+       if (!ddb_entry->conn) {
+               iscsi_remove_session(ddb_entry->sess);
+               DEBUG2(printk(KERN_ERR "Could not add connection.\n"));
+               return -ENOMEM;
+       }
+
+       ddb_entry->sess->recovery_tmo = ddb_entry->ha->port_down_retry_count;
+       iscsi_if_create_session_done(ddb_entry->conn);
+       return 0;
+}
+
+struct ddb_entry *qla4xxx_alloc_sess(struct scsi_qla_host *ha)
+{
+       struct ddb_entry *ddb_entry;
+       struct iscsi_cls_session *sess;
+
+       sess = iscsi_alloc_session(ha->host, &qla4xxx_iscsi_transport);
+       if (!sess)
+               return NULL;
+
+       ddb_entry = sess->dd_data;
+       memset(ddb_entry, 0, sizeof(*ddb_entry));
+       ddb_entry->ha = ha;
+       ddb_entry->sess = sess;
+       return ddb_entry;
+}
+
+/*
+ * Timer routines
+ */
+
+static void qla4xxx_start_timer(struct scsi_qla_host *ha, void *func,
+                               unsigned long interval)
+{
+       DEBUG(printk("scsi: %s: Starting timer thread for adapter %d\n",
+                    __func__, ha->host->host_no));
+       init_timer(&ha->timer);
+       ha->timer.expires = jiffies + interval * HZ;
+       ha->timer.data = (unsigned long)ha;
+       ha->timer.function = (void (*)(unsigned long))func;
+       add_timer(&ha->timer);
+       ha->timer_active = 1;
+}
+
+static void qla4xxx_stop_timer(struct scsi_qla_host *ha)
+{
+       del_timer_sync(&ha->timer);
+       ha->timer_active = 0;
+}
+
+/***
+ * qla4xxx_mark_device_missing - mark a device as missing.
+ * @ha: Pointer to host adapter structure.
+ * @ddb_entry: Pointer to device database entry
+ *
+ * This routine marks a device missing and resets the relogin retry count.
+ **/
+void qla4xxx_mark_device_missing(struct scsi_qla_host *ha,
+                                struct ddb_entry *ddb_entry)
+{
+       atomic_set(&ddb_entry->state, DDB_STATE_MISSING);
+       DEBUG3(printk("scsi%d:%d:%d: index [%d] marked MISSING\n",
+                     ha->host_no, ddb_entry->bus, ddb_entry->target,
+                     ddb_entry->fw_ddb_index));
+       iscsi_conn_error(ddb_entry->conn, ISCSI_ERR_CONN_FAILED);
+}
+
+static struct srb* qla4xxx_get_new_srb(struct scsi_qla_host *ha,
+                                      struct ddb_entry *ddb_entry,
+                                      struct scsi_cmnd *cmd,
+                                      void (*done)(struct scsi_cmnd *))
+{
+       struct srb *srb;
+
+       srb = mempool_alloc(ha->srb_mempool, GFP_ATOMIC);
+       if (!srb)
+               return srb;
+
+       atomic_set(&srb->ref_count, 1);
+       srb->ha = ha;
+       srb->ddb = ddb_entry;
+       srb->cmd = cmd;
+       srb->flags = 0;
+       cmd->SCp.ptr = (void *)srb;
+       cmd->scsi_done = done;
+
+       return srb;
+}
+
+static void qla4xxx_srb_free_dma(struct scsi_qla_host *ha, struct srb *srb)
+{
+       struct scsi_cmnd *cmd = srb->cmd;
+
+       if (srb->flags & SRB_DMA_VALID) {
+               if (cmd->use_sg) {
+                       pci_unmap_sg(ha->pdev, cmd->request_buffer,
+                                    cmd->use_sg, cmd->sc_data_direction);
+               } else if (cmd->request_bufflen) {
+                       pci_unmap_single(ha->pdev, srb->dma_handle,
+                                        cmd->request_bufflen,
+                                        cmd->sc_data_direction);
+               }
+               srb->flags &= ~SRB_DMA_VALID;
+       }
+       cmd->SCp.ptr = NULL;
+}
+
+void qla4xxx_srb_compl(struct scsi_qla_host *ha, struct srb *srb)
+{
+       struct scsi_cmnd *cmd = srb->cmd;
+
+       qla4xxx_srb_free_dma(ha, srb);
+
+       mempool_free(srb, ha->srb_mempool);
+
+       cmd->scsi_done(cmd);
+}
+
+/**
+ * qla4xxx_queuecommand - scsi layer issues scsi command to driver.
+ * @cmd: Pointer to Linux's SCSI command structure
+ * @done_fn: Function that the driver calls to notify the SCSI mid-layer
+ *     that the command has been processed.
+ *
+ * Remarks:
+ * This routine is invoked by Linux to send a SCSI command to the driver.
+ * The mid-level driver tries to ensure that queuecommand never gets
+ * invoked concurrently with itself or the interrupt handler (although
+ * the interrupt handler may call this routine as part of request-
+ * completion handling).   Unfortunely, it sometimes calls the scheduler
+ * in interrupt context which is a big NO! NO!.
+ **/
+static int qla4xxx_queuecommand(struct scsi_cmnd *cmd,
+                               void (*done)(struct scsi_cmnd *))
+{
+       struct scsi_qla_host *ha = to_qla_host(cmd->device->host);
+       struct ddb_entry *ddb_entry = cmd->device->hostdata;
+       struct srb *srb;
+       int rval;
+
+       if (atomic_read(&ddb_entry->state) != DDB_STATE_ONLINE) {
+               if (atomic_read(&ddb_entry->state) == DDB_STATE_DEAD) {
+                       cmd->result = DID_NO_CONNECT << 16;
+                       goto qc_fail_command;
+               }
+               goto qc_host_busy;
+       }
+
+       spin_unlock_irq(ha->host->host_lock);
+
+       srb = qla4xxx_get_new_srb(ha, ddb_entry, cmd, done);
+       if (!srb)
+               goto qc_host_busy_lock;
+
+       rval = qla4xxx_send_command_to_isp(ha, srb);
+       if (rval != QLA_SUCCESS)
+               goto qc_host_busy_free_sp;
+
+       spin_lock_irq(ha->host->host_lock);
+       return 0;
+
+qc_host_busy_free_sp:
+       qla4xxx_srb_free_dma(ha, srb);
+       mempool_free(srb, ha->srb_mempool);
+
+qc_host_busy_lock:
+       spin_lock_irq(ha->host->host_lock);
+
+qc_host_busy:
+       return SCSI_MLQUEUE_HOST_BUSY;
+
+qc_fail_command:
+       done(cmd);
+
+       return 0;
+}
+
+/**
+ * qla4xxx_mem_free - frees memory allocated to adapter
+ * @ha: Pointer to host adapter structure.
+ *
+ * Frees memory previously allocated by qla4xxx_mem_alloc
+ **/
+static void qla4xxx_mem_free(struct scsi_qla_host *ha)
+{
+       if (ha->queues)
+               dma_free_coherent(&ha->pdev->dev, ha->queues_len, ha->queues,
+                                 ha->queues_dma);
+
+       ha->queues_len = 0;
+       ha->queues = NULL;
+       ha->queues_dma = 0;
+       ha->request_ring = NULL;
+       ha->request_dma = 0;
+       ha->response_ring = NULL;
+       ha->response_dma = 0;
+       ha->shadow_regs = NULL;
+       ha->shadow_regs_dma = 0;
+
+       /* Free srb pool. */
+       if (ha->srb_mempool)
+               mempool_destroy(ha->srb_mempool);
+
+       ha->srb_mempool = NULL;
+
+       /* release io space registers  */
+       if (ha->reg)
+               iounmap(ha->reg);
+       pci_release_regions(ha->pdev);
+}
+
+/**
+ * qla4xxx_mem_alloc - allocates memory for use by adapter.
+ * @ha: Pointer to host adapter structure
+ *
+ * Allocates DMA memory for request and response queues. Also allocates memory
+ * for srbs.
+ **/
+static int qla4xxx_mem_alloc(struct scsi_qla_host *ha)
+{
+       unsigned long align;
+
+       /* Allocate contiguous block of DMA memory for queues. */
+       ha->queues_len = ((REQUEST_QUEUE_DEPTH * QUEUE_SIZE) +
+                         (RESPONSE_QUEUE_DEPTH * QUEUE_SIZE) +
+                         sizeof(struct shadow_regs) +
+                         MEM_ALIGN_VALUE +
+                         (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
+       ha->queues = dma_alloc_coherent(&ha->pdev->dev, ha->queues_len,
+                                       &ha->queues_dma, GFP_KERNEL);
+       if (ha->queues == NULL) {
+               dev_warn(&ha->pdev->dev,
+                       "Memory Allocation failed - queues.\n");
+
+               goto mem_alloc_error_exit;
+       }
+       memset(ha->queues, 0, ha->queues_len);
+
+       /*
+        * As per RISC alignment requirements -- the bus-address must be a
+        * multiple of the request-ring size (in bytes).
+        */
+       align = 0;
+       if ((unsigned long)ha->queues_dma & (MEM_ALIGN_VALUE - 1))
+               align = MEM_ALIGN_VALUE - ((unsigned long)ha->queues_dma &
+                                          (MEM_ALIGN_VALUE - 1));
+
+       /* Update request and response queue pointers. */
+       ha->request_dma = ha->queues_dma + align;
+       ha->request_ring = (struct queue_entry *) (ha->queues + align);
+       ha->response_dma = ha->queues_dma + align +
+               (REQUEST_QUEUE_DEPTH * QUEUE_SIZE);
+       ha->response_ring = (struct queue_entry *) (ha->queues + align +
+                                                   (REQUEST_QUEUE_DEPTH *
+                                                    QUEUE_SIZE));
+       ha->shadow_regs_dma = ha->queues_dma + align +
+               (REQUEST_QUEUE_DEPTH * QUEUE_SIZE) +
+               (RESPONSE_QUEUE_DEPTH * QUEUE_SIZE);
+       ha->shadow_regs = (struct shadow_regs *) (ha->queues + align +
+                                                 (REQUEST_QUEUE_DEPTH *
+                                                  QUEUE_SIZE) +
+                                                 (RESPONSE_QUEUE_DEPTH *
+                                                  QUEUE_SIZE));
+
+       /* Allocate memory for srb pool. */
+       ha->srb_mempool = mempool_create(SRB_MIN_REQ, mempool_alloc_slab,
+                                        mempool_free_slab, srb_cachep);
+       if (ha->srb_mempool == NULL) {
+               dev_warn(&ha->pdev->dev,
+                       "Memory Allocation failed - SRB Pool.\n");
+
+               goto mem_alloc_error_exit;
+       }
+
+       return QLA_SUCCESS;
+
+mem_alloc_error_exit:
+       qla4xxx_mem_free(ha);
+       return QLA_ERROR;
+}
+
+/**
+ * qla4xxx_timer - checks every second for work to do.
+ * @ha: Pointer to host adapter structure.
+ **/
+static void qla4xxx_timer(struct scsi_qla_host *ha)
+{
+       struct ddb_entry *ddb_entry, *dtemp;
+       int start_dpc = 0;
+
+       /* Search for relogin's to time-out and port down retry. */
+       list_for_each_entry_safe(ddb_entry, dtemp, &ha->ddb_list, list) {
+               /* Count down time between sending relogins */
+               if (adapter_up(ha) &&
+                   !test_bit(DF_RELOGIN, &ddb_entry->flags) &&
+                   atomic_read(&ddb_entry->state) != DDB_STATE_ONLINE) {
+                       if (atomic_read(&ddb_entry->retry_relogin_timer) !=
+                           INVALID_ENTRY) {
+                               if (atomic_read(&ddb_entry->retry_relogin_timer)
+                                               == 0) {
+                                       atomic_set(&ddb_entry->
+                                               retry_relogin_timer,
+                                               INVALID_ENTRY);
+                                       set_bit(DPC_RELOGIN_DEVICE,
+                                               &ha->dpc_flags);
+                                       set_bit(DF_RELOGIN, &ddb_entry->flags);
+                                       DEBUG2(printk("scsi%ld: %s: index [%d]"
+                                                     " login device\n",
+                                                     ha->host_no, __func__,
+                                                     ddb_entry->fw_ddb_index));
+                               } else
+                                       atomic_dec(&ddb_entry->
+                                                       retry_relogin_timer);
+                       }
+               }
+
+               /* Wait for relogin to timeout */
+               if (atomic_read(&ddb_entry->relogin_timer) &&
+                   (atomic_dec_and_test(&ddb_entry->relogin_timer) != 0)) {
+                       /*
+                        * If the relogin times out and the device is
+                        * still NOT ONLINE then try and relogin again.
+                        */
+                       if (atomic_read(&ddb_entry->state) !=
+                           DDB_STATE_ONLINE &&
+                           ddb_entry->fw_ddb_device_state ==
+                           DDB_DS_SESSION_FAILED) {
+                               /* Reset retry relogin timer */
+                               atomic_inc(&ddb_entry->relogin_retry_count);
+                               DEBUG2(printk("scsi%ld: index[%d] relogin"
+                                             " timed out-retrying"
+                                             " relogin (%d)\n",
+                                             ha->host_no,
+                                             ddb_entry->fw_ddb_index,
+                                             atomic_read(&ddb_entry->
+                                                         relogin_retry_count))
+                                       );
+                               start_dpc++;
+                               DEBUG(printk("scsi%ld:%d:%d: index [%d] "
+                                            "initate relogin after"
+                                            " %d seconds\n",
+                                            ha->host_no, ddb_entry->bus,
+                                            ddb_entry->target,
+                                            ddb_entry->fw_ddb_index,
+                                            ddb_entry->default_time2wait + 4)
+                                       );
+
+                               atomic_set(&ddb_entry->retry_relogin_timer,
+                                          ddb_entry->default_time2wait + 4);
+                       }
+               }
+       }
+
+       /* Check for heartbeat interval. */
+       if (ha->firmware_options & FWOPT_HEARTBEAT_ENABLE &&
+           ha->heartbeat_interval != 0) {
+               ha->seconds_since_last_heartbeat++;
+               if (ha->seconds_since_last_heartbeat >
+                   ha->heartbeat_interval + 2)
+                       set_bit(DPC_RESET_HA, &ha->dpc_flags);
+       }
+
+
+       /* Wakeup the dpc routine for this adapter, if needed. */
+       if ((start_dpc ||
+            test_bit(DPC_RESET_HA, &ha->dpc_flags) ||
+            test_bit(DPC_RETRY_RESET_HA, &ha->dpc_flags) ||
+            test_bit(DPC_RELOGIN_DEVICE, &ha->dpc_flags) ||
+            test_bit(DPC_RESET_HA_DESTROY_DDB_LIST, &ha->dpc_flags) ||
+            test_bit(DPC_RESET_HA_INTR, &ha->dpc_flags) ||
+            test_bit(DPC_GET_DHCP_IP_ADDR, &ha->dpc_flags) ||
+            test_bit(DPC_AEN, &ha->dpc_flags)) &&
+            ha->dpc_thread) {
+               DEBUG2(printk("scsi%ld: %s: scheduling dpc routine"
+                             " - dpc flags = 0x%lx\n",
+                             ha->host_no, __func__, ha->dpc_flags));
+               queue_work(ha->dpc_thread, &ha->dpc_work);
+       }
+
+       /* Reschedule timer thread to call us back in one second */
+       mod_timer(&ha->timer, jiffies + HZ);
+
+       DEBUG2(ha->seconds_since_last_intr++);
+}
+
+/**
+ * qla4xxx_cmd_wait - waits for all outstanding commands to complete
+ * @ha: Pointer to host adapter structure.
+ *
+ * This routine stalls the driver until all outstanding commands are returned.
+ * Caller must release the Hardware Lock prior to calling this routine.
+ **/
+static int qla4xxx_cmd_wait(struct scsi_qla_host *ha)
+{
+       uint32_t index = 0;
+       int stat = QLA_SUCCESS;
+       unsigned long flags;
+       struct scsi_cmnd *cmd;
+       int wait_cnt = WAIT_CMD_TOV;    /*
+                                        * Initialized for 30 seconds as we
+                                        * expect all commands to retuned
+                                        * ASAP.
+                                        */
+
+       while (wait_cnt) {
+               spin_lock_irqsave(&ha->hardware_lock, flags);
+               /* Find a command that hasn't completed. */
+               for (index = 0; index < ha->host->can_queue; index++) {
+                       cmd = scsi_host_find_tag(ha->host, index);
+                       if (cmd != NULL)
+                               break;
+               }
+               spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
+               /* If No Commands are pending, wait is complete */
+               if (index == ha->host->can_queue) {
+                       break;
+               }
+
+               /* If we timed out on waiting for commands to come back
+                * return ERROR.
+                */
+               wait_cnt--;
+               if (wait_cnt == 0)
+                       stat = QLA_ERROR;
+               else {
+                       msleep(1000);
+               }
+       }                       /* End of While (wait_cnt) */
+
+       return stat;
+}
+
+/**
+ * qla4010_soft_reset - performs soft reset.
+ * @ha: Pointer to host adapter structure.
+ **/
+static int qla4010_soft_reset(struct scsi_qla_host *ha)
+{
+       uint32_t max_wait_time;
+       unsigned long flags = 0;
+       int status = QLA_ERROR;
+       uint32_t ctrl_status;
+
+       spin_lock_irqsave(&ha->hardware_lock, flags);
+
+       /*
+        * If the SCSI Reset Interrupt bit is set, clear it.
+        * Otherwise, the Soft Reset won't work.
+        */
+       ctrl_status = readw(&ha->reg->ctrl_status);
+       if ((ctrl_status & CSR_SCSI_RESET_INTR) != 0)
+               writel(set_rmask(CSR_SCSI_RESET_INTR), &ha->reg->ctrl_status);
+
+       /* Issue Soft Reset */
+       writel(set_rmask(CSR_SOFT_RESET), &ha->reg->ctrl_status);
+       readl(&ha->reg->ctrl_status);
+
+       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
+       /* Wait until the Network Reset Intr bit is cleared */
+       max_wait_time = RESET_INTR_TOV;
+       do {
+               spin_lock_irqsave(&ha->hardware_lock, flags);
+               ctrl_status = readw(&ha->reg->ctrl_status);
+               spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
+               if ((ctrl_status & CSR_NET_RESET_INTR) == 0)
+                       break;
+
+               msleep(1000);
+       } while ((--max_wait_time));
+
+       if ((ctrl_status & CSR_NET_RESET_INTR) != 0) {
+               DEBUG2(printk(KERN_WARNING
+                             "scsi%ld: Network Reset Intr not cleared by "
+                             "Network function, clearing it now!\n",
+                             ha->host_no));
+               spin_lock_irqsave(&ha->hardware_lock, flags);
+               writel(set_rmask(CSR_NET_RESET_INTR), &ha->reg->ctrl_status);
+               readl(&ha->reg->ctrl_status);
+               spin_unlock_irqrestore(&ha->hardware_lock, flags);
+       }
+
+       /* Wait until the firmware tells us the Soft Reset is done */
+       max_wait_time = SOFT_RESET_TOV;
+       do {
+               spin_lock_irqsave(&ha->hardware_lock, flags);
+               ctrl_status = readw(&ha->reg->ctrl_status);
+               spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
+               if ((ctrl_status & CSR_SOFT_RESET) == 0) {
+                       status = QLA_SUCCESS;
+                       break;
+               }
+
+               msleep(1000);
+       } while ((--max_wait_time));
+
+       /*
+        * Also, make sure that the SCSI Reset Interrupt bit has been cleared
+        * after the soft reset has taken place.
+        */
+       spin_lock_irqsave(&ha->hardware_lock, flags);
+       ctrl_status = readw(&ha->reg->ctrl_status);
+       if ((ctrl_status & CSR_SCSI_RESET_INTR) != 0) {
+               writel(set_rmask(CSR_SCSI_RESET_INTR), &ha->reg->ctrl_status);
+               readl(&ha->reg->ctrl_status);
+       }
+       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
+       /* If soft reset fails then most probably the bios on other
+        * function is also enabled.
+        * Since the initialization is sequential the other fn
+        * wont be able to acknowledge the soft reset.
+        * Issue a force soft reset to workaround this scenario.
+        */
+       if (max_wait_time == 0) {
+               /* Issue Force Soft Reset */
+               spin_lock_irqsave(&ha->hardware_lock, flags);
+               writel(set_rmask(CSR_FORCE_SOFT_RESET), &ha->reg->ctrl_status);
+               readl(&ha->reg->ctrl_status);
+               spin_unlock_irqrestore(&ha->hardware_lock, flags);
+               /* Wait until the firmware tells us the Soft Reset is done */
+               max_wait_time = SOFT_RESET_TOV;
+               do {
+                       spin_lock_irqsave(&ha->hardware_lock, flags);
+                       ctrl_status = readw(&ha->reg->ctrl_status);
+                       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
+                       if ((ctrl_status & CSR_FORCE_SOFT_RESET) == 0) {
+                               status = QLA_SUCCESS;
+                               break;
+                       }
+
+                       msleep(1000);
+               } while ((--max_wait_time));
+       }
+
+       return status;
+}
+
+/**
+ * qla4xxx_topcat_reset - performs hard reset of TopCat Chip.
+ * @ha: Pointer to host adapter structure.
+ **/
+static int qla4xxx_topcat_reset(struct scsi_qla_host *ha)
+{
+       unsigned long flags;
+
+       ql4xxx_lock_nvram(ha);
+       spin_lock_irqsave(&ha->hardware_lock, flags);
+       writel(set_rmask(GPOR_TOPCAT_RESET), isp_gp_out(ha));
+       readl(isp_gp_out(ha));
+       mdelay(1);
+
+       writel(clr_rmask(GPOR_TOPCAT_RESET), isp_gp_out(ha));
+       readl(isp_gp_out(ha));
+       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+       mdelay(2523);
+
+       ql4xxx_unlock_nvram(ha);
+       return QLA_SUCCESS;
+}
+
+/**
+ * qla4xxx_flush_active_srbs - returns all outstanding i/o requests to O.S.
+ * @ha: Pointer to host adapter structure.
+ *
+ * This routine is called just prior to a HARD RESET to return all
+ * outstanding commands back to the Operating System.
+ * Caller should make sure that the following locks are released
+ * before this calling routine: Hardware lock, and io_request_lock.
+ **/
+static void qla4xxx_flush_active_srbs(struct scsi_qla_host *ha)
+{
+       struct srb *srb;
+       int i;
+       unsigned long flags;
+
+       spin_lock_irqsave(&ha->hardware_lock, flags);
+       for (i = 0; i < ha->host->can_queue; i++) {
+               srb = qla4xxx_del_from_active_array(ha, i);
+               if (srb != NULL) {
+                       srb->cmd->result = DID_RESET << 16;
+                       qla4xxx_srb_compl(ha, srb);
+               }
+       }
+       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
+}
+
+/**
+ * qla4xxx_hard_reset - performs HBA Hard Reset
+ * @ha: Pointer to host adapter structure.
+ **/
+static int qla4xxx_hard_reset(struct scsi_qla_host *ha)
+{
+       /* The QLA4010 really doesn't have an equivalent to a hard reset */
+       qla4xxx_flush_active_srbs(ha);
+       if (test_bit(AF_TOPCAT_CHIP_PRESENT, &ha->flags)) {
+               int status = QLA_ERROR;
+
+               if ((qla4010_soft_reset(ha) == QLA_SUCCESS) &&
+                   (qla4xxx_topcat_reset(ha) == QLA_SUCCESS) &&
+                   (qla4010_soft_reset(ha) == QLA_SUCCESS))
+                       status = QLA_SUCCESS;
+               return status;
+       } else
+               return qla4010_soft_reset(ha);
+}
+
+/**
+ * qla4xxx_recover_adapter - recovers adapter after a fatal error
+ * @ha: Pointer to host adapter structure.
+ * @renew_ddb_list: Indicates what to do with the adapter's ddb list
+ *     after adapter recovery has completed.
+ *     0=preserve ddb list, 1=destroy and rebuild ddb list
+ **/
+static int qla4xxx_recover_adapter(struct scsi_qla_host *ha,
+                               uint8_t renew_ddb_list)
+{
+       int status;
+
+       /* Stall incoming I/O until we are done */
+       clear_bit(AF_ONLINE, &ha->flags);
+       DEBUG2(printk("scsi%ld: %s calling qla4xxx_cmd_wait\n", ha->host_no,
+                     __func__));
+
+       /* Wait for outstanding commands to complete.
+        * Stalls the driver for max 30 secs
+        */
+       status = qla4xxx_cmd_wait(ha);
+
+       qla4xxx_disable_intrs(ha);
+
+       /* Flush any pending ddb changed AENs */
+       qla4xxx_process_aen(ha, FLUSH_DDB_CHANGED_AENS);
+
+       /* Reset the firmware.  If successful, function
+        * returns with ISP interrupts enabled.
+        */
+       if (status == QLA_SUCCESS) {
+               DEBUG2(printk("scsi%ld: %s - Performing soft reset..\n",
+                             ha->host_no, __func__));
+               status = qla4xxx_soft_reset(ha);
+       }
+       /* FIXMEkaren: Do we want to keep interrupts enabled and process
+          AENs after soft reset */
+
+       /* If firmware (SOFT) reset failed, or if all outstanding
+        * commands have not returned, then do a HARD reset.
+        */
+       if (status == QLA_ERROR) {
+               DEBUG2(printk("scsi%ld: %s - Performing hard reset..\n",
+                             ha->host_no, __func__));
+               status = qla4xxx_hard_reset(ha);
+       }
+
+       /* Flush any pending ddb changed AENs */
+       qla4xxx_process_aen(ha, FLUSH_DDB_CHANGED_AENS);
+
+       /* Re-initialize firmware. If successful, function returns
+        * with ISP interrupts enabled */
+       if (status == QLA_SUCCESS) {
+               DEBUG2(printk("scsi%ld: %s - Initializing adapter..\n",
+                             ha->host_no, __func__));
+
+               /* If successful, AF_ONLINE flag set in
+                * qla4xxx_initialize_adapter */
+               status = qla4xxx_initialize_adapter(ha, renew_ddb_list);
+       }
+
+       /* Failed adapter initialization?
+        * Retry reset_ha only if invoked via DPC (DPC_RESET_HA) */
+       if ((test_bit(AF_ONLINE, &ha->flags) == 0) &&
+           (test_bit(DPC_RESET_HA, &ha->dpc_flags))) {
+               /* Adapter initialization failed, see if we can retry
+                * resetting the ha */
+               if (!test_bit(DPC_RETRY_RESET_HA, &ha->dpc_flags)) {
+                       ha->retry_reset_ha_cnt = MAX_RESET_HA_RETRIES;
+                       DEBUG2(printk("scsi%ld: recover adapter - retrying "
+                                     "(%d) more times\n", ha->host_no,
+                                     ha->retry_reset_ha_cnt));
+                       set_bit(DPC_RETRY_RESET_HA, &ha->dpc_flags);
+                       status = QLA_ERROR;
+               } else {
+                       if (ha->retry_reset_ha_cnt > 0) {
+                               /* Schedule another Reset HA--DPC will retry */
+                               ha->retry_reset_ha_cnt--;
+                               DEBUG2(printk("scsi%ld: recover adapter - "
+                                             "retry remaining %d\n",
+                                             ha->host_no,
+                                             ha->retry_reset_ha_cnt));
+                               status = QLA_ERROR;
+                       }
+
+                       if (ha->retry_reset_ha_cnt == 0) {
+                               /* Recover adapter retries have been exhausted.
+                                * Adapter DEAD */
+                               DEBUG2(printk("scsi%ld: recover adapter "
+                                             "failed - board disabled\n",
+                                             ha->host_no));
+                               qla4xxx_flush_active_srbs(ha);
+                               clear_bit(DPC_RETRY_RESET_HA, &ha->dpc_flags);
+                               clear_bit(DPC_RESET_HA, &ha->dpc_flags);
+                               clear_bit(DPC_RESET_HA_DESTROY_DDB_LIST,
+                                         &ha->dpc_flags);
+                               status = QLA_ERROR;
+                       }
+               }
+       } else {
+               clear_bit(DPC_RESET_HA, &ha->dpc_flags);
+               clear_bit(DPC_RESET_HA_DESTROY_DDB_LIST, &ha->dpc_flags);
+               clear_bit(DPC_RETRY_RESET_HA, &ha->dpc_flags);
+       }
+
+       ha->adapter_error_count++;
+
+       if (status == QLA_SUCCESS)
+               qla4xxx_enable_intrs(ha);
+
+       DEBUG2(printk("scsi%ld: recover adapter .. DONE\n", ha->host_no));
+       return status;
+}
+
+/**
+ * qla4xxx_do_dpc - dpc routine
+ * @data: in our case pointer to adapter structure
+ *
+ * This routine is a task that is schedule by the interrupt handler
+ * to perform the background processing for interrupts.  We put it
+ * on a task queue that is consumed whenever the scheduler runs; that's
+ * so you can do anything (i.e. put the process to sleep etc).  In fact,
+ * the mid-level tries to sleep when it reaches the driver threshold
+ * "host->can_queue". This can cause a panic if we were in our interrupt code.
+ **/
+static void qla4xxx_do_dpc(void *data)
+{
+       struct scsi_qla_host *ha = (struct scsi_qla_host *) data;
+       struct ddb_entry *ddb_entry, *dtemp;
+
+       DEBUG2(printk("scsi%ld: %s: DPC handler waking up.\n",
+                     ha->host_no, __func__));
+
+       DEBUG2(printk("scsi%ld: %s: ha->flags = 0x%08lx\n",
+                     ha->host_no, __func__, ha->flags));
+       DEBUG2(printk("scsi%ld: %s: ha->dpc_flags = 0x%08lx\n",
+                     ha->host_no, __func__, ha->dpc_flags));
+
+       /* Initialization not yet finished. Don't do anything yet. */
+       if (!test_bit(AF_INIT_DONE, &ha->flags))
+               return;
+
+       if (adapter_up(ha) ||
+           test_bit(DPC_RESET_HA, &ha->dpc_flags) ||
+           test_bit(DPC_RESET_HA_INTR, &ha->dpc_flags) ||
+           test_bit(DPC_RESET_HA_DESTROY_DDB_LIST, &ha->dpc_flags)) {
+               if (test_bit(DPC_RESET_HA_DESTROY_DDB_LIST, &ha->dpc_flags))
+                       /*
+                        * dg 09/23 Never initialize ddb list
+                        * once we up and running
+                        * qla4xxx_recover_adapter(ha,
+                        *    REBUILD_DDB_LIST);
+                        */
+                       qla4xxx_recover_adapter(ha, PRESERVE_DDB_LIST);
+
+               if (test_bit(DPC_RESET_HA, &ha->dpc_flags))
+                       qla4xxx_recover_adapter(ha, PRESERVE_DDB_LIST);
+
+               if (test_and_clear_bit(DPC_RESET_HA_INTR, &ha->dpc_flags)) {
+                       uint8_t wait_time = RESET_INTR_TOV;
+                       unsigned long flags = 0;
+
+                       qla4xxx_flush_active_srbs(ha);
+
+                       spin_lock_irqsave(&ha->hardware_lock, flags);
+                       while ((readw(&ha->reg->ctrl_status) &
+                               (CSR_SOFT_RESET | CSR_FORCE_SOFT_RESET)) != 0) {
+                               if (--wait_time == 0)
+                                       break;
+
+                               spin_unlock_irqrestore(&ha->hardware_lock,
+                                                      flags);
+
+                               msleep(1000);
+
+                               spin_lock_irqsave(&ha->hardware_lock, flags);
+                       }
+                       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
+                       if (wait_time == 0)
+                               DEBUG2(printk("scsi%ld: %s: SR|FSR "
+                                             "bit not cleared-- resetting\n",
+                                             ha->host_no, __func__));
+               }
+       }
+
+       /* ---- process AEN? --- */
+       if (test_and_clear_bit(DPC_AEN, &ha->dpc_flags))
+               qla4xxx_process_aen(ha, PROCESS_ALL_AENS);
+
+       /* ---- Get DHCP IP Address? --- */
+       if (test_and_clear_bit(DPC_GET_DHCP_IP_ADDR, &ha->dpc_flags))
+               qla4xxx_get_dhcp_ip_address(ha);
+
+       /* ---- relogin device? --- */
+       if (adapter_up(ha) &&
+           test_and_clear_bit(DPC_RELOGIN_DEVICE, &ha->dpc_flags)) {
+               list_for_each_entry_safe(ddb_entry, dtemp,
+                                        &ha->ddb_list, list) {
+                       if (test_and_clear_bit(DF_RELOGIN, &ddb_entry->flags) &&
+                           atomic_read(&ddb_entry->state) != DDB_STATE_ONLINE)
+                               qla4xxx_relogin_device(ha, ddb_entry);
+
+                       /*
+                        * If mbx cmd times out there is no point
+                        * in continuing further.
+                        * With large no of targets this can hang
+                        * the system.
+                        */
+                       if (test_bit(DPC_RESET_HA, &ha->dpc_flags)) {
+                               printk(KERN_WARNING "scsi%ld: %s: "
+                                      "need to reset hba\n",
+                                      ha->host_no, __func__);
+                               break;
+                       }
+               }
+       }
+}
+
+/**
+ * qla4xxx_free_adapter - release the adapter
+ * @ha: pointer to adapter structure
+ **/
+static void qla4xxx_free_adapter(struct scsi_qla_host *ha)
+{
+
+       if (test_bit(AF_INTERRUPTS_ON, &ha->flags)) {
+               /* Turn-off interrupts on the card. */
+               qla4xxx_disable_intrs(ha);
+       }
+
+       /* Kill the kernel thread for this host */
+       if (ha->dpc_thread)
+               destroy_workqueue(ha->dpc_thread);
+
+       /* Issue Soft Reset to put firmware in unknown state */
+       qla4xxx_soft_reset(ha);
+
+       /* Remove timer thread, if present */
+       if (ha->timer_active)
+               qla4xxx_stop_timer(ha);
+
+       /* free extra memory */
+       qla4xxx_mem_free(ha);
+
+       /* Detach interrupts */
+       if (test_and_clear_bit(AF_IRQ_ATTACHED, &ha->flags))
+               free_irq(ha->pdev->irq, ha);
+
+       pci_disable_device(ha->pdev);
+
+}
+
+/***
+ * qla4xxx_iospace_config - maps registers
+ * @ha: pointer to adapter structure
+ *
+ * This routines maps HBA's registers from the pci address space
+ * into the kernel virtual address space for memory mapped i/o.
+ **/
+static int qla4xxx_iospace_config(struct scsi_qla_host *ha)
+{
+       unsigned long pio, pio_len, pio_flags;
+       unsigned long mmio, mmio_len, mmio_flags;
+
+       pio = pci_resource_start(ha->pdev, 0);
+       pio_len = pci_resource_len(ha->pdev, 0);
+       pio_flags = pci_resource_flags(ha->pdev, 0);
+       if (pio_flags & IORESOURCE_IO) {
+               if (pio_len < MIN_IOBASE_LEN) {
+                       dev_warn(&ha->pdev->dev,
+                               "Invalid PCI I/O region size\n");
+                       pio = 0;
+               }
+       } else {
+               dev_warn(&ha->pdev->dev, "region #0 not a PIO resource\n");
+               pio = 0;
+       }
+
+       /* Use MMIO operations for all accesses. */
+       mmio = pci_resource_start(ha->pdev, 1);
+       mmio_len = pci_resource_len(ha->pdev, 1);
+       mmio_flags = pci_resource_flags(ha->pdev, 1);
+
+       if (!(mmio_flags & IORESOURCE_MEM)) {
+               dev_err(&ha->pdev->dev,
+                       "region #0 not an MMIO resource, aborting\n");
+
+               goto iospace_error_exit;
+       }
+       if (mmio_len < MIN_IOBASE_LEN) {
+               dev_err(&ha->pdev->dev,
+                       "Invalid PCI mem region size, aborting\n");
+               goto iospace_error_exit;
+       }
+
+       if (pci_request_regions(ha->pdev, DRIVER_NAME)) {
+               dev_warn(&ha->pdev->dev,
+                       "Failed to reserve PIO/MMIO regions\n");
+
+               goto iospace_error_exit;
+       }
+
+       ha->pio_address = pio;
+       ha->pio_length = pio_len;
+       ha->reg = ioremap(mmio, MIN_IOBASE_LEN);
+       if (!ha->reg) {
+               dev_err(&ha->pdev->dev,
+                       "cannot remap MMIO, aborting\n");
+
+               goto iospace_error_exit;
+       }
+
+       return 0;
+
+iospace_error_exit:
+       return -ENOMEM;
+}
+
+/**
+ * qla4xxx_probe_adapter - callback function to probe HBA
+ * @pdev: pointer to pci_dev structure
+ * @pci_device_id: pointer to pci_device entry
+ *
+ * This routine will probe for Qlogic 4xxx iSCSI host adapters.
+ * It returns zero if successful. It also initializes all data necessary for
+ * the driver.
+ **/
+static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev,
+                                          const struct pci_device_id *ent)
+{
+       int ret = -ENODEV, status;
+       struct Scsi_Host *host;
+       struct scsi_qla_host *ha;
+       struct ddb_entry *ddb_entry, *ddbtemp;
+       uint8_t init_retry_count = 0;
+       char buf[34];
+
+       if (pci_enable_device(pdev))
+               return -1;
+
+       host = scsi_host_alloc(&qla4xxx_driver_template, sizeof(*ha));
+       if (host == NULL) {
+               printk(KERN_WARNING
+                      "qla4xxx: Couldn't allocate host from scsi layer!\n");
+               goto probe_disable_device;
+       }
+
+       /* Clear our data area */
+       ha = (struct scsi_qla_host *) host->hostdata;
+       memset(ha, 0, sizeof(*ha));
+
+       /* Save the information from PCI BIOS.  */
+       ha->pdev = pdev;
+       ha->host = host;
+       ha->host_no = host->host_no;
+
+       /* Configure PCI I/O space. */
+       ret = qla4xxx_iospace_config(ha);
+       if (ret)
+               goto probe_failed;
+
+       dev_info(&ha->pdev->dev, "Found an ISP%04x, irq %d, iobase 0x%p\n",
+                  pdev->device, pdev->irq, ha->reg);
+
+       qla4xxx_config_dma_addressing(ha);
+
+       /* Initialize lists and spinlocks. */
+       INIT_LIST_HEAD(&ha->ddb_list);
+       INIT_LIST_HEAD(&ha->free_srb_q);
+
+       mutex_init(&ha->mbox_sem);
+       init_waitqueue_head(&ha->mailbox_wait_queue);
+
+       spin_lock_init(&ha->hardware_lock);
+       spin_lock_init(&ha->list_lock);
+
+       /* Allocate dma buffers */
+       if (qla4xxx_mem_alloc(ha)) {
+               dev_warn(&ha->pdev->dev,
+                          "[ERROR] Failed to allocate memory for adapter\n");
+
+               ret = -ENOMEM;
+               goto probe_failed;
+       }
+
+       /*
+        * Initialize the Host adapter request/response queues and
+        * firmware
+        * NOTE: interrupts enabled upon successful completion
+        */
+       status = qla4xxx_initialize_adapter(ha, REBUILD_DDB_LIST);
+       while (status == QLA_ERROR && init_retry_count++ < MAX_INIT_RETRIES) {
+               DEBUG2(printk("scsi: %s: retrying adapter initialization "
+                             "(%d)\n", __func__, init_retry_count));
+               qla4xxx_soft_reset(ha);
+               status = qla4xxx_initialize_adapter(ha, REBUILD_DDB_LIST);
+       }
+       if (status == QLA_ERROR) {
+               dev_warn(&ha->pdev->dev, "Failed to initialize adapter\n");
+
+               ret = -ENODEV;
+               goto probe_failed;
+       }
+
+       host->cmd_per_lun = 3;
+       host->max_channel = 0;
+       host->max_lun = MAX_LUNS - 1;
+       host->max_id = MAX_TARGETS;
+       host->max_cmd_len = IOCB_MAX_CDB_LEN;
+       host->can_queue = MAX_SRBS ;
+       host->transportt = qla4xxx_scsi_transport;
+
+        ret = scsi_init_shared_tag_map(host, MAX_SRBS);
+        if (ret) {
+                dev_warn(&ha->pdev->dev, "scsi_init_shared_tag_map failed");
+                goto probe_failed;
+        }
+
+       /* Startup the kernel thread for this host adapter. */
+       DEBUG2(printk("scsi: %s: Starting kernel thread for "
+                     "qla4xxx_dpc\n", __func__));
+       sprintf(buf, "qla4xxx_%lu_dpc", ha->host_no);
+       ha->dpc_thread = create_singlethread_workqueue(buf);
+       if (!ha->dpc_thread) {
+               dev_warn(&ha->pdev->dev, "Unable to start DPC thread!\n");
+               ret = -ENODEV;
+               goto probe_failed;
+       }
+       INIT_WORK(&ha->dpc_work, qla4xxx_do_dpc, ha);
+
+       ret = request_irq(pdev->irq, qla4xxx_intr_handler,
+                         SA_INTERRUPT|SA_SHIRQ, "qla4xxx", ha);
+       if (ret) {
+               dev_warn(&ha->pdev->dev, "Failed to reserve interrupt %d"
+                       " already in use.\n", pdev->irq);
+               goto probe_failed;
+       }
+       set_bit(AF_IRQ_ATTACHED, &ha->flags);
+       host->irq = pdev->irq;
+       DEBUG(printk("scsi%d: irq %d attached\n", ha->host_no, ha->pdev->irq));
+
+       qla4xxx_enable_intrs(ha);
+
+       /* Start timer thread. */
+       qla4xxx_start_timer(ha, qla4xxx_timer, 1);
+
+       set_bit(AF_INIT_DONE, &ha->flags);
+
+       pci_set_drvdata(pdev, ha);
+
+       ret = scsi_add_host(host, &pdev->dev);
+       if (ret)
+               goto probe_failed;
+
+       /* Update transport device information for all devices. */
+       list_for_each_entry_safe(ddb_entry, ddbtemp, &ha->ddb_list, list) {
+               if (ddb_entry->fw_ddb_device_state == DDB_DS_SESSION_ACTIVE)
+                       if (qla4xxx_add_sess(ddb_entry))
+                               goto remove_host;
+       }
+
+       printk(KERN_INFO
+              " QLogic iSCSI HBA Driver version: %s\n"
+              "  QLogic ISP%04x @ %s, host#=%ld, fw=%02d.%02d.%02d.%02d\n",
+              qla4xxx_version_str, ha->pdev->device, pci_name(ha->pdev),
+              ha->host_no, ha->firmware_version[0], ha->firmware_version[1],
+              ha->patch_number, ha->build_number);
+
+       return 0;
+
+remove_host:
+       qla4xxx_free_ddb_list(ha);
+       scsi_remove_host(host);
+
+probe_failed:
+       qla4xxx_free_adapter(ha);
+       scsi_host_put(ha->host);
+
+probe_disable_device:
+       pci_disable_device(pdev);
+
+       return ret;
+}
+
+/**
+ * qla4xxx_remove_adapter - calback function to remove adapter.
+ * @pci_dev: PCI device pointer
+ **/
+static void __devexit qla4xxx_remove_adapter(struct pci_dev *pdev)
+{
+       struct scsi_qla_host *ha;
+
+       ha = pci_get_drvdata(pdev);
+
+       /* remove devs from iscsi_sessions to scsi_devices */
+       qla4xxx_free_ddb_list(ha);
+
+       scsi_remove_host(ha->host);
+
+       qla4xxx_free_adapter(ha);
+
+       scsi_host_put(ha->host);
+
+       pci_set_drvdata(pdev, NULL);
+}
+
+/**
+ * qla4xxx_config_dma_addressing() - Configure OS DMA addressing method.
+ * @ha: HA context
+ *
+ * At exit, the @ha's flags.enable_64bit_addressing set to indicated
+ * supported addressing method.
+ */
+void qla4xxx_config_dma_addressing(struct scsi_qla_host *ha)
+{
+       int retval;
+
+       /* Update our PCI device dma_mask for full 64 bit mask */
+       if (pci_set_dma_mask(ha->pdev, DMA_64BIT_MASK) == 0) {
+               if (pci_set_consistent_dma_mask(ha->pdev, DMA_64BIT_MASK)) {
+                       dev_dbg(&ha->pdev->dev,
+                                 "Failed to set 64 bit PCI consistent mask; "
+                                  "using 32 bit.\n");
+                       retval = pci_set_consistent_dma_mask(ha->pdev,
+                                                            DMA_32BIT_MASK);
+               }
+       } else
+               retval = pci_set_dma_mask(ha->pdev, DMA_32BIT_MASK);
+}
+
+static int qla4xxx_slave_alloc(struct scsi_device *sdev)
+{
+       struct iscsi_cls_session *sess = starget_to_session(sdev->sdev_target);
+       struct ddb_entry *ddb = sess->dd_data;
+
+       sdev->hostdata = ddb;
+       sdev->tagged_supported = 1;
+       scsi_activate_tcq(sdev, sdev->host->can_queue);
+       return 0;
+}
+
+static int qla4xxx_slave_configure(struct scsi_device *sdev)
+{
+       sdev->tagged_supported = 1;
+       return 0;
+}
+
+static void qla4xxx_slave_destroy(struct scsi_device *sdev)
+{
+       scsi_deactivate_tcq(sdev, 1);
+}
+
+/**
+ * qla4xxx_del_from_active_array - returns an active srb
+ * @ha: Pointer to host adapter structure.
+ * @index: index into to the active_array
+ *
+ * This routine removes and returns the srb at the specified index
+ **/
+struct srb * qla4xxx_del_from_active_array(struct scsi_qla_host *ha, uint32_t index)
+{
+       struct srb *srb = NULL;
+       struct scsi_cmnd *cmd;
+
+       if (!(cmd = scsi_host_find_tag(ha->host, index)))
+               return srb;
+
+       if (!(srb = (struct srb *)cmd->host_scribble))
+               return srb;
+
+       /* update counters */
+       if (srb->flags & SRB_DMA_VALID) {
+               ha->req_q_count += srb->iocb_cnt;
+               ha->iocb_cnt -= srb->iocb_cnt;
+               if (srb->cmd)
+                       srb->cmd->host_scribble = NULL;
+       }
+       return srb;
+}
+
+/**
+ * qla4xxx_soft_reset - performs a SOFT RESET of hba.
+ * @ha: Pointer to host adapter structure.
+ **/
+int qla4xxx_soft_reset(struct scsi_qla_host *ha)
+{
+
+       DEBUG2(printk(KERN_WARNING "scsi%ld: %s: chip reset!\n", ha->host_no,
+                     __func__));
+       if (test_bit(AF_TOPCAT_CHIP_PRESENT, &ha->flags)) {
+               int status = QLA_ERROR;
+
+               if ((qla4010_soft_reset(ha) == QLA_SUCCESS) &&
+                   (qla4xxx_topcat_reset(ha) == QLA_SUCCESS) &&
+                   (qla4010_soft_reset(ha) == QLA_SUCCESS) )
+                       status = QLA_SUCCESS;
+               return status;
+       } else
+               return qla4010_soft_reset(ha);
+}
+
+/**
+ * qla4xxx_eh_wait_on_command - waits for command to be returned by firmware
+ * @ha: actual ha whose done queue will contain the comd returned by firmware.
+ * @cmd: Scsi Command to wait on.
+ *
+ * This routine waits for the command to be returned by the Firmware
+ * for some max time.
+ **/
+static int qla4xxx_eh_wait_on_command(struct scsi_qla_host *ha,
+                                     struct scsi_cmnd *cmd)
+{
+       int done = 0;
+       struct srb *rp;
+       uint32_t max_wait_time = EH_WAIT_CMD_TOV;
+
+       do {
+               /* Checking to see if its returned to OS */
+               rp = (struct srb *) cmd->SCp.ptr;
+               if (rp == NULL) {
+                       done++;
+                       break;
+               }
+
+               msleep(2000);
+       } while (max_wait_time--);
+
+       return done;
+}
+
+/**
+ * qla4xxx_wait_for_hba_online - waits for HBA to come online
+ * @ha: Pointer to host adapter structure
+ **/
+static int qla4xxx_wait_for_hba_online(struct scsi_qla_host *ha)
+{
+       unsigned long wait_online;
+
+       wait_online = jiffies + (30 * HZ);
+       while (time_before(jiffies, wait_online)) {
+
+               if (adapter_up(ha))
+                       return QLA_SUCCESS;
+               else if (ha->retry_reset_ha_cnt == 0)
+                       return QLA_ERROR;
+
+               msleep(2000);
+       }
+
+       return QLA_ERROR;
+}
+
+/**
+ * qla4xxx_eh_wait_for_active_target_commands - wait for active cmds to finish.
+ * @ha: pointer to to HBA
+ * @t: target id
+ * @l: lun id
+ *
+ * This function waits for all outstanding commands to a lun to complete. It
+ * returns 0 if all pending commands are returned and 1 otherwise.
+ **/
+static int qla4xxx_eh_wait_for_active_target_commands(struct scsi_qla_host *ha,
+                                                int t, int l)
+{
+       int cnt;
+       int status = 0;
+       struct scsi_cmnd *cmd;
+
+       /*
+        * Waiting for all commands for the designated target in the active
+        * array
+        */
+       for (cnt = 0; cnt < ha->host->can_queue; cnt++) {
+               cmd = scsi_host_find_tag(ha->host, cnt);
+               if (cmd && cmd->device->id == t && cmd->device->lun == l) {
+                       if (!qla4xxx_eh_wait_on_command(ha, cmd)) {
+                               status++;
+                               break;
+                       }
+               }
+       }
+       return status;
+}
+
+/**
+ * qla4xxx_eh_device_reset - callback for target reset.
+ * @cmd: Pointer to Linux's SCSI command structure
+ *
+ * This routine is called by the Linux OS to reset all luns on the
+ * specified target.
+ **/
+static int qla4xxx_eh_device_reset(struct scsi_cmnd *cmd)
+{
+       struct scsi_qla_host *ha = to_qla_host(cmd->device->host);
+       struct ddb_entry *ddb_entry = cmd->device->hostdata;
+       struct srb *sp;
+       int ret = FAILED, stat;
+
+       sp = (struct srb *) cmd->SCp.ptr;
+       if (!sp || !ddb_entry)
+               return ret;
+
+       dev_info(&ha->pdev->dev,
+                  "scsi%ld:%d:%d:%d: DEVICE RESET ISSUED.\n", ha->host_no,
+                  cmd->device->channel, cmd->device->id, cmd->device->lun);
+
+       DEBUG2(printk(KERN_INFO
+                     "scsi%ld: DEVICE_RESET cmd=%p jiffies = 0x%lx, to=%x,"
+                     "dpc_flags=%lx, status=%x allowed=%d\n", ha->host_no,
+                     cmd, jiffies, cmd->timeout_per_command / HZ,
+                     ha->dpc_flags, cmd->result, cmd->allowed));
+
+       /* FIXME: wait for hba to go online */
+       stat = qla4xxx_reset_lun(ha, ddb_entry, cmd->device->lun);
+       if (stat != QLA_SUCCESS) {
+               dev_info(&ha->pdev->dev, "DEVICE RESET FAILED. %d\n", stat);
+               goto eh_dev_reset_done;
+       }
+
+       /* Send marker. */
+       ha->marker_needed = 1;
+
+       /*
+        * If we are coming down the EH path, wait for all commands to complete
+        * for the device.
+        */
+       if (cmd->device->host->shost_state == SHOST_RECOVERY) {
+               if (qla4xxx_eh_wait_for_active_target_commands(ha,
+                                                         cmd->device->id,
+                                                         cmd->device->lun)){
+                       dev_info(&ha->pdev->dev,
+                                  "DEVICE RESET FAILED - waiting for "
+                                  "commands.\n");
+                       goto eh_dev_reset_done;
+               }
+       }
+
+       dev_info(&ha->pdev->dev,
+                  "scsi(%ld:%d:%d:%d): DEVICE RESET SUCCEEDED.\n",
+                  ha->host_no, cmd->device->channel, cmd->device->id,
+                  cmd->device->lun);
+
+       ret = SUCCESS;
+
+eh_dev_reset_done:
+
+       return ret;
+}
+
+/**
+ * qla4xxx_eh_host_reset - kernel callback
+ * @cmd: Pointer to Linux's SCSI command structure
+ *
+ * This routine is invoked by the Linux kernel to perform fatal error
+ * recovery on the specified adapter.
+ **/
+static int qla4xxx_eh_host_reset(struct scsi_cmnd *cmd)
+{
+       int return_status = FAILED;
+       struct scsi_qla_host *ha;
+
+       ha = (struct scsi_qla_host *) cmd->device->host->hostdata;
+
+       dev_info(&ha->pdev->dev,
+                  "scsi(%ld:%d:%d:%d): ADAPTER RESET ISSUED.\n", ha->host_no,
+                  cmd->device->channel, cmd->device->id, cmd->device->lun);
+
+       if (qla4xxx_wait_for_hba_online(ha) != QLA_SUCCESS) {
+               DEBUG2(printk("scsi%ld:%d: %s: Unable to reset host.  Adapter "
+                             "DEAD.\n", ha->host_no, cmd->device->channel,
+                             __func__));
+
+               return FAILED;
+       }
+
+       if (qla4xxx_recover_adapter(ha, PRESERVE_DDB_LIST) == QLA_SUCCESS) {
+               return_status = SUCCESS;
+       }
+
+       dev_info(&ha->pdev->dev, "HOST RESET %s.\n",
+                  return_status == FAILED ? "FAILED" : "SUCCEDED");
+
+       return return_status;
+}
+
+
+static struct pci_device_id qla4xxx_pci_tbl[] = {
+       {
+               .vendor         = PCI_VENDOR_ID_QLOGIC,
+               .device         = PCI_DEVICE_ID_QLOGIC_ISP4010,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+       },
+       {
+               .vendor         = PCI_VENDOR_ID_QLOGIC,
+               .device         = PCI_DEVICE_ID_QLOGIC_ISP4022,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+       },
+       {0, 0},
+};
+MODULE_DEVICE_TABLE(pci, qla4xxx_pci_tbl);
+
+struct pci_driver qla4xxx_pci_driver = {
+       .name           = DRIVER_NAME,
+       .id_table       = qla4xxx_pci_tbl,
+       .probe          = qla4xxx_probe_adapter,
+       .remove         = qla4xxx_remove_adapter,
+};
+
+static int __init qla4xxx_module_init(void)
+{
+       int ret;
+
+       /* Allocate cache for SRBs. */
+       srb_cachep = kmem_cache_create("qla4xxx_srbs", sizeof(struct srb), 0,
+                                      SLAB_HWCACHE_ALIGN, NULL, NULL);
+       if (srb_cachep == NULL) {
+               printk(KERN_ERR
+                      "%s: Unable to allocate SRB cache..."
+                      "Failing load!\n", DRIVER_NAME);
+               ret = -ENOMEM;
+               goto no_srp_cache;
+       }
+
+       /* Derive version string. */
+       strcpy(qla4xxx_version_str, QLA4XXX_DRIVER_VERSION);
+       if (qla4_extended_error_logging)
+               strcat(qla4xxx_version_str, "-debug");
+
+       qla4xxx_scsi_transport =
+               iscsi_register_transport(&qla4xxx_iscsi_transport);
+       if (!qla4xxx_scsi_transport){
+               ret = -ENODEV;
+               goto release_srb_cache;
+       }
+
+       printk(KERN_INFO "QLogic iSCSI HBA Driver\n");
+       ret = pci_register_driver(&qla4xxx_pci_driver);
+       if (ret)
+               goto unregister_transport;
+
+       printk(KERN_INFO "QLogic iSCSI HBA Driver\n");
+       return 0;
+unregister_transport:
+       iscsi_unregister_transport(&qla4xxx_iscsi_transport);
+release_srb_cache:
+       kmem_cache_destroy(srb_cachep);
+no_srp_cache:
+       return ret;
+}
+
+static void __exit qla4xxx_module_exit(void)
+{
+       pci_unregister_driver(&qla4xxx_pci_driver);
+       iscsi_unregister_transport(&qla4xxx_iscsi_transport);
+       kmem_cache_destroy(srb_cachep);
+}
+
+module_init(qla4xxx_module_init);
+module_exit(qla4xxx_module_exit);
+
+MODULE_AUTHOR("QLogic Corporation");
+MODULE_DESCRIPTION("QLogic iSCSI HBA Driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(QLA4XXX_DRIVER_VERSION);
diff --git a/drivers/scsi/qla4xxx/ql4_version.h b/drivers/scsi/qla4xxx/ql4_version.h
new file mode 100644 (file)
index 0000000..b3fe7e6
--- /dev/null
@@ -0,0 +1,13 @@
+/*
+ * QLogic iSCSI HBA Driver
+ * Copyright (c)  2003-2006 QLogic Corporation
+ *
+ * See LICENSE.qla4xxx for copyright and licensing details.
+ */
+
+#define QLA4XXX_DRIVER_VERSION "5.00.05b9-k"
+
+#define QL4_DRIVER_MAJOR_VER   5
+#define QL4_DRIVER_MINOR_VER   0
+#define QL4_DRIVER_PATCH_VER   5
+#define QL4_DRIVER_BETA_VER    9
index 52fb2ec3da70a452ad9bfe427ec2efb9740c7ab5..e0725353c99cdaf18e7f1708ada202348ca1977c 100644 (file)
@@ -405,10 +405,10 @@ static unsigned int ql_pcmd(Scsi_Cmnd * cmd)
  *     Interrupt handler 
  */
 
-static void ql_ihandl(int irq, void *dev_id, struct pt_regs *regs)
+static void ql_ihandl(void *dev_id)
 {
        Scsi_Cmnd *icmd;
-       struct Scsi_Host *host = (struct Scsi_Host *)dev_id;
+       struct Scsi_Host *host = dev_id;
        struct qlogicfas408_priv *priv = get_priv_by_host(host);
        int qbase = priv->qbase;
        REG0;
@@ -432,13 +432,13 @@ static void ql_ihandl(int irq, void *dev_id, struct pt_regs *regs)
        (icmd->scsi_done) (icmd);
 }
 
-irqreturn_t qlogicfas408_ihandl(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t qlogicfas408_ihandl(int irq, void *dev_id)
 {
        unsigned long flags;
        struct Scsi_Host *host = dev_id;
 
        spin_lock_irqsave(host->host_lock, flags);
-       ql_ihandl(irq, dev_id, regs);
+       ql_ihandl(dev_id);
        spin_unlock_irqrestore(host->host_lock, flags);
        return IRQ_HANDLED;
 }
index 4b3df200366042c2b1a76ab9d7f747e53dedbefa..8fd5555c75b11acb95e3ffc9cf51b88abc13cf55 100644 (file)
@@ -102,7 +102,7 @@ struct qlogicfas408_priv {
 #define get_priv_by_cmd(x) (struct qlogicfas408_priv *)&((x)->device->host->hostdata[0])
 #define get_priv_by_host(x) (struct qlogicfas408_priv *)&((x)->hostdata[0])
 
-irqreturn_t qlogicfas408_ihandl(int irq, void *dev_id, struct pt_regs *regs);
+irqreturn_t qlogicfas408_ihandl(int irq, void *dev_id);
 int qlogicfas408_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *));
 int qlogicfas408_biosparam(struct scsi_device * disk,
                        struct block_device *dev,
index 5b2f0741a55b841f06ad6dc93e9eba81dd809e27..9b827ceec50125734cd6ef3cafebb6f87949d4fe 100644 (file)
@@ -461,7 +461,7 @@ static int qlogicpti_reset_hardware(struct Scsi_Host *host)
 
 #define PTI_RESET_LIMIT 400
 
-static int __init qlogicpti_load_firmware(struct qlogicpti *qpti)
+static int __devinit qlogicpti_load_firmware(struct qlogicpti *qpti)
 {
        struct Scsi_Host *host = qpti->qhost;
        unsigned short csum = 0;
@@ -649,7 +649,7 @@ static int qlogicpti_verify_tmon(struct qlogicpti *qpti)
        return 0;
 }
 
-static irqreturn_t qpti_intr(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t qpti_intr(int irq, void *dev_id);
 
 static void __init qpti_chain_add(struct qlogicpti *qpti)
 {
@@ -1297,7 +1297,7 @@ static struct scsi_cmnd *qlogicpti_intr_handler(struct qlogicpti *qpti)
        return done_queue;
 }
 
-static irqreturn_t qpti_intr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t qpti_intr(int irq, void *dev_id)
 {
        struct qlogicpti *qpti = dev_id;
        unsigned long flags;
index 1545b30681b4f1b93a3d2f0b6988438d0d69ffc5..19aa84f460182c5dba50deccc3e9684a7d08082e 100644 (file)
@@ -1,5 +1,5 @@
 /* Version 1.31.00 ISP1000 Initiator RISC firmware */
-unsigned short sbus_risc_code01[] __initdata = {
+unsigned short sbus_risc_code01[] __devinitdata = {
        0x0078, 0x1030, 0x0000, 0x2419, 0x0000, 0x12ff, 0x2043, 0x4f50,
        0x5952, 0x4947, 0x4854, 0x2031, 0x3939, 0x312c, 0x3139, 0x3932,
        0x2c31, 0x3939, 0x332c, 0x3139, 0x3934, 0x2051, 0x4c4f, 0x4749,
@@ -1157,4 +1157,4 @@ unsigned short sbus_risc_code01[] __initdata = {
        0x003c, 0x0040, 0x3415, 0x2019, 0x2626, 0x7b22, 0x7b26, 0x007c,
        0x92a7
 };
-unsigned short sbus_risc_code_length01 = 0x2419;
+unsigned short __devinitdata sbus_risc_code_length01 = 0x2419;
index 327b33a57b0a1b865ce5c55e91f9c312f2e3d1ec..86e13183c9bab421418f3fb706662d0f24d6f666 100644 (file)
@@ -215,18 +215,19 @@ static void raid_component_release(struct class_device *cdev)
        kfree(rc);
 }
 
-void raid_component_add(struct raid_template *r,struct device *raid_dev,
-                       struct device *component_dev)
+int raid_component_add(struct raid_template *r,struct device *raid_dev,
+                      struct device *component_dev)
 {
        struct class_device *cdev =
                attribute_container_find_class_device(&r->raid_attrs.ac,
                                                      raid_dev);
        struct raid_component *rc;
        struct raid_data *rd = class_get_devdata(cdev);
+       int err;
 
        rc = kzalloc(sizeof(*rc), GFP_KERNEL);
        if (!rc)
-               return;
+               return -ENOMEM;
 
        INIT_LIST_HEAD(&rc->node);
        class_device_initialize(&rc->cdev);
@@ -239,7 +240,18 @@ void raid_component_add(struct raid_template *r,struct device *raid_dev,
        list_add_tail(&rc->node, &rd->component_list);
        rc->cdev.parent = cdev;
        rc->cdev.class = &raid_class.class;
-       class_device_add(&rc->cdev);
+       err = class_device_add(&rc->cdev);
+       if (err)
+               goto err_out;
+
+       return 0;
+
+err_out:
+       list_del(&rc->node);
+       rd->component_count--;
+       put_device(component_dev);
+       kfree(rc);
+       return err;
 }
 EXPORT_SYMBOL(raid_component_add);
 
index da95bce907dd3a23257637510bb12e3613bc6a6c..c59f31533ab4d2b0d072ead30c61a4a7ea6b199e 100644 (file)
@@ -128,7 +128,7 @@ const char * scsi_device_type(unsigned type)
                return "Well-known LUN   ";
        if (type == 0x1f)
                return "No Device        ";
-       if (type > ARRAY_SIZE(scsi_device_types))
+       if (type >= ARRAY_SIZE(scsi_device_types))
                return "Unknown          ";
        return scsi_device_types[type];
 }
index 3d0429bc14abeb74052ea756790b41bf1de4f894..ce63044b1ec8a630711120ea287d73617a922b61 100644 (file)
@@ -150,6 +150,7 @@ static struct {
        {"DELL", "PERCRAID", NULL, BLIST_FORCELUN},
        {"DGC", "RAID", NULL, BLIST_SPARSELUN}, /* Dell PV 650F, storage on LUN 0 */
        {"DGC", "DISK", NULL, BLIST_SPARSELUN}, /* Dell PV 650F, no storage on LUN 0 */
+       {"EMC",  "Invista", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
        {"EMC", "SYMMETRIX", NULL, BLIST_SPARSELUN | BLIST_LARGELUN | BLIST_FORCELUN},
        {"EMULEX", "MD21/S2     ESDI", NULL, BLIST_SINGLELUN},
        {"FSC", "CentricStor", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
@@ -161,6 +162,11 @@ static struct {
        {"HITACHI", "DF600", "*", BLIST_SPARSELUN},
        {"HITACHI", "DISK-SUBSYSTEM", "*", BLIST_ATTACH_PQ3 | BLIST_SPARSELUN | BLIST_LARGELUN},
        {"HITACHI", "OPEN-E", "*", BLIST_ATTACH_PQ3 | BLIST_SPARSELUN | BLIST_LARGELUN},
+       {"HITACHI", "OP-C-", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
+       {"HITACHI", "3380-", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
+       {"HITACHI", "3390-", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
+       {"HITACHI", "6586-", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
+       {"HITACHI", "6588-", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
        {"HP", "A6189A", NULL, BLIST_SPARSELUN | BLIST_LARGELUN},       /* HP VA7400 */
        {"HP", "OPEN-", "*", BLIST_REPORTLUN2}, /* HP XP Arrays */
        {"HP", "NetRAID-4M", NULL, BLIST_FORCELUN},
@@ -168,6 +174,14 @@ static struct {
        {"HP", "C1557A", NULL, BLIST_FORCELUN},
        {"HP", "C3323-300", "4269", BLIST_NOTQ},
        {"HP", "C5713A", NULL, BLIST_NOREPORTLUN},
+       {"HP", "DF400", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
+       {"HP", "DF500", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
+       {"HP", "DF600", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
+       {"HP", "OP-C-", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
+       {"HP", "3380-", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
+       {"HP", "3390-", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
+       {"HP", "6586-", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
+       {"HP", "6588-", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
        {"IBM", "AuSaV1S2", NULL, BLIST_FORCELUN},
        {"IBM", "ProFibre 4000R", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
        {"IBM", "2105", NULL, BLIST_RETRY_HWERROR},
@@ -188,6 +202,7 @@ static struct {
        {"NAKAMICH", "MJ-4.8S", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
        {"NAKAMICH", "MJ-5.16S", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
        {"NEC", "PD-1 ODX654P", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
+       {"NEC", "iStorage", NULL, BLIST_REPORTLUN2},
        {"NRC", "MBR-7", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
        {"NRC", "MBR-7.4", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
        {"PIONEER", "CD-ROM DRM-600", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
@@ -210,6 +225,7 @@ static struct {
        {"SUN", "T300", "*", BLIST_SPARSELUN},
        {"SUN", "T4", "*", BLIST_SPARSELUN},
        {"TEXEL", "CD-ROM", "1.06", BLIST_BORKEN},
+       {"Tornado-", "F4", "*", BLIST_NOREPORTLUN},
        {"TOSHIBA", "CDROM", NULL, BLIST_ISROM},
        {"TOSHIBA", "CD-ROM", NULL, BLIST_ISROM},
        {"USB2.0", "SMARTMEDIA/XD", NULL, BLIST_FORCELUN | BLIST_INQUIRY_36},
index 3d355d054612bd0ec6a30cda4af65ff8aacd6001..aff1b0cfd4b25bfcdf2ceda22e6d522969d7ab9b 100644 (file)
@@ -495,7 +495,7 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd,
        memcpy(scmd->cmnd, cmnd, cmnd_size);
 
        if (copy_sense) {
-               int gfp_mask = GFP_ATOMIC;
+               gfp_t gfp_mask = GFP_ATOMIC;
 
                if (shost->hostt->unchecked_isa_dma)
                        gfp_mask |= __GFP_DMA;
index 71084728eb42322462af7a6f0980d627af54e725..743f67ed76400e1433d8f4bbd00d2bf91bd8fbca 100644 (file)
@@ -426,7 +426,7 @@ int scsi_execute_async(struct scsi_device *sdev, const unsigned char *cmd,
 free_req:
        blk_put_request(req);
 free_sense:
-       kfree(sioc);
+       kmem_cache_free(scsi_io_context_cache, sioc);
        return DRIVER_ERROR << 24;
 }
 EXPORT_SYMBOL_GPL(scsi_execute_async);
index 10bc99c911faf55744dc226f04b4fe84fc210800..84ff203ffedd77749276358825e488fb6d8cfd9d 100644 (file)
@@ -1794,7 +1794,7 @@ static void sd_shutdown(struct device *dev)
  **/
 static int __init init_sd(void)
 {
-       int majors = 0, i;
+       int majors = 0, i, err;
 
        SCSI_LOG_HLQUEUE(3, printk("init_sd: sd driver entry point\n"));
 
@@ -1805,9 +1805,22 @@ static int __init init_sd(void)
        if (!majors)
                return -ENODEV;
 
-       class_register(&sd_disk_class);
+       err = class_register(&sd_disk_class);
+       if (err)
+               goto err_out;
 
-       return scsi_register_driver(&sd_template.gendrv);
+       err = scsi_register_driver(&sd_template.gendrv);
+       if (err)
+               goto err_out_class;
+
+       return 0;
+
+err_out_class:
+       class_unregister(&sd_disk_class);
+err_out:
+       for (i = 0; i < SD_MAJORS; i++)
+               unregister_blkdev(sd_major(i), "sd");
+       return err;
 }
 
 /**
@@ -1822,10 +1835,10 @@ static void __exit exit_sd(void)
        SCSI_LOG_HLQUEUE(3, printk("exit_sd: exiting sd driver\n"));
 
        scsi_unregister_driver(&sd_template.gendrv);
+       class_unregister(&sd_disk_class);
+
        for (i = 0; i < SD_MAJORS; i++)
                unregister_blkdev(sd_major(i), "sd");
-
-       class_unregister(&sd_disk_class);
 }
 
 module_init(init_sd);
index 2679ea8bff1a98365225ff22662c7a3990239321..5ffec2721b28566738b6d620305cd18887fcde38 100644 (file)
 #include <linux/string.h>
 #include <linux/proc_fs.h>
 #include <linux/init.h>
-#include <linux/delay.h>
 #include <linux/blkdev.h>
 #include <linux/stat.h>
 #include <linux/delay.h>
+#include <linux/io.h>
 
-#include <asm/io.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
 
-#include "scsi.h"
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi.h>
+
 #include <scsi/scsi_dbg.h>
 #include <scsi/scsi_host.h>
-#include "seagate.h"
 
-#include <scsi/scsi_ioctl.h>
 
 #ifdef DEBUG
 #define DPRINTK( when, msg... ) do { if ( (DEBUG & (when)) == (when) ) printk( msg ); } while (0)
@@ -320,8 +320,9 @@ static Signature __initdata signatures[] = {
  */
 
 static int hostno = -1;
-static void seagate_reconnect_intr (int, void *, struct pt_regs *);
-static irqreturn_t do_seagate_reconnect_intr (int, void *, struct pt_regs *);
+static void seagate_reconnect_intr (int, void *);
+static irqreturn_t do_seagate_reconnect_intr (int, void *);
+static int seagate_st0x_bus_reset(struct scsi_cmnd *);
 
 #ifdef FAST
 static int fast = 1;
@@ -585,8 +586,8 @@ static int linked_connected = 0;
 static unsigned char linked_target, linked_lun;
 #endif
 
-static void (*done_fn) (Scsi_Cmnd *) = NULL;
-static Scsi_Cmnd *SCint = NULL;
+static void (*done_fn) (struct scsi_cmnd *) = NULL;
+static struct scsi_cmnd *SCint = NULL;
 
 /*
  * These control whether or not disconnect / reconnect will be attempted,
@@ -618,22 +619,21 @@ static int should_reconnect = 0;
  * asserting SEL.
  */
 
-static irqreturn_t do_seagate_reconnect_intr(int irq, void *dev_id,
-                                               struct pt_regs *regs)
+static irqreturn_t do_seagate_reconnect_intr(int irq, void *dev_id)
 {
        unsigned long flags;
        struct Scsi_Host *dev = dev_id;
        
        spin_lock_irqsave (dev->host_lock, flags);
-       seagate_reconnect_intr (irq, dev_id, regs);
+       seagate_reconnect_intr (irq, dev_id);
        spin_unlock_irqrestore (dev->host_lock, flags);
        return IRQ_HANDLED;
 }
 
-static void seagate_reconnect_intr (int irq, void *dev_id, struct pt_regs *regs)
+static void seagate_reconnect_intr (int irq, void *dev_id)
 {
        int temp;
-       Scsi_Cmnd *SCtmp;
+       struct scsi_cmnd *SCtmp;
 
        DPRINTK (PHASE_RESELECT, "scsi%d : seagate_reconnect_intr() called\n", hostno);
 
@@ -675,10 +675,11 @@ static void seagate_reconnect_intr (int irq, void *dev_id, struct pt_regs *regs)
 
 static int recursion_depth = 0;
 
-static int seagate_st0x_queue_command (Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
+static int seagate_st0x_queue_command(struct scsi_cmnd * SCpnt,
+                                     void (*done) (struct scsi_cmnd *))
 {
        int result, reconnect;
-       Scsi_Cmnd *SCtmp;
+       struct scsi_cmnd *SCtmp;
 
        DANY ("seagate: que_command");
        done_fn = done;
@@ -1609,7 +1610,7 @@ connect_loop:
        return retcode (st0x_aborted);
 }                              /* end of internal_command */
 
-static int seagate_st0x_abort (Scsi_Cmnd * SCpnt)
+static int seagate_st0x_abort(struct scsi_cmnd * SCpnt)
 {
        st0x_aborted = DID_ABORT;
        return SUCCESS;
@@ -1624,7 +1625,7 @@ static int seagate_st0x_abort (Scsi_Cmnd * SCpnt)
  * May be called with SCpnt = NULL
  */
 
-static int seagate_st0x_bus_reset(Scsi_Cmnd * SCpnt)
+static int seagate_st0x_bus_reset(struct scsi_cmnd * SCpnt)
 {
        /* No timeouts - this command is going to fail because it was reset. */
        DANY ("scsi%d: Reseting bus... ", hostno);
diff --git a/drivers/scsi/seagate.h b/drivers/scsi/seagate.h
deleted file mode 100644 (file)
index fb5f380..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- *     seagate.h Copyright (C) 1992 Drew Eckhardt 
- *     low level scsi driver header for ST01/ST02 by
- *             Drew Eckhardt 
- *
- *     <drew@colorado.edu>
- */
-
-#ifndef _SEAGATE_H
-#define SEAGATE_H
-
-static int seagate_st0x_detect(struct scsi_host_template *);
-static int seagate_st0x_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-
-static int seagate_st0x_abort(Scsi_Cmnd *);
-static const char *seagate_st0x_info(struct Scsi_Host *);
-static int seagate_st0x_bus_reset(Scsi_Cmnd *);
-
-#endif /* _SEAGATE_H */
index 34f9343ed0af58a5cddf55c1379b2181d272ac40..3f8b93188567909201b12d209030990495405804 100644 (file)
@@ -60,7 +60,7 @@ static int sg_version_num = 30534;    /* 2 digits for each component */
 
 #ifdef CONFIG_SCSI_PROC_FS
 #include <linux/proc_fs.h>
-static char *sg_version_date = "20060818";
+static char *sg_version_date = "20060920";
 
 static int sg_proc_init(void);
 static void sg_proc_cleanup(void);
@@ -94,6 +94,9 @@ int sg_big_buff = SG_DEF_RESERVED_SIZE;
 static int def_reserved_size = -1;     /* picks up init parameter */
 static int sg_allow_dio = SG_ALLOW_DIO_DEF;
 
+static int scatter_elem_sz = SG_SCATTER_SZ;
+static int scatter_elem_sz_prev = SG_SCATTER_SZ;
+
 #define SG_SECTOR_SZ 512
 #define SG_SECTOR_MSK (SG_SECTOR_SZ - 1)
 
@@ -1537,11 +1540,9 @@ sg_remove(struct class_device *cl_dev, struct class_interface *cl_intf)
                msleep(10);     /* dirty detach so delay device destruction */
 }
 
-/* Set 'perm' (4th argument) to 0 to disable module_param's definition
- * of sysfs parameters (which module_param doesn't yet support).
- * Sysfs parameters defined explicitly below.
- */
-module_param_named(def_reserved_size, def_reserved_size, int, S_IRUGO);
+module_param_named(scatter_elem_sz, scatter_elem_sz, int, S_IRUGO | S_IWUSR);
+module_param_named(def_reserved_size, def_reserved_size, int,
+                  S_IRUGO | S_IWUSR);
 module_param_named(allow_dio, sg_allow_dio, int, S_IRUGO | S_IWUSR);
 
 MODULE_AUTHOR("Douglas Gilbert");
@@ -1550,6 +1551,8 @@ MODULE_LICENSE("GPL");
 MODULE_VERSION(SG_VERSION_STR);
 MODULE_ALIAS_CHARDEV_MAJOR(SCSI_GENERIC_MAJOR);
 
+MODULE_PARM_DESC(scatter_elem_sz, "scatter gather element "
+                "size (default: max(SG_SCATTER_SZ, PAGE_SIZE))");
 MODULE_PARM_DESC(def_reserved_size, "size of buffer reserved for each fd");
 MODULE_PARM_DESC(allow_dio, "allow direct I/O (default: 0 (disallow))");
 
@@ -1558,8 +1561,14 @@ init_sg(void)
 {
        int rc;
 
+       if (scatter_elem_sz < PAGE_SIZE) {
+               scatter_elem_sz = PAGE_SIZE;
+               scatter_elem_sz_prev = scatter_elem_sz;
+       }
        if (def_reserved_size >= 0)
                sg_big_buff = def_reserved_size;
+       else
+               def_reserved_size = sg_big_buff;
 
        rc = register_chrdev_region(MKDEV(SCSI_GENERIC_MAJOR, 0), 
                                    SG_MAX_DEVS, "sg");
@@ -1842,15 +1851,30 @@ sg_build_indirect(Sg_scatter_hold * schp, Sg_fd * sfp, int buff_size)
        if (mx_sc_elems < 0)
                return mx_sc_elems;     /* most likely -ENOMEM */
 
+       num = scatter_elem_sz;
+       if (unlikely(num != scatter_elem_sz_prev)) {
+               if (num < PAGE_SIZE) {
+                       scatter_elem_sz = PAGE_SIZE;
+                       scatter_elem_sz_prev = PAGE_SIZE;
+               } else
+                       scatter_elem_sz_prev = num;
+       }
        for (k = 0, sg = schp->buffer, rem_sz = blk_size;
             (rem_sz > 0) && (k < mx_sc_elems);
             ++k, rem_sz -= ret_sz, ++sg) {
                
-               num = (rem_sz > SG_SCATTER_SZ) ? SG_SCATTER_SZ : rem_sz;
+               num = (rem_sz > scatter_elem_sz_prev) ?
+                     scatter_elem_sz_prev : rem_sz;
                p = sg_page_malloc(num, sfp->low_dma, &ret_sz);
                if (!p)
                        return -ENOMEM;
 
+               if (num == scatter_elem_sz_prev) {
+                       if (unlikely(ret_sz > scatter_elem_sz_prev)) {
+                               scatter_elem_sz = ret_sz;
+                               scatter_elem_sz_prev = ret_sz;
+                       }
+               }
                sg->page = p;
                sg->length = ret_sz;
 
@@ -2341,6 +2365,9 @@ sg_add_sfp(Sg_device * sdp, int dev)
        }
        write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
        SCSI_LOG_TIMEOUT(3, printk("sg_add_sfp: sfp=0x%p\n", sfp));
+       if (unlikely(sg_big_buff != def_reserved_size))
+               sg_big_buff = def_reserved_size;
+
        sg_build_reserve(sfp, sg_big_buff);
        SCSI_LOG_TIMEOUT(3, printk("sg_add_sfp:   bufflen=%d, k_use_sg=%d\n",
                           sfp->reserve.bufflen, sfp->reserve.k_use_sg));
@@ -2437,16 +2464,16 @@ sg_res_in_use(Sg_fd * sfp)
        return srp ? 1 : 0;
 }
 
-/* If retSzp==NULL want exact size or fail */
+/* The size fetched (value output via retSzp) set when non-NULL return */
 static struct page *
 sg_page_malloc(int rqSz, int lowDma, int *retSzp)
 {
        struct page *resp = NULL;
        gfp_t page_mask;
        int order, a_size;
-       int resSz = rqSz;
+       int resSz;
 
-       if (rqSz <= 0)
+       if ((rqSz <= 0) || (NULL == retSzp))
                return resp;
 
        if (lowDma)
@@ -2456,8 +2483,9 @@ sg_page_malloc(int rqSz, int lowDma, int *retSzp)
 
        for (order = 0, a_size = PAGE_SIZE; a_size < rqSz;
             order++, a_size <<= 1) ;
+       resSz = a_size;         /* rounded up if necessary */
        resp = alloc_pages(page_mask, order);
-       while ((!resp) && order && retSzp) {
+       while ((!resp) && order) {
                --order;
                a_size >>= 1;   /* divide by 2, until PAGE_SIZE */
                resp =  alloc_pages(page_mask, order);  /* try half */
@@ -2466,8 +2494,7 @@ sg_page_malloc(int rqSz, int lowDma, int *retSzp)
        if (resp) {
                if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
                        memset(page_address(resp), 0, resSz);
-               if (retSzp)
-                       *retSzp = resSz;
+               *retSzp = resSz;
        }
        return resp;
 }
index 4f1db6f2aae88617f689ae46f3dfa62af0fd0499..e81f97a35bc8775d6bc9ae34d676c0d680345df0 100644 (file)
@@ -84,7 +84,7 @@ static inline unsigned long read_wd33c93_count(const wd33c93_regs regs)
        return value;
 }
 
-static irqreturn_t sgiwd93_intr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t sgiwd93_intr(int irq, void *dev_id)
 {
        struct Scsi_Host * host = (struct Scsi_Host *) dev_id;
        unsigned long flags;
index 7f669b6006777a05ee8e5509c25df824332887eb..3babdc76b3fb37f3e361243f8d5b7167a0d85f8b 100644 (file)
@@ -195,9 +195,9 @@ static int sgl_unmap_user_pages(struct scatterlist *, const unsigned int, int);
 static int st_probe(struct device *);
 static int st_remove(struct device *);
 
-static void do_create_driverfs_files(void);
+static int do_create_driverfs_files(void);
 static void do_remove_driverfs_files(void);
-static void do_create_class_files(struct scsi_tape *, int, int);
+static int do_create_class_files(struct scsi_tape *, int, int);
 
 static struct scsi_driver st_template = {
        .owner                  = THIS_MODULE,
@@ -4048,7 +4048,9 @@ static int st_probe(struct device *dev)
                        STm->cdevs[j] = cdev;
 
                }
-               do_create_class_files(tpnt, dev_num, mode);
+               error = do_create_class_files(tpnt, dev_num, mode);
+               if (error)
+                       goto out_free_tape;
        }
 
        sdev_printk(KERN_WARNING, SDp,
@@ -4157,32 +4159,45 @@ static void scsi_tape_release(struct kref *kref)
 
 static int __init init_st(void)
 {
+       int err;
+
        validate_options();
 
-       printk(KERN_INFO
-               "st: Version %s, fixed bufsize %d, s/g segs %d\n",
+       printk(KERN_INFO "st: Version %s, fixed bufsize %d, s/g segs %d\n",
                verstr, st_fixed_buffer_size, st_max_sg_segs);
 
        st_sysfs_class = class_create(THIS_MODULE, "scsi_tape");
        if (IS_ERR(st_sysfs_class)) {
-               st_sysfs_class = NULL;
                printk(KERN_ERR "Unable create sysfs class for SCSI tapes\n");
-               return 1;
+               return PTR_ERR(st_sysfs_class);
        }
 
-       if (!register_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
-                                   ST_MAX_TAPE_ENTRIES, "st")) {
-               if (scsi_register_driver(&st_template.gendrv) == 0) {
-                       do_create_driverfs_files();
-                       return 0;
-               }
-               unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
-                                        ST_MAX_TAPE_ENTRIES);
+       err = register_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
+                                    ST_MAX_TAPE_ENTRIES, "st");
+       if (err) {
+               printk(KERN_ERR "Unable to get major %d for SCSI tapes\n",
+                      SCSI_TAPE_MAJOR);
+               goto err_class;
        }
-       class_destroy(st_sysfs_class);
 
-       printk(KERN_ERR "Unable to get major %d for SCSI tapes\n", SCSI_TAPE_MAJOR);
-       return 1;
+       err = scsi_register_driver(&st_template.gendrv);
+       if (err)
+               goto err_chrdev;
+
+       err = do_create_driverfs_files();
+       if (err)
+               goto err_scsidrv;
+
+       return 0;
+
+err_scsidrv:
+       scsi_unregister_driver(&st_template.gendrv);
+err_chrdev:
+       unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
+                                ST_MAX_TAPE_ENTRIES);
+err_class:
+       class_destroy(st_sysfs_class);
+       return err;
 }
 
 static void __exit exit_st(void)
@@ -4225,14 +4240,33 @@ static ssize_t st_version_show(struct device_driver *ddd, char *buf)
 }
 static DRIVER_ATTR(version, S_IRUGO, st_version_show, NULL);
 
-static void do_create_driverfs_files(void)
+static int do_create_driverfs_files(void)
 {
        struct device_driver *driverfs = &st_template.gendrv;
+       int err;
+
+       err = driver_create_file(driverfs, &driver_attr_try_direct_io);
+       if (err)
+               return err;
+       err = driver_create_file(driverfs, &driver_attr_fixed_buffer_size);
+       if (err)
+               goto err_try_direct_io;
+       err = driver_create_file(driverfs, &driver_attr_max_sg_segs);
+       if (err)
+               goto err_attr_fixed_buf;
+       err = driver_create_file(driverfs, &driver_attr_version);
+       if (err)
+               goto err_attr_max_sg;
 
-       driver_create_file(driverfs, &driver_attr_try_direct_io);
-       driver_create_file(driverfs, &driver_attr_fixed_buffer_size);
-       driver_create_file(driverfs, &driver_attr_max_sg_segs);
-       driver_create_file(driverfs, &driver_attr_version);
+       return 0;
+
+err_attr_max_sg:
+       driver_remove_file(driverfs, &driver_attr_max_sg_segs);
+err_attr_fixed_buf:
+       driver_remove_file(driverfs, &driver_attr_fixed_buffer_size);
+err_try_direct_io:
+       driver_remove_file(driverfs, &driver_attr_try_direct_io);
+       return err;
 }
 
 static void do_remove_driverfs_files(void)
@@ -4293,15 +4327,12 @@ static ssize_t st_defcompression_show(struct class_device *class_dev, char *buf)
 
 CLASS_DEVICE_ATTR(default_compression, S_IRUGO, st_defcompression_show, NULL);
 
-static void do_create_class_files(struct scsi_tape *STp, int dev_num, int mode)
+static int do_create_class_files(struct scsi_tape *STp, int dev_num, int mode)
 {
        int i, rew, error;
        char name[10];
        struct class_device *st_class_member;
 
-       if (!st_sysfs_class)
-               return;
-
        for (rew=0; rew < 2; rew++) {
                /* Make sure that the minor numbers corresponding to the four
                   first modes always get the same names */
@@ -4316,18 +4347,24 @@ static void do_create_class_files(struct scsi_tape *STp, int dev_num, int mode)
                if (IS_ERR(st_class_member)) {
                        printk(KERN_WARNING "st%d: class_device_create failed\n",
                               dev_num);
+                       error = PTR_ERR(st_class_member);
                        goto out;
                }
                class_set_devdata(st_class_member, &STp->modes[mode]);
 
-               class_device_create_file(st_class_member,
-                                        &class_device_attr_defined);
-               class_device_create_file(st_class_member,
-                                        &class_device_attr_default_blksize);
-               class_device_create_file(st_class_member,
-                                        &class_device_attr_default_density);
-               class_device_create_file(st_class_member,
-                                        &class_device_attr_default_compression);
+               error = class_device_create_file(st_class_member,
+                                              &class_device_attr_defined);
+               if (error) goto out;
+               error = class_device_create_file(st_class_member,
+                                           &class_device_attr_default_blksize);
+               if (error) goto out;
+               error = class_device_create_file(st_class_member,
+                                           &class_device_attr_default_density);
+               if (error) goto out;
+               error = class_device_create_file(st_class_member,
+                                       &class_device_attr_default_compression);
+               if (error) goto out;
+
                if (mode == 0 && rew == 0) {
                        error = sysfs_create_link(&STp->device->sdev_gendev.kobj,
                                                  &st_class_member->kobj,
@@ -4336,11 +4373,15 @@ static void do_create_class_files(struct scsi_tape *STp, int dev_num, int mode)
                                printk(KERN_ERR
                                       "st%d: Can't create sysfs link from SCSI device.\n",
                                       dev_num);
+                               goto out;
                        }
                }
        }
- out:
-       return;
+
+       return 0;
+
+out:
+       return error;
 }
 
 /* The following functions may be useful for a larger audience. */
index 3cf3106a29b8e45fb6515817e5c9280cff07900d..185c270bb0433f9dae1bb9427e61092d9c905796 100644 (file)
@@ -11,7 +11,7 @@
  *     Written By:
  *             Ed Lin <promise_linux@promise.com>
  *
- *     Version: 2.9.0.13
+ *     Version: 3.0.0.1
  *
  */
 
 #include <scsi/scsi_tcq.h>
 
 #define DRV_NAME "stex"
-#define ST_DRIVER_VERSION "2.9.0.13"
-#define ST_VER_MAJOR           2
-#define ST_VER_MINOR           9
+#define ST_DRIVER_VERSION "3.0.0.1"
+#define ST_VER_MAJOR           3
+#define ST_VER_MINOR           0
 #define ST_OEM                         0
-#define ST_BUILD_VER           13
+#define ST_BUILD_VER           1
 
 enum {
        /* MU register offset */
@@ -120,12 +120,18 @@ enum {
 
        st_shasta                               = 0,
        st_vsc                                  = 1,
+       st_yosemite                             = 2,
 
        PASSTHRU_REQ_TYPE                       = 0x00000001,
        PASSTHRU_REQ_NO_WAKEUP                  = 0x00000100,
        ST_INTERNAL_TIMEOUT                     = 30,
 
+       ST_TO_CMD                               = 0,
+       ST_FROM_CMD                             = 1,
+
        /* vendor specific commands of Promise */
+       MGT_CMD                                 = 0xd8,
+       SINBAND_MGT_CMD                         = 0xd9,
        ARRAY_CMD                               = 0xe0,
        CONTROLLER_CMD                          = 0xe1,
        DEBUGGING_CMD                           = 0xe2,
@@ -133,14 +139,48 @@ enum {
 
        PASSTHRU_GET_ADAPTER                    = 0x05,
        PASSTHRU_GET_DRVVER                     = 0x10,
+
+       CTLR_CONFIG_CMD                         = 0x03,
+       CTLR_SHUTDOWN                           = 0x0d,
+
        CTLR_POWER_STATE_CHANGE                 = 0x0e,
        CTLR_POWER_SAVING                       = 0x01,
 
        PASSTHRU_SIGNATURE                      = 0x4e415041,
+       MGT_CMD_SIGNATURE                       = 0xba,
 
        INQUIRY_EVPD                            = 0x01,
 };
 
+/* SCSI inquiry data */
+typedef struct st_inq {
+       u8 DeviceType                   :5;
+       u8 DeviceTypeQualifier          :3;
+       u8 DeviceTypeModifier           :7;
+       u8 RemovableMedia               :1;
+       u8 Versions;
+       u8 ResponseDataFormat           :4;
+       u8 HiSupport                    :1;
+       u8 NormACA                      :1;
+       u8 ReservedBit                  :1;
+       u8 AERC                         :1;
+       u8 AdditionalLength;
+       u8 Reserved[2];
+       u8 SoftReset                    :1;
+       u8 CommandQueue                 :1;
+       u8 Reserved2                    :1;
+       u8 LinkedCommands               :1;
+       u8 Synchronous                  :1;
+       u8 Wide16Bit                    :1;
+       u8 Wide32Bit                    :1;
+       u8 RelativeAddressing           :1;
+       u8 VendorId[8];
+       u8 ProductId[16];
+       u8 ProductRevisionLevel[4];
+       u8 VendorSpecific[20];
+       u8 Reserved3[40];
+} ST_INQ;
+
 struct st_sgitem {
        u8 ctrl;        /* SG_CF_xxx */
        u8 reserved[3];
@@ -181,7 +221,7 @@ struct req_msg {
        u8 task_attr;
        u8 task_manage;
        u8 prd_entry;
-       u8 payload_sz;          /* payload size in 4-byte */
+       u8 payload_sz;          /* payload size in 4-byte, not used */
        u8 cdb[STEX_CDB_LENGTH];
        u8 variable[REQ_VARIABLE_LEN];
 };
@@ -242,7 +282,8 @@ struct st_drvver {
 #define MU_REQ_BUFFER_SIZE     (MU_REQ_COUNT * sizeof(struct req_msg))
 #define MU_STATUS_BUFFER_SIZE  (MU_STATUS_COUNT * sizeof(struct status_msg))
 #define MU_BUFFER_SIZE         (MU_REQ_BUFFER_SIZE + MU_STATUS_BUFFER_SIZE)
-#define STEX_BUFFER_SIZE       (MU_BUFFER_SIZE + sizeof(struct st_frame))
+#define STEX_EXTRA_SIZE                max(sizeof(struct st_frame), sizeof(ST_INQ))
+#define STEX_BUFFER_SIZE       (MU_BUFFER_SIZE + STEX_EXTRA_SIZE)
 
 struct st_ccb {
        struct req_msg *req;
@@ -403,7 +444,7 @@ static int stex_map_sg(struct st_hba *hba,
 }
 
 static void stex_internal_copy(struct scsi_cmnd *cmd,
-       const void *src, size_t *count, int sg_count)
+       const void *src, size_t *count, int sg_count, int direction)
 {
        size_t lcount;
        size_t len;
@@ -427,7 +468,10 @@ static void stex_internal_copy(struct scsi_cmnd *cmd,
                } else
                        d = cmd->request_buffer;
 
-               memcpy(d, s, len);
+               if (direction == ST_TO_CMD)
+                       memcpy(d, s, len);
+               else
+                       memcpy(s, d, len);
 
                lcount -= len;
                if (cmd->use_sg)
@@ -449,7 +493,7 @@ static int stex_direct_copy(struct scsi_cmnd *cmd,
                        return 0;
        }
 
-       stex_internal_copy(cmd, src, &cp_len, n_elem);
+       stex_internal_copy(cmd, src, &cp_len, n_elem, ST_TO_CMD);
 
        if (cmd->use_sg)
                pci_unmap_sg(hba->pdev, cmd->request_buffer,
@@ -480,7 +524,7 @@ static void stex_controller_info(struct st_hba *hba, struct st_ccb *ccb)
        p->subid =
                hba->pdev->subsystem_vendor << 16 | hba->pdev->subsystem_device;
 
-       stex_internal_copy(ccb->cmd, p, &count, ccb->sg_count);
+       stex_internal_copy(ccb->cmd, p, &count, ccb->sg_count, ST_TO_CMD);
 }
 
 static void
@@ -489,7 +533,6 @@ stex_send_cmd(struct st_hba *hba, struct req_msg *req, u16 tag)
        req->tag = cpu_to_le16(tag);
        req->task_attr = TASK_ATTRIBUTE_SIMPLE;
        req->task_manage = 0; /* not supported yet */
-       req->payload_sz = (u8)(sizeof(struct req_msg)/sizeof(u32));
 
        hba->ccb[tag].req = req;
        hba->out_req_cnt++;
@@ -595,8 +638,14 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
                return SCSI_MLQUEUE_HOST_BUSY;
 
        req = stex_alloc_req(hba);
-       req->lun = lun;
-       req->target = id;
+
+       if (hba->cardtype == st_yosemite) {
+               req->lun = lun * (ST_MAX_TARGET_NUM - 1) + id;
+               req->target = 0;
+       } else {
+               req->lun = lun;
+               req->target = id;
+       }
 
        /* cdb */
        memcpy(req->cdb, cmd->cmnd, STEX_CDB_LENGTH);
@@ -680,7 +729,51 @@ static void stex_copy_data(struct st_ccb *ccb,
 
        if (ccb->cmd == NULL)
                return;
-       stex_internal_copy(ccb->cmd, resp->variable, &count, ccb->sg_count);
+       stex_internal_copy(ccb->cmd,
+               resp->variable, &count, ccb->sg_count, ST_TO_CMD);
+}
+
+static void stex_ys_commands(struct st_hba *hba,
+       struct st_ccb *ccb, struct status_msg *resp)
+{
+       size_t count;
+
+       if (ccb->cmd->cmnd[0] == MGT_CMD &&
+               resp->scsi_status != SAM_STAT_CHECK_CONDITION) {
+               ccb->cmd->request_bufflen =
+                       le32_to_cpu(*(__le32 *)&resp->variable[0]);
+               return;
+       }
+
+       if (resp->srb_status != 0)
+               return;
+
+       /* determine inquiry command status by DeviceTypeQualifier */
+       if (ccb->cmd->cmnd[0] == INQUIRY &&
+               resp->scsi_status == SAM_STAT_GOOD) {
+               ST_INQ *inq_data;
+
+               count = STEX_EXTRA_SIZE;
+               stex_internal_copy(ccb->cmd, hba->copy_buffer,
+                       &count, ccb->sg_count, ST_FROM_CMD);
+               inq_data = (ST_INQ *)hba->copy_buffer;
+               if (inq_data->DeviceTypeQualifier != 0)
+                       ccb->srb_status = SRB_STATUS_SELECTION_TIMEOUT;
+               else
+                       ccb->srb_status = SRB_STATUS_SUCCESS;
+       } else if (ccb->cmd->cmnd[0] == REPORT_LUNS) {
+               u8 *report_lun_data = (u8 *)hba->copy_buffer;
+
+               count = STEX_EXTRA_SIZE;
+               stex_internal_copy(ccb->cmd, report_lun_data,
+                       &count, ccb->sg_count, ST_FROM_CMD);
+               if (report_lun_data[2] || report_lun_data[3]) {
+                       report_lun_data[2] = 0x00;
+                       report_lun_data[3] = 0x08;
+                       stex_internal_copy(ccb->cmd, report_lun_data,
+                               &count, ccb->sg_count, ST_TO_CMD);
+               }
+       }
 }
 
 static void stex_mu_intr(struct st_hba *hba, u32 doorbell)
@@ -702,8 +795,17 @@ static void stex_mu_intr(struct st_hba *hba, u32 doorbell)
                return;
        }
 
-       if (unlikely(hba->mu_status != MU_STATE_STARTED ||
-               hba->out_req_cnt <= 0)) {
+       /*
+        * it's not a valid status payload if:
+        * 1. there are no pending requests(e.g. during init stage)
+        * 2. there are some pending requests, but the controller is in
+        *     reset status, and its type is not st_yosemite
+        * firmware of st_yosemite in reset status will return pending requests
+        * to driver, so we allow it to pass
+        */
+       if (unlikely(hba->out_req_cnt <= 0 ||
+                       (hba->mu_status == MU_STATE_RESETTING &&
+                        hba->cardtype != st_yosemite))) {
                hba->status_tail = hba->status_head;
                goto update_status;
        }
@@ -723,6 +825,7 @@ static void stex_mu_intr(struct st_hba *hba, u32 doorbell)
                if (unlikely(ccb->req == NULL)) {
                        printk(KERN_WARNING DRV_NAME
                                "(%s): lagging req\n", pci_name(hba->pdev));
+                       hba->out_req_cnt--;
                        continue;
                }
 
@@ -741,9 +844,13 @@ static void stex_mu_intr(struct st_hba *hba, u32 doorbell)
                ccb->scsi_status = resp->scsi_status;
 
                if (likely(ccb->cmd != NULL)) {
+                       if (hba->cardtype == st_yosemite)
+                               stex_ys_commands(hba, ccb, resp);
+
                        if (unlikely(ccb->cmd->cmnd[0] == PASSTHRU_CMD &&
                                ccb->cmd->cmnd[1] == PASSTHRU_GET_ADAPTER))
                                stex_controller_info(hba, ccb);
+
                        stex_unmap_sg(hba, ccb->cmd);
                        stex_scsi_done(ccb);
                        hba->out_req_cnt--;
@@ -764,7 +871,7 @@ update_status:
        readl(base + IMR1); /* flush */
 }
 
-static irqreturn_t stex_intr(int irq, void *__hba, struct pt_regs *regs)
+static irqreturn_t stex_intr(int irq, void *__hba)
 {
        struct st_hba *hba = __hba;
        void __iomem *base = hba->mmio_base;
@@ -948,6 +1055,7 @@ static int stex_reset(struct scsi_cmnd *cmd)
 {
        struct st_hba *hba;
        unsigned long flags;
+       unsigned long before;
        hba = (struct st_hba *) &cmd->device->host->hostdata[0];
 
        hba->mu_status = MU_STATE_RESETTING;
@@ -955,20 +1063,37 @@ static int stex_reset(struct scsi_cmnd *cmd)
        if (hba->cardtype == st_shasta)
                stex_hard_reset(hba);
 
-       if (stex_handshake(hba)) {
-               printk(KERN_WARNING DRV_NAME
-                       "(%s): resetting: handshake failed\n",
-                       pci_name(hba->pdev));
-               return FAILED;
+       if (hba->cardtype != st_yosemite) {
+               if (stex_handshake(hba)) {
+                       printk(KERN_WARNING DRV_NAME
+                               "(%s): resetting: handshake failed\n",
+                               pci_name(hba->pdev));
+                       return FAILED;
+               }
+               spin_lock_irqsave(hba->host->host_lock, flags);
+               hba->req_head = 0;
+               hba->req_tail = 0;
+               hba->status_head = 0;
+               hba->status_tail = 0;
+               hba->out_req_cnt = 0;
+               spin_unlock_irqrestore(hba->host->host_lock, flags);
+               return SUCCESS;
+       }
+
+       /* st_yosemite */
+       writel(MU_INBOUND_DOORBELL_RESET, hba->mmio_base + IDBL);
+       readl(hba->mmio_base + IDBL); /* flush */
+       before = jiffies;
+       while (hba->out_req_cnt > 0) {
+               if (time_after(jiffies, before + ST_INTERNAL_TIMEOUT * HZ)) {
+                       printk(KERN_WARNING DRV_NAME
+                               "(%s): reset timeout\n", pci_name(hba->pdev));
+                       return FAILED;
+               }
+               msleep(1);
        }
-       spin_lock_irqsave(hba->host->host_lock, flags);
-       hba->req_head = 0;
-       hba->req_tail = 0;
-       hba->status_head = 0;
-       hba->status_tail = 0;
-       hba->out_req_cnt = 0;
-       spin_unlock_irqrestore(hba->host->host_lock, flags);
 
+       hba->mu_status = MU_STATE_STARTED;
        return SUCCESS;
 }
 
@@ -1156,9 +1281,16 @@ static void stex_hba_stop(struct st_hba *hba)
        req = stex_alloc_req(hba);
        memset(req->cdb, 0, STEX_CDB_LENGTH);
 
-       req->cdb[0] = CONTROLLER_CMD;
-       req->cdb[1] = CTLR_POWER_STATE_CHANGE;
-       req->cdb[2] = CTLR_POWER_SAVING;
+       if (hba->cardtype == st_yosemite) {
+               req->cdb[0] = MGT_CMD;
+               req->cdb[1] = MGT_CMD_SIGNATURE;
+               req->cdb[2] = CTLR_CONFIG_CMD;
+               req->cdb[3] = CTLR_SHUTDOWN;
+       } else {
+               req->cdb[0] = CONTROLLER_CMD;
+               req->cdb[1] = CTLR_POWER_STATE_CHANGE;
+               req->cdb[2] = CTLR_POWER_SAVING;
+       }
 
        hba->ccb[tag].cmd = NULL;
        hba->ccb[tag].sg_count = 0;
@@ -1222,6 +1354,7 @@ static struct pci_device_id stex_pci_tbl[] = {
        { 0x105a, 0x8301, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_shasta },
        { 0x105a, 0x8302, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_shasta },
        { 0x1725, 0x7250, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_vsc },
+       { 0x105a, 0x8650, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_yosemite },
        { }     /* terminate list */
 };
 MODULE_DEVICE_TABLE(pci, stex_pci_tbl);
index 7f9bcef6adfa941cfa07cc3301a57b62177cd7ca..5ec5af8e337903c78a8277712d770d1b83b8e7b0 100644 (file)
@@ -1252,7 +1252,7 @@ static void NCR5380_dma_complete( struct Scsi_Host *instance )
  *
  */
 
-static irqreturn_t NCR5380_intr (int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t NCR5380_intr (int irq, void *dev_id)
 {
     struct Scsi_Host *instance = first_instance;
     int done = 1, handled = 0;
index 44a99aeb818046355a17a4fbb9b94b34506878f7..e625b4c5833adda4a422735e1f3046acc10274bb 100644 (file)
@@ -102,7 +102,7 @@ static void NCR5380_print(struct Scsi_Host *instance);
 #define        ENABLE_IRQ()    enable_irq( IRQ_SUN3_SCSI ); 
 
 
-static irqreturn_t scsi_sun3_intr(int irq, void *dummy, struct pt_regs *fp);
+static irqreturn_t scsi_sun3_intr(int irq, void *dummy);
 static inline unsigned char sun3scsi_read(int reg);
 static inline void sun3scsi_write(int reg, int value);
 
@@ -371,7 +371,7 @@ const char * sun3scsi_info (struct Scsi_Host *spnt) {
 // safe bits for the CSR
 #define CSR_GOOD 0x060f
 
-static irqreturn_t scsi_sun3_intr(int irq, void *dummy, struct pt_regs *fp)
+static irqreturn_t scsi_sun3_intr(int irq, void *dummy)
 {
        unsigned short csr = dregs->csr;
        int handled = 0;
@@ -388,7 +388,7 @@ static irqreturn_t scsi_sun3_intr(int irq, void *dummy, struct pt_regs *fp)
        }
 
        if(csr & (CSR_SDB_INT | CSR_DMA_INT)) {
-               NCR5380_intr(irq, dummy, fp);
+               NCR5380_intr(irq, dummy);
                handled = 1;
        }
 
index f5742b84b27aa28bf4b6ed0e16f23a4c20cc1745..e8faab16567b69b9a0f58eb79adc014b67b33d28 100644 (file)
@@ -67,7 +67,7 @@ extern int sun3_map_test(unsigned long, char *);
 #define ENABLE_IRQ()
 
 
-static irqreturn_t scsi_sun3_intr(int irq, void *dummy, struct pt_regs *fp);
+static irqreturn_t scsi_sun3_intr(int irq, void *dummy);
 static inline unsigned char sun3scsi_read(int reg);
 static inline void sun3scsi_write(int reg, int value);
 
@@ -340,7 +340,7 @@ static const char * sun3scsi_info (struct Scsi_Host *spnt) {
 // safe bits for the CSR
 #define CSR_GOOD 0x060f
 
-static irqreturn_t scsi_sun3_intr(int irq, void *dummy, struct pt_regs *fp)
+static irqreturn_t scsi_sun3_intr(int irq, void *dummy)
 {
        unsigned short csr = dregs->csr;
        int handled = 0;
@@ -371,7 +371,7 @@ static irqreturn_t scsi_sun3_intr(int irq, void *dummy, struct pt_regs *fp)
        }
 
        if(csr & (CSR_SDB_INT | CSR_DMA_INT)) {
-               NCR5380_intr(irq, dummy, fp);
+               NCR5380_intr(irq, dummy);
                handled = 1;
        }
 
index 8640253d6215051c16d5603d9c818f079f8de621..32c883f1efa1aecbd5f525af8354f552bf5d1e6c 100644 (file)
@@ -326,8 +326,7 @@ static __inline__ unsigned int sym53c416_write(int base, unsigned char *buffer,
        return orig_len - len;
 }
 
-static irqreturn_t sym53c416_intr_handle(int irq, void *dev_id,
-                                       struct pt_regs *regs)
+static irqreturn_t sym53c416_intr_handle(int irq, void *dev_id)
 {
        struct Scsi_Host *dev = dev_id;
        int base = 0;
index 739d3ef46a407d14d1d3a309676a6c1588b182f0..4d78c7e87cca3b34c82796ec4a481024003c2606 100644 (file)
@@ -652,7 +652,7 @@ static int sym53c8xx_queue_command(struct scsi_cmnd *cmd,
 /*
  *  Linux entry point of the interrupt handler.
  */
-static irqreturn_t sym53c8xx_intr(int irq, void *dev_id, struct pt_regs * regs)
+static irqreturn_t sym53c8xx_intr(int irq, void *dev_id)
 {
        unsigned long flags;
        struct sym_hcb *np = (struct sym_hcb *)dev_id;
index 2df6747cb76fb5ce68a410b42ed748513ab5b80f..0b7a70f61e0d973112c251bd74087b635f26c358 100644 (file)
 #include <asm/system.h>
 #include <linux/signal.h>
 #include <linux/sched.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/blkdev.h>
 #include <linux/interrupt.h>
 #include <linux/stat.h>
index 9404ff3d4c79233ff63a471a2f14901d03d167b2..d03aa6ce8fe8afef715018917d257daad01b31ab 100644 (file)
@@ -279,6 +279,10 @@ static void dc390_ResetDevParam(struct dc390_acb* pACB);
 static u32     dc390_laststatus = 0;
 static u8      dc390_adapterCnt = 0;
 
+static int disable_clustering;
+module_param(disable_clustering, int, S_IRUGO);
+MODULE_PARM_DESC(disable_clustering, "If you experience problems with your devices, try setting to 1");
+
 /* Startup values, to be overriden on the commandline */
 static int tmscsim[] = {-2, -2, -2, -2, -2, -2};
 
@@ -696,9 +700,9 @@ dc390_InvalidCmd(struct dc390_acb* pACB)
 
 
 static irqreturn_t __inline__
-DC390_Interrupt(int irq, void *dev_id, struct pt_regs *regs)
+DC390_Interrupt(void *dev_id)
 {
-    struct dc390_acb *pACB = (struct dc390_acb*)dev_id;
+    struct dc390_acb *pACB = dev_id;
     struct dc390_dcb *pDCB;
     struct dc390_srb *pSRB;
     u8  sstatus=0;
@@ -807,12 +811,12 @@ DC390_Interrupt(int irq, void *dev_id, struct pt_regs *regs)
     return IRQ_HANDLED;
 }
 
-static irqreturn_t do_DC390_Interrupt( int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t do_DC390_Interrupt(int irq, void *dev_id)
 {
     irqreturn_t ret;
     DEBUG1(printk (KERN_INFO "DC390: Irq (%i) caught: ", irq));
     /* Locking is done in DC390_Interrupt */
-    ret = DC390_Interrupt(irq, dev_id, regs);
+    ret = DC390_Interrupt(dev_id);
     DEBUG1(printk (".. IRQ returned\n"));
     return ret;
 }
@@ -2299,7 +2303,7 @@ static struct scsi_host_template driver_template = {
        .this_id                = 7,
        .sg_tablesize           = SG_ALL,
        .cmd_per_lun            = 1,
-       .use_clustering         = DISABLE_CLUSTERING,
+       .use_clustering         = ENABLE_CLUSTERING,
 };
 
 /***********************************************************************
@@ -2525,6 +2529,8 @@ static int __devinit dc390_probe_one(struct pci_dev *pdev,
        pci_set_master(pdev);
 
        error = -ENOMEM;
+       if (disable_clustering)
+               driver_template.use_clustering = DISABLE_CLUSTERING;
        shost = scsi_host_alloc(&driver_template, sizeof(struct dc390_acb));
        if (!shost)
                goto out_disable_device;
@@ -2660,6 +2666,10 @@ static struct pci_driver dc390_driver = {
 
 static int __init dc390_module_init(void)
 {
+       if (!disable_clustering)
+               printk(KERN_INFO "DC390: clustering now enabled by default. If you get problems load\n"
+                      "\twith \"disable_clustering=1\" and report to maintainers\n");
+
        if (tmscsim[0] == -1 || tmscsim[0] > 15) {
                tmscsim[0] = 7;
                tmscsim[1] = 4;
index 57449611e714ec86e44fd02c02c28044a248cb37..3de08a15de4067bde88d8384a20a0409f065839b 100644 (file)
@@ -634,7 +634,7 @@ static unsigned long io_port[] = {
 #define H2DEV(x) cpu_to_le32(x)
 #define DEV2H(x) le32_to_cpu(x)
 
-static irqreturn_t do_interrupt_handler(int, void *, struct pt_regs *);
+static irqreturn_t do_interrupt_handler(int, void *);
 static void flush_dev(struct scsi_device *, unsigned long, unsigned int, unsigned int);
 static int do_trace = FALSE;
 static int setup_done = FALSE;
@@ -1932,8 +1932,7 @@ none:
    return IRQ_NONE;
 }
 
-static irqreturn_t do_interrupt_handler(int irq, void *shap,
-                                        struct pt_regs *regs) {
+static irqreturn_t do_interrupt_handler(int irq, void *shap) {
    unsigned int j;
    unsigned long spin_flags;
    irqreturn_t ret;
index 0372aa9fa1903e53e86554a5b264d100f5ea59e8..56906aba5ee351ffce54935f69acaaae7a19c5a7 100644 (file)
@@ -287,8 +287,8 @@ static const unsigned short ultrastor_ports_14f[] = {
 };
 #endif
 
-static void ultrastor_interrupt(int, void *, struct pt_regs *);
-static irqreturn_t do_ultrastor_interrupt(int, void *, struct pt_regs *);
+static void ultrastor_interrupt(void *);
+static irqreturn_t do_ultrastor_interrupt(int, void *);
 static inline void build_sg_list(struct mscp *, struct scsi_cmnd *SCpnt);
 
 
@@ -893,7 +893,7 @@ static int ultrastor_abort(struct scsi_cmnd *SCpnt)
        
        spin_lock_irqsave(host->host_lock, flags);
        /* FIXME: Ewww... need to think about passing host around properly */
-       ultrastor_interrupt(0, NULL, NULL);
+       ultrastor_interrupt(NULL);
        spin_unlock_irqrestore(host->host_lock, flags);
        return SUCCESS;
       }
@@ -1039,7 +1039,7 @@ int ultrastor_biosparam(struct scsi_device *sdev, struct block_device *bdev,
     return 0;
 }
 
-static void ultrastor_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static void ultrastor_interrupt(void *dev_id)
 {
     unsigned int status;
 #if ULTRASTOR_MAX_CMDS > 1
@@ -1171,14 +1171,13 @@ static void ultrastor_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 #endif
 }
 
-static irqreturn_t do_ultrastor_interrupt(int irq, void *dev_id,
-                                               struct pt_regs *regs)
+static irqreturn_t do_ultrastor_interrupt(int irq, void *dev_id)
 {
     unsigned long flags;
     struct Scsi_Host *dev = dev_id;
     
     spin_lock_irqsave(dev->host_lock, flags);
-    ultrastor_interrupt(irq, dev_id, regs);
+    ultrastor_interrupt(dev_id);
     spin_unlock_irqrestore(dev->host_lock, flags);
     return IRQ_HANDLED;
 }
index a0b61af48f1c422532609b367e6c131ea258225f..30be76514c43c50e97942d58d390758bf612c7d7 100644 (file)
 #include <linux/blkdev.h>
 #include <linux/init.h>
 #include <linux/stat.h>
+#include <linux/io.h>
 
 #include <asm/system.h>
 #include <asm/dma.h>
-#include <asm/io.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
@@ -998,7 +998,7 @@ static int make_code(unsigned hosterr, unsigned scsierr)
 #define wd7000_intr_ack(host)   outb (0, host->iobase + ASC_INTR_ACK)
 
 
-static irqreturn_t wd7000_intr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t wd7000_intr(int irq, void *dev_id)
 {
        Adapter *host = (Adapter *) dev_id;
        int flag, icmb, errstatus, icmb_status;
index 76d83ade9857ea4efc696a123538d5df7d581961..6a1a568ca6498b932c89c5eaeed32142885ebf02 100644 (file)
@@ -85,7 +85,7 @@ static void serial21285_enable_ms(struct uart_port *port)
 {
 }
 
-static irqreturn_t serial21285_rx_chars(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t serial21285_rx_chars(int irq, void *dev_id)
 {
        struct uart_port *port = dev_id;
        struct tty_struct *tty = port->info->tty;
@@ -123,7 +123,7 @@ static irqreturn_t serial21285_rx_chars(int irq, void *dev_id, struct pt_regs *r
        return IRQ_HANDLED;
 }
 
-static irqreturn_t serial21285_tx_chars(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t serial21285_tx_chars(int irq, void *dev_id)
 {
        struct uart_port *port = dev_id;
        struct circ_buf *xmit = &port->info->xmit;
index bac853c5abb565dfeb11cc32ed910191f956a9c9..9b8b585513ec5aaeccf108f0d0a0498b174a7ea3 100644 (file)
@@ -275,8 +275,7 @@ static void status_handle(struct m68k_serial *info, unsigned short status)
        return;
 }
 
-static void receive_chars(struct m68k_serial *info, struct pt_regs *regs,
-                         unsigned short rx)
+static void receive_chars(struct m68k_serial *info, unsigned short rx)
 {
        struct tty_struct *tty = info->tty;
        m68328_uart *uart = &uart_addr[info->line];
@@ -377,7 +376,7 @@ clear_and_return:
 /*
  * This is the serial driver's generic interrupt routine
  */
-irqreturn_t rs_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+irqreturn_t rs_interrupt(int irq, void *dev_id)
 {
        struct m68k_serial * info;
        m68328_uart *uart;
@@ -394,10 +393,10 @@ irqreturn_t rs_interrupt(int irq, void *dev_id, struct pt_regs * regs)
 #ifdef USE_INTS
        tx = uart->utx.w;
 
-       if (rx & URX_DATA_READY) receive_chars(info, regs, rx);
+       if (rx & URX_DATA_READY) receive_chars(info, rx);
        if (tx & UTX_TX_AVAIL)   transmit_chars(info);
 #else
-       receive_chars(info, regs, rx);          
+       receive_chars(info, rx);                
 #endif
        return IRQ_HANDLED;
 }
index 1b299e8c57cdf7071b5d155aa556d4ef05d51b29..634ecca36a7737d19397ea9b32d2d6636a6fc65a 100644 (file)
@@ -612,7 +612,7 @@ static _INLINE_ void check_modem_status(struct async_struct *info)
  * This is the serial driver's interrupt routine for a single port
  */
 /* static void rs_360_interrupt(void *dev_id) */ /* until and if we start servicing irqs here */
-static void rs_360_interrupt(int vec, void *dev_id, struct pt_regs *fp)
+static void rs_360_interrupt(int vec, void *dev_id)
 {
        u_char  events;
        int     idx;
@@ -620,7 +620,7 @@ static void rs_360_interrupt(int vec, void *dev_id, struct pt_regs *fp)
        volatile struct smc_regs *smcp;
        volatile struct scc_regs *sccp;
        
-       info = (ser_info_t *)dev_id;
+       info = dev_id;
 
        idx = PORT_NUM(info->state->smc_scc_num);
        if (info->state->smc_scc_num & NUM_IS_SCC) {
index cc2a205d42300af96e6f0ecfda63172c5e151425..e34bd03cfce738c4d82ff34aae9718af1e53332d 100644 (file)
@@ -1175,7 +1175,7 @@ static void serial8250_enable_ms(struct uart_port *port)
 }
 
 static void
-receive_chars(struct uart_8250_port *up, int *status, struct pt_regs *regs)
+receive_chars(struct uart_8250_port *up, int *status)
 {
        struct tty_struct *tty = up->port.info->tty;
        unsigned char ch, lsr = *status;
@@ -1233,7 +1233,7 @@ receive_chars(struct uart_8250_port *up, int *status, struct pt_regs *regs)
                        else if (lsr & UART_LSR_FE)
                                flag = TTY_FRAME;
                }
-               if (uart_handle_sysrq_char(&up->port, ch, regs))
+               if (uart_handle_sysrq_char(&up->port, ch))
                        goto ignore_char;
 
                uart_insert_char(&up->port, lsr, UART_LSR_OE, ch, flag);
@@ -1309,7 +1309,7 @@ static unsigned int check_modem_status(struct uart_8250_port *up)
  * This handles the interrupt from one port.
  */
 static inline void
-serial8250_handle_port(struct uart_8250_port *up, struct pt_regs *regs)
+serial8250_handle_port(struct uart_8250_port *up)
 {
        unsigned int status;
 
@@ -1320,7 +1320,7 @@ serial8250_handle_port(struct uart_8250_port *up, struct pt_regs *regs)
        DEBUG_INTR("status = %x...", status);
 
        if (status & UART_LSR_DR)
-               receive_chars(up, &status, regs);
+               receive_chars(up, &status);
        check_modem_status(up);
        if (status & UART_LSR_THRE)
                transmit_chars(up);
@@ -1342,7 +1342,7 @@ serial8250_handle_port(struct uart_8250_port *up, struct pt_regs *regs)
  * This means we need to loop through all ports. checking that they
  * don't have an interrupt pending.
  */
-static irqreturn_t serial8250_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t serial8250_interrupt(int irq, void *dev_id)
 {
        struct irq_info *i = dev_id;
        struct list_head *l, *end = NULL;
@@ -1361,7 +1361,7 @@ static irqreturn_t serial8250_interrupt(int irq, void *dev_id, struct pt_regs *r
 
                iir = serial_in(up, UART_IIR);
                if (!(iir & UART_IIR_NO_INT)) {
-                       serial8250_handle_port(up, regs);
+                       serial8250_handle_port(up);
 
                        handled = 1;
 
@@ -1461,7 +1461,7 @@ static void serial8250_timeout(unsigned long data)
 
        iir = serial_in(up, UART_IIR);
        if (!(iir & UART_IIR_NO_INT))
-               serial8250_handle_port(up, NULL);
+               serial8250_handle_port(up);
 
        timeout = up->port.timeout;
        timeout = timeout > 6 ? (timeout / 2 - 2) : 1;
index b0d502622d9452c9cdfa091d282d36e612104205..0b71e7d18903ddd6d36e1d859cde23beee02c891 100644 (file)
@@ -767,37 +767,37 @@ config SERIAL_CPM_SCC1
        bool "Support for SCC1 serial port"
        depends on SERIAL_CPM=y
        help
-         Select this option to use SCC1 as a serial port
+         Select this option to use SCC1 as a serial port
 
 config SERIAL_CPM_SCC2
        bool "Support for SCC2 serial port"
        depends on SERIAL_CPM=y
        help
-         Select this option to use SCC2 as a serial port
+         Select this option to use SCC2 as a serial port
 
 config SERIAL_CPM_SCC3
        bool "Support for SCC3 serial port"
        depends on SERIAL_CPM=y
        help
-         Select this option to use SCC3 as a serial port
+         Select this option to use SCC3 as a serial port
 
 config SERIAL_CPM_SCC4
        bool "Support for SCC4 serial port"
        depends on SERIAL_CPM=y
        help
-         Select this option to use SCC4 as a serial port
+         Select this option to use SCC4 as a serial port
 
 config SERIAL_CPM_SMC1
        bool "Support for SMC1 serial port"
        depends on SERIAL_CPM=y
        help
-         Select this option to use SMC1 as a serial port
+         Select this option to use SMC1 as a serial port
 
 config SERIAL_CPM_SMC2
        bool "Support for SMC2 serial port"
        depends on SERIAL_CPM=y
        help
-         Select this option to use SMC2 as a serial port
+         Select this option to use SMC2 as a serial port
 
 config SERIAL_SGI_L1_CONSOLE
        bool "SGI Altix L1 serial console support"
index 7311d8487c9693f8e9b980faad8a8ee8210ee970..4213fabc62bf864a033aca5ff1c5b120b830cf57 100644 (file)
@@ -111,12 +111,7 @@ static void pl010_enable_ms(struct uart_port *port)
        writel(cr, port->membase + UART010_CR);
 }
 
-static void
-#ifdef SUPPORT_SYSRQ
-pl010_rx_chars(struct uart_port *port, struct pt_regs *regs)
-#else
-pl010_rx_chars(struct uart_port *port)
-#endif
+static void pl010_rx_chars(struct uart_port *port)
 {
        struct tty_struct *tty = port->info->tty;
        unsigned int status, ch, flag, rsr, max_count = 256;
@@ -156,7 +151,7 @@ pl010_rx_chars(struct uart_port *port)
                                flag = TTY_FRAME;
                }
 
-               if (uart_handle_sysrq_char(port, ch, regs))
+               if (uart_handle_sysrq_char(port, ch))
                        goto ignore_char;
 
                uart_insert_char(port, rsr, UART01x_RSR_OE, ch, flag);
@@ -227,7 +222,7 @@ static void pl010_modem_status(struct uart_port *port)
        wake_up_interruptible(&uap->port.info->delta_msr_wait);
 }
 
-static irqreturn_t pl010_int(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t pl010_int(int irq, void *dev_id)
 {
        struct uart_port *port = dev_id;
        unsigned int status, pass_counter = AMBA_ISR_PASS_LIMIT;
@@ -239,11 +234,7 @@ static irqreturn_t pl010_int(int irq, void *dev_id, struct pt_regs *regs)
        if (status) {
                do {
                        if (status & (UART010_IIR_RTIS | UART010_IIR_RIS))
-#ifdef SUPPORT_SYSRQ
-                               pl010_rx_chars(port, regs);
-#else
                                pl010_rx_chars(port);
-#endif
                        if (status & UART010_IIR_MIS)
                                pl010_modem_status(port);
                        if (status & UART010_IIR_TIS)
index a8d7124e84a1a515a97caf514231efb5ae160ee6..d503625730df56dc4334868acba23a33d486e802 100644 (file)
@@ -107,12 +107,7 @@ static void pl011_enable_ms(struct uart_port *port)
        writew(uap->im, uap->port.membase + UART011_IMSC);
 }
 
-static void
-#ifdef SUPPORT_SYSRQ
-pl011_rx_chars(struct uart_amba_port *uap, struct pt_regs *regs)
-#else
-pl011_rx_chars(struct uart_amba_port *uap)
-#endif
+static void pl011_rx_chars(struct uart_amba_port *uap)
 {
        struct tty_struct *tty = uap->port.info->tty;
        unsigned int status, ch, flag, max_count = 256;
@@ -150,7 +145,7 @@ pl011_rx_chars(struct uart_amba_port *uap)
                                flag = TTY_FRAME;
                }
 
-               if (uart_handle_sysrq_char(&uap->port, ch & 255, regs))
+               if (uart_handle_sysrq_char(&uap->port, ch & 255))
                        goto ignore_char;
 
                uart_insert_char(&uap->port, ch, UART011_DR_OE, ch, flag);
@@ -218,7 +213,7 @@ static void pl011_modem_status(struct uart_amba_port *uap)
        wake_up_interruptible(&uap->port.info->delta_msr_wait);
 }
 
-static irqreturn_t pl011_int(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t pl011_int(int irq, void *dev_id)
 {
        struct uart_amba_port *uap = dev_id;
        unsigned int status, pass_counter = AMBA_ISR_PASS_LIMIT;
@@ -234,11 +229,7 @@ static irqreturn_t pl011_int(int irq, void *dev_id, struct pt_regs *regs)
                               uap->port.membase + UART011_ICR);
 
                        if (status & (UART011_RTIS|UART011_RXIS))
-#ifdef SUPPORT_SYSRQ
-                               pl011_rx_chars(uap, regs);
-#else
                                pl011_rx_chars(uap);
-#endif
                        if (status & (UART011_DSRMIS|UART011_DCDMIS|
                                      UART011_CTSMIS|UART011_RIMIS))
                                pl011_modem_status(uap);
index 955c46da580041de800d8ced1cc5c23af2b60dda..391a1f4167a4f38819997c5a80cb12607e788fa6 100644 (file)
@@ -249,7 +249,7 @@ static void atmel_break_ctl(struct uart_port *port, int break_state)
 /*
  * Characters received (called from interrupt handler)
  */
-static void atmel_rx_chars(struct uart_port *port, struct pt_regs *regs)
+static void atmel_rx_chars(struct uart_port *port)
 {
        struct tty_struct *tty = port->info->tty;
        unsigned int status, ch, flg;
@@ -291,7 +291,7 @@ static void atmel_rx_chars(struct uart_port *port, struct pt_regs *regs)
                                flg = TTY_FRAME;
                }
 
-               if (uart_handle_sysrq_char(port, ch, regs))
+               if (uart_handle_sysrq_char(port, ch))
                        goto ignore_char;
 
                uart_insert_char(port, status, ATMEL_US_OVRE, ch, flg);
@@ -339,7 +339,7 @@ static void atmel_tx_chars(struct uart_port *port)
 /*
  * Interrupt handler
  */
-static irqreturn_t atmel_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t atmel_interrupt(int irq, void *dev_id)
 {
        struct uart_port *port = dev_id;
        struct atmel_uart_port *atmel_port = (struct atmel_uart_port *) port;
@@ -350,7 +350,7 @@ static irqreturn_t atmel_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        while (pending) {
                /* Interrupt receive */
                if (pending & ATMEL_US_RXRDY)
-                       atmel_rx_chars(port, regs);
+                       atmel_rx_chars(port);
 
                // TODO: All reads to CSR will clear these interrupts!
                if (pending & ATMEL_US_RIIC) port->icount.rng++;
index f27d852ce50db48947e6343a958ac261eb3ffc41..598012714882751888ede1f3dda4f11941c94680 100644 (file)
@@ -93,7 +93,7 @@ static void clps711xuart_enable_ms(struct uart_port *port)
 {
 }
 
-static irqreturn_t clps711xuart_int_rx(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t clps711xuart_int_rx(int irq, void *dev_id)
 {
        struct uart_port *port = dev_id;
        struct tty_struct *tty = port->info->tty;
@@ -131,7 +131,7 @@ static irqreturn_t clps711xuart_int_rx(int irq, void *dev_id, struct pt_regs *re
 #endif
                }
 
-               if (uart_handle_sysrq_char(port, ch, regs))
+               if (uart_handle_sysrq_char(port, ch))
                        goto ignore_char;
 
                /*
@@ -147,7 +147,7 @@ static irqreturn_t clps711xuart_int_rx(int irq, void *dev_id, struct pt_regs *re
        return IRQ_HANDLED;
 }
 
-static irqreturn_t clps711xuart_int_tx(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t clps711xuart_int_tx(int irq, void *dev_id)
 {
        struct uart_port *port = dev_id;
        struct circ_buf *xmit = &port->info->xmit;
index a0d6136deb9b0d47a8af0e970dd0b891876e7a5b..0abb544ae63dbc34a7acc19eaad39c84e5152a17 100644 (file)
@@ -248,7 +248,7 @@ static void cpm_uart_break_ctl(struct uart_port *port, int break_state)
 /*
  * Transmit characters, refill buffer descriptor, if possible
  */
-static void cpm_uart_int_tx(struct uart_port *port, struct pt_regs *regs)
+static void cpm_uart_int_tx(struct uart_port *port)
 {
        pr_debug("CPM uart[%d]:TX INT\n", port->line);
 
@@ -258,7 +258,7 @@ static void cpm_uart_int_tx(struct uart_port *port, struct pt_regs *regs)
 /*
  * Receive characters
  */
-static void cpm_uart_int_rx(struct uart_port *port, struct pt_regs *regs)
+static void cpm_uart_int_rx(struct uart_port *port)
 {
        int i;
        unsigned char ch, *cp;
@@ -304,7 +304,7 @@ static void cpm_uart_int_rx(struct uart_port *port, struct pt_regs *regs)
                        if (status &
                            (BD_SC_BR | BD_SC_FR | BD_SC_PR | BD_SC_OV))
                                goto handle_error;
-                       if (uart_handle_sysrq_char(port, ch, regs))
+                       if (uart_handle_sysrq_char(port, ch))
                                continue;
 
                      error_return:
@@ -373,7 +373,7 @@ static void cpm_uart_int_rx(struct uart_port *port, struct pt_regs *regs)
 /*
  * Asynchron mode interrupt handler
  */
-static irqreturn_t cpm_uart_int(int irq, void *data, struct pt_regs *regs)
+static irqreturn_t cpm_uart_int(int irq, void *data)
 {
        u8 events;
        struct uart_port *port = (struct uart_port *)data;
@@ -389,18 +389,18 @@ static irqreturn_t cpm_uart_int(int irq, void *data, struct pt_regs *regs)
                if (events & SMCM_BRKE)
                        uart_handle_break(port);
                if (events & SMCM_RX)
-                       cpm_uart_int_rx(port, regs);
+                       cpm_uart_int_rx(port);
                if (events & SMCM_TX)
-                       cpm_uart_int_tx(port, regs);
+                       cpm_uart_int_tx(port);
        } else {
                events = sccp->scc_scce;
                sccp->scc_scce = events;
                if (events & UART_SCCM_BRKE)
                        uart_handle_break(port);
                if (events & UART_SCCM_RX)
-                       cpm_uart_int_rx(port, regs);
+                       cpm_uart_int_rx(port);
                if (events & UART_SCCM_TX)
-                       cpm_uart_int_tx(port, regs);
+                       cpm_uart_int_tx(port);
        }
        return (events) ? IRQ_HANDLED : IRQ_NONE;
 }
index 9851d9eff022a6e655db1011fa1f93cbd8cd03b4..7a24e53546c71501c4017cf231a6615ce57ab8c2 100644 (file)
@@ -2346,7 +2346,7 @@ start_receive(struct e100_serial *info)
 */
 
 static irqreturn_t
-tr_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+tr_interrupt(int irq, void *dev_id)
 {
        struct e100_serial *info;
        unsigned long ireg;
@@ -2395,7 +2395,7 @@ tr_interrupt(int irq, void *dev_id, struct pt_regs * regs)
 /* dma input channel interrupt handler */
 
 static irqreturn_t
-rec_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+rec_interrupt(int irq, void *dev_id)
 {
        struct e100_serial *info;
        unsigned long ireg;
@@ -3054,7 +3054,7 @@ static void handle_ser_tx_interrupt(struct e100_serial *info)
  * ser_int duration: just sending: 8-15 us normally, up to 73 us
  */
 static irqreturn_t
-ser_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+ser_interrupt(int irq, void *dev_id)
 {
        static volatile int tx_started = 0;
        struct e100_serial *info;
index 8a98aae80e228ffd8afc2c57b868b8394aa7d765..53662b33b84164c9f023033a3cdbb7d4dcd5b429 100644 (file)
@@ -339,7 +339,7 @@ static inline void check_modem_status(struct dz_port *dport)
  * It deals with the multiple ports.
  * ------------------------------------------------------------
  */
-static irqreturn_t dz_interrupt(int irq, void *dev, struct pt_regs *regs)
+static irqreturn_t dz_interrupt(int irq, void *dev)
 {
        struct dz_port *dport;
        unsigned short status;
index a3c00a2521497c7c326678853d32179de40e4e96..8aa0f641866b3622338b21542e9638ce3a101e26 100644 (file)
@@ -844,8 +844,7 @@ static void process_interrupt(u16 port_int_reg,
        spin_unlock(&icom_port->uart_port.lock);
 }
 
-static irqreturn_t icom_interrupt(int irq, void *dev_id,
-                                 struct pt_regs *regs)
+static irqreturn_t icom_interrupt(int irq, void *dev_id)
 {
        void __iomem * int_reg;
        u32 adapter_interrupts;
index 4a142d6b8f3890aa11c0bc16b3978806e42bb539..ee5c782597dd82cac10689462f3322779ff5f29d 100644 (file)
@@ -182,7 +182,7 @@ static void imx_start_tx(struct uart_port *port)
                imx_transmit_buffer(sport);
 }
 
-static irqreturn_t imx_rtsint(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t imx_rtsint(int irq, void *dev_id)
 {
        struct imx_port *sport = (struct imx_port *)dev_id;
        unsigned int val = USR1((u32)sport->port.membase)&USR1_RTSS;
@@ -198,7 +198,7 @@ static irqreturn_t imx_rtsint(int irq, void *dev_id, struct pt_regs *regs)
        return IRQ_HANDLED;
 }
 
-static irqreturn_t imx_txint(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t imx_txint(int irq, void *dev_id)
 {
        struct imx_port *sport = (struct imx_port *)dev_id;
        struct circ_buf *xmit = &sport->port.info->xmit;
@@ -227,7 +227,7 @@ out:
        return IRQ_HANDLED;
 }
 
-static irqreturn_t imx_rxint(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t imx_rxint(int irq, void *dev_id)
 {
        struct imx_port *sport = dev_id;
        unsigned int rx,flg,ignored = 0;
@@ -248,7 +248,7 @@ static irqreturn_t imx_rxint(int irq, void *dev_id, struct pt_regs *regs)
                }
 
                if (uart_handle_sysrq_char
-                           (&sport->port, (unsigned char)rx, regs))
+                           (&sport->port, (unsigned char)rx))
                        goto ignore_char;
 
                if( rx & (URXD_PRERR | URXD_OVRRUN | URXD_FRMERR) )
index 8097cd91f16b5869d6c42af6ce504f629c70f82a..2308d26c862987a24c1a055cbcb27af325216036 100644 (file)
@@ -1428,13 +1428,12 @@ static int receive_chars(struct uart_port *the_port)
  * @is : submodule
  * @idd: driver data
  * @pending: interrupts to handle
- * @regs: pt_regs
  */
 
 static int inline
 ioc3uart_intr_one(struct ioc3_submodule *is,
                        struct ioc3_driver_data *idd,
-                       unsigned int pending, struct pt_regs *regs)
+                       unsigned int pending)
 {
        int port_num = GET_PORT_FROM_SIO_IR(pending);
        struct port_hooks *hooks;
@@ -1628,13 +1627,12 @@ ioc3uart_intr_one(struct ioc3_submodule *is,
  * @is : submodule
  * @idd: driver data
  * @pending: interrupts to handle
- * @regs: pt_regs
  *
  */
 
 static int ioc3uart_intr(struct ioc3_submodule *is,
                        struct ioc3_driver_data *idd,
-                       unsigned int pending, struct pt_regs *regs)
+                       unsigned int pending)
 {
        int ret = 0;
 
@@ -1644,9 +1642,9 @@ static int ioc3uart_intr(struct ioc3_submodule *is,
         */
 
        if (pending & SIO_IR_SA)
-               ret |= ioc3uart_intr_one(is, idd, pending & SIO_IR_SA, regs);
+               ret |= ioc3uart_intr_one(is, idd, pending & SIO_IR_SA);
        if (pending & SIO_IR_SB)
-               ret |= ioc3uart_intr_one(is, idd, pending & SIO_IR_SB, regs);
+               ret |= ioc3uart_intr_one(is, idd, pending & SIO_IR_SB);
 
        return ret;
 }
index 5ec4716c99bf30e5bd16bb271e45aa1f38207343..ff4fa25f9fd12cdac405130e096c2200d9eb40fc 100644 (file)
@@ -987,10 +987,9 @@ intr_connect(struct ioc4_soft *soft, int type,
  * ioc4_intr - Top level IOC4 interrupt handler.
  * @irq: irq value
  * @arg: handler arg
- * @regs: registers
  */
 
-static irqreturn_t ioc4_intr(int irq, void *arg, struct pt_regs *regs)
+static irqreturn_t ioc4_intr(int irq, void *arg)
 {
        struct ioc4_soft *soft;
        uint32_t this_ir, this_mir;
@@ -2936,7 +2935,7 @@ static void __devexit ioc4_serial_exit(void)
        uart_unregister_driver(&ioc4_uart_rs422);
 }
 
-module_init(ioc4_serial_init);
+late_initcall(ioc4_serial_init); /* Call only after tty init is done */
 module_exit(ioc4_serial_exit);
 
 MODULE_AUTHOR("Pat Gefre - Silicon Graphics Inc. (SGI) <pfg@sgi.com>");
index dbf13c03a1bbceac17df1de52d1608f8812ceac0..dca6c1bde8f9f5180ce28c08293b6e3da4103fdd 100644 (file)
@@ -252,8 +252,7 @@ static void ip22zilog_maybe_update_regs(struct uart_ip22zilog_port *up,
 }
 
 static void ip22zilog_receive_chars(struct uart_ip22zilog_port *up,
-                                  struct zilog_channel *channel,
-                                  struct pt_regs *regs)
+                                  struct zilog_channel *channel)
 {
        struct tty_struct *tty = up->port.info->tty;    /* XXX info==NULL? */
 
@@ -319,7 +318,7 @@ static void ip22zilog_receive_chars(struct uart_ip22zilog_port *up,
                        else if (r1 & CRC_ERR)
                                flag = TTY_FRAME;
                }
-               if (uart_handle_sysrq_char(&up->port, ch, regs))
+               if (uart_handle_sysrq_char(&up->port, ch))
                        goto next_char;
 
                if (up->port.ignore_status_mask == 0xff ||
@@ -339,8 +338,7 @@ static void ip22zilog_receive_chars(struct uart_ip22zilog_port *up,
 }
 
 static void ip22zilog_status_handle(struct uart_ip22zilog_port *up,
-                                  struct zilog_channel *channel,
-                                  struct pt_regs *regs)
+                                  struct zilog_channel *channel)
 {
        unsigned char status;
 
@@ -443,7 +441,7 @@ ack_tx_int:
        ZS_WSYNC(channel);
 }
 
-static irqreturn_t ip22zilog_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t ip22zilog_interrupt(int irq, void *dev_id)
 {
        struct uart_ip22zilog_port *up = dev_id;
 
@@ -462,9 +460,9 @@ static irqreturn_t ip22zilog_interrupt(int irq, void *dev_id, struct pt_regs *re
                        ZS_WSYNC(channel);
 
                        if (r3 & CHARxIP)
-                               ip22zilog_receive_chars(up, channel, regs);
+                               ip22zilog_receive_chars(up, channel);
                        if (r3 & CHAEXT)
-                               ip22zilog_status_handle(up, channel, regs);
+                               ip22zilog_status_handle(up, channel);
                        if (r3 & CHATxIP)
                                ip22zilog_transmit_chars(up, channel);
                }
@@ -481,9 +479,9 @@ static irqreturn_t ip22zilog_interrupt(int irq, void *dev_id, struct pt_regs *re
                        ZS_WSYNC(channel);
 
                        if (r3 & CHBRxIP)
-                               ip22zilog_receive_chars(up, channel, regs);
+                               ip22zilog_receive_chars(up, channel);
                        if (r3 & CHBEXT)
-                               ip22zilog_status_handle(up, channel, regs);
+                               ip22zilog_status_handle(up, channel);
                        if (r3 & CHBTxIP)
                                ip22zilog_transmit_chars(up, channel);
                }
index 043f50b1d10c73934edc9b749bb834c199087839..12c934a1f2742c88a7b80e1b3ed00588d73e521b 100644 (file)
@@ -99,7 +99,7 @@ struct jsm_channel;
  * Per board operations structure                                      *
  ************************************************************************/
 struct board_ops {
-       irqreturn_t (*intr) (int irq, void *voidbrd, struct pt_regs *regs);
+       irq_handler_t intr;
        void (*uart_init) (struct jsm_channel *ch);
        void (*uart_off) (struct jsm_channel *ch);
        void (*param) (struct jsm_channel *ch);
index a5fc589d6ef5d8f3cf015fb692e8d539bfe5bafb..8be8da37f629b86418d6d9a4ee671cbc8c975878 100644 (file)
@@ -1114,9 +1114,9 @@ static void neo_param(struct jsm_channel *ch)
  *
  * Neo specific interrupt handler.
  */
-static irqreturn_t neo_intr(int irq, void *voidbrd, struct pt_regs *regs)
+static irqreturn_t neo_intr(int irq, void *voidbrd)
 {
-       struct jsm_board *brd = (struct jsm_board *) voidbrd;
+       struct jsm_board *brd = voidbrd;
        struct jsm_channel *ch;
        int port = 0;
        int type = 0;
index 28c9ce6f0bdc52023816e1e7dfc555debd08327f..7656a35f5e2f34fe06b3c0d6898e9e99d555de6f 100644 (file)
@@ -323,8 +323,7 @@ static void m32r_sio_enable_ms(struct uart_port *port)
        serial_out(up, UART_IER, up->ier);
 }
 
-static void receive_chars(struct uart_sio_port *up, int *status,
-                         struct pt_regs *regs)
+static void receive_chars(struct uart_sio_port *up, int *status)
 {
        struct tty_struct *tty = up->port.info->tty;
        unsigned char ch;
@@ -378,7 +377,7 @@ static void receive_chars(struct uart_sio_port *up, int *status,
                        else if (*status & UART_LSR_FE)
                                flag = TTY_FRAME;
                }
-               if (uart_handle_sysrq_char(&up->port, ch, regs))
+               if (uart_handle_sysrq_char(&up->port, ch))
                        goto ignore_char;
                if ((*status & up->port.ignore_status_mask) == 0)
                        tty_insert_flip_char(tty, ch, flag);
@@ -439,12 +438,12 @@ static void transmit_chars(struct uart_sio_port *up)
  * This handles the interrupt from one port.
  */
 static inline void m32r_sio_handle_port(struct uart_sio_port *up,
-       unsigned int status, struct pt_regs *regs)
+       unsigned int status)
 {
        DEBUG_INTR("status = %x...", status);
 
        if (status & 0x04)
-               receive_chars(up, &status, regs);
+               receive_chars(up, &status);
        if (status & 0x01)
                transmit_chars(up);
 }
@@ -463,8 +462,7 @@ static inline void m32r_sio_handle_port(struct uart_sio_port *up,
  * This means we need to loop through all ports. checking that they
  * don't have an interrupt pending.
  */
-static irqreturn_t m32r_sio_interrupt(int irq, void *dev_id,
-       struct pt_regs *regs)
+static irqreturn_t m32r_sio_interrupt(int irq, void *dev_id)
 {
        struct irq_info *i = dev_id;
        struct list_head *l, *end = NULL;
@@ -492,7 +490,7 @@ static irqreturn_t m32r_sio_interrupt(int irq, void *dev_id,
                sts = sio_in(up, SIOSTS);
                if (sts & 0x5) {
                        spin_lock(&up->port.lock);
-                       m32r_sio_handle_port(up, sts, regs);
+                       m32r_sio_handle_port(up, sts);
                        spin_unlock(&up->port.lock);
 
                        end = NULL;
@@ -592,7 +590,7 @@ static void m32r_sio_timeout(unsigned long data)
        sts = sio_in(up, SIOSTS);
        if (sts & 0x5) {
                spin_lock(&up->port.lock);
-               m32r_sio_handle_port(up, sts, NULL);
+               m32r_sio_handle_port(up, sts);
                spin_unlock(&up->port.lock);
        }
 
index 00d7859c167ec7c246c885cc918e2932cd1df69e..aee1b31f1a1c4c6f3456694ccf7a8272b80744a8 100644 (file)
@@ -385,7 +385,7 @@ static inline void transmit_chars(struct mcf_serial *info)
 /*
  * This is the serial driver's generic interrupt routine
  */
-irqreturn_t mcfrs_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t mcfrs_interrupt(int irq, void *dev_id)
 {
        struct mcf_serial       *info;
        unsigned char           isr;
index dbad0e31e005864cb02c72b9f293ecbc11e906d5..4f80c5b4a7533590ad6a51a22708d868fb43fdec 100644 (file)
@@ -85,7 +85,7 @@ static struct uart_port mpc52xx_uart_ports[MPC52xx_PSC_MAXNUM];
 
 
 /* Forward declaration of the interruption handling routine */
-static irqreturn_t mpc52xx_uart_int(int irq,void *dev_id,struct pt_regs *regs);
+static irqreturn_t mpc52xx_uart_int(int irq,void *dev_id);
 
 
 /* Simple macro to test if a port is console or not. This one is taken
@@ -410,7 +410,7 @@ static struct uart_ops mpc52xx_uart_ops = {
 /* ======================================================================== */
        
 static inline int
-mpc52xx_uart_int_rx_chars(struct uart_port *port, struct pt_regs *regs)
+mpc52xx_uart_int_rx_chars(struct uart_port *port)
 {
        struct tty_struct *tty = port->info->tty;
        unsigned char ch, flag;
@@ -425,7 +425,7 @@ mpc52xx_uart_int_rx_chars(struct uart_port *port, struct pt_regs *regs)
 
                /* Handle sysreq char */
 #ifdef SUPPORT_SYSRQ
-               if (uart_handle_sysrq_char(port, ch, regs)) {
+               if (uart_handle_sysrq_char(port, ch)) {
                        port->sysrq = 0;
                        continue;
                }
@@ -510,21 +510,13 @@ mpc52xx_uart_int_tx_chars(struct uart_port *port)
 }
 
 static irqreturn_t 
-mpc52xx_uart_int(int irq, void *dev_id, struct pt_regs *regs)
+mpc52xx_uart_int(int irq, void *dev_id)
 {
-       struct uart_port *port = (struct uart_port *) dev_id;
+       struct uart_port *port = dev_id;
        unsigned long pass = ISR_PASS_LIMIT;
        unsigned int keepgoing;
        unsigned short status;
        
-       if ( irq != port->irq ) {
-               printk( KERN_WARNING
-                       "mpc52xx_uart_int : " \
-                       "Received wrong int %d. Waiting for %d\n",
-                      irq, port->irq);
-               return IRQ_NONE;
-       }
-       
        spin_lock(&port->lock);
        
        /* While we have stuff to do, we continue */
@@ -539,7 +531,7 @@ mpc52xx_uart_int(int irq, void *dev_id, struct pt_regs *regs)
                /* Do we need to receive chars ? */
                /* For this RX interrupts must be on and some chars waiting */
                if ( status & MPC52xx_PSC_IMR_RXRDY )
-                       keepgoing |= mpc52xx_uart_int_rx_chars(port, regs);
+                       keepgoing |= mpc52xx_uart_int_rx_chars(port);
 
                /* Do we need to send chars ? */
                /* For this, TX must be ready and TX interrupt enabled */
index 704243c9f78a44c2d58f560d1cd4301aaafeb138..8eea69f29989947d3c8ca0f16c08a0ee08f965bc 100644 (file)
@@ -992,7 +992,7 @@ mpsc_make_ready(struct mpsc_port_info *pi)
  */
 
 static inline int
-mpsc_rx_intr(struct mpsc_port_info *pi, struct pt_regs *regs)
+mpsc_rx_intr(struct mpsc_port_info *pi)
 {
        struct mpsc_rx_desc *rxre;
        struct tty_struct *tty = pi->port.info->tty;
@@ -1072,7 +1072,7 @@ mpsc_rx_intr(struct mpsc_port_info *pi, struct pt_regs *regs)
                                flag = TTY_PARITY;
                }
 
-               if (uart_handle_sysrq_char(&pi->port, *bp, regs)) {
+               if (uart_handle_sysrq_char(&pi->port, *bp)) {
                        bp++;
                        bytes_in--;
                        goto next_frame;
@@ -1257,7 +1257,7 @@ mpsc_tx_intr(struct mpsc_port_info *pi)
  * handling those descriptors, we restart the Rx/Tx engines if they're stopped.
  */
 static irqreturn_t
-mpsc_sdma_intr(int irq, void *dev_id, struct pt_regs *regs)
+mpsc_sdma_intr(int irq, void *dev_id)
 {
        struct mpsc_port_info *pi = dev_id;
        ulong iflags;
@@ -1267,7 +1267,7 @@ mpsc_sdma_intr(int irq, void *dev_id, struct pt_regs *regs)
 
        spin_lock_irqsave(&pi->port.lock, iflags);
        mpsc_sdma_intr_ack(pi);
-       if (mpsc_rx_intr(pi, regs))
+       if (mpsc_rx_intr(pi))
                rc = IRQ_HANDLED;
        if (mpsc_tx_intr(pi))
                rc = IRQ_HANDLED;
index aa819d3f8ee51344d58b2939c39f396d4698a058..8ad1b8c5ec5d2427eaeef6baefe217874a1eb6d6 100644 (file)
@@ -230,7 +230,7 @@ static void mux_read(struct uart_port *port)
                                continue;
                }
 
-               if (uart_handle_sysrq_char(port, data & 0xffu, NULL))
+               if (uart_handle_sysrq_char(port, data & 0xffu))
                        continue;
 
                tty_insert_flip_char(tty, data & 0xFF, TTY_NORMAL);
index 7502109d37f09755d9f31dd128e6bcf708e880d9..062bad457b1a6775c5566e6a311a2e09798cb642 100644 (file)
@@ -200,7 +200,7 @@ static void netx_txint(struct uart_port *port)
                uart_write_wakeup(port);
 }
 
-static void netx_rxint(struct uart_port *port, struct pt_regs *regs)
+static void netx_rxint(struct uart_port *port)
 {
        unsigned char rx, flg, status;
        struct tty_struct *tty = port->info->tty;
@@ -235,7 +235,7 @@ static void netx_rxint(struct uart_port *port, struct pt_regs *regs)
                                flg = TTY_FRAME;
                }
 
-               if (uart_handle_sysrq_char(port, rx, regs))
+               if (uart_handle_sysrq_char(port, rx))
                        continue;
 
                uart_insert_char(port, status, SR_OE, rx, flg);
@@ -245,9 +245,9 @@ static void netx_rxint(struct uart_port *port, struct pt_regs *regs)
        return;
 }
 
-static irqreturn_t netx_int(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t netx_int(int irq, void *dev_id)
 {
-       struct uart_port *port = (struct uart_port *)dev_id;
+       struct uart_port *port = dev_id;
        unsigned long flags;
        unsigned char status;
 
@@ -256,7 +256,7 @@ static irqreturn_t netx_int(int irq, void *dev_id, struct pt_regs *regs)
        status = readl(port->membase + UART_IIR) & IIR_MASK;
        while (status) {
                if (status & IIR_RIS)
-                       netx_rxint(port, regs);
+                       netx_rxint(port);
                if (status & IIR_TIS)
                        netx_txint(port);
                if (status & IIR_MIS) {
index a3b99caf80e64a2f379c437ae19c2f59f012eb97..bf9809ed9c0ba72177887be032914008cc5ca490 100644 (file)
@@ -204,8 +204,7 @@ static void pmz_maybe_update_regs(struct uart_pmac_port *uap)
        }
 }
 
-static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap,
-                                           struct pt_regs *regs)
+static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap)
 {
        struct tty_struct *tty = NULL;
        unsigned char ch, r1, drop, error, flag;
@@ -267,7 +266,7 @@ static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap,
                if (uap->port.sysrq) {
                        int swallow;
                        spin_unlock(&uap->port.lock);
-                       swallow = uart_handle_sysrq_char(&uap->port, ch, regs);
+                       swallow = uart_handle_sysrq_char(&uap->port, ch);
                        spin_lock(&uap->port.lock);
                        if (swallow)
                                goto next_char;
@@ -335,7 +334,7 @@ static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap,
        return tty;
 }
 
-static void pmz_status_handle(struct uart_pmac_port *uap, struct pt_regs *regs)
+static void pmz_status_handle(struct uart_pmac_port *uap)
 {
        unsigned char status;
 
@@ -438,7 +437,7 @@ ack_tx_int:
 }
 
 /* Hrm... we register that twice, fixme later.... */
-static irqreturn_t pmz_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t pmz_interrupt(int irq, void *dev_id)
 {
        struct uart_pmac_port *uap = dev_id;
        struct uart_pmac_port *uap_a;
@@ -462,9 +461,9 @@ static irqreturn_t pmz_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                write_zsreg(uap_a, R0, RES_H_IUS);
                zssync(uap_a);          
                        if (r3 & CHAEXT)
-                               pmz_status_handle(uap_a, regs);
+                               pmz_status_handle(uap_a);
                if (r3 & CHARxIP)
-                       tty = pmz_receive_chars(uap_a, regs);
+                       tty = pmz_receive_chars(uap_a);
                        if (r3 & CHATxIP)
                                pmz_transmit_chars(uap_a);
                rc = IRQ_HANDLED;
@@ -482,9 +481,9 @@ static irqreturn_t pmz_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                write_zsreg(uap_b, R0, RES_H_IUS);
                zssync(uap_b);
                        if (r3 & CHBEXT)
-                               pmz_status_handle(uap_b, regs);
+                               pmz_status_handle(uap_b);
                        if (r3 & CHBRxIP)
-                               tty = pmz_receive_chars(uap_b, regs);
+                               tty = pmz_receive_chars(uap_b);
                        if (r3 & CHBTxIP)
                                pmz_transmit_chars(uap_b);
                rc = IRQ_HANDLED;
index a720953a404ee3be6d6da99484f537b40a116d66..415fe9633a9b7ce81cddade5929a71b72fd12370 100644 (file)
@@ -98,8 +98,7 @@ static void serial_pxa_stop_rx(struct uart_port *port)
        serial_out(up, UART_IER, up->ier);
 }
 
-static inline void
-receive_chars(struct uart_pxa_port *up, int *status, struct pt_regs *regs)
+static inline void receive_chars(struct uart_pxa_port *up, int *status)
 {
        struct tty_struct *tty = up->port.info->tty;
        unsigned int ch, flag;
@@ -153,7 +152,7 @@ receive_chars(struct uart_pxa_port *up, int *status, struct pt_regs *regs)
                                flag = TTY_FRAME;
                }
 
-               if (uart_handle_sysrq_char(&up->port, ch, regs))
+               if (uart_handle_sysrq_char(&up->port, ch))
                        goto ignore_char;
 
                uart_insert_char(&up->port, *status, UART_LSR_OE, ch, flag);
@@ -231,10 +230,9 @@ static inline void check_modem_status(struct uart_pxa_port *up)
 /*
  * This handles the interrupt from one port.
  */
-static inline irqreturn_t
-serial_pxa_irq(int irq, void *dev_id, struct pt_regs *regs)
+static inline irqreturn_t serial_pxa_irq(int irq, void *dev_id)
 {
-       struct uart_pxa_port *up = (struct uart_pxa_port *)dev_id;
+       struct uart_pxa_port *up = dev_id;
        unsigned int iir, lsr;
 
        iir = serial_in(up, UART_IIR);
@@ -242,7 +240,7 @@ serial_pxa_irq(int irq, void *dev_id, struct pt_regs *regs)
                return IRQ_NONE;
        lsr = serial_in(up, UART_LSR);
        if (lsr & UART_LSR_DR)
-               receive_chars(up, &lsr, regs);
+               receive_chars(up, &lsr);
        check_modem_status(up);
        if (lsr & UART_LSR_THRE)
                transmit_chars(up);
index 95738a19cde78fb4f288661add8c3caa0ec7a7eb..8dfc2dd058ca4ba74aee7f2467f890c04698c006 100644 (file)
@@ -310,7 +310,7 @@ static int s3c24xx_serial_rx_fifocnt(struct s3c24xx_uart_port *ourport,
 #define S3C2410_UERSTAT_PARITY (0x1000)
 
 static irqreturn_t
-s3c24xx_serial_rx_chars(int irq, void *dev_id, struct pt_regs *regs)
+s3c24xx_serial_rx_chars(int irq, void *dev_id)
 {
        struct s3c24xx_uart_port *ourport = dev_id;
        struct uart_port *port = &ourport->port;
@@ -379,7 +379,7 @@ s3c24xx_serial_rx_chars(int irq, void *dev_id, struct pt_regs *regs)
                                flag = TTY_FRAME;
                }
 
-               if (uart_handle_sysrq_char(port, ch, regs))
+               if (uart_handle_sysrq_char(port, ch))
                        goto ignore_char;
 
                uart_insert_char(port, uerstat, S3C2410_UERSTAT_OVERRUN, ch, flag);
@@ -393,7 +393,7 @@ s3c24xx_serial_rx_chars(int irq, void *dev_id, struct pt_regs *regs)
        return IRQ_HANDLED;
 }
 
-static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id, struct pt_regs *regs)
+static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id)
 {
        struct s3c24xx_uart_port *ourport = id;
        struct uart_port *port = &ourport->port;
index db3486d338707cd9d1e22e24d78bf3d9e80f4c2c..d4065266b6fcf9af83e7714aa8da9eb74b50d221 100644 (file)
@@ -190,7 +190,7 @@ static void sa1100_enable_ms(struct uart_port *port)
 }
 
 static void
-sa1100_rx_chars(struct sa1100_port *sport, struct pt_regs *regs)
+sa1100_rx_chars(struct sa1100_port *sport)
 {
        struct tty_struct *tty = sport->port.info->tty;
        unsigned int status, ch, flg;
@@ -228,7 +228,7 @@ sa1100_rx_chars(struct sa1100_port *sport, struct pt_regs *regs)
 #endif
                }
 
-               if (uart_handle_sysrq_char(&sport->port, ch, regs))
+               if (uart_handle_sysrq_char(&sport->port, ch))
                        goto ignore_char;
 
                uart_insert_char(&sport->port, status, UTSR1_TO_SM(UTSR1_ROR), ch, flg);
@@ -281,7 +281,7 @@ static void sa1100_tx_chars(struct sa1100_port *sport)
                sa1100_stop_tx(&sport->port);
 }
 
-static irqreturn_t sa1100_int(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t sa1100_int(int irq, void *dev_id)
 {
        struct sa1100_port *sport = dev_id;
        unsigned int status, pass_counter = 0;
@@ -294,7 +294,7 @@ static irqreturn_t sa1100_int(int irq, void *dev_id, struct pt_regs *regs)
                        /* Clear the receiver idle bit, if set */
                        if (status & UTSR0_RID)
                                UART_PUT_UTSR0(sport, UTSR0_RID);
-                       sa1100_rx_chars(sport, regs);
+                       sa1100_rx_chars(sport);
                }
 
                /* Clear the relevant break bits */
index 23ddedbaec086b8bf307137492e8f2a8820f14f7..5e1ac356bbb07b7630bb5453a850fb25daf047ce 100644 (file)
@@ -135,12 +135,7 @@ static void lh7a40xuart_enable_ms (struct uart_port* port)
        BIT_SET (port, UART_R_INTEN, ModemInt);
 }
 
-static void
-#ifdef SUPPORT_SYSRQ
-lh7a40xuart_rx_chars (struct uart_port* port, struct pt_regs* regs)
-#else
-lh7a40xuart_rx_chars (struct uart_port* port)
-#endif
+static void lh7a40xuart_rx_chars (struct uart_port* port)
 {
        struct tty_struct* tty = port->info->tty;
        int cbRxMax = 256;      /* (Gross) limit on receive */
@@ -177,7 +172,7 @@ lh7a40xuart_rx_chars (struct uart_port* port)
                                flag = TTY_FRAME;
                }
 
-               if (uart_handle_sysrq_char (port, (unsigned char) data, regs))
+               if (uart_handle_sysrq_char (port, (unsigned char) data))
                        continue;
 
                uart_insert_char(port, data, RxOverrunError, data, flag);
@@ -248,8 +243,7 @@ static void lh7a40xuart_modem_status (struct uart_port* port)
        wake_up_interruptible (&port->info->delta_msr_wait);
 }
 
-static irqreturn_t lh7a40xuart_int (int irq, void* dev_id,
-                                   struct pt_regs* regs)
+static irqreturn_t lh7a40xuart_int (int irq, void* dev_id)
 {
        struct uart_port* port = dev_id;
        unsigned int cLoopLimit = ISR_LOOP_LIMIT;
@@ -258,11 +252,7 @@ static irqreturn_t lh7a40xuart_int (int irq, void* dev_id,
 
        do {
                if (isr & (RxInt | RxTimeoutInt))
-#ifdef SUPPORT_SYSRQ
-                       lh7a40xuart_rx_chars(port, regs);
-#else
                        lh7a40xuart_rx_chars(port);
-#endif
                if (isr & ModemInt)
                        lh7a40xuart_modem_status (port);
                if (isr & TxInt)
index ebd8d2bb17fd24949701f4af6d4e07a0c68a00fb..2a48289ac72277b6f516b16635595400009dbd17 100644 (file)
@@ -283,7 +283,7 @@ static void serial_txx9_enable_ms(struct uart_port *port)
 }
 
 static inline void
-receive_chars(struct uart_txx9_port *up, unsigned int *status, struct pt_regs *regs)
+receive_chars(struct uart_txx9_port *up, unsigned int *status)
 {
        struct tty_struct *tty = up->port.info->tty;
        unsigned char ch;
@@ -344,7 +344,7 @@ receive_chars(struct uart_txx9_port *up, unsigned int *status, struct pt_regs *r
                        else if (disr & TXX9_SIDISR_UFER)
                                flag = TTY_FRAME;
                }
-               if (uart_handle_sysrq_char(&up->port, ch, regs))
+               if (uart_handle_sysrq_char(&up->port, ch))
                        goto ignore_char;
 
                uart_insert_char(&up->port, disr, TXX9_SIDISR_UOER, ch, flag);
@@ -391,7 +391,7 @@ static inline void transmit_chars(struct uart_txx9_port *up)
                serial_txx9_stop_tx(&up->port);
 }
 
-static irqreturn_t serial_txx9_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t serial_txx9_interrupt(int irq, void *dev_id)
 {
        int pass_counter = 0;
        struct uart_txx9_port *up = dev_id;
@@ -409,7 +409,7 @@ static irqreturn_t serial_txx9_interrupt(int irq, void *dev_id, struct pt_regs *
                }
 
                if (status & TXX9_SIDISR_RDIS)
-                       receive_chars(up, &status, regs);
+                       receive_chars(up, &status);
                if (status & TXX9_SIDISR_TDIS)
                        transmit_chars(up);
                /* Clear TX/RX Int. Status */
index 5c025d1190c171762f4f6c625010d0ed7b3968d7..cfcc3caf49d8f5a0a71997ee1bb6b1833035e6ac 100644 (file)
@@ -446,8 +446,7 @@ static void sci_transmit_chars(struct uart_port *port)
 /* On SH3, SCIF may read end-of-break as a space->mark char */
 #define STEPFN(c)  ({int __c=(c); (((__c-1)|(__c)) == -1); })
 
-static inline void sci_receive_chars(struct uart_port *port,
-                                    struct pt_regs *regs)
+static inline void sci_receive_chars(struct uart_port *port)
 {
        struct sci_port *sci_port = (struct sci_port *)port;
        struct tty_struct *tty = port->info->tty;
@@ -476,7 +475,7 @@ static inline void sci_receive_chars(struct uart_port *port,
 
                if (port->type == PORT_SCI) {
                        char c = sci_in(port, SCxRDR);
-                       if (uart_handle_sysrq_char(port, c, regs) || sci_port->break_flag)
+                       if (uart_handle_sysrq_char(port, c) || sci_port->break_flag)
                                count = 0;
                        else {
                                tty_insert_flip_char(tty, c, TTY_NORMAL);
@@ -504,7 +503,7 @@ static inline void sci_receive_chars(struct uart_port *port,
                                        }
                                }
 #endif /* CONFIG_CPU_SH3 */
-                               if (uart_handle_sysrq_char(port, c, regs)) {
+                               if (uart_handle_sysrq_char(port, c)) {
                                        count--; i--;
                                        continue;
                                }
@@ -652,18 +651,18 @@ static inline int sci_handle_breaks(struct uart_port *port)
        return copied;
 }
 
-static irqreturn_t sci_rx_interrupt(int irq, void *port, struct pt_regs *regs)
+static irqreturn_t sci_rx_interrupt(int irq, void *port)
 {
        /* I think sci_receive_chars has to be called irrespective
         * of whether the I_IXOFF is set, otherwise, how is the interrupt
         * to be disabled?
         */
-       sci_receive_chars(port, regs);
+       sci_receive_chars(port);
 
        return IRQ_HANDLED;
 }
 
-static irqreturn_t sci_tx_interrupt(int irq, void *ptr, struct pt_regs *regs)
+static irqreturn_t sci_tx_interrupt(int irq, void *ptr)
 {
        struct uart_port *port = ptr;
 
@@ -674,7 +673,7 @@ static irqreturn_t sci_tx_interrupt(int irq, void *ptr, struct pt_regs *regs)
        return IRQ_HANDLED;
 }
 
-static irqreturn_t sci_er_interrupt(int irq, void *ptr, struct pt_regs *regs)
+static irqreturn_t sci_er_interrupt(int irq, void *ptr)
 {
        struct uart_port *port = ptr;
 
@@ -696,18 +695,18 @@ static irqreturn_t sci_er_interrupt(int irq, void *ptr, struct pt_regs *regs)
                        pr_debug("scif: overrun error\n");
                }
 #endif
-               sci_rx_interrupt(irq, ptr, regs);
+               sci_rx_interrupt(irq, ptr);
        }
 
        sci_out(port, SCxSR, SCxSR_ERROR_CLEAR(port));
 
        /* Kick the transmission */
-       sci_tx_interrupt(irq, ptr, regs);
+       sci_tx_interrupt(irq, ptr);
 
        return IRQ_HANDLED;
 }
 
-static irqreturn_t sci_br_interrupt(int irq, void *ptr, struct pt_regs *regs)
+static irqreturn_t sci_br_interrupt(int irq, void *ptr)
 {
        struct uart_port *port = ptr;
 
@@ -724,7 +723,7 @@ static irqreturn_t sci_br_interrupt(int irq, void *ptr, struct pt_regs *regs)
        return IRQ_HANDLED;
 }
 
-static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr, struct pt_regs *regs)
+static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr)
 {
         unsigned short ssr_status, scr_status;
         struct uart_port *port = ptr;
@@ -734,16 +733,16 @@ static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr, struct pt_regs *regs)
 
        /* Tx Interrupt */
         if ((ssr_status & 0x0020) && (scr_status & 0x0080))
-                sci_tx_interrupt(irq, ptr, regs);
+                sci_tx_interrupt(irq, ptr);
        /* Rx Interrupt */
         if ((ssr_status & 0x0002) && (scr_status & 0x0040))
-                sci_rx_interrupt(irq, ptr, regs);
+                sci_rx_interrupt(irq, ptr);
        /* Error Interrupt */
         if ((ssr_status & 0x0080) && (scr_status & 0x0400))
-                sci_er_interrupt(irq, ptr, regs);
+                sci_er_interrupt(irq, ptr);
        /* Break Interrupt */
         if ((ssr_status & 0x0010) && (scr_status & 0x0200))
-                sci_br_interrupt(irq, ptr, regs);
+                sci_br_interrupt(irq, ptr);
 
        return IRQ_HANDLED;
 }
@@ -795,7 +794,7 @@ static struct notifier_block sci_nb = { &sci_notifier, NULL, 0 };
 static int sci_request_irq(struct sci_port *port)
 {
        int i;
-       irqreturn_t (*handlers[4])(int irq, void *ptr, struct pt_regs *regs) = {
+       irqreturn_t (*handlers[4])(int irq, void *ptr) = {
                sci_er_interrupt, sci_rx_interrupt, sci_tx_interrupt,
                sci_br_interrupt,
        };
@@ -809,7 +808,7 @@ static int sci_request_irq(struct sci_port *port)
                }
 
                if (request_irq(port->irqs[0], sci_mpxed_interrupt,
-                               SA_INTERRUPT, "sci", port)) {
+                               IRQF_DISABLED, "sci", port)) {
                        printk(KERN_ERR "sci: Cannot allocate irq.\n");
                        return -ENODEV;
                }
@@ -818,7 +817,7 @@ static int sci_request_irq(struct sci_port *port)
                        if (!port->irqs[i])
                                continue;
                        if (request_irq(port->irqs[i], handlers[i],
-                                       SA_INTERRUPT, desc[i], port)) {
+                                       IRQF_DISABLED, desc[i], port)) {
                                printk(KERN_ERR "sci: Cannot allocate irq.\n");
                                return -ENODEV;
                        }
index 2f148e5b92557f17d0ca76aa92054984062fcbc3..956b2cf08e1e09f39d90f0a4d12df15b93817979 100644 (file)
@@ -447,7 +447,6 @@ static int sn_debug_printf(const char *fmt, ...)
 /**
  * sn_receive_chars - Grab characters, pass them to tty layer
  * @port: Port to operate on
- * @regs: Saved registers (needed by uart_handle_sysrq_char)
  * @flags: irq flags
  *
  * Note: If we're not registered with the serial core infrastructure yet,
@@ -455,8 +454,7 @@ static int sn_debug_printf(const char *fmt, ...)
  *
  */
 static void
-sn_receive_chars(struct sn_cons_port *port, struct pt_regs *regs,
-                unsigned long flags)
+sn_receive_chars(struct sn_cons_port *port, unsigned long flags)
 {
        int ch;
        struct tty_struct *tty;
@@ -494,7 +492,7 @@ sn_receive_chars(struct sn_cons_port *port, struct pt_regs *regs,
                         sysrq_requested = 0;
                         if (ch && time_before(jiffies, sysrq_timeout)) {
                                 spin_unlock_irqrestore(&port->sc_port.lock, flags);
-                                handle_sysrq(ch, regs, NULL);
+                                handle_sysrq(ch, NULL);
                                 spin_lock_irqsave(&port->sc_port.lock, flags);
                                 /* ignore actual sysrq command char */
                                 continue;
@@ -615,10 +613,9 @@ static void sn_transmit_chars(struct sn_cons_port *port, int raw)
  * sn_sal_interrupt - Handle console interrupts
  * @irq: irq #, useful for debug statements
  * @dev_id: our pointer to our port (sn_cons_port which contains the uart port)
- * @regs: Saved registers, used by sn_receive_chars for uart_handle_sysrq_char
  *
  */
-static irqreturn_t sn_sal_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t sn_sal_interrupt(int irq, void *dev_id)
 {
        struct sn_cons_port *port = (struct sn_cons_port *)dev_id;
        unsigned long flags;
@@ -629,7 +626,7 @@ static irqreturn_t sn_sal_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 
        spin_lock_irqsave(&port->sc_port.lock, flags);
        if (status & SAL_CONSOLE_INTR_RECV) {
-               sn_receive_chars(port, regs, flags);
+               sn_receive_chars(port, flags);
        }
        if (status & SAL_CONSOLE_INTR_XMIT) {
                sn_transmit_chars(port, TRANSMIT_BUFFERED);
@@ -677,7 +674,7 @@ static void sn_sal_timer_poll(unsigned long data)
        if (!port->sc_port.irq) {
                spin_lock_irqsave(&port->sc_port.lock, flags);
                if (sn_process_input)
-                       sn_receive_chars(port, NULL, flags);
+                       sn_receive_chars(port, flags);
                sn_transmit_chars(port, TRANSMIT_RAW);
                spin_unlock_irqrestore(&port->sc_port.lock, flags);
                mod_timer(&port->sc_timer,
index f851f0f44f9b83352aea262b58dc869ca01f1ee0..03941d27d15dcdb2d8338e47b63d852bf73e2fb0 100644 (file)
@@ -73,7 +73,7 @@ static inline long hypervisor_con_putchar(long ch)
 
 static int hung_up = 0;
 
-static struct tty_struct *receive_chars(struct uart_port *port, struct pt_regs *regs)
+static struct tty_struct *receive_chars(struct uart_port *port)
 {
        struct tty_struct *tty = NULL;
        int saw_console_brk = 0;
@@ -106,7 +106,7 @@ static struct tty_struct *receive_chars(struct uart_port *port, struct pt_regs *
                }
 
                if (tty == NULL) {
-                       uart_handle_sysrq_char(port, c, regs);
+                       uart_handle_sysrq_char(port, c);
                        continue;
                }
 
@@ -119,7 +119,7 @@ static struct tty_struct *receive_chars(struct uart_port *port, struct pt_regs *
                        flag = TTY_BREAK;
                }
 
-               if (uart_handle_sysrq_char(port, c, regs))
+               if (uart_handle_sysrq_char(port, c))
                        continue;
 
                if ((port->ignore_status_mask & IGNORE_ALL) ||
@@ -161,14 +161,14 @@ static void transmit_chars(struct uart_port *port)
                uart_write_wakeup(port);
 }
 
-static irqreturn_t sunhv_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t sunhv_interrupt(int irq, void *dev_id)
 {
        struct uart_port *port = dev_id;
        struct tty_struct *tty;
        unsigned long flags;
 
        spin_lock_irqsave(&port->lock, flags);
-       tty = receive_chars(port, regs);
+       tty = receive_chars(port);
        transmit_chars(port);
        spin_unlock_irqrestore(&port->lock, flags);
 
index cfe20f730436159f92b1422bd082079da595737b..08a7cd6a3a0c77a6a11497bd73be4141b33bfd0c 100644 (file)
@@ -108,8 +108,7 @@ static __inline__ void sunsab_cec_wait(struct uart_sunsab_port *up)
 
 static struct tty_struct *
 receive_chars(struct uart_sunsab_port *up,
-             union sab82532_irq_status *stat,
-             struct pt_regs *regs)
+             union sab82532_irq_status *stat)
 {
        struct tty_struct *tty = NULL;
        unsigned char buf[32];
@@ -161,7 +160,7 @@ receive_chars(struct uart_sunsab_port *up,
                unsigned char ch = buf[i], flag;
 
                if (tty == NULL) {
-                       uart_handle_sysrq_char(&up->port, ch, regs);
+                       uart_handle_sysrq_char(&up->port, ch);
                        continue;
                }
 
@@ -208,7 +207,7 @@ receive_chars(struct uart_sunsab_port *up,
                                flag = TTY_FRAME;
                }
 
-               if (uart_handle_sysrq_char(&up->port, ch, regs))
+               if (uart_handle_sysrq_char(&up->port, ch))
                        continue;
 
                if ((stat->sreg.isr0 & (up->port.ignore_status_mask & 0xff)) == 0 &&
@@ -301,7 +300,7 @@ static void check_status(struct uart_sunsab_port *up,
        wake_up_interruptible(&up->port.info->delta_msr_wait);
 }
 
-static irqreturn_t sunsab_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t sunsab_interrupt(int irq, void *dev_id)
 {
        struct uart_sunsab_port *up = dev_id;
        struct tty_struct *tty;
@@ -321,7 +320,7 @@ static irqreturn_t sunsab_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                if ((status.sreg.isr0 & (SAB82532_ISR0_TCD | SAB82532_ISR0_TIME |
                                         SAB82532_ISR0_RFO | SAB82532_ISR0_RPF)) ||
                    (status.sreg.isr1 & SAB82532_ISR1_BRK))
-                       tty = receive_chars(up, &status, regs);
+                       tty = receive_chars(up, &status);
                if ((status.sreg.isr0 & SAB82532_ISR0_CDSC) ||
                    (status.sreg.isr1 & SAB82532_ISR1_CSC))
                        check_status(up, &status);
@@ -350,7 +349,7 @@ static irqreturn_t sunsab_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                                         SAB82532_ISR0_RFO | SAB82532_ISR0_RPF)) ||
                    (status.sreg.isr1 & SAB82532_ISR1_BRK))
 
-                       tty = receive_chars(up, &status, regs);
+                       tty = receive_chars(up, &status);
                if ((status.sreg.isr0 & SAB82532_ISR0_CDSC) ||
                    (status.sreg.isr1 & (SAB82532_ISR1_BRK | SAB82532_ISR1_CSC)))
                        check_status(up, &status);
index 9b3b9aaa6b909efd4a7bc61e111a01cd8b6a373b..c577faea60e8ae7437a77e3f36b668805af174b4 100644 (file)
@@ -310,7 +310,7 @@ static void sunsu_enable_ms(struct uart_port *port)
 }
 
 static struct tty_struct *
-receive_chars(struct uart_sunsu_port *up, unsigned char *status, struct pt_regs *regs)
+receive_chars(struct uart_sunsu_port *up, unsigned char *status)
 {
        struct tty_struct *tty = up->port.info->tty;
        unsigned char ch, flag;
@@ -367,7 +367,7 @@ receive_chars(struct uart_sunsu_port *up, unsigned char *status, struct pt_regs
                        else if (*status & UART_LSR_FE)
                                flag = TTY_FRAME;
                }
-               if (uart_handle_sysrq_char(&up->port, ch, regs))
+               if (uart_handle_sysrq_char(&up->port, ch))
                        goto ignore_char;
                if ((*status & up->port.ignore_status_mask) == 0)
                        tty_insert_flip_char(tty, ch, flag);
@@ -445,7 +445,7 @@ static void check_modem_status(struct uart_sunsu_port *up)
        wake_up_interruptible(&up->port.info->delta_msr_wait);
 }
 
-static irqreturn_t sunsu_serial_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t sunsu_serial_interrupt(int irq, void *dev_id)
 {
        struct uart_sunsu_port *up = dev_id;
        unsigned long flags;
@@ -459,7 +459,7 @@ static irqreturn_t sunsu_serial_interrupt(int irq, void *dev_id, struct pt_regs
                status = serial_inp(up, UART_LSR);
                tty = NULL;
                if (status & UART_LSR_DR)
-                       tty = receive_chars(up, &status, regs);
+                       tty = receive_chars(up, &status);
                check_modem_status(up);
                if (status & UART_LSR_THRE)
                        transmit_chars(up);
@@ -497,7 +497,7 @@ static void sunsu_change_mouse_baud(struct uart_sunsu_port *up)
        sunsu_change_speed(&up->port, up->cflag, 0, quot);
 }
 
-static void receive_kbd_ms_chars(struct uart_sunsu_port *up, struct pt_regs *regs, int is_break)
+static void receive_kbd_ms_chars(struct uart_sunsu_port *up, int is_break)
 {
        do {
                unsigned char ch = serial_inp(up, UART_RX);
@@ -505,7 +505,7 @@ static void receive_kbd_ms_chars(struct uart_sunsu_port *up, struct pt_regs *reg
                /* Stop-A is handled by drivers/char/keyboard.c now. */
                if (up->su_type == SU_PORT_KBD) {
 #ifdef CONFIG_SERIO
-                       serio_interrupt(&up->serio, ch, 0, regs);
+                       serio_interrupt(&up->serio, ch, 0);
 #endif
                } else if (up->su_type == SU_PORT_MS) {
                        int ret = suncore_mouse_baud_detection(ch, is_break);
@@ -519,7 +519,7 @@ static void receive_kbd_ms_chars(struct uart_sunsu_port *up, struct pt_regs *reg
 
                        case 0:
 #ifdef CONFIG_SERIO
-                               serio_interrupt(&up->serio, ch, 0, regs);
+                               serio_interrupt(&up->serio, ch, 0);
 #endif
                                break;
                        };
@@ -527,7 +527,7 @@ static void receive_kbd_ms_chars(struct uart_sunsu_port *up, struct pt_regs *reg
        } while (serial_in(up, UART_LSR) & UART_LSR_DR);
 }
 
-static irqreturn_t sunsu_kbd_ms_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t sunsu_kbd_ms_interrupt(int irq, void *dev_id)
 {
        struct uart_sunsu_port *up = dev_id;
 
@@ -535,8 +535,7 @@ static irqreturn_t sunsu_kbd_ms_interrupt(int irq, void *dev_id, struct pt_regs
                unsigned char status = serial_inp(up, UART_LSR);
 
                if ((status & UART_LSR_DR) || (status & UART_LSR_BI))
-                       receive_kbd_ms_chars(up, regs,
-                                            (status & UART_LSR_BI) != 0);
+                       receive_kbd_ms_chars(up, (status & UART_LSR_BI) != 0);
        }
 
        return IRQ_HANDLED;
index 0da3ebfff82dc55cc4750640ae7f92530f63562d..b2cc703b2b9e976e6fc74d0f9f652a7960612c4e 100644 (file)
@@ -277,14 +277,13 @@ static void sunzilog_change_mouse_baud(struct uart_sunzilog_port *up)
 }
 
 static void sunzilog_kbdms_receive_chars(struct uart_sunzilog_port *up,
-                                        unsigned char ch, int is_break,
-                                        struct pt_regs *regs)
+                                        unsigned char ch, int is_break)
 {
        if (ZS_IS_KEYB(up)) {
                /* Stop-A is handled by drivers/char/keyboard.c now. */
 #ifdef CONFIG_SERIO
                if (up->serio_open)
-                       serio_interrupt(&up->serio, ch, 0, regs);
+                       serio_interrupt(&up->serio, ch, 0);
 #endif
        } else if (ZS_IS_MOUSE(up)) {
                int ret = suncore_mouse_baud_detection(ch, is_break);
@@ -299,7 +298,7 @@ static void sunzilog_kbdms_receive_chars(struct uart_sunzilog_port *up,
                case 0:
 #ifdef CONFIG_SERIO
                        if (up->serio_open)
-                               serio_interrupt(&up->serio, ch, 0, regs);
+                               serio_interrupt(&up->serio, ch, 0);
 #endif
                        break;
                };
@@ -308,8 +307,7 @@ static void sunzilog_kbdms_receive_chars(struct uart_sunzilog_port *up,
 
 static struct tty_struct *
 sunzilog_receive_chars(struct uart_sunzilog_port *up,
-                      struct zilog_channel __iomem *channel,
-                      struct pt_regs *regs)
+                      struct zilog_channel __iomem *channel)
 {
        struct tty_struct *tty;
        unsigned char ch, r1, flag;
@@ -346,12 +344,12 @@ sunzilog_receive_chars(struct uart_sunzilog_port *up,
                ch &= up->parity_mask;
 
                if (unlikely(ZS_IS_KEYB(up)) || unlikely(ZS_IS_MOUSE(up))) {
-                       sunzilog_kbdms_receive_chars(up, ch, 0, regs);
+                       sunzilog_kbdms_receive_chars(up, ch, 0);
                        continue;
                }
 
                if (tty == NULL) {
-                       uart_handle_sysrq_char(&up->port, ch, regs);
+                       uart_handle_sysrq_char(&up->port, ch);
                        continue;
                }
 
@@ -379,7 +377,7 @@ sunzilog_receive_chars(struct uart_sunzilog_port *up,
                        else if (r1 & CRC_ERR)
                                flag = TTY_FRAME;
                }
-               if (uart_handle_sysrq_char(&up->port, ch, regs))
+               if (uart_handle_sysrq_char(&up->port, ch))
                        continue;
 
                if (up->port.ignore_status_mask == 0xff ||
@@ -394,8 +392,7 @@ sunzilog_receive_chars(struct uart_sunzilog_port *up,
 }
 
 static void sunzilog_status_handle(struct uart_sunzilog_port *up,
-                                  struct zilog_channel __iomem *channel,
-                                  struct pt_regs *regs)
+                                  struct zilog_channel __iomem *channel)
 {
        unsigned char status;
 
@@ -408,7 +405,7 @@ static void sunzilog_status_handle(struct uart_sunzilog_port *up,
 
        if (status & BRK_ABRT) {
                if (ZS_IS_MOUSE(up))
-                       sunzilog_kbdms_receive_chars(up, 0, 1, regs);
+                       sunzilog_kbdms_receive_chars(up, 0, 1);
                if (ZS_IS_CONS(up)) {
                        /* Wait for BREAK to deassert to avoid potentially
                         * confusing the PROM.
@@ -517,7 +514,7 @@ ack_tx_int:
        ZS_WSYNC(channel);
 }
 
-static irqreturn_t sunzilog_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t sunzilog_interrupt(int irq, void *dev_id)
 {
        struct uart_sunzilog_port *up = dev_id;
 
@@ -538,9 +535,9 @@ static irqreturn_t sunzilog_interrupt(int irq, void *dev_id, struct pt_regs *reg
                        ZS_WSYNC(channel);
 
                        if (r3 & CHARxIP)
-                               tty = sunzilog_receive_chars(up, channel, regs);
+                               tty = sunzilog_receive_chars(up, channel);
                        if (r3 & CHAEXT)
-                               sunzilog_status_handle(up, channel, regs);
+                               sunzilog_status_handle(up, channel);
                        if (r3 & CHATxIP)
                                sunzilog_transmit_chars(up, channel);
                }
@@ -561,9 +558,9 @@ static irqreturn_t sunzilog_interrupt(int irq, void *dev_id, struct pt_regs *reg
                        ZS_WSYNC(channel);
 
                        if (r3 & CHBRxIP)
-                               tty = sunzilog_receive_chars(up, channel, regs);
+                               tty = sunzilog_receive_chars(up, channel);
                        if (r3 & CHBEXT)
-                               sunzilog_status_handle(up, channel, regs);
+                               sunzilog_status_handle(up, channel);
                        if (r3 & CHBTxIP)
                                sunzilog_transmit_chars(up, channel);
                }
@@ -1060,7 +1057,7 @@ static void sunzilog_free_tables(void)
 
 static void sunzilog_putchar(struct uart_port *port, int ch)
 {
-       struct zilog_channel *channel = ZILOG_CHANNEL_FROM_PORT(port);
+       struct zilog_channel __iomem *channel = ZILOG_CHANNEL_FROM_PORT(port);
        int loops = ZS_PUT_CHAR_MAX_DELAY;
 
        /* This is a timed polling loop so do not switch the explicit
@@ -1185,7 +1182,7 @@ static int __init sunzilog_console_setup(struct console *con, char *options)
        return 0;
 }
 
-static struct console sunzilog_console = {
+static struct console sunzilog_console_ops = {
        .name   =       "ttyS",
        .write  =       sunzilog_console_write,
        .device =       uart_console_device,
@@ -1211,10 +1208,10 @@ static inline struct console *SUNZILOG_CONSOLE(void)
        if (i == NUM_CHANNELS)
                return NULL;
 
-       sunzilog_console.index = i;
+       sunzilog_console_ops.index = i;
        sunzilog_port_table[i].flags |= SUNZILOG_FLAG_IS_CONS;
 
-       return &sunzilog_console;
+       return &sunzilog_console_ops;
 }
 
 #else
index f802867c95c5ad4a7f3ca55b521b70712ae5cb84..28f3bbff87bf48f1c5bbc16b8cc4affc26429b65 100644 (file)
@@ -271,14 +271,14 @@ void v850e_uart_tx (struct uart_port *port)
                v850e_uart_stop_tx (port, stopped);
 }
 
-static irqreturn_t v850e_uart_tx_irq(int irq, void *data, struct pt_regs *regs)
+static irqreturn_t v850e_uart_tx_irq(int irq, void *data)
 {
        struct uart_port *port = data;
        v850e_uart_tx (port);
        return IRQ_HANDLED;
 }
 
-static irqreturn_t v850e_uart_rx_irq(int irq, void *data, struct pt_regs *regs)
+static irqreturn_t v850e_uart_rx_irq(int irq, void *data)
 {
        struct uart_port *port = data;
        unsigned ch_stat = TTY_NORMAL;
index 6c8b0ea83c3c5b0318637526747c3dfee62a53f6..fd51f8182dec1f20f3a4d43d6c66361d5485b5e0 100644 (file)
@@ -359,8 +359,7 @@ static void siu_break_ctl(struct uart_port *port, int ctl)
        spin_unlock_irqrestore(&port->lock, flags);
 }
 
-static inline void receive_chars(struct uart_port *port, uint8_t *status,
-                                 struct pt_regs *regs)
+static inline void receive_chars(struct uart_port *port, uint8_t *status)
 {
        struct tty_struct *tty;
        uint8_t lsr, ch;
@@ -405,7 +404,7 @@ static inline void receive_chars(struct uart_port *port, uint8_t *status,
                                flag = TTY_PARITY;
                }
 
-               if (uart_handle_sysrq_char(port, ch, regs))
+               if (uart_handle_sysrq_char(port, ch))
                        goto ignore_char;
 
                uart_insert_char(port, lsr, UART_LSR_OE, ch, flag);
@@ -472,7 +471,7 @@ static inline void transmit_chars(struct uart_port *port)
                siu_stop_tx(port);
 }
 
-static irqreturn_t siu_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t siu_interrupt(int irq, void *dev_id)
 {
        struct uart_port *port;
        uint8_t iir, lsr;
@@ -485,7 +484,7 @@ static irqreturn_t siu_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 
        lsr = siu_read(port, UART_LSR);
        if (lsr & UART_LSR_DR)
-               receive_chars(port, &lsr, regs);
+               receive_chars(port, &lsr);
 
        check_modem_status(port);
 
index a3473162587745dc276f632537bd60cdd9732e4f..c66ba9ad833df2d4f4dd141e2246d9fb6ccdd901 100644 (file)
@@ -5,19 +5,6 @@
 menu "SN Devices"
        depends on SGI_SN
 
-config SGI_IOC4
-       tristate "SGI IOC4 Base IO support"
-       depends on MMTIMER
-       default m
-       ---help---
-       This option enables basic support for the SGI IOC4-based Base IO
-       controller card.  This option does not enable any specific
-       functions on such a card, but provides necessary infrastructure
-       for other drivers to utilize.
-
-       If you have an SGI Altix with an IOC4-based
-       I/O controller say Y.  Otherwise say N.
-
 config SGI_IOC3
        tristate "SGI IOC3 Base IO support"
        default m
index 2cda011597c0e018ea931a2393f59526effeba9a..693db8bb8d9c0659ceb94a0ae98c81bd6bc9f423 100644 (file)
@@ -3,5 +3,4 @@
 #
 #
 
-obj-$(CONFIG_SGI_IOC4) += ioc4.o
 obj-$(CONFIG_SGI_IOC3) += ioc3.o
index 6c7e0352d561f6ffdae0bfc568aea97f1baf4c2e..cd6b65333b71a51660471128e4128dd8d90116dc 100644 (file)
@@ -398,10 +398,10 @@ static inline uint32_t get_pending_intrs(struct ioc3_driver_data *idd)
        return intrs;
 }
 
-static irqreturn_t ioc3_intr_io(int irq, void *arg, struct pt_regs *regs)
+static irqreturn_t ioc3_intr_io(int irq, void *arg)
 {
        unsigned long flags;
-       struct ioc3_driver_data *idd = (struct ioc3_driver_data *)arg;
+       struct ioc3_driver_data *idd = arg;
        int handled = 1, id;
        unsigned int pending;
 
@@ -412,7 +412,7 @@ static irqreturn_t ioc3_intr_io(int irq, void *arg, struct pt_regs *regs)
                if(ioc3_ethernet && idd->active[ioc3_ethernet->id] &&
                                                ioc3_ethernet->intr) {
                        handled = handled && !ioc3_ethernet->intr(ioc3_ethernet,
-                                                       idd, 0, regs);
+                                                       idd, 0);
                }
        }
        pending = get_pending_intrs(idd);       /* look at the IO IRQs */
@@ -424,8 +424,7 @@ static irqreturn_t ioc3_intr_io(int irq, void *arg, struct pt_regs *regs)
                        write_ireg(idd, ioc3_submodules[id]->irq_mask,
                                                        IOC3_W_IEC);
                        if(!ioc3_submodules[id]->intr(ioc3_submodules[id],
-                                  idd, pending & ioc3_submodules[id]->irq_mask,
-                                       regs))
+                                  idd, pending & ioc3_submodules[id]->irq_mask))
                                pending &= ~ioc3_submodules[id]->irq_mask;
                        if (ioc3_submodules[id]->reset_mask)
                                write_ireg(idd, ioc3_submodules[id]->irq_mask,
@@ -442,7 +441,7 @@ static irqreturn_t ioc3_intr_io(int irq, void *arg, struct pt_regs *regs)
        return handled?IRQ_HANDLED:IRQ_NONE;
 }
 
-static irqreturn_t ioc3_intr_eth(int irq, void *arg, struct pt_regs *regs)
+static irqreturn_t ioc3_intr_eth(int irq, void *arg)
 {
        unsigned long flags;
        struct ioc3_driver_data *idd = (struct ioc3_driver_data *)arg;
@@ -453,8 +452,7 @@ static irqreturn_t ioc3_intr_eth(int irq, void *arg, struct pt_regs *regs)
        read_lock_irqsave(&ioc3_submodules_lock, flags);
        if(ioc3_ethernet && idd->active[ioc3_ethernet->id]
                                && ioc3_ethernet->intr)
-               handled = handled && !ioc3_ethernet->intr(ioc3_ethernet, idd, 0,
-                                                               regs);
+               handled = handled && !ioc3_ethernet->intr(ioc3_ethernet, idd, 0);
        read_unlock_irqrestore(&ioc3_submodules_lock, flags);
        return handled?IRQ_HANDLED:IRQ_NONE;
 }
diff --git a/drivers/sn/ioc4.c b/drivers/sn/ioc4.c
deleted file mode 100644 (file)
index 8562821..0000000
+++ /dev/null
@@ -1,476 +0,0 @@
-/*
- * 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) 2005 Silicon Graphics, Inc.  All Rights Reserved.
- */
-
-/* This file contains the master driver module for use by SGI IOC4 subdrivers.
- *
- * It allocates any resources shared between multiple subdevices, and
- * provides accessor functions (where needed) and the like for those
- * resources.  It also provides a mechanism for the subdevice modules
- * to support loading and unloading.
- *
- * Non-shared resources (e.g. external interrupt A_INT_OUT register page
- * alias, serial port and UART registers) are handled by the subdevice
- * modules themselves.
- *
- * This is all necessary because IOC4 is not implemented as a multi-function
- * PCI device, but an amalgamation of disparate registers for several
- * types of device (ATA, serial, external interrupts).  The normal
- * resource management in the kernel doesn't have quite the right interfaces
- * to handle this situation (e.g. multiple modules can't claim the same
- * PCI ID), thus this IOC4 master module.
- */
-
-#include <linux/errno.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/ioc4.h>
-#include <linux/mmtimer.h>
-#include <linux/rtc.h>
-#include <linux/mutex.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/clksupport.h>
-#include <asm/sn/shub_mmr.h>
-
-/***************
- * Definitions *
- ***************/
-
-/* Tweakable values */
-
-/* PCI bus speed detection/calibration */
-#define IOC4_CALIBRATE_COUNT 63        /* Calibration cycle period */
-#define IOC4_CALIBRATE_CYCLES 256      /* Average over this many cycles */
-#define IOC4_CALIBRATE_DISCARD 2       /* Discard first few cycles */
-#define IOC4_CALIBRATE_LOW_MHZ 25      /* Lower bound on bus speed sanity */
-#define IOC4_CALIBRATE_HIGH_MHZ 75     /* Upper bound on bus speed sanity */
-#define IOC4_CALIBRATE_DEFAULT_MHZ 66  /* Assumed if sanity check fails */
-
-/************************
- * Submodule management *
- ************************/
-
-static DEFINE_MUTEX(ioc4_mutex);
-
-static LIST_HEAD(ioc4_devices);
-static LIST_HEAD(ioc4_submodules);
-
-/* Register an IOC4 submodule */
-int
-ioc4_register_submodule(struct ioc4_submodule *is)
-{
-       struct ioc4_driver_data *idd;
-
-       mutex_lock(&ioc4_mutex);
-       list_add(&is->is_list, &ioc4_submodules);
-
-       /* Initialize submodule for each IOC4 */
-       if (!is->is_probe)
-               goto out;
-
-       list_for_each_entry(idd, &ioc4_devices, idd_list) {
-               if (is->is_probe(idd)) {
-                       printk(KERN_WARNING
-                              "%s: IOC4 submodule %s probe failed "
-                              "for pci_dev %s",
-                              __FUNCTION__, module_name(is->is_owner),
-                              pci_name(idd->idd_pdev));
-               }
-       }
- out:
-       mutex_unlock(&ioc4_mutex);
-       return 0;
-}
-
-/* Unregister an IOC4 submodule */
-void
-ioc4_unregister_submodule(struct ioc4_submodule *is)
-{
-       struct ioc4_driver_data *idd;
-
-       mutex_lock(&ioc4_mutex);
-       list_del(&is->is_list);
-
-       /* Remove submodule for each IOC4 */
-       if (!is->is_remove)
-               goto out;
-
-       list_for_each_entry(idd, &ioc4_devices, idd_list) {
-               if (is->is_remove(idd)) {
-                       printk(KERN_WARNING
-                              "%s: IOC4 submodule %s remove failed "
-                              "for pci_dev %s.\n",
-                              __FUNCTION__, module_name(is->is_owner),
-                              pci_name(idd->idd_pdev));
-               }
-       }
- out:
-       mutex_unlock(&ioc4_mutex);
-}
-
-/*********************
- * Device management *
- *********************/
-
-#define IOC4_CALIBRATE_LOW_LIMIT \
-       (1000*IOC4_EXTINT_COUNT_DIVISOR/IOC4_CALIBRATE_LOW_MHZ)
-#define IOC4_CALIBRATE_HIGH_LIMIT \
-       (1000*IOC4_EXTINT_COUNT_DIVISOR/IOC4_CALIBRATE_HIGH_MHZ)
-#define IOC4_CALIBRATE_DEFAULT \
-       (1000*IOC4_EXTINT_COUNT_DIVISOR/IOC4_CALIBRATE_DEFAULT_MHZ)
-
-#define IOC4_CALIBRATE_END \
-       (IOC4_CALIBRATE_CYCLES + IOC4_CALIBRATE_DISCARD)
-
-#define IOC4_INT_OUT_MODE_TOGGLE 0x7   /* Toggle INT_OUT every COUNT+1 ticks */
-
-/* Determines external interrupt output clock period of the PCI bus an
- * IOC4 is attached to.  This value can be used to determine the PCI
- * bus speed.
- *
- * IOC4 has a design feature that various internal timers are derived from
- * the PCI bus clock.  This causes IOC4 device drivers to need to take the
- * bus speed into account when setting various register values (e.g. INT_OUT
- * register COUNT field, UART divisors, etc).  Since this information is
- * needed by several subdrivers, it is determined by the main IOC4 driver,
- * even though the following code utilizes external interrupt registers
- * to perform the speed calculation.
- */
-static void
-ioc4_clock_calibrate(struct ioc4_driver_data *idd)
-{
-       extern unsigned long sn_rtc_cycles_per_second;
-       union ioc4_int_out int_out;
-       union ioc4_gpcr gpcr;
-       unsigned int state, last_state = 1;
-       uint64_t start = 0, end, period;
-       unsigned int count = 0;
-
-       /* Enable output */
-       gpcr.raw = 0;
-       gpcr.fields.dir = IOC4_GPCR_DIR_0;
-       gpcr.fields.int_out_en = 1;
-       writel(gpcr.raw, &idd->idd_misc_regs->gpcr_s.raw);
-
-       /* Reset to power-on state */
-       writel(0, &idd->idd_misc_regs->int_out.raw);
-       mmiowb();
-
-       /* Set up square wave */
-       int_out.raw = 0;
-       int_out.fields.count = IOC4_CALIBRATE_COUNT;
-       int_out.fields.mode = IOC4_INT_OUT_MODE_TOGGLE;
-       int_out.fields.diag = 0;
-       writel(int_out.raw, &idd->idd_misc_regs->int_out.raw);
-       mmiowb();
-
-       /* Check square wave period averaged over some number of cycles */
-       do {
-               int_out.raw = readl(&idd->idd_misc_regs->int_out.raw);
-               state = int_out.fields.int_out;
-               if (!last_state && state) {
-                       count++;
-                       if (count == IOC4_CALIBRATE_END) {
-                               end = rtc_time();
-                               break;
-                       } else if (count == IOC4_CALIBRATE_DISCARD)
-                               start = rtc_time();
-               }
-               last_state = state;
-       } while (1);
-
-       /* Calculation rearranged to preserve intermediate precision.
-        * Logically:
-        * 1. "end - start" gives us number of RTC cycles over all the
-        *    square wave cycles measured.
-        * 2. Divide by number of square wave cycles to get number of
-        *    RTC cycles per square wave cycle.
-        * 3. Divide by 2*(int_out.fields.count+1), which is the formula
-        *    by which the IOC4 generates the square wave, to get the
-        *    number of RTC cycles per IOC4 INT_OUT count.
-        * 4. Divide by sn_rtc_cycles_per_second to get seconds per
-        *    count.
-        * 5. Multiply by 1E9 to get nanoseconds per count.
-        */
-       period = ((end - start) * 1000000000) /
-           (IOC4_CALIBRATE_CYCLES * 2 * (IOC4_CALIBRATE_COUNT + 1)
-            * sn_rtc_cycles_per_second);
-
-       /* Bounds check the result. */
-       if (period > IOC4_CALIBRATE_LOW_LIMIT ||
-           period < IOC4_CALIBRATE_HIGH_LIMIT) {
-               printk(KERN_INFO
-                      "IOC4 %s: Clock calibration failed.  Assuming"
-                      "PCI clock is %d ns.\n",
-                      pci_name(idd->idd_pdev),
-                      IOC4_CALIBRATE_DEFAULT / IOC4_EXTINT_COUNT_DIVISOR);
-               period = IOC4_CALIBRATE_DEFAULT;
-       } else {
-               printk(KERN_DEBUG
-                      "IOC4 %s: PCI clock is %ld ns.\n",
-                      pci_name(idd->idd_pdev),
-                      period / IOC4_EXTINT_COUNT_DIVISOR);
-       }
-
-       /* Remember results.  We store the extint clock period rather
-        * than the PCI clock period so that greater precision is
-        * retained.  Divide by IOC4_EXTINT_COUNT_DIVISOR to get
-        * PCI clock period.
-        */
-       idd->count_period = period;
-}
-
-/* There are three variants of IOC4 cards: IO9, IO10, and PCI-RT.
- * Each brings out different combinations of IOC4 signals, thus.
- * the IOC4 subdrivers need to know to which we're attached.
- *
- * We look for the presence of a SCSI (IO9) or SATA (IO10) controller
- * on the same PCI bus at slot number 3 to differentiate IO9 from IO10.
- * If neither is present, it's a PCI-RT.
- */
-static unsigned int
-ioc4_variant(struct ioc4_driver_data *idd)
-{
-       struct pci_dev *pdev = NULL;
-       int found = 0;
-
-       /* IO9: Look for a QLogic ISP 12160 at the same bus and slot 3. */
-       do {
-               pdev = pci_get_device(PCI_VENDOR_ID_QLOGIC,
-                                     PCI_DEVICE_ID_QLOGIC_ISP12160, pdev);
-               if (pdev &&
-                   idd->idd_pdev->bus->number == pdev->bus->number &&
-                   3 == PCI_SLOT(pdev->devfn))
-                       found = 1;
-               pci_dev_put(pdev);
-       } while (pdev && !found);
-       if (NULL != pdev)
-               return IOC4_VARIANT_IO9;
-
-       /* IO10: Look for a Vitesse VSC 7174 at the same bus and slot 3. */
-       pdev = NULL;
-       do {
-               pdev = pci_get_device(PCI_VENDOR_ID_VITESSE,
-                                     PCI_DEVICE_ID_VITESSE_VSC7174, pdev);
-               if (pdev &&
-                   idd->idd_pdev->bus->number == pdev->bus->number &&
-                   3 == PCI_SLOT(pdev->devfn))
-                       found = 1;
-               pci_dev_put(pdev);
-       } while (pdev && !found);
-       if (NULL != pdev)
-               return IOC4_VARIANT_IO10;
-
-       /* PCI-RT: No SCSI/SATA controller will be present */
-       return IOC4_VARIANT_PCI_RT;
-}
-
-/* Adds a new instance of an IOC4 card */
-static int
-ioc4_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
-{
-       struct ioc4_driver_data *idd;
-       struct ioc4_submodule *is;
-       uint32_t pcmd;
-       int ret;
-
-       /* Enable IOC4 and take ownership of it */
-       if ((ret = pci_enable_device(pdev))) {
-               printk(KERN_WARNING
-                      "%s: Failed to enable IOC4 device for pci_dev %s.\n",
-                      __FUNCTION__, pci_name(pdev));
-               goto out;
-       }
-       pci_set_master(pdev);
-
-       /* Set up per-IOC4 data */
-       idd = kmalloc(sizeof(struct ioc4_driver_data), GFP_KERNEL);
-       if (!idd) {
-               printk(KERN_WARNING
-                      "%s: Failed to allocate IOC4 data for pci_dev %s.\n",
-                      __FUNCTION__, pci_name(pdev));
-               ret = -ENODEV;
-               goto out_idd;
-       }
-       idd->idd_pdev = pdev;
-       idd->idd_pci_id = pci_id;
-
-       /* Map IOC4 misc registers.  These are shared between subdevices
-        * so the main IOC4 module manages them.
-        */
-       idd->idd_bar0 = pci_resource_start(idd->idd_pdev, 0);
-       if (!idd->idd_bar0) {
-               printk(KERN_WARNING
-                      "%s: Unable to find IOC4 misc resource "
-                      "for pci_dev %s.\n",
-                      __FUNCTION__, pci_name(idd->idd_pdev));
-               ret = -ENODEV;
-               goto out_pci;
-       }
-       if (!request_region(idd->idd_bar0, sizeof(struct ioc4_misc_regs),
-                           "ioc4_misc")) {
-               printk(KERN_WARNING
-                      "%s: Unable to request IOC4 misc region "
-                      "for pci_dev %s.\n",
-                      __FUNCTION__, pci_name(idd->idd_pdev));
-               ret = -ENODEV;
-               goto out_pci;
-       }
-       idd->idd_misc_regs = ioremap(idd->idd_bar0,
-                                    sizeof(struct ioc4_misc_regs));
-       if (!idd->idd_misc_regs) {
-               printk(KERN_WARNING
-                      "%s: Unable to remap IOC4 misc region "
-                      "for pci_dev %s.\n",
-                      __FUNCTION__, pci_name(idd->idd_pdev));
-               ret = -ENODEV;
-               goto out_misc_region;
-       }
-
-       /* Failsafe portion of per-IOC4 initialization */
-
-       /* Detect card variant */
-       idd->idd_variant = ioc4_variant(idd);
-       printk(KERN_INFO "IOC4 %s: %s card detected.\n", pci_name(pdev),
-              idd->idd_variant == IOC4_VARIANT_IO9 ? "IO9" :
-              idd->idd_variant == IOC4_VARIANT_PCI_RT ? "PCI-RT" :
-              idd->idd_variant == IOC4_VARIANT_IO10 ? "IO10" : "unknown");
-
-       /* Initialize IOC4 */
-       pci_read_config_dword(idd->idd_pdev, PCI_COMMAND, &pcmd);
-       pci_write_config_dword(idd->idd_pdev, PCI_COMMAND,
-                              pcmd | PCI_COMMAND_PARITY | PCI_COMMAND_SERR);
-
-       /* Determine PCI clock */
-       ioc4_clock_calibrate(idd);
-
-       /* Disable/clear all interrupts.  Need to do this here lest
-        * one submodule request the shared IOC4 IRQ, but interrupt
-        * is generated by a different subdevice.
-        */
-       /* Disable */
-       writel(~0, &idd->idd_misc_regs->other_iec.raw);
-       writel(~0, &idd->idd_misc_regs->sio_iec);
-       /* Clear (i.e. acknowledge) */
-       writel(~0, &idd->idd_misc_regs->other_ir.raw);
-       writel(~0, &idd->idd_misc_regs->sio_ir);
-
-       /* Track PCI-device specific data */
-       idd->idd_serial_data = NULL;
-       pci_set_drvdata(idd->idd_pdev, idd);
-
-       mutex_lock(&ioc4_mutex);
-       list_add_tail(&idd->idd_list, &ioc4_devices);
-
-       /* Add this IOC4 to all submodules */
-       list_for_each_entry(is, &ioc4_submodules, is_list) {
-               if (is->is_probe && is->is_probe(idd)) {
-                       printk(KERN_WARNING
-                              "%s: IOC4 submodule 0x%s probe failed "
-                              "for pci_dev %s.\n",
-                              __FUNCTION__, module_name(is->is_owner),
-                              pci_name(idd->idd_pdev));
-               }
-       }
-       mutex_unlock(&ioc4_mutex);
-
-       return 0;
-
-out_misc_region:
-       release_region(idd->idd_bar0, sizeof(struct ioc4_misc_regs));
-out_pci:
-       kfree(idd);
-out_idd:
-       pci_disable_device(pdev);
-out:
-       return ret;
-}
-
-/* Removes a particular instance of an IOC4 card. */
-static void
-ioc4_remove(struct pci_dev *pdev)
-{
-       struct ioc4_submodule *is;
-       struct ioc4_driver_data *idd;
-
-       idd = pci_get_drvdata(pdev);
-
-       /* Remove this IOC4 from all submodules */
-       mutex_lock(&ioc4_mutex);
-       list_for_each_entry(is, &ioc4_submodules, is_list) {
-               if (is->is_remove && is->is_remove(idd)) {
-                       printk(KERN_WARNING
-                              "%s: IOC4 submodule 0x%s remove failed "
-                              "for pci_dev %s.\n",
-                              __FUNCTION__, module_name(is->is_owner),
-                              pci_name(idd->idd_pdev));
-               }
-       }
-       mutex_unlock(&ioc4_mutex);
-
-       /* Release resources */
-       iounmap(idd->idd_misc_regs);
-       if (!idd->idd_bar0) {
-               printk(KERN_WARNING
-                      "%s: Unable to get IOC4 misc mapping for pci_dev %s. "
-                      "Device removal may be incomplete.\n",
-                      __FUNCTION__, pci_name(idd->idd_pdev));
-       }
-       release_region(idd->idd_bar0, sizeof(struct ioc4_misc_regs));
-
-       /* Disable IOC4 and relinquish */
-       pci_disable_device(pdev);
-
-       /* Remove and free driver data */
-       mutex_lock(&ioc4_mutex);
-       list_del(&idd->idd_list);
-       mutex_unlock(&ioc4_mutex);
-       kfree(idd);
-}
-
-static struct pci_device_id ioc4_id_table[] = {
-       {PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_IOC4, PCI_ANY_ID,
-        PCI_ANY_ID, 0x0b4000, 0xFFFFFF},
-       {0}
-};
-
-static struct pci_driver ioc4_driver = {
-       .name = "IOC4",
-       .id_table = ioc4_id_table,
-       .probe = ioc4_probe,
-       .remove = ioc4_remove,
-};
-
-MODULE_DEVICE_TABLE(pci, ioc4_id_table);
-
-/*********************
- * Module management *
- *********************/
-
-/* Module load */
-static int __devinit
-ioc4_init(void)
-{
-       return pci_register_driver(&ioc4_driver);
-}
-
-/* Module unload */
-static void __devexit
-ioc4_exit(void)
-{
-       pci_unregister_driver(&ioc4_driver);
-}
-
-module_init(ioc4_init);
-module_exit(ioc4_exit);
-
-MODULE_AUTHOR("Brent Casavant - Silicon Graphics, Inc. <bcasavan@sgi.com>");
-MODULE_DESCRIPTION("PCI driver master module for SGI IOC4 Base-IO Card");
-MODULE_LICENSE("GPL");
-
-EXPORT_SYMBOL(ioc4_register_submodule);
-EXPORT_SYMBOL(ioc4_unregister_submodule);
index 29aec77f98be53a758311f78d71cc86c26ec7a64..72025df5561d5baa7836d58c2ea073e8f25728df 100644 (file)
@@ -409,7 +409,7 @@ static int wait_dma_channel_stop(int channel)
        return limit;
 }
 
-static void dma_handler(int channel, void *data, struct pt_regs *regs)
+static void dma_handler(int channel, void *data)
 {
        struct driver_data *drv_data = data;
        struct spi_message *msg = drv_data->cur_msg;
@@ -667,9 +667,9 @@ static irqreturn_t interrupt_transfer(struct driver_data *drv_data)
        return IRQ_HANDLED;
 }
 
-static irqreturn_t ssp_int(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t ssp_int(int irq, void *dev_id)
 {
-       struct driver_data *drv_data = (struct driver_data *)dev_id;
+       struct driver_data *drv_data = dev_id;
        void *reg = drv_data->ioaddr;
 
        if (!drv_data->cur_msg) {
index 5d92a7e5cb41652042da4ad3fa9a70376323aaf8..ff0b04895db06b763b1a225ac983965f4c122372 100644 (file)
@@ -296,8 +296,7 @@ static int mpc83xx_spi_bufs(struct spi_device *spi, struct spi_transfer *t)
        return t->len - mpc83xx_spi->count;
 }
 
-irqreturn_t mpc83xx_spi_irq(s32 irq, void *context_data,
-                           struct pt_regs * ptregs)
+irqreturn_t mpc83xx_spi_irq(s32 irq, void *context_data)
 {
        struct mpc83xx_spi *mpc83xx_spi = context_data;
        u32 event;
index 20eb6e95a3a04a965c68ca1e2ab8a01fe1ff31c4..2ebe1fc4c398e790181ef91da19cf0fbb1fc0cb2 100644 (file)
@@ -196,7 +196,7 @@ static int s3c24xx_spi_txrx(struct spi_device *spi, struct spi_transfer *t)
        return hw->count;
 }
 
-static irqreturn_t s3c24xx_spi_irq(int irq, void *dev, struct pt_regs *regs)
+static irqreturn_t s3c24xx_spi_irq(int irq, void *dev)
 {
        struct s3c24xx_spi *hw = dev;
        unsigned int spsta = readb(hw->regs + S3C2410_SPSTA);
index 622881f26761263dafef90ed1dec8c611950a696..792becdfe6f844737b06ccc6dca776b4934b3e4c 100644 (file)
@@ -347,7 +347,7 @@ static void rs_sched_event(struct dec_serial *info, int event)
        tasklet_schedule(&info->tlet);
 }
 
-static void receive_chars(struct dec_serial *info, struct pt_regs *regs)
+static void receive_chars(struct dec_serial *info)
 {
        struct tty_struct *tty = info->tty;
        unsigned char ch, stat, flag;
@@ -389,7 +389,7 @@ static void receive_chars(struct dec_serial *info, struct pt_regs *regs)
                        if (ch == 0)
                                continue;
                        if (time_before(jiffies, break_pressed + HZ * 5)) {
-                               handle_sysrq(ch, regs, NULL);
+                               handle_sysrq(ch, NULL);
                                break_pressed = 0;
                                continue;
                        }
@@ -490,7 +490,7 @@ static void status_handle(struct dec_serial *info)
 /*
  * This is the serial driver's generic interrupt routine
  */
-static irqreturn_t rs_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t rs_interrupt(int irq, void *dev_id)
 {
        struct dec_serial *info = (struct dec_serial *) dev_id;
        irqreturn_t status = IRQ_NONE;
@@ -518,7 +518,7 @@ static irqreturn_t rs_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                status = IRQ_HANDLED;
 
                if (zs_intreg & CHBRxIP) {
-                       receive_chars(info, regs);
+                       receive_chars(info);
                }
                if (zs_intreg & CHBTxIP) {
                        transmit_chars(info);
index f6b2948ab28856dad684763d2e9e4c52102bf54e..1b601b6cf2a2b78c148395d641955523e07b7515 100644 (file)
@@ -284,6 +284,14 @@ static int samplerate = 100;
 
 module_param(ixjdebug, int, 0);
 
+static struct pci_device_id ixj_pci_tbl[] __devinitdata = {
+       { PCI_VENDOR_ID_QUICKNET, PCI_DEVICE_ID_QUICKNET_XJ,
+         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+       { }
+};
+
+MODULE_DEVICE_TABLE(pci, ixj_pci_tbl);
+
 /************************************************************************
 *
 * ixjdebug meanings are now bit mapped instead of level based
@@ -7683,7 +7691,8 @@ static int __init ixj_probe_pci(int *cnt)
        IXJ *j = NULL;
 
        for (i = 0; i < IXJMAX - *cnt; i++) {
-               pci = pci_find_device(0x15E2, 0x0500, pci);
+               pci = pci_find_device(PCI_VENDOR_ID_QUICKNET,
+                                     PCI_DEVICE_ID_QUICKNET_XJ, pci);
                if (!pci)
                        break;
 
index 97d57cfc343b628fb81f78820c2ad6cea9e5b958..825bf884537a2204ecdd6019093be9f52bfe4e96 100644 (file)
@@ -33,7 +33,6 @@ obj-$(CONFIG_USB_KBTAB)               += input/
 obj-$(CONFIG_USB_MOUSE)                += input/
 obj-$(CONFIG_USB_MTOUCH)       += input/
 obj-$(CONFIG_USB_POWERMATE)    += input/
-obj-$(CONFIG_USB_TRANCEVIBRATOR)+= input/
 obj-$(CONFIG_USB_WACOM)                += input/
 obj-$(CONFIG_USB_XPAD)         += input/
 
@@ -66,6 +65,7 @@ obj-$(CONFIG_USB_PHIDGETSERVO)        += misc/
 obj-$(CONFIG_USB_RIO500)       += misc/
 obj-$(CONFIG_USB_SISUSBVGA)    += misc/
 obj-$(CONFIG_USB_TEST)         += misc/
+obj-$(CONFIG_USB_TRANCEVIBRATOR)+= misc/
 obj-$(CONFIG_USB_USS720)       += misc/
 
 obj-$(CONFIG_USB_ATM)          += atm/
index 04631dcbabbce2673529aeffc7e16131d796d817..e6565633ba0fa7801fa8687ff0580fbb1c92b879 100644 (file)
@@ -171,7 +171,7 @@ struct cxacru_data {
 };
 
 /* the following three functions are stolen from drivers/usb/core/message.c */
-static void cxacru_blocking_completion(struct urb *urb, struct pt_regs *regs)
+static void cxacru_blocking_completion(struct urb *urb)
 {
        complete((struct completion *)urb->context);
 }
@@ -793,6 +793,9 @@ static const struct usb_device_id cxacru_usb_ids[] = {
        { /* V = Conexant                       P = ADSL modem                          */
                USB_DEVICE(0x0572, 0xcb06),     .driver_info = (unsigned long) &cxacru_cb00
        },
+       { /* V = Conexant                       P = ADSL modem (ZTE ZXDSL 852)          */
+               USB_DEVICE(0x0572, 0xcb07),     .driver_info = (unsigned long) &cxacru_cb00
+       },
        { /* V = Olitec                         P = ADSL modem version 2                */
                USB_DEVICE(0x08e3, 0x0100),     .driver_info = (unsigned long) &cxacru_cafe
        },
index 956b7a1e8af98c0a37056f280c371b6dd785a5dd..c870c804470fb09d9a286764b7fc09b8db415a50 100644 (file)
@@ -55,7 +55,6 @@ static const char speedtch_driver_name[] = "speedtch";
 #define OFFSET_d       9               /* size 4 */
 #define OFFSET_e       13              /* size 1 */
 #define OFFSET_f       14              /* size 1 */
-#define TOTAL          15
 
 #define SIZE_7         1
 #define SIZE_b         8
@@ -79,6 +78,18 @@ static int dl_512_first = DEFAULT_DL_512_FIRST;
 static int enable_isoc = DEFAULT_ENABLE_ISOC;
 static int sw_buffering = DEFAULT_SW_BUFFERING;
 
+#define DEFAULT_B_MAX_DSL      8128
+#define DEFAULT_MODEM_MODE     11
+#define MODEM_OPTION_LENGTH    16
+static const unsigned char DEFAULT_MODEM_OPTION[MODEM_OPTION_LENGTH] = {
+       0x10, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+static unsigned int BMaxDSL = DEFAULT_B_MAX_DSL;
+static unsigned char ModemMode = DEFAULT_MODEM_MODE;
+static unsigned char ModemOption[MODEM_OPTION_LENGTH];
+static int num_ModemOption;
+
 module_param(altsetting, uint, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(altsetting,
                "Alternative setting for data interface (bulk_default: "
@@ -100,6 +111,17 @@ MODULE_PARM_DESC(sw_buffering,
                 "Enable software buffering (default: "
                 __MODULE_STRING(DEFAULT_SW_BUFFERING) ")");
 
+module_param(BMaxDSL, uint, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(BMaxDSL,
+               "default: " __MODULE_STRING(DEFAULT_B_MAX_DSL));
+
+module_param(ModemMode, byte, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(ModemMode,
+               "default: " __MODULE_STRING(DEFAULT_MODEM_MODE));
+
+module_param_array(ModemOption, byte, &num_ModemOption, S_IRUGO);
+MODULE_PARM_DESC(ModemOption, "default: 0x10,0x00,0x00,0x00,0x20");
+
 #define INTERFACE_DATA         1
 #define ENDPOINT_INT           0x81
 #define ENDPOINT_BULK_DATA     0x07
@@ -108,10 +130,17 @@ MODULE_PARM_DESC(sw_buffering,
 
 #define hex2int(c) ( (c >= '0') && (c <= '9') ? (c - '0') : ((c & 0xf) + 9) )
 
+struct speedtch_params {
+       unsigned int altsetting;
+       unsigned int BMaxDSL;
+       unsigned char ModemMode;
+       unsigned char ModemOption[MODEM_OPTION_LENGTH];
+};
+
 struct speedtch_instance_data {
        struct usbatm_data *usbatm;
 
-       unsigned int altsetting;
+       struct speedtch_params params; /* set in probe, constant afterwards */
 
        struct work_struct status_checker;
 
@@ -123,7 +152,7 @@ struct speedtch_instance_data {
        struct urb *int_urb;
        unsigned char int_data[16];
 
-       unsigned char scratch_buffer[TOTAL];
+       unsigned char scratch_buffer[16];
 };
 
 /***************
@@ -186,6 +215,34 @@ static void speedtch_test_sequence(struct speedtch_instance_data *instance)
                              0x01, 0x40, 0x04, 0x00, buf, 3, CTRL_TIMEOUT);
        if (ret < 0)
                usb_warn(usbatm, "%s failed on URB150: %d\n", __func__, ret);
+
+       /* Extra initialisation in recent drivers - gives higher speeds */
+
+       /* URBext1 */
+       buf[0] = instance->params.ModemMode;
+       ret = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
+                             0x01, 0x40, 0x11, 0x00, buf, 1, CTRL_TIMEOUT);
+       if (ret < 0)
+               usb_warn(usbatm, "%s failed on URBext1: %d\n", __func__, ret);
+
+       /* URBext2 */
+       /* This seems to be the one which actually triggers the higher sync
+          rate -- it does require the new firmware too, although it works OK
+          with older firmware */
+       ret = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
+                             0x01, 0x40, 0x14, 0x00,
+                             instance->params.ModemOption,
+                             MODEM_OPTION_LENGTH, CTRL_TIMEOUT);
+       if (ret < 0)
+               usb_warn(usbatm, "%s failed on URBext2: %d\n", __func__, ret);
+
+       /* URBext3 */
+       buf[0] = instance->params.BMaxDSL & 0xff;
+       buf[1] = instance->params.BMaxDSL >> 8;
+       ret = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
+                             0x01, 0x40, 0x12, 0x00, buf, 2, CTRL_TIMEOUT);
+       if (ret < 0)
+               usb_warn(usbatm, "%s failed on URBext3: %d\n", __func__, ret);
 }
 
 static int speedtch_upload_firmware(struct speedtch_instance_data *instance,
@@ -285,8 +342,8 @@ static int speedtch_upload_firmware(struct speedtch_instance_data *instance,
           because we're in our own kernel thread anyway. */
        msleep_interruptible(1000);
 
-       if ((ret = usb_set_interface(usb_dev, INTERFACE_DATA, instance->altsetting)) < 0) {
-               usb_err(usbatm, "%s: setting interface to %d failed (%d)!\n", __func__, instance->altsetting, ret);
+       if ((ret = usb_set_interface(usb_dev, INTERFACE_DATA, instance->params.altsetting)) < 0) {
+               usb_err(usbatm, "%s: setting interface to %d failed (%d)!\n", __func__, instance->params.altsetting, ret);
                goto out_free;
        }
 
@@ -372,7 +429,7 @@ static int speedtch_read_status(struct speedtch_instance_data *instance)
        unsigned char *buf = instance->scratch_buffer;
        int ret;
 
-       memset(buf, 0, TOTAL);
+       memset(buf, 0, 16);
 
        ret = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
                              0x12, 0xc0, 0x07, 0x00, buf + OFFSET_7, SIZE_7,
@@ -547,7 +604,7 @@ static void speedtch_resubmit_int(unsigned long data)
        }
 }
 
-static void speedtch_handle_int(struct urb *int_urb, struct pt_regs *regs)
+static void speedtch_handle_int(struct urb *int_urb)
 {
        struct speedtch_instance_data *instance = int_urb->context;
        struct usbatm_data *usbatm = instance->usbatm;
@@ -746,17 +803,21 @@ static int speedtch_bind(struct usbatm_data *usbatm,
 
        instance->usbatm = usbatm;
 
-       /* altsetting and enable_isoc may change at any moment, so take a snapshot */
-       instance->altsetting = altsetting;
+       /* module parameters may change at any moment, so take a snapshot */
+       instance->params.altsetting = altsetting;
+       instance->params.BMaxDSL = BMaxDSL;
+       instance->params.ModemMode = ModemMode;
+       memcpy(instance->params.ModemOption, DEFAULT_MODEM_OPTION, MODEM_OPTION_LENGTH);
+       memcpy(instance->params.ModemOption, ModemOption, num_ModemOption);
        use_isoc = enable_isoc;
 
-       if (instance->altsetting)
-               if ((ret = usb_set_interface(usb_dev, INTERFACE_DATA, instance->altsetting)) < 0) {
-                       usb_err(usbatm, "%s: setting interface to %2d failed (%d)!\n", __func__, instance->altsetting, ret);
-                       instance->altsetting = 0; /* fall back to default */
+       if (instance->params.altsetting)
+               if ((ret = usb_set_interface(usb_dev, INTERFACE_DATA, instance->params.altsetting)) < 0) {
+                       usb_err(usbatm, "%s: setting interface to %2d failed (%d)!\n", __func__, instance->params.altsetting, ret);
+                       instance->params.altsetting = 0; /* fall back to default */
                }
 
-       if (!instance->altsetting && use_isoc)
+       if (!instance->params.altsetting && use_isoc)
                if ((ret = usb_set_interface(usb_dev, INTERFACE_DATA, DEFAULT_ISOC_ALTSETTING)) < 0) {
                        usb_dbg(usbatm, "%s: setting interface to %2d failed (%d)!\n", __func__, DEFAULT_ISOC_ALTSETTING, ret);
                        use_isoc = 0; /* fall back to bulk */
@@ -783,14 +844,14 @@ static int speedtch_bind(struct usbatm_data *usbatm,
                        usb_info(usbatm, "isochronous transfer not supported - using bulk\n");
        }
 
-       if (!use_isoc && !instance->altsetting)
+       if (!use_isoc && !instance->params.altsetting)
                if ((ret = usb_set_interface(usb_dev, INTERFACE_DATA, DEFAULT_BULK_ALTSETTING)) < 0) {
                        usb_err(usbatm, "%s: setting interface to %2d failed (%d)!\n", __func__, DEFAULT_BULK_ALTSETTING, ret);
                        goto fail_free;
                }
 
-       if (!instance->altsetting)
-               instance->altsetting = use_isoc ? DEFAULT_ISOC_ALTSETTING : DEFAULT_BULK_ALTSETTING;
+       if (!instance->params.altsetting)
+               instance->params.altsetting = use_isoc ? DEFAULT_ISOC_ALTSETTING : DEFAULT_BULK_ALTSETTING;
 
        usbatm->flags |= (use_isoc ? UDSL_USE_ISOC : 0);
 
index 465961a26e4a9131af4fe96671fe42eac202c16f..f6b9f7e1f716d5dd05c84b4bf836cfc57212adff 100644 (file)
@@ -68,7 +68,7 @@
 
 #include "usbatm.h"
 
-#define EAGLEUSBVERSION "ueagle 1.3"
+#define EAGLEUSBVERSION "ueagle 1.4"
 
 
 /*
                        dev_dbg(&(usb_dev)->dev, \
                                "[ueagle-atm dbg] %s: " format, \
                                        __FUNCTION__, ##args); \
-       } while (0)
+       } while (0)
 
 #define uea_vdbg(usb_dev, format, args...)     \
        do { \
                if (debug >= 2) \
                        dev_dbg(&(usb_dev)->dev, \
                                "[ueagle-atm vdbg]  " format, ##args); \
-       } while (0)
+       } while (0)
 
 #define uea_enters(usb_dev) \
        uea_vdbg(usb_dev, "entering %s\n", __FUNCTION__)
@@ -218,8 +218,8 @@ enum {
 #define UEA_CHIP_VERSION(x) \
        ((x)->driver_info & 0xf)
 
-#define IS_ISDN(sc) \
-       (le16_to_cpu(sc->usb_dev->descriptor.bcdDevice) & 0x80)
+#define IS_ISDN(usb_dev) \
+       (le16_to_cpu((usb_dev)->descriptor.bcdDevice) & 0x80)
 
 #define INS_TO_USBDEV(ins) ins->usb_dev
 
@@ -625,12 +625,12 @@ static int request_dsp(struct uea_softc *sc)
        char *dsp_name;
 
        if (UEA_CHIP_VERSION(sc) == ADI930) {
-               if (IS_ISDN(sc))
+               if (IS_ISDN(sc->usb_dev))
                        dsp_name = FW_DIR "DSP9i.bin";
                else
                        dsp_name = FW_DIR "DSP9p.bin";
        } else {
-               if (IS_ISDN(sc))
+               if (IS_ISDN(sc->usb_dev))
                        dsp_name = FW_DIR "DSPei.bin";
                else
                        dsp_name = FW_DIR "DSPep.bin";
@@ -744,7 +744,7 @@ static inline void wake_up_cmv_ack(struct uea_softc *sc)
 
 static inline int wait_cmv_ack(struct uea_softc *sc)
 {
-       int ret = wait_event_timeout(sc->cmv_ack_wait,
+       int ret = wait_event_interruptible_timeout(sc->cmv_ack_wait,
                                                   sc->cmv_ack, ACK_TIMEOUT);
        sc->cmv_ack = 0;
 
@@ -885,7 +885,8 @@ static int uea_stat(struct uea_softc *sc)
                break;
 
        case 3:         /* fail ... */
-               uea_info(INS_TO_USBDEV(sc), "modem synchronization failed\n");
+               uea_info(INS_TO_USBDEV(sc), "modem synchronization failed"
+                               " (may be try other cmv/dsp)\n");
                return -EAGAIN;
 
        case 4 ... 6:   /* test state */
@@ -913,12 +914,6 @@ static int uea_stat(struct uea_softc *sc)
                        release_firmware(sc->dsp_firm);
                        sc->dsp_firm = NULL;
                }
-
-               ret = uea_read_cmv(sc, SA_INFO, 10, &sc->stats.phy.firmid);
-               if (ret < 0)
-                       return ret;
-               uea_info(INS_TO_USBDEV(sc), "ATU-R firmware version : %x\n",
-                               sc->stats.phy.firmid);
        }
 
        /* always update it as atm layer could not be init when we switch to
@@ -1033,9 +1028,9 @@ static int request_cmvs(struct uea_softc *sc,
 
        if (cmv_file[sc->modem_index] == NULL) {
                if (UEA_CHIP_VERSION(sc) == ADI930)
-                       file = (IS_ISDN(sc)) ? "CMV9i.bin" : "CMV9p.bin";
+                       file = (IS_ISDN(sc->usb_dev)) ? "CMV9i.bin" : "CMV9p.bin";
                else
-                       file = (IS_ISDN(sc)) ? "CMVei.bin" : "CMVep.bin";
+                       file = (IS_ISDN(sc->usb_dev)) ? "CMVei.bin" : "CMVep.bin";
        } else
                file = cmv_file[sc->modem_index];
 
@@ -1131,6 +1126,13 @@ static int uea_start_reset(struct uea_softc *sc)
        if (ret < 0)
                return ret;
 
+       /* Dump firmware version */
+       ret = uea_read_cmv(sc, SA_INFO, 10, &sc->stats.phy.firmid);
+       if (ret < 0)
+               return ret;
+       uea_info(INS_TO_USBDEV(sc), "ATU-R firmware version : %x\n",
+                       sc->stats.phy.firmid);
+
        /* get options */
        ret = len = request_cmvs(sc, &cmvs, &cmvs_fw);
        if (ret < 0)
@@ -1147,6 +1149,8 @@ static int uea_start_reset(struct uea_softc *sc)
        /* Enter in R-ACT-REQ */
        ret = uea_write_cmv(sc, SA_CNTL, 0, 2);
        uea_vdbg(INS_TO_USBDEV(sc), "Entering in R-ACT-REQ state\n");
+       uea_info(INS_TO_USBDEV(sc), "Modem started, "
+               "waiting synchronization\n");
 out:
        release_firmware(cmvs_fw);
        sc->reset = 0;
@@ -1172,7 +1176,10 @@ static int uea_kthread(void *data)
                if (!ret)
                        ret = uea_stat(sc);
                if (ret != -EAGAIN)
-                       msleep(1000);
+                       msleep_interruptible(1000);
+               if (try_to_freeze())
+                       uea_err(INS_TO_USBDEV(sc), "suspend/resume not supported, "
+                               "please unplug/replug your modem\n");
        }
        uea_leaves(INS_TO_USBDEV(sc));
        return ret;
@@ -1297,7 +1304,7 @@ bad1:
 /*
  * interrupt handler
  */
-static void uea_intr(struct urb *urb, struct pt_regs *regs)
+static void uea_intr(struct urb *urb)
 {
        struct uea_softc *sc = urb->context;
        struct intr_pkt *intr = urb->transfer_buffer;
@@ -1566,6 +1573,7 @@ UEA_ATTR(uscorr, 0);
 UEA_ATTR(dscorr, 0);
 UEA_ATTR(usunc, 0);
 UEA_ATTR(dsunc, 0);
+UEA_ATTR(firmid, 0);
 
 /* Retrieve the device End System Identifier (MAC) */
 
@@ -1597,7 +1605,7 @@ static int uea_heavy(struct usbatm_data *usbatm, struct usb_interface *intf)
 {
        struct uea_softc *sc = usbatm->driver_data;
 
-       wait_event(sc->sync_q, IS_OPERATIONAL(sc));
+       wait_event_interruptible(sc->sync_q, IS_OPERATIONAL(sc));
 
        return 0;
 
@@ -1639,16 +1647,13 @@ static struct attribute *attrs[] = {
        &dev_attr_stat_dscorr.attr,
        &dev_attr_stat_usunc.attr,
        &dev_attr_stat_dsunc.attr,
+       &dev_attr_stat_firmid.attr,
+       NULL,
 };
 static struct attribute_group attr_grp = {
        .attrs = attrs,
 };
 
-static int create_fs_entries(struct usb_interface *intf)
-{
-       return sysfs_create_group(&intf->dev.kobj, &attr_grp);
-}
-
 static int uea_bind(struct usbatm_data *usbatm, struct usb_interface *intf,
                   const struct usb_device_id *id)
 {
@@ -1708,31 +1713,25 @@ static int uea_bind(struct usbatm_data *usbatm, struct usb_interface *intf,
                }
        }
 
+       ret = sysfs_create_group(&intf->dev.kobj, &attr_grp);
+       if (ret < 0)
+               goto error;
+
        ret = uea_boot(sc);
-       if (ret < 0) {
-               kfree(sc);
-               return ret;
-       }
+       if (ret < 0)
+               goto error;
 
-       ret = create_fs_entries(intf);
-       if (ret) {
-               uea_stop(sc);
-               kfree(sc);
-               return ret;
-       }
        return 0;
-}
-
-static void destroy_fs_entries(struct usb_interface *intf)
-{
-       sysfs_remove_group(&intf->dev.kobj, &attr_grp);
+error:
+       kfree(sc);
+       return ret;
 }
 
 static void uea_unbind(struct usbatm_data *usbatm, struct usb_interface *intf)
 {
        struct uea_softc *sc = usbatm->driver_data;
 
-       destroy_fs_entries(intf);
+       sysfs_remove_group(&intf->dev.kobj, &attr_grp);
        uea_stop(sc);
        kfree(sc);
 }
@@ -1753,10 +1752,10 @@ static int uea_probe(struct usb_interface *intf, const struct usb_device_id *id)
        struct usb_device *usb = interface_to_usbdev(intf);
 
        uea_enters(usb);
-       uea_info(usb, "ADSL device founded vid (%#X) pid (%#X) : %s\n",
+       uea_info(usb, "ADSL device founded vid (%#X) pid (%#X) : %s %s\n",
               le16_to_cpu(usb->descriptor.idVendor),
               le16_to_cpu(usb->descriptor.idProduct),
-              chip_name[UEA_CHIP_VERSION(id)]);
+              chip_name[UEA_CHIP_VERSION(id)], IS_ISDN(usb)?"isdn":"pots");
 
        usb_reset_device(usb);
 
index a38701c742c3209cb0599faf558099b51a0db452..ec63b0ee07437312f8c9abc6a4f3dfbe057d7d70 100644 (file)
@@ -254,7 +254,7 @@ static int usbatm_submit_urb(struct urb *urb)
        return ret;
 }
 
-static void usbatm_complete(struct urb *urb, struct pt_regs *regs)
+static void usbatm_complete(struct urb *urb)
 {
        struct usbatm_channel *channel = urb->context;
        unsigned long flags;
@@ -1001,6 +1001,7 @@ static int usbatm_do_heavy_init(void *arg)
 
        daemonize(instance->driver->driver_name);
        allow_signal(SIGTERM);
+       instance->thread_pid = current->pid;
 
        complete(&instance->thread_started);
 
@@ -1025,10 +1026,6 @@ static int usbatm_heavy_init(struct usbatm_data *instance)
                return ret;
        }
 
-       mutex_lock(&instance->serialize);
-       instance->thread_pid = ret;
-       mutex_unlock(&instance->serialize);
-
        wait_for_completion(&instance->thread_started);
 
        return 0;
index 71288295df2f7f5113c30a25fc1d054c019319aa..9a9012fd284b48668e7feb7d46b32bcfd97810f2 100644 (file)
@@ -218,7 +218,7 @@ static int acm_write_start(struct acm *acm)
  */
 
 /* control interface reports status changes with "interrupt" transfers */
-static void acm_ctrl_irq(struct urb *urb, struct pt_regs *regs)
+static void acm_ctrl_irq(struct urb *urb)
 {
        struct acm *acm = urb->context;
        struct usb_cdc_notification *dr = urb->transfer_buffer;
@@ -285,7 +285,7 @@ exit:
 }
 
 /* data interface returns incoming bytes, or we got unthrottled */
-static void acm_read_bulk(struct urb *urb, struct pt_regs *regs)
+static void acm_read_bulk(struct urb *urb)
 {
        struct acm_rb *buf;
        struct acm_ru *rcv = urb->context;
@@ -325,7 +325,7 @@ static void acm_rx_tasklet(unsigned long _acm)
        struct acm_rb *buf;
        struct tty_struct *tty = acm->tty;
        struct acm_ru *rcv;
-       //unsigned long flags;
+       unsigned long flags;
        int i = 0;
        dbg("Entering acm_rx_tasklet");
 
@@ -333,15 +333,15 @@ static void acm_rx_tasklet(unsigned long _acm)
                return;
 
 next_buffer:
-       spin_lock(&acm->read_lock);
+       spin_lock_irqsave(&acm->read_lock, flags);
        if (list_empty(&acm->filled_read_bufs)) {
-               spin_unlock(&acm->read_lock);
+               spin_unlock_irqrestore(&acm->read_lock, flags);
                goto urbs;
        }
        buf = list_entry(acm->filled_read_bufs.next,
                         struct acm_rb, list);
        list_del(&buf->list);
-       spin_unlock(&acm->read_lock);
+       spin_unlock_irqrestore(&acm->read_lock, flags);
 
        dbg("acm_rx_tasklet: procesing buf 0x%p, size = %d", buf, buf->size);
 
@@ -356,29 +356,29 @@ next_buffer:
                memmove(buf->base, buf->base + i, buf->size - i);
                buf->size -= i;
                spin_unlock(&acm->throttle_lock);
-               spin_lock(&acm->read_lock);
+               spin_lock_irqsave(&acm->read_lock, flags);
                list_add(&buf->list, &acm->filled_read_bufs);
-               spin_unlock(&acm->read_lock);
+               spin_unlock_irqrestore(&acm->read_lock, flags);
                return;
        }
        spin_unlock(&acm->throttle_lock);
 
-       spin_lock(&acm->read_lock);
+       spin_lock_irqsave(&acm->read_lock, flags);
        list_add(&buf->list, &acm->spare_read_bufs);
-       spin_unlock(&acm->read_lock);
+       spin_unlock_irqrestore(&acm->read_lock, flags);
        goto next_buffer;
 
 urbs:
        while (!list_empty(&acm->spare_read_bufs)) {
-               spin_lock(&acm->read_lock);
+               spin_lock_irqsave(&acm->read_lock, flags);
                if (list_empty(&acm->spare_read_urbs)) {
-                       spin_unlock(&acm->read_lock);
+                       spin_unlock_irqrestore(&acm->read_lock, flags);
                        return;
                }
                rcv = list_entry(acm->spare_read_urbs.next,
                                 struct acm_ru, list);
                list_del(&rcv->list);
-               spin_unlock(&acm->read_lock);
+               spin_unlock_irqrestore(&acm->read_lock, flags);
 
                buf = list_entry(acm->spare_read_bufs.next,
                                 struct acm_rb, list);
@@ -400,16 +400,16 @@ urbs:
                   free-urbs-pool and resubmited ASAP */
                if (usb_submit_urb(rcv->urb, GFP_ATOMIC) < 0) {
                        list_add(&buf->list, &acm->spare_read_bufs);
-                       spin_lock(&acm->read_lock);
+                       spin_lock_irqsave(&acm->read_lock, flags);
                        list_add(&rcv->list, &acm->spare_read_urbs);
-                       spin_unlock(&acm->read_lock);
+                       spin_unlock_irqrestore(&acm->read_lock, flags);
                        return;
                }
        }
 }
 
 /* data interface wrote those outgoing bytes */
-static void acm_write_bulk(struct urb *urb, struct pt_regs *regs)
+static void acm_write_bulk(struct urb *urb)
 {
        struct acm *acm = (struct acm *)urb->context;
 
@@ -1083,6 +1083,9 @@ static struct usb_device_id acm_ids[] = {
        { USB_DEVICE(0x0482, 0x0203), /* KYOCERA AH-K3001V */
        .driver_info = NO_UNION_NORMAL, /* has no union descriptor */
        },
+       { USB_DEVICE(0x079b, 0x000f), /* BT On-Air USB MODEM */
+       .driver_info = NO_UNION_NORMAL, /* has no union descriptor */
+       },
        { USB_DEVICE(0x0ace, 0x1608), /* ZyDAS 56K USB MODEM */
        .driver_info = SINGLE_RX_URB, /* firmware bug */
        },
index 9cac11ca1bb73f83cada5a12f77bf4f6ebb4fc11..809d465eb25726dfd0806869f99f4725f8089c43 100644 (file)
@@ -154,6 +154,7 @@ struct usblp {
        unsigned char           used;                   /* True if open */
        unsigned char           present;                /* True if not disconnected */
        unsigned char           bidir;                  /* interface is bidirectional */
+       unsigned char           sleeping;               /* interface is suspended */
        unsigned char           *device_id_string;      /* IEEE 1284 DEVICE ID string (ptr) */
                                                        /* first 2 bytes are (big-endian) length */
 };
@@ -183,6 +184,7 @@ static void usblp_dump(struct usblp *usblp) {
        dbg("quirks=%d", usblp->quirks);
        dbg("used=%d", usblp->used);
        dbg("bidir=%d", usblp->bidir);
+       dbg("sleeping=%d", usblp->sleeping);
        dbg("device_id_string=\"%s\"",
                usblp->device_id_string ?
                        usblp->device_id_string + 2 :
@@ -271,7 +273,7 @@ static int proto_bias = -1;
  * URB callback.
  */
 
-static void usblp_bulk_read(struct urb *urb, struct pt_regs *regs)
+static void usblp_bulk_read(struct urb *urb)
 {
        struct usblp *usblp = urb->context;
 
@@ -288,7 +290,7 @@ unplug:
        wake_up_interruptible(&usblp->wait);
 }
 
-static void usblp_bulk_write(struct urb *urb, struct pt_regs *regs)
+static void usblp_bulk_write(struct urb *urb)
 {
        struct usblp *usblp = urb->context;
 
@@ -338,6 +340,20 @@ static int usblp_check_status(struct usblp *usblp, int err)
        return newerr;
 }
 
+static int handle_bidir (struct usblp *usblp)
+{
+       if (usblp->bidir && usblp->used && !usblp->sleeping) {
+               usblp->readcount = 0;
+               usblp->readurb->dev = usblp->dev;
+               if (usb_submit_urb(usblp->readurb, GFP_KERNEL) < 0) {
+                       usblp->used = 0;
+                       return -EIO;
+               }
+       }
+
+       return 0;
+}
+
 /*
  * File op functions.
  */
@@ -390,14 +406,9 @@ static int usblp_open(struct inode *inode, struct file *file)
        usblp->writeurb->status = 0;
        usblp->readurb->status = 0;
 
-       if (usblp->bidir) {
-               usblp->readcount = 0;
-               usblp->readurb->dev = usblp->dev;
-               if (usb_submit_urb(usblp->readurb, GFP_KERNEL) < 0) {
-                       retval = -EIO;
-                       usblp->used = 0;
-                       file->private_data = NULL;
-               }
+       if (handle_bidir(usblp) < 0) {
+               file->private_data = NULL;
+               retval = -EIO;
        }
 out:
        mutex_unlock (&usblp_mutex);
@@ -460,6 +471,11 @@ static long usblp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                goto done;
        }
 
+       if (usblp->sleeping) {
+               retval = -ENODEV;
+               goto done;
+       }
+
        dbg("usblp_ioctl: cmd=0x%x (%c nr=%d len=%d dir=%d)", cmd, _IOC_TYPE(cmd),
                _IOC_NR(cmd), _IOC_SIZE(cmd), _IOC_DIR(cmd) );
 
@@ -658,6 +674,11 @@ static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t
                        return -ENODEV;
                }
 
+               if (usblp->sleeping) {
+                       up (&usblp->sem);
+                       return writecount ? writecount : -ENODEV;
+               }
+
                if (usblp->writeurb->status != 0) {
                        if (usblp->quirks & USBLP_QUIRK_BIDIR) {
                                if (!usblp->wcomplete)
@@ -749,6 +770,11 @@ static ssize_t usblp_read(struct file *file, char __user *buffer, size_t count,
                goto done;
        }
 
+       if (usblp->sleeping) {
+               count = -ENODEV;
+               goto done;
+       }
+
        if (usblp->readurb->status) {
                err("usblp%d: error %d reading from printer",
                        usblp->minor, usblp->readurb->status);
@@ -1167,6 +1193,41 @@ static void usblp_disconnect(struct usb_interface *intf)
        mutex_unlock (&usblp_mutex);
 }
 
+static int usblp_suspend (struct usb_interface *intf, pm_message_t message)
+{
+       struct usblp *usblp = usb_get_intfdata (intf);
+
+       /* this races against normal access and open */
+       mutex_lock (&usblp_mutex);
+       down (&usblp->sem);
+       /* we take no more IO */
+       usblp->sleeping = 1;
+       /* we wait for anything printing */
+       wait_event (usblp->wait, usblp->wcomplete || !usblp->present);
+       usblp_unlink_urbs(usblp);
+       up (&usblp->sem);
+       mutex_unlock (&usblp_mutex);
+
+       return 0;
+}
+
+static int usblp_resume (struct usb_interface *intf)
+{
+       struct usblp *usblp = usb_get_intfdata (intf);
+       int r;
+
+       mutex_lock (&usblp_mutex);
+       down (&usblp->sem);
+
+       usblp->sleeping = 0;
+       r = handle_bidir (usblp);
+
+       up (&usblp->sem);
+       mutex_unlock (&usblp_mutex);
+
+       return r;
+}
+
 static struct usb_device_id usblp_ids [] = {
        { USB_DEVICE_INFO(7, 1, 1) },
        { USB_DEVICE_INFO(7, 1, 2) },
@@ -1183,6 +1244,8 @@ static struct usb_driver usblp_driver = {
        .name =         "usblp",
        .probe =        usblp_probe,
        .disconnect =   usblp_disconnect,
+       .suspend =      usblp_suspend,
+       .resume =       usblp_resume,
        .id_table =     usblp_ids,
 };
 
index 3f509beb88e4771906f4badd0237e8ff45b59b24..fed92be63b5ebf2ff0f5247b23b7bd349f4dcd85 100644 (file)
@@ -304,7 +304,7 @@ static void snoop_urb(struct urb *urb, void __user *userurb)
        printk("\n");
 }
 
-static void async_completed(struct urb *urb, struct pt_regs *regs)
+static void async_completed(struct urb *urb)
 {
         struct async *as = urb->context;
         struct dev_state *ps = as->ps;
@@ -1216,7 +1216,7 @@ static int proc_submiturb_compat(struct dev_state *ps, void __user *arg)
 {
        struct usbdevfs_urb uurb;
 
-       if (get_urb32(&uurb,(struct usbdevfs_urb32 *)arg))
+       if (get_urb32(&uurb,(struct usbdevfs_urb32 __user *)arg))
                return -EFAULT;
 
        return proc_do_submiturb(ps, &uurb, ((struct usbdevfs_urb32 __user *)arg)->iso_frame_desc, arg);
@@ -1251,7 +1251,7 @@ static int processcompl_compat(struct async *as, void __user * __user *arg)
        }
 
        free_async(as);
-       if (put_user((u32)(u64)addr, (u32 __user *)arg))
+       if (put_user(ptr_to_compat(addr), (u32 __user *)arg))
                return -EFAULT;
        return 0;
 }
@@ -1520,7 +1520,7 @@ static int usbdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
 
        case USBDEVFS_IOCTL32:
                snoop(&dev->dev, "%s: IOCTL\n", __FUNCTION__);
-               ret = proc_ioctl_compat(ps, (compat_uptr_t)(long)p);
+               ret = proc_ioctl_compat(ps, ptr_to_compat(p));
                break;
 #endif
 
@@ -1588,15 +1588,18 @@ const struct file_operations usbfs_device_file_operations = {
        .release =      usbdev_release,
 };
 
-static void usbdev_add(struct usb_device *dev)
+static int usbdev_add(struct usb_device *dev)
 {
        int minor = ((dev->bus->busnum-1) * 128) + (dev->devnum-1);
 
        dev->class_dev = class_device_create(usb_device_class, NULL,
                                MKDEV(USB_DEVICE_MAJOR, minor), &dev->dev,
                                "usbdev%d.%d", dev->bus->busnum, dev->devnum);
+       if (IS_ERR(dev->class_dev))
+               return PTR_ERR(dev->class_dev);
 
        dev->class_dev->class_data = dev;
+       return 0;
 }
 
 static void usbdev_remove(struct usb_device *dev)
@@ -1609,7 +1612,8 @@ static int usbdev_notify(struct notifier_block *self, unsigned long action,
 {
        switch (action) {
        case USB_DEVICE_ADD:
-               usbdev_add(dev);
+               if (usbdev_add(dev))
+                       return NOTIFY_BAD;
                break;
        case USB_DEVICE_REMOVE:
                usbdev_remove(dev);
index 3ebb90149e93ef7319ae529c22da546032172730..3b2d137912beb6dce921d925adccff2873bb6f86 100644 (file)
@@ -223,7 +223,7 @@ int usb_create_ep_files(struct device *parent,
        ep_dev = kzalloc(sizeof(*ep_dev), GFP_KERNEL);
        if (!ep_dev) {
                retval = -ENOMEM;
-               goto exit;
+               goto error_alloc;
        }
 
        /* fun calculation to determine the minor of this endpoint */
@@ -241,33 +241,31 @@ int usb_create_ep_files(struct device *parent,
 
        retval = device_register(&ep_dev->dev);
        if (retval)
-               goto error;
+               goto error_register;
        retval = sysfs_create_group(&ep_dev->dev.kobj, &ep_dev_attr_grp);
        if (retval)
                goto error_group;
 
-       endpoint->ep_dev = ep_dev;
-
        /* create the symlink to the old-style "ep_XX" directory */
        sprintf(name, "ep_%02x", endpoint->desc.bEndpointAddress);
-       retval = sysfs_create_link(&parent->kobj,
-                                  &endpoint->ep_dev->dev.kobj, name);
+       retval = sysfs_create_link(&parent->kobj, &ep_dev->dev.kobj, name);
        if (retval)
                goto error_link;
-exit:
+       endpoint->ep_dev = ep_dev;
        return retval;
 
 error_link:
        sysfs_remove_group(&ep_dev->dev.kobj, &ep_dev_attr_grp);
-
 error_group:
        device_unregister(&ep_dev->dev);
-       endpoint->ep_dev = NULL;
        destroy_endpoint_class();
        return retval;
-error:
+
+error_register:
        kfree(ep_dev);
+error_alloc:
        destroy_endpoint_class();
+exit:
        return retval;
 }
 
@@ -282,8 +280,6 @@ void usb_remove_ep_files(struct usb_host_endpoint *endpoint)
                sysfs_remove_group(&endpoint->ep_dev->dev.kobj, &ep_dev_attr_grp);
                device_unregister(&endpoint->ep_dev->dev);
                endpoint->ep_dev = NULL;
+               destroy_endpoint_class();
        }
-       destroy_endpoint_class();
 }
-
-
index e658089f7b504d9a6ba90d42bdff3abc57b150f3..afa2dd203329d7c4787d62f5a12a54dcef956171 100644 (file)
@@ -522,7 +522,7 @@ error:
        if (urb->status == -EINPROGRESS)
                urb->status = status;
        spin_unlock (&urb->lock);
-       usb_hcd_giveback_urb (hcd, urb, NULL);
+       usb_hcd_giveback_urb (hcd, urb);
        local_irq_restore (flags);
        return 0;
 }
@@ -572,7 +572,7 @@ void usb_hcd_poll_rh_status(struct usb_hcd *hcd)
 
                /* local irqs are always blocked in completions */
                if (length > 0)
-                       usb_hcd_giveback_urb (hcd, urb, NULL);
+                       usb_hcd_giveback_urb (hcd, urb);
                else
                        hcd->poll_pending = 1;
                local_irq_restore (flags);
@@ -656,7 +656,7 @@ static int usb_rh_urb_dequeue (struct usb_hcd *hcd, struct urb *urb)
                        urb = NULL;             /* wasn't fully queued */
                spin_unlock (&hcd_root_hub_lock);
                if (urb)
-                       usb_hcd_giveback_urb (hcd, urb, NULL);
+                       usb_hcd_giveback_urb (hcd, urb);
                local_irq_restore (flags);
        }
 
@@ -1498,7 +1498,6 @@ EXPORT_SYMBOL (usb_bus_start_enum);
  * usb_hcd_giveback_urb - return URB from HCD to device driver
  * @hcd: host controller returning the URB
  * @urb: urb being returned to the USB device driver.
- * @regs: pt_regs, passed down to the URB completion handler
  * Context: in_interrupt()
  *
  * This hands the URB from HCD to its USB device driver, using its
@@ -1507,7 +1506,7 @@ EXPORT_SYMBOL (usb_bus_start_enum);
  * the device driver won't cause problems if it frees, modifies,
  * or resubmits this URB.
  */
-void usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb, struct pt_regs *regs)
+void usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb)
 {
        int at_root_hub;
 
@@ -1534,7 +1533,7 @@ void usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb, struct pt_regs
 
        usbmon_urb_complete (&hcd->self, urb);
        /* pass ownership to the completion handler */
-       urb->complete (urb, regs);
+       urb->complete (urb);
        atomic_dec (&urb->use_count);
        if (unlikely (urb->reject))
                wake_up (&usb_kill_urb_queue);
@@ -1553,7 +1552,7 @@ EXPORT_SYMBOL (usb_hcd_giveback_urb);
  * If the controller isn't HALTed, calls the driver's irq handler.
  * Checks whether the controller is now dead.
  */
-irqreturn_t usb_hcd_irq (int irq, void *__hcd, struct pt_regs * r)
+irqreturn_t usb_hcd_irq (int irq, void *__hcd)
 {
        struct usb_hcd          *hcd = __hcd;
        int                     start = hcd->state;
@@ -1561,7 +1560,7 @@ irqreturn_t usb_hcd_irq (int irq, void *__hcd, struct pt_regs * r)
        if (unlikely(start == HC_STATE_HALT ||
            !test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)))
                return IRQ_NONE;
-       if (hcd->driver->irq (hcd, r) == IRQ_NONE)
+       if (hcd->driver->irq (hcd) == IRQ_NONE)
                return IRQ_NONE;
 
        set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags);
index 676877c15f8187731e833bab4750407ce1c0bdd2..8f8df0d4382e886f8c5df347f09a606cf4682e2f 100644 (file)
@@ -143,15 +143,13 @@ struct hcd_timeout {      /* timeouts we allocate */
 /*-------------------------------------------------------------------------*/
 
 
-struct pt_regs;
-
 struct hc_driver {
        const char      *description;   /* "ehci-hcd" etc */
        const char      *product_desc;  /* product/vendor string */
        size_t          hcd_priv_size;  /* size of private data */
 
        /* irq handler */
-       irqreturn_t     (*irq) (struct usb_hcd *hcd, struct pt_regs *regs);
+       irqreturn_t     (*irq) (struct usb_hcd *hcd);
 
        int     flags;
 #define        HCD_MEMORY      0x0001          /* HC regs use memory (else I/O) */
@@ -205,8 +203,7 @@ struct hc_driver {
 
 extern int usb_hcd_submit_urb (struct urb *urb, gfp_t mem_flags);
 extern int usb_hcd_unlink_urb (struct urb *urb, int status);
-extern void usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb,
-               struct pt_regs *regs);
+extern void usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb);
 extern void usb_hcd_endpoint_disable (struct usb_device *udev,
                struct usb_host_endpoint *ep);
 extern int usb_hcd_get_frame_number (struct usb_device *udev);
@@ -248,7 +245,7 @@ void hcd_buffer_free (struct usb_bus *bus, size_t size,
        void *addr, dma_addr_t dma);
 
 /* generic bus glue, needed for host controllers that don't use PCI */
-extern irqreturn_t usb_hcd_irq (int irq, void *__hcd, struct pt_regs *r);
+extern irqreturn_t usb_hcd_irq (int irq, void *__hcd);
 
 extern void usb_hc_died (struct usb_hcd *hcd);
 extern void usb_hcd_poll_rh_status(struct usb_hcd *hcd);
index 7676690a0386aedc56242def77c874825714b13b..66bff184a30c2e6ff62345b4d565cf7593169d62 100644 (file)
@@ -291,7 +291,7 @@ void usb_kick_khubd(struct usb_device *hdev)
 
 
 /* completion function, fires on port status changes and various faults */
-static void hub_irq(struct urb *urb, struct pt_regs *regs)
+static void hub_irq(struct urb *urb)
 {
        struct usb_hub *hub = urb->context;
        int status;
index 85b1cd18336f03c63b875c2431f87942eb43c007..fccd1952bad3f41dd37ffc5af913f3c94966e643 100644 (file)
@@ -17,7 +17,7 @@
 #include "hcd.h"       /* for usbcore internals */
 #include "usb.h"
 
-static void usb_api_blocking_completion(struct urb *urb, struct pt_regs *regs)
+static void usb_api_blocking_completion(struct urb *urb)
 {
        complete((struct completion *)urb->context);
 }
@@ -246,7 +246,7 @@ static void sg_clean (struct usb_sg_request *io)
        io->dev = NULL;
 }
 
-static void sg_complete (struct urb *urb, struct pt_regs *regs)
+static void sg_complete (struct urb *urb)
 {
        struct usb_sg_request   *io = urb->context;
 
index 77beba485a8430e343eddffdd7f91e223ef7a712..72f3db99ff940f40978de7764953920c7e18093d 100644 (file)
@@ -1366,7 +1366,7 @@ static void handle_ep0(struct at91_udc *udc)
        }
 }
 
-static irqreturn_t at91_udc_irq (int irq, void *_udc, struct pt_regs *r)
+static irqreturn_t at91_udc_irq (int irq, void *_udc)
 {
        struct at91_udc         *udc = _udc;
        u32                     rescans = 5;
@@ -1552,7 +1552,7 @@ static struct at91_udc controller = {
        /* ep6 and ep7 are also reserved (custom silicon might use them) */
 };
 
-static irqreturn_t at91_vbus_irq(int irq, void *_udc, struct pt_regs *r)
+static irqreturn_t at91_vbus_irq(int irq, void *_udc)
 {
        struct at91_udc *udc = _udc;
        unsigned        value;
index 4d2946e540cf9462538db8b51274fd5a40621ffe..f1f32d7be5f929d022660952c18d8e11b202e4dd 100644 (file)
@@ -1551,7 +1551,7 @@ return_urb:
                        ep->already_seen = ep->setup_stage = 0;
 
                spin_unlock (&dum->lock);
-               usb_hcd_giveback_urb (dummy_to_hcd(dum), urb, NULL);
+               usb_hcd_giveback_urb (dummy_to_hcd(dum), urb);
                spin_lock (&dum->lock);
 
                goto restart;
index 7cf2999e8616b3b8ae68a5e6a699ea26bcc90fe2..a3076da3f4eb03f60dc93494346b2b9d54755fb6 100644 (file)
@@ -1628,7 +1628,7 @@ stall:
                handled = 1; \
                }
 
-static irqreturn_t goku_irq(int irq, void *_dev, struct pt_regs *r)
+static irqreturn_t goku_irq(int irq, void *_dev)
 {
        struct goku_udc                 *dev = _dev;
        struct goku_udc_regs __iomem    *regs = dev->regs;
index 36db7257937728e8d399bf13576c03d6c305c7a5..179259664c18de7260c115bbe28b86c4f20739d3 100644 (file)
@@ -922,7 +922,7 @@ static void lh7a40x_reset_intr(struct lh7a40x_udc *dev)
 /*
  *     lh7a40x usb client interrupt handler.
  */
-static irqreturn_t lh7a40x_udc_irq(int irq, void *_dev, struct pt_regs *r)
+static irqreturn_t lh7a40x_udc_irq(int irq, void *_dev)
 {
        struct lh7a40x_udc *dev = _dev;
 
index 3bda37f9a35f7d54ebf254de672bc44d44e1027d..3acc896a5d4c4abc08e6df1149d575ec52438da5 100644 (file)
@@ -1774,8 +1774,8 @@ static DEVICE_ATTR (queues, S_IRUGO, show_queues, NULL);
 
 #else
 
-#define device_create_file(a,b)        do {} while (0)
-#define device_remove_file     device_create_file
+#define device_create_file(a,b)        (0)
+#define device_remove_file(a,b)        do { } while (0)
 
 #endif
 
@@ -2044,8 +2044,10 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver)
                return retval;
        }
 
-       device_create_file (&dev->pdev->dev, &dev_attr_function);
-       device_create_file (&dev->pdev->dev, &dev_attr_queues);
+       retval = device_create_file (&dev->pdev->dev, &dev_attr_function);
+       if (retval) goto err_unbind;
+       retval = device_create_file (&dev->pdev->dev, &dev_attr_queues);
+       if (retval) goto err_func;
 
        /* ... then enable host detection and ep0; and we're ready
         * for set_configuration as well as eventual disconnect.
@@ -2060,6 +2062,14 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver)
 
        /* pci writes may still be posted */
        return 0;
+
+err_func:
+       device_remove_file (&dev->pdev->dev, &dev_attr_function);
+err_unbind:
+       driver->unbind (&dev->gadget);
+       dev->gadget.dev.driver = NULL;
+       dev->driver = NULL;
+       return retval;
 }
 EXPORT_SYMBOL (usb_gadget_register_driver);
 
@@ -2753,7 +2763,7 @@ static void handle_stat1_irqs (struct net2280 *dev, u32 stat)
                DEBUG (dev, "unhandled irqstat1 %08x\n", stat);
 }
 
-static irqreturn_t net2280_irq (int irq, void *_dev, struct pt_regs * r)
+static irqreturn_t net2280_irq (int irq, void *_dev)
 {
        struct net2280          *dev = _dev;
 
@@ -2974,8 +2984,10 @@ static int net2280_probe (struct pci_dev *pdev, const struct pci_device_id *id)
                                : "disabled");
        the_controller = dev;
 
-       device_register (&dev->gadget.dev);
-       device_create_file (&pdev->dev, &dev_attr_registers);
+       retval = device_register (&dev->gadget.dev);
+       if (retval) goto done;
+       retval = device_create_file (&pdev->dev, &dev_attr_registers);
+       if (retval) goto done;
 
        return 0;
 
index 8c18df86983330a8e29118546a680d208a90d74d..48a09fd89d18f44158ebcfe2e4041b01698c5679 100644 (file)
@@ -1815,8 +1815,7 @@ static void devstate_irq(struct omap_udc *udc, u16 irq_src)
        UDC_IRQ_SRC_REG = UDC_DS_CHG;
 }
 
-static irqreturn_t
-omap_udc_irq(int irq, void *_udc, struct pt_regs *r)
+static irqreturn_t omap_udc_irq(int irq, void *_udc)
 {
        struct omap_udc *udc = _udc;
        u16             irq_src;
@@ -1888,8 +1887,7 @@ static void pio_out_timer(unsigned long _ep)
        spin_unlock_irqrestore(&ep->udc->lock, flags);
 }
 
-static irqreturn_t
-omap_udc_pio_irq(int irq, void *_dev, struct pt_regs *r)
+static irqreturn_t omap_udc_pio_irq(int irq, void *_dev)
 {
        u16             epn_stat, irq_src;
        irqreturn_t     status = IRQ_NONE;
@@ -1968,8 +1966,7 @@ omap_udc_pio_irq(int irq, void *_dev, struct pt_regs *r)
 }
 
 #ifdef USE_ISO
-static irqreturn_t
-omap_udc_iso_irq(int irq, void *_dev, struct pt_regs *r)
+static irqreturn_t omap_udc_iso_irq(int irq, void *_dev)
 {
        struct omap_udc *udc = _dev;
        struct omap_ep  *ep;
index f1adcf8b202307f4d6bf0c1b4d373541ccc4ab14..671c24bc6d75361f670e3dc172eca76fd9eedf18 100644 (file)
 #include <linux/mm.h>
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
+#include <linux/irq.h>
 
 #include <asm/byteorder.h>
 #include <asm/dma.h>
 #include <asm/io.h>
-#include <asm/irq.h>
 #include <asm/system.h>
 #include <asm/mach-types.h>
 #include <asm/unaligned.h>
@@ -110,7 +110,7 @@ static int use_dma = 1;
 module_param(use_dma, bool, 0);
 MODULE_PARM_DESC (use_dma, "true to use dma");
 
-static void dma_nodesc_handler (int dmach, void *_ep, struct pt_regs *r);
+static void dma_nodesc_handler (int dmach, void *_ep);
 static void kick_dma(struct pxa2xx_ep *ep, struct pxa2xx_request *req);
 
 #ifdef USE_OUT_DMA
@@ -828,7 +828,7 @@ static void cancel_dma(struct pxa2xx_ep *ep)
 }
 
 /* dma channel stopped ... normal tx end (IN), or on error (IN/OUT) */
-static void dma_nodesc_handler(int dmach, void *_ep, struct pt_regs *r)
+static void dma_nodesc_handler(int dmach, void *_ep)
 {
        struct pxa2xx_ep        *ep = _ep;
        struct pxa2xx_request   *req;
@@ -1724,7 +1724,7 @@ EXPORT_SYMBOL(usb_gadget_unregister_driver);
  */
 
 static irqreturn_t
-lubbock_vbus_irq(int irq, void *_dev, struct pt_regs *r)
+lubbock_vbus_irq(int irq, void *_dev)
 {
        struct pxa2xx_udc       *dev = _dev;
        int                     vbus;
@@ -1754,8 +1754,7 @@ lubbock_vbus_irq(int irq, void *_dev, struct pt_regs *r)
 
 #endif
 
-static irqreturn_t
-udc_vbus_irq(int irq, void *_dev, struct pt_regs *r)
+static irqreturn_t udc_vbus_irq(int irq, void *_dev)
 {
        struct pxa2xx_udc       *dev = _dev;
        int                     vbus = pxa_gpio_get(dev->mach->gpio_vbus);
@@ -2084,7 +2083,7 @@ static void handle_ep(struct pxa2xx_ep *ep)
  * could cause usb protocol errors.
  */
 static irqreturn_t
-pxa2xx_udc_irq(int irq, void *_dev, struct pt_regs *r)
+pxa2xx_udc_irq(int irq, void *_dev)
 {
        struct pxa2xx_udc       *dev = _dev;
        int                     handled;
index 23b95b2bfe1572e7788a6422e4a09f3a60261d2e..34b7a31cd85b90900a45a8626c186084a16f234f 100644 (file)
@@ -754,7 +754,9 @@ show_registers (struct class_device *class_dev, char *buf)
        }
 
        if (ehci->reclaim) {
-               temp = scnprintf (next, size, "reclaim qh %p\n", ehci->reclaim);
+               temp = scnprintf (next, size, "reclaim qh %p%s\n",
+                               ehci->reclaim,
+                               ehci->reclaim_ready ? " ready" : "");
                size -= temp;
                next += temp;
        }
index 5ac918591131a5a11e08d75bc87a7d1d40363aec..9030994aba985b5d2fd23b8e967a290263e30d42 100644 (file)
@@ -111,7 +111,7 @@ static const char   hcd_name [] = "ehci_hcd";
 #define        EHCI_TUNE_MULT_TT       1
 #define        EHCI_TUNE_FLS           2       /* (small) 256 frame schedule */
 
-#define EHCI_IAA_MSECS         10              /* arbitrary */
+#define EHCI_IAA_JIFFIES       (HZ/100)        /* arbitrary; ~10 msec */
 #define EHCI_IO_JIFFIES                (HZ/10)         /* io watchdog > irq_thresh */
 #define EHCI_ASYNC_JIFFIES     (HZ/20)         /* async idle timeout */
 #define EHCI_SHRINK_JIFFIES    (HZ/200)        /* async qh unlink delay */
@@ -254,8 +254,7 @@ static void ehci_quiesce (struct ehci_hcd *ehci)
 
 /*-------------------------------------------------------------------------*/
 
-static void end_unlink_async (struct ehci_hcd *ehci, struct pt_regs *regs);
-static void ehci_work(struct ehci_hcd *ehci, struct pt_regs *regs);
+static void ehci_work(struct ehci_hcd *ehci);
 
 #include "ehci-hub.c"
 #include "ehci-mem.c"
@@ -264,42 +263,30 @@ static void ehci_work(struct ehci_hcd *ehci, struct pt_regs *regs);
 
 /*-------------------------------------------------------------------------*/
 
-static void ehci_iaa_watchdog (unsigned long param)
+static void ehci_watchdog (unsigned long param)
 {
        struct ehci_hcd         *ehci = (struct ehci_hcd *) param;
        unsigned long           flags;
-       u32                     status;
 
        spin_lock_irqsave (&ehci->lock, flags);
-       WARN_ON(!ehci->reclaim);
 
-       /* lost IAA irqs wedge things badly; seen first with a vt8235 */
+       /* lost IAA irqs wedge things badly; seen with a vt8235 */
        if (ehci->reclaim) {
-               status = readl (&ehci->regs->status);
+               u32             status = readl (&ehci->regs->status);
                if (status & STS_IAA) {
                        ehci_vdbg (ehci, "lost IAA\n");
                        COUNT (ehci->stats.lost_iaa);
                        writel (STS_IAA, &ehci->regs->status);
-                       end_unlink_async (ehci, NULL);
+                       ehci->reclaim_ready = 1;
                }
        }
 
-       spin_unlock_irqrestore (&ehci->lock, flags);
-}
-
-static void ehci_watchdog (unsigned long param)
-{
-       struct ehci_hcd         *ehci = (struct ehci_hcd *) param;
-       unsigned long           flags;
-
-       spin_lock_irqsave (&ehci->lock, flags);
-
-       /* stop async processing after it's idled a bit */
+       /* stop async processing after it's idled a bit */
        if (test_bit (TIMER_ASYNC_OFF, &ehci->actions))
                start_unlink_async (ehci, ehci->async);
 
        /* ehci could run by timer, without IRQs ... */
-       ehci_work (ehci, NULL);
+       ehci_work (ehci);
 
        spin_unlock_irqrestore (&ehci->lock, flags);
 }
@@ -342,9 +329,11 @@ static void ehci_port_power (struct ehci_hcd *ehci, int is_on)
  * ehci_work is called from some interrupts, timers, and so on.
  * it calls driver completion functions, after dropping ehci->lock.
  */
-static void ehci_work (struct ehci_hcd *ehci, struct pt_regs *regs)
+static void ehci_work (struct ehci_hcd *ehci)
 {
        timer_action_done (ehci, TIMER_IO_WATCHDOG);
+       if (ehci->reclaim_ready)
+               end_unlink_async (ehci);
 
        /* another CPU may drop ehci->lock during a schedule scan while
         * it reports urb completions.  this flag guards against bogus
@@ -353,9 +342,9 @@ static void ehci_work (struct ehci_hcd *ehci, struct pt_regs *regs)
        if (ehci->scanning)
                return;
        ehci->scanning = 1;
-       scan_async (ehci, regs);
+       scan_async (ehci);
        if (ehci->next_uframe != -1)
-               scan_periodic (ehci, regs);
+               scan_periodic (ehci);
        ehci->scanning = 0;
 
        /* the IO watchdog guards against hardware or driver bugs that
@@ -379,7 +368,6 @@ static void ehci_stop (struct usb_hcd *hcd)
 
        /* no more interrupts ... */
        del_timer_sync (&ehci->watchdog);
-       del_timer_sync (&ehci->iaa_watchdog);
 
        spin_lock_irq(&ehci->lock);
        if (HC_IS_RUNNING (hcd->state))
@@ -397,7 +385,7 @@ static void ehci_stop (struct usb_hcd *hcd)
        /* root hub is shut down separately (first, when possible) */
        spin_lock_irq (&ehci->lock);
        if (ehci->async)
-               ehci_work (ehci, NULL);
+               ehci_work (ehci);
        spin_unlock_irq (&ehci->lock);
        ehci_mem_cleanup (ehci);
 
@@ -426,10 +414,6 @@ static int ehci_init(struct usb_hcd *hcd)
        ehci->watchdog.function = ehci_watchdog;
        ehci->watchdog.data = (unsigned long) ehci;
 
-       init_timer(&ehci->iaa_watchdog);
-       ehci->iaa_watchdog.function = ehci_iaa_watchdog;
-       ehci->iaa_watchdog.data = (unsigned long) ehci;
-
        /*
         * hw default: 1K periodic list heads, one per frame.
         * periodic_size can shrink by USBCMD update if hcc_params allows.
@@ -446,6 +430,7 @@ static int ehci_init(struct usb_hcd *hcd)
                ehci->i_thresh = 2 + HCC_ISOC_THRES(hcc_params);
 
        ehci->reclaim = NULL;
+       ehci->reclaim_ready = 0;
        ehci->next_uframe = -1;
 
        /*
@@ -573,7 +558,7 @@ static int ehci_run (struct usb_hcd *hcd)
 
 /*-------------------------------------------------------------------------*/
 
-static irqreturn_t ehci_irq (struct usb_hcd *hcd, struct pt_regs *regs)
+static irqreturn_t ehci_irq (struct usb_hcd *hcd)
 {
        struct ehci_hcd         *ehci = hcd_to_ehci (hcd);
        u32                     status;
@@ -619,7 +604,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd, struct pt_regs *regs)
        /* complete the unlinking of some qh [4.15.2.3] */
        if (status & STS_IAA) {
                COUNT (ehci->stats.reclaim);
-               end_unlink_async (ehci, regs);
+               ehci->reclaim_ready = 1;
                bh = 1;
        }
 
@@ -670,7 +655,7 @@ dead:
        }
 
        if (bh)
-               ehci_work (ehci, regs);
+               ehci_work (ehci);
        spin_unlock (&ehci->lock);
        return IRQ_HANDLED;
 }
@@ -723,14 +708,10 @@ static int ehci_urb_enqueue (
 
 static void unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
 {
-       // BUG_ON(qh->qh_state != QH_STATE_LINKED);
-
-       /* failfast */
-       if (!HC_IS_RUNNING (ehci_to_hcd(ehci)->state))
-               end_unlink_async (ehci, NULL);
-
-       /* defer till later if busy */
-       else if (ehci->reclaim) {
+       /* if we need to use IAA and it's busy, defer */
+       if (qh->qh_state == QH_STATE_LINKED
+                       && ehci->reclaim
+                       && HC_IS_RUNNING (ehci_to_hcd(ehci)->state)) {
                struct ehci_qh          *last;
 
                for (last = ehci->reclaim;
@@ -740,8 +721,12 @@ static void unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
                qh->qh_state = QH_STATE_UNLINK_WAIT;
                last->reclaim = qh;
 
-       /* start IAA cycle */
-       } else
+       /* bypass IAA if the hc can't care */
+       } else if (!HC_IS_RUNNING (ehci_to_hcd(ehci)->state) && ehci->reclaim)
+               end_unlink_async (ehci);
+
+       /* something else might have unlinked the qh by now */
+       if (qh->qh_state == QH_STATE_LINKED)
                start_unlink_async (ehci, qh);
 }
 
@@ -763,19 +748,7 @@ static int ehci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb)
                qh = (struct ehci_qh *) urb->hcpriv;
                if (!qh)
                        break;
-               switch (qh->qh_state) {
-               case QH_STATE_LINKED:
-               case QH_STATE_COMPLETING:
-                       unlink_async (ehci, qh);
-                       break;
-               case QH_STATE_UNLINK:
-               case QH_STATE_UNLINK_WAIT:
-                       /* already started */
-                       break;
-               case QH_STATE_IDLE:
-                       WARN_ON(1);
-                       break;
-               }
+               unlink_async (ehci, qh);
                break;
 
        case PIPE_INTERRUPT:
@@ -787,7 +760,7 @@ static int ehci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb)
                        intr_deschedule (ehci, qh);
                        /* FALL THROUGH */
                case QH_STATE_IDLE:
-                       qh_completions (ehci, qh, NULL);
+                       qh_completions (ehci, qh);
                        break;
                default:
                        ehci_dbg (ehci, "bogus qh %p state %d\n",
@@ -867,7 +840,6 @@ rescan:
                unlink_async (ehci, qh);
                /* FALL THROUGH */
        case QH_STATE_UNLINK:           /* wait for hw to finish? */
-       case QH_STATE_UNLINK_WAIT:
 idle_timeout:
                spin_unlock_irqrestore (&ehci->lock, flags);
                schedule_timeout_uninterruptible(1);
index b2ee13c58517cc9182fccc533c7c5ca4aff0c77a..1b20722c102b5ad5c936252a6c5f1243fc443de9 100644 (file)
@@ -48,8 +48,8 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
        }
        ehci->command = readl (&ehci->regs->command);
        if (ehci->reclaim)
-               end_unlink_async (ehci, NULL);
-       ehci_work(ehci, NULL);
+               ehci->reclaim_ready = 1;
+       ehci_work(ehci);
 
        /* suspend any active/unsuspended ports, maybe allow wakeup */
        while (port--) {
index 08d0472d4f57f4201e430a625f18702fccdfdc10..e51c1ed81ac463cdc677c1a84883ede4e6a2ec9c 100644 (file)
@@ -303,8 +303,8 @@ restart:
        /* emptying the schedule aborts any urbs */
        spin_lock_irq(&ehci->lock);
        if (ehci->reclaim)
-               end_unlink_async (ehci, NULL);
-       ehci_work(ehci, NULL);
+               ehci->reclaim_ready = 1;
+       ehci_work(ehci);
        spin_unlock_irq(&ehci->lock);
 
        /* restart; khubd will disconnect devices */
index 7fc25b6bd7d249f487e4d2adf8a4ecc150613733..62e46dc60e86d6cbb3a6b36d28052f375b4aecfb 100644 (file)
@@ -214,7 +214,7 @@ static void qtd_copy_status (
 }
 
 static void
-ehci_urb_done (struct ehci_hcd *ehci, struct urb *urb, struct pt_regs *regs)
+ehci_urb_done (struct ehci_hcd *ehci, struct urb *urb)
 __releases(ehci->lock)
 __acquires(ehci->lock)
 {
@@ -262,7 +262,7 @@ __acquires(ehci->lock)
 
        /* complete() can reenter this HCD */
        spin_unlock (&ehci->lock);
-       usb_hcd_giveback_urb (ehci_to_hcd(ehci), urb, regs);
+       usb_hcd_giveback_urb (ehci_to_hcd(ehci), urb);
        spin_lock (&ehci->lock);
 }
 
@@ -279,7 +279,7 @@ static int qh_schedule (struct ehci_hcd *ehci, struct ehci_qh *qh);
  */
 #define HALT_BIT __constant_cpu_to_le32(QTD_STS_HALT)
 static unsigned
-qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh, struct pt_regs *regs)
+qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh)
 {
        struct ehci_qtd         *last = NULL, *end = qh->dummy;
        struct list_head        *entry, *tmp;
@@ -317,7 +317,7 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh, struct pt_regs *regs)
                /* clean up any state from previous QTD ...*/
                if (last) {
                        if (likely (last->urb != urb)) {
-                               ehci_urb_done (ehci, last->urb, regs);
+                               ehci_urb_done (ehci, last->urb);
                                count++;
                        }
                        ehci_qtd_free (ehci, last);
@@ -407,7 +407,7 @@ halt:
 
        /* last urb's completion might still need calling */
        if (likely (last != NULL)) {
-               ehci_urb_done (ehci, last->urb, regs);
+               ehci_urb_done (ehci, last->urb);
                count++;
                ehci_qtd_free (ehci, last);
        }
@@ -962,12 +962,12 @@ submit_async (
 
 /* the async qh for the qtds being reclaimed are now unlinked from the HC */
 
-static void end_unlink_async (struct ehci_hcd *ehci, struct pt_regs *regs)
+static void end_unlink_async (struct ehci_hcd *ehci)
 {
        struct ehci_qh          *qh = ehci->reclaim;
        struct ehci_qh          *next;
 
-       iaa_watchdog_done (ehci);
+       timer_action_done (ehci, TIMER_IAA_WATCHDOG);
 
        // qh->hw_next = cpu_to_le32 (qh->qh_dma);
        qh->qh_state = QH_STATE_IDLE;
@@ -977,9 +977,10 @@ static void end_unlink_async (struct ehci_hcd *ehci, struct pt_regs *regs)
        /* other unlink(s) may be pending (in QH_STATE_UNLINK_WAIT) */
        next = qh->reclaim;
        ehci->reclaim = next;
+       ehci->reclaim_ready = 0;
        qh->reclaim = NULL;
 
-       qh_completions (ehci, qh, regs);
+       qh_completions (ehci, qh);
 
        if (!list_empty (&qh->qtd_list)
                        && HC_IS_RUNNING (ehci_to_hcd(ehci)->state))
@@ -1047,20 +1048,20 @@ static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
                /* if (unlikely (qh->reclaim != 0))
                 *      this will recurse, probably not much
                 */
-               end_unlink_async (ehci, NULL);
+               end_unlink_async (ehci);
                return;
        }
 
+       ehci->reclaim_ready = 0;
        cmd |= CMD_IAAD;
        writel (cmd, &ehci->regs->command);
        (void) readl (&ehci->regs->command);
-       iaa_watchdog_start (ehci);
+       timer_action (ehci, TIMER_IAA_WATCHDOG);
 }
 
 /*-------------------------------------------------------------------------*/
 
-static void
-scan_async (struct ehci_hcd *ehci, struct pt_regs *regs)
+static void scan_async (struct ehci_hcd *ehci)
 {
        struct ehci_qh          *qh;
        enum ehci_timer_action  action = TIMER_IO_WATCHDOG;
@@ -1084,7 +1085,7 @@ rescan:
                                 */
                                qh = qh_get (qh);
                                qh->stamp = ehci->stamp;
-                               temp = qh_completions (ehci, qh, regs);
+                               temp = qh_completions (ehci, qh);
                                qh_put (qh);
                                if (temp != 0) {
                                        goto rescan;
index e5e9c653c90725ea99d54e5c40c4d3dd0753f01f..65c402a0fa7a10d92e06035eb52c02afc408a075 100644 (file)
@@ -1553,8 +1553,7 @@ itd_link_urb (
 static unsigned
 itd_complete (
        struct ehci_hcd *ehci,
-       struct ehci_itd *itd,
-       struct pt_regs  *regs
+       struct ehci_itd *itd
 ) {
        struct urb                              *urb = itd->urb;
        struct usb_iso_packet_descriptor        *desc;
@@ -1613,7 +1612,7 @@ itd_complete (
 
        /* give urb back to the driver ... can be out-of-order */
        dev = urb->dev;
-       ehci_urb_done (ehci, urb, regs);
+       ehci_urb_done (ehci, urb);
        urb = NULL;
 
        /* defer stopping schedule; completion can submit */
@@ -1930,8 +1929,7 @@ sitd_link_urb (
 static unsigned
 sitd_complete (
        struct ehci_hcd         *ehci,
-       struct ehci_sitd        *sitd,
-       struct pt_regs          *regs
+       struct ehci_sitd        *sitd
 ) {
        struct urb                              *urb = sitd->urb;
        struct usb_iso_packet_descriptor        *desc;
@@ -1978,7 +1976,7 @@ sitd_complete (
 
        /* give urb back to the driver */
        dev = urb->dev;
-       ehci_urb_done (ehci, urb, regs);
+       ehci_urb_done (ehci, urb);
        urb = NULL;
 
        /* defer stopping schedule; completion can submit */
@@ -2065,8 +2063,7 @@ sitd_submit (struct ehci_hcd *ehci, struct urb *urb, gfp_t mem_flags)
 static inline unsigned
 sitd_complete (
        struct ehci_hcd         *ehci,
-       struct ehci_sitd        *sitd,
-       struct pt_regs          *regs
+       struct ehci_sitd        *sitd
 ) {
        ehci_err (ehci, "sitd_complete %p?\n", sitd);
        return 0;
@@ -2077,7 +2074,7 @@ sitd_complete (
 /*-------------------------------------------------------------------------*/
 
 static void
-scan_periodic (struct ehci_hcd *ehci, struct pt_regs *regs)
+scan_periodic (struct ehci_hcd *ehci)
 {
        unsigned        frame, clock, now_uframe, mod;
        unsigned        modified;
@@ -2131,7 +2128,7 @@ restart:
                                temp.qh = qh_get (q.qh);
                                type = Q_NEXT_TYPE (q.qh->hw_next);
                                q = q.qh->qh_next;
-                               modified = qh_completions (ehci, temp.qh, regs);
+                               modified = qh_completions (ehci, temp.qh);
                                if (unlikely (list_empty (&temp.qh->qtd_list)))
                                        intr_deschedule (ehci, temp.qh);
                                qh_put (temp.qh);
@@ -2169,7 +2166,7 @@ restart:
                                *hw_p = q.itd->hw_next;
                                type = Q_NEXT_TYPE (q.itd->hw_next);
                                wmb();
-                               modified = itd_complete (ehci, q.itd, regs);
+                               modified = itd_complete (ehci, q.itd);
                                q = *q_p;
                                break;
                        case Q_TYPE_SITD:
@@ -2185,7 +2182,7 @@ restart:
                                *hw_p = q.sitd->hw_next;
                                type = Q_NEXT_TYPE (q.sitd->hw_next);
                                wmb();
-                               modified = sitd_complete (ehci, q.sitd, regs);
+                               modified = sitd_complete (ehci, q.sitd);
                                q = *q_p;
                                break;
                        default:
index 6aac39f50e0734d35e33f2fb3cfd5c6e2fcec627..bbc3082a73d752ae359b4c45fb1ae59cd0764699 100644 (file)
@@ -58,6 +58,7 @@ struct ehci_hcd {                     /* one per controller */
        /* async schedule support */
        struct ehci_qh          *async;
        struct ehci_qh          *reclaim;
+       unsigned                reclaim_ready : 1;
        unsigned                scanning : 1;
 
        /* periodic schedule support */
@@ -80,7 +81,6 @@ struct ehci_hcd {                     /* one per controller */
        struct dma_pool         *itd_pool;      /* itd per iso urb */
        struct dma_pool         *sitd_pool;     /* sitd per split iso urb */
 
-       struct timer_list       iaa_watchdog;
        struct timer_list       watchdog;
        unsigned long           actions;
        unsigned                stamp;
@@ -114,21 +114,9 @@ static inline struct usb_hcd *ehci_to_hcd (struct ehci_hcd *ehci)
 }
 
 
-static inline void
-iaa_watchdog_start (struct ehci_hcd *ehci)
-{
-       WARN_ON(timer_pending(&ehci->iaa_watchdog));
-       mod_timer (&ehci->iaa_watchdog,
-                       jiffies + msecs_to_jiffies(EHCI_IAA_MSECS));
-}
-
-static inline void iaa_watchdog_done (struct ehci_hcd *ehci)
-{
-       del_timer (&ehci->iaa_watchdog);
-}
-
 enum ehci_timer_action {
        TIMER_IO_WATCHDOG,
+       TIMER_IAA_WATCHDOG,
        TIMER_ASYNC_SHRINK,
        TIMER_ASYNC_OFF,
 };
@@ -146,6 +134,9 @@ timer_action (struct ehci_hcd *ehci, enum ehci_timer_action action)
                unsigned long t;
 
                switch (action) {
+               case TIMER_IAA_WATCHDOG:
+                       t = EHCI_IAA_JIFFIES;
+                       break;
                case TIMER_IO_WATCHDOG:
                        t = EHCI_IO_JIFFIES;
                        break;
@@ -162,7 +153,8 @@ timer_action (struct ehci_hcd *ehci, enum ehci_timer_action action)
                // async queue SHRINK often precedes IAA.  while it's ready
                // to go OFF neither can matter, and afterwards the IO
                // watchdog stops unless there's still periodic traffic.
-               if (time_before_eq(t, ehci->watchdog.expires)
+               if (action != TIMER_IAA_WATCHDOG
+                               && t > ehci->watchdog.expires
                                && timer_pending (&ehci->watchdog))
                        return;
                mod_timer (&ehci->watchdog, t);
index 61e571782cf7a9222d629d7e81c97076c15c3c17..87eca6aeacf255dcf04b0fce1e0effbd4eee9e0d 100644 (file)
@@ -478,9 +478,9 @@ static int etrax_usb_submit_urb(struct urb *urb, unsigned mem_flags);
 static int etrax_usb_unlink_urb(struct urb *urb, int status);
 static int etrax_usb_get_frame_number(struct usb_device *usb_dev);
 
-static irqreturn_t etrax_usb_tx_interrupt(int irq, void *vhc, struct pt_regs *regs);
-static irqreturn_t etrax_usb_rx_interrupt(int irq, void *vhc, struct pt_regs *regs);
-static irqreturn_t etrax_usb_hc_interrupt_top_half(int irq, void *vhc, struct pt_regs *regs);
+static irqreturn_t etrax_usb_tx_interrupt(int irq, void *vhc);
+static irqreturn_t etrax_usb_rx_interrupt(int irq, void *vhc);
+static irqreturn_t etrax_usb_hc_interrupt_top_half(int irq, void *vhc);
 static void etrax_usb_hc_interrupt_bottom_half(void *data);
 
 static void etrax_usb_isoc_descr_interrupt_bottom_half(void *data);
@@ -1573,7 +1573,7 @@ static int etrax_usb_get_frame_number(struct usb_device *usb_dev)
        return (*R_USB_FM_NUMBER & 0x7ff);
 }
 
-static irqreturn_t etrax_usb_tx_interrupt(int irq, void *vhc, struct pt_regs *regs)
+static irqreturn_t etrax_usb_tx_interrupt(int irq, void *vhc)
 {
        DBFENTER;
 
@@ -1839,7 +1839,7 @@ static void etrax_usb_isoc_descr_interrupt_bottom_half(void *data)
 
 
 
-static irqreturn_t etrax_usb_rx_interrupt(int irq, void *vhc, struct pt_regs *regs)
+static irqreturn_t etrax_usb_rx_interrupt(int irq, void *vhc)
 {
        struct urb *urb;
        etrax_urb_priv_t *urb_priv;
@@ -3280,7 +3280,7 @@ static void etrax_usb_complete_urb(struct urb *urb, int status)
 
 
 
-static irqreturn_t etrax_usb_hc_interrupt_top_half(int irq, void *vhc, struct pt_regs *regs)
+static irqreturn_t etrax_usb_hc_interrupt_top_half(int irq, void *vhc)
 {
        usb_interrupt_registers_t *reg;
        unsigned long flags;
index a72e041df8e7256b800c08226493ea46df82b32b..2718b5dc4ec1d9825cd0fe6a38fea384c17b1b4e 100644 (file)
@@ -418,7 +418,7 @@ static void postproc_atl_queue(struct isp116x *isp116x)
   processed urbs.
 */
 static void finish_request(struct isp116x *isp116x, struct isp116x_ep *ep,
-                          struct urb *urb, struct pt_regs *regs)
+                          struct urb *urb)
 __releases(isp116x->lock) __acquires(isp116x->lock)
 {
        unsigned i;
@@ -432,7 +432,7 @@ __releases(isp116x->lock) __acquires(isp116x->lock)
        urb_dbg(urb, "Finish");
 
        spin_unlock(&isp116x->lock);
-       usb_hcd_giveback_urb(isp116x_to_hcd(isp116x), urb, regs);
+       usb_hcd_giveback_urb(isp116x_to_hcd(isp116x), urb);
        spin_lock(&isp116x->lock);
 
        /* take idle endpoints out of the schedule */
@@ -568,7 +568,7 @@ static void start_atl_transfers(struct isp116x *isp116x)
 /*
   Finish the processed transfers
 */
-static void finish_atl_transfers(struct isp116x *isp116x, struct pt_regs *regs)
+static void finish_atl_transfers(struct isp116x *isp116x)
 {
        struct isp116x_ep *ep;
        struct urb *urb;
@@ -590,12 +590,12 @@ static void finish_atl_transfers(struct isp116x *isp116x, struct pt_regs *regs)
                   occured, while URB_SHORT_NOT_OK was set */
                if (urb && urb->status != -EINPROGRESS
                    && ep->nextpid != USB_PID_ACK)
-                       finish_request(isp116x, ep, urb, regs);
+                       finish_request(isp116x, ep, urb);
        }
        atomic_dec(&isp116x->atl_finishing);
 }
 
-static irqreturn_t isp116x_irq(struct usb_hcd *hcd, struct pt_regs *regs)
+static irqreturn_t isp116x_irq(struct usb_hcd *hcd)
 {
        struct isp116x *isp116x = hcd_to_isp116x(hcd);
        u16 irqstat;
@@ -608,7 +608,7 @@ static irqreturn_t isp116x_irq(struct usb_hcd *hcd, struct pt_regs *regs)
 
        if (irqstat & (HCuPINT_ATL | HCuPINT_SOF)) {
                ret = IRQ_HANDLED;
-               finish_atl_transfers(isp116x, regs);
+               finish_atl_transfers(isp116x);
        }
 
        if (irqstat & HCuPINT_OPR) {
@@ -824,7 +824,7 @@ static int isp116x_urb_enqueue(struct usb_hcd *hcd,
        spin_lock(&urb->lock);
        if (urb->status != -EINPROGRESS) {
                spin_unlock(&urb->lock);
-               finish_request(isp116x, ep, urb, NULL);
+               finish_request(isp116x, ep, urb);
                ret = 0;
                goto fail;
        }
@@ -870,7 +870,7 @@ static int isp116x_urb_dequeue(struct usb_hcd *hcd, struct urb *urb)
                        }
 
        if (urb)
-               finish_request(isp116x, ep, urb, NULL);
+               finish_request(isp116x, ep, urb);
 
        spin_unlock_irqrestore(&isp116x->lock, flags);
        return 0;
index d1d68c4022519bf8aedcdb075193ded74c07dc44..9be6b303e7846a5ff2e5e21919b385b158543ddb 100644 (file)
@@ -261,7 +261,7 @@ static int ohci_urb_enqueue (
        if (urb->status != -EINPROGRESS) {
                spin_unlock (&urb->lock);
                urb->hcpriv = urb_priv;
-               finish_urb (ohci, urb, NULL);
+               finish_urb (ohci, urb);
                retval = 0;
                goto fail;
        }
@@ -337,7 +337,7 @@ static int ohci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb)
                 * any more ... just clean up every urb's memory.
                 */
                if (urb->hcpriv)
-                       finish_urb (ohci, urb, NULL);
+                       finish_urb (ohci, urb);
        }
        spin_unlock_irqrestore (&ohci->lock, flags);
        return 0;
@@ -369,7 +369,7 @@ rescan:
        if (!HC_IS_RUNNING (hcd->state)) {
 sanitize:
                ed->state = ED_IDLE;
-               finish_unlinks (ohci, 0, NULL);
+               finish_unlinks (ohci, 0);
        }
 
        switch (ed->state) {
@@ -691,7 +691,7 @@ retry:
 
 /* an interrupt happens */
 
-static irqreturn_t ohci_irq (struct usb_hcd *hcd, struct pt_regs *ptregs)
+static irqreturn_t ohci_irq (struct usb_hcd *hcd)
 {
        struct ohci_hcd         *ohci = hcd_to_ohci (hcd);
        struct ohci_regs __iomem *regs = ohci->regs;
@@ -747,7 +747,7 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd, struct pt_regs *ptregs)
                if (HC_IS_RUNNING(hcd->state))
                        ohci_writel (ohci, OHCI_INTR_WDH, &regs->intrdisable);
                spin_lock (&ohci->lock);
-               dl_done_list (ohci, ptregs);
+               dl_done_list (ohci);
                spin_unlock (&ohci->lock);
                if (HC_IS_RUNNING(hcd->state))
                        ohci_writel (ohci, OHCI_INTR_WDH, &regs->intrenable); 
@@ -760,7 +760,7 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd, struct pt_regs *ptregs)
         */
        spin_lock (&ohci->lock);
        if (ohci->ed_rm_list)
-               finish_unlinks (ohci, ohci_frame_no(ohci), ptregs);
+               finish_unlinks (ohci, ohci_frame_no(ohci));
        if ((ints & OHCI_INTR_SF) != 0 && !ohci->ed_rm_list
                        && HC_IS_RUNNING(hcd->state))
                ohci_writel (ohci, OHCI_INTR_SF, &regs->intrdisable);   
@@ -852,7 +852,7 @@ static int ohci_restart (struct ohci_hcd *ohci)
                urb->status = -ESHUTDOWN;
                spin_unlock (&urb->lock);
        }
-       finish_unlinks (ohci, 0, NULL);
+       finish_unlinks (ohci, 0);
        spin_unlock_irq(&ohci->lock);
 
        /* paranoia, in case that didn't work: */
index ec75774abeac581eabb0a57b6de6fb30e4594a92..6f113596af66c1660ecc2548f6b8c40b5c26d4e5 100644 (file)
@@ -47,8 +47,8 @@ static void ohci_rhsc_enable (struct usb_hcd *hcd)
 #define OHCI_SCHED_ENABLES \
        (OHCI_CTRL_CLE|OHCI_CTRL_BLE|OHCI_CTRL_PLE|OHCI_CTRL_IE)
 
-static void dl_done_list (struct ohci_hcd *, struct pt_regs *);
-static void finish_unlinks (struct ohci_hcd *, u16 , struct pt_regs *);
+static void dl_done_list (struct ohci_hcd *);
+static void finish_unlinks (struct ohci_hcd *, u16);
 
 static int ohci_rh_suspend (struct ohci_hcd *ohci, int autostop)
 __releases(ohci->lock)
@@ -94,8 +94,8 @@ __acquires(ohci->lock)
                msleep (8);
                spin_lock_irq (&ohci->lock);
        }
-       dl_done_list (ohci, NULL);
-       finish_unlinks (ohci, ohci_frame_no(ohci), NULL);
+       dl_done_list (ohci);
+       finish_unlinks (ohci, ohci_frame_no(ohci));
 
        /* maybe resume can wake root hub */
        if (device_may_wakeup(&ohci_to_hcd(ohci)->self.root_hub->dev) ||
index 82cb22f002e775a3d9078ed8f475d99cc2b667f3..2dbb77414905209969e86724c5a15f80791c061c 100644 (file)
@@ -262,6 +262,7 @@ static const struct hc_driver ohci_pnx4008_hc_driver = {
         */
        .start = ohci_pnx4008_start,
        .stop = ohci_stop,
+       .shutdown = ohci_shutdown,
 
        /*
         * managing i/o requests and associated device resources
@@ -280,7 +281,11 @@ static const struct hc_driver ohci_pnx4008_hc_driver = {
         */
        .hub_status_data = ohci_hub_status_data,
        .hub_control = ohci_hub_control,
-
+       .hub_irq_enable = ohci_rhsc_enable,
+#ifdef CONFIG_PM
+       .bus_suspend = ohci_bus_suspend,
+       .bus_resume = ohci_bus_resume,
+#endif
        .start_port_reset = ohci_start_port_reset,
 };
 
@@ -410,8 +415,6 @@ static int __devinit usb_hcd_pnx4008_probe(struct platform_device *pdev)
                goto out4;
        }
 
-       hcd->self.hcpriv = (void *)hcd;
-
        pnx4008_start_hc();
        platform_set_drvdata(pdev, hcd);
        ohci = hcd_to_ohci(hcd);
index e372306ed0daa1dd4bfb9231e0d5eb841a2864bb..fe1fe2f97cb5bbff22371cce9ca60dcf01842878 100644 (file)
@@ -7,6 +7,8 @@
  * This file is licenced under the GPL.
  */
 
+#include <linux/irq.h>
+
 static void urb_free_priv (struct ohci_hcd *hc, urb_priv_t *urb_priv)
 {
        int             last = urb_priv->length - 1;
@@ -34,7 +36,7 @@ static void urb_free_priv (struct ohci_hcd *hc, urb_priv_t *urb_priv)
  * PRECONDITION:  ohci lock held, irqs blocked.
  */
 static void
-finish_urb (struct ohci_hcd *ohci, struct urb *urb, struct pt_regs *regs)
+finish_urb (struct ohci_hcd *ohci, struct urb *urb)
 __releases(ohci->lock)
 __acquires(ohci->lock)
 {
@@ -73,7 +75,7 @@ __acquires(ohci->lock)
 
        /* urb->complete() can reenter this HCD */
        spin_unlock (&ohci->lock);
-       usb_hcd_giveback_urb (ohci_to_hcd(ohci), urb, regs);
+       usb_hcd_giveback_urb (ohci_to_hcd(ohci), urb);
        spin_lock (&ohci->lock);
 
        /* stop periodic dma if it's not needed */
@@ -910,7 +912,7 @@ static struct td *dl_reverse_done_list (struct ohci_hcd *ohci)
 
 /* there are some urbs/eds to unlink; called in_irq(), with HCD locked */
 static void
-finish_unlinks (struct ohci_hcd *ohci, u16 tick, struct pt_regs *regs)
+finish_unlinks (struct ohci_hcd *ohci, u16 tick)
 {
        struct ed       *ed, **last;
 
@@ -923,7 +925,7 @@ rescan_all:
                /* only take off EDs that the HC isn't using, accounting for
                 * frame counter wraps and EDs with partially retired TDs
                 */
-               if (likely (regs && HC_IS_RUNNING(ohci_to_hcd(ohci)->state))) {
+               if (likely (HC_IS_RUNNING(ohci_to_hcd(ohci)->state))) {
                        if (tick_before (tick, ed->tick)) {
 skip_ed:
                                last = &ed->ed_next;
@@ -990,7 +992,7 @@ rescan_this:
                        /* if URB is done, clean up */
                        if (urb_priv->td_cnt == urb_priv->length) {
                                modified = completed = 1;
-                               finish_urb (ohci, urb, regs);
+                               finish_urb (ohci, urb);
                        }
                }
                if (completed && !list_empty (&ed->td_list))
@@ -1068,7 +1070,7 @@ rescan_this:
  * scanning the (re-reversed) donelist as this does.
  */
 static void
-dl_done_list (struct ohci_hcd *ohci, struct pt_regs *regs)
+dl_done_list (struct ohci_hcd *ohci)
 {
        struct td       *td = dl_reverse_done_list (ohci);
 
@@ -1084,7 +1086,7 @@ dl_done_list (struct ohci_hcd *ohci, struct pt_regs *regs)
 
                /* If all this urb's TDs are done, call complete() */
                if (urb_priv->td_cnt == urb_priv->length)
-                       finish_urb (ohci, urb, regs);
+                       finish_urb (ohci, urb);
 
                /* clean schedule:  unlink EDs that are no longer busy */
                if (list_empty (&ed->td_list)) {
index 3a586aab39395580ef2fa68c3b0e393bd9adbc3b..5fa5647ea0951a9b28958060848eb195e67b58b2 100644 (file)
@@ -428,7 +428,6 @@ static void finish_request(
        struct sl811            *sl811,
        struct sl811h_ep        *ep,
        struct urb              *urb,
-       struct pt_regs          *regs,
        int                     status
 ) __releases(sl811->lock) __acquires(sl811->lock)
 {
@@ -444,7 +443,7 @@ static void finish_request(
        spin_unlock(&urb->lock);
 
        spin_unlock(&sl811->lock);
-       usb_hcd_giveback_urb(sl811_to_hcd(sl811), urb, regs);
+       usb_hcd_giveback_urb(sl811_to_hcd(sl811), urb);
        spin_lock(&sl811->lock);
 
        /* leave active endpoints in the schedule */
@@ -484,7 +483,7 @@ static void finish_request(
 }
 
 static void
-done(struct sl811 *sl811, struct sl811h_ep *ep, u8 bank, struct pt_regs *regs)
+done(struct sl811 *sl811, struct sl811h_ep *ep, u8 bank)
 {
        u8                      status;
        struct urb              *urb;
@@ -608,7 +607,7 @@ done(struct sl811 *sl811, struct sl811h_ep *ep, u8 bank, struct pt_regs *regs)
        }
 
        if (urb && (urbstat != -EINPROGRESS || urb->status != -EINPROGRESS))
-               finish_request(sl811, ep, urb, regs, urbstat);
+               finish_request(sl811, ep, urb, urbstat);
 }
 
 static inline u8 checkdone(struct sl811 *sl811)
@@ -641,7 +640,7 @@ static inline u8 checkdone(struct sl811 *sl811)
        return irqstat;
 }
 
-static irqreturn_t sl811h_irq(struct usb_hcd *hcd, struct pt_regs *regs)
+static irqreturn_t sl811h_irq(struct usb_hcd *hcd)
 {
        struct sl811    *sl811 = hcd_to_sl811(hcd);
        u8              irqstat;
@@ -670,13 +669,13 @@ retry:
         * issued ... that's fine if they're different endpoints.
         */
        if (irqstat & SL11H_INTMASK_DONE_A) {
-               done(sl811, sl811->active_a, SL811_EP_A(SL811_HOST_BUF), regs);
+               done(sl811, sl811->active_a, SL811_EP_A(SL811_HOST_BUF));
                sl811->active_a = NULL;
                sl811->stat_a++;
        }
 #ifdef USE_B
        if (irqstat & SL11H_INTMASK_DONE_B) {
-               done(sl811, sl811->active_b, SL811_EP_B(SL811_HOST_BUF), regs);
+               done(sl811, sl811->active_b, SL811_EP_B(SL811_HOST_BUF));
                sl811->active_b = NULL;
                sl811->stat_b++;
        }
@@ -723,7 +722,7 @@ retry:
                                container_of(sl811->active_a
                                                ->hep->urb_list.next,
                                        struct urb, urb_list),
-                               NULL, -ESHUTDOWN);
+                               -ESHUTDOWN);
                        sl811->active_a = NULL;
                }
 #ifdef USE_B
@@ -957,7 +956,7 @@ static int sl811h_urb_enqueue(
        spin_lock(&urb->lock);
        if (urb->status != -EINPROGRESS) {
                spin_unlock(&urb->lock);
-               finish_request(sl811, ep, urb, NULL, 0);
+               finish_request(sl811, ep, urb, 0);
                retval = 0;
                goto fail;
        }
@@ -1026,7 +1025,7 @@ static int sl811h_urb_dequeue(struct usb_hcd *hcd, struct urb *urb)
                }
 
                if (urb)
-                       finish_request(sl811, ep, urb, NULL, 0);
+                       finish_request(sl811, ep, urb, 0);
                else
                        VDBG("dequeue, urb %p active %s; wait4irq\n", urb,
                                (sl811->active_a == ep) ? "A" : "B");
@@ -1083,7 +1082,7 @@ sl811h_hub_status_data(struct usb_hcd *hcd, char *buf)
         */
        local_irq_save(flags);
        if (!timer_pending(&sl811->timer)) {
-               if (sl811h_irq( /* ~0, */ hcd, NULL) != IRQ_NONE)
+               if (sl811h_irq( /* ~0, */ hcd) != IRQ_NONE)
                        sl811->stat_lost++;
        }
        local_irq_restore(flags);
index 0a315200b331c2212e154cf311470fc6b2b0b55d..32c635ecbf314cd6e3984c514753675ef7480887 100644 (file)
@@ -557,7 +557,7 @@ static void u132_hcd_giveback_urb(struct u132 *u132, struct u132_endp *endp,
         u132_ring_queue_work(u132, ring, 0);
         up(&u132->scheduler_lock);
         u132_endp_put_kref(u132, endp);
-        usb_hcd_giveback_urb(hcd, urb, NULL);
+        usb_hcd_giveback_urb(hcd, urb);
         return;
 }
 
@@ -590,7 +590,7 @@ static void u132_hcd_abandon_urb(struct u132 *u132, struct u132_endp *endp,
                 endp->active = 0;
                 spin_unlock_irqrestore(&endp->queue_lock.slock, irqs);
                 kfree(urbq);
-        } usb_hcd_giveback_urb(hcd, urb, NULL);
+        } usb_hcd_giveback_urb(hcd, urb);
         return;
 }
 
@@ -2434,7 +2434,7 @@ static int dequeue_from_overflow_chain(struct u132 *u132,
                         endp->queue_size -= 1;
                         urb->error_count = 0;
                         urb->hcpriv = NULL;
-                        usb_hcd_giveback_urb(hcd, urb, NULL);
+                        usb_hcd_giveback_urb(hcd, urb);
                         return 0;
                 } else
                         continue;
@@ -2512,7 +2512,7 @@ static int u132_endp_urb_dequeue(struct u132 *u132, struct u132_endp *endp,
                                 kfree(urbq);
                         } urb->error_count = 0;
                         urb->hcpriv = NULL;
-                        usb_hcd_giveback_urb(hcd, urb, NULL);
+                        usb_hcd_giveback_urb(hcd, urb);
                         return 0;
                 } else if (list_empty(&endp->urb_more)) {
                         dev_err(&u132->platform_dev->dev, "urb=%p not found in "
index eb4eab98e8bf7ec62c1015e746f9a2e43777e852..226bf3de8edd5ce092c551f0a90daa96ba2fc9e4 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/usb.h>
 #include <linux/bitops.h>
+#include <linux/dmi.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
@@ -196,12 +197,42 @@ static int resume_detect_interrupts_are_broken(struct uhci_hcd *uhci)
        return 0;
 }
 
+static int remote_wakeup_is_broken(struct uhci_hcd *uhci)
+{
+       static struct dmi_system_id broken_wakeup_table[] = {
+               {
+                       .ident = "Asus A7V8X",
+                       .matches = {
+                               DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK"),
+                               DMI_MATCH(DMI_BOARD_NAME, "A7V8X"),
+                               DMI_MATCH(DMI_BOARD_VERSION, "REV 1.xx"),
+                       }
+               },
+               { }
+       };
+       int port;
+
+       /* One of Asus's motherboards has a bug which causes it to
+        * wake up immediately from suspend-to-RAM if any of the ports
+        * are connected.  In such cases we will not set EGSM.
+        */
+       if (dmi_check_system(broken_wakeup_table)) {
+               for (port = 0; port < uhci->rh_numports; ++port) {
+                       if (inw(uhci->io_addr + USBPORTSC1 + port * 2) &
+                                       USBPORTSC_CCS)
+                               return 1;
+               }
+       }
+
+       return 0;
+}
+
 static void suspend_rh(struct uhci_hcd *uhci, enum uhci_rh_state new_state)
 __releases(uhci->lock)
 __acquires(uhci->lock)
 {
        int auto_stop;
-       int int_enable;
+       int int_enable, egsm_enable;
 
        auto_stop = (new_state == UHCI_RH_AUTO_STOPPED);
        dev_dbg(&uhci_to_hcd(uhci)->self.root_hub->dev,
@@ -217,15 +248,18 @@ __acquires(uhci->lock)
        }
 
        /* Enable resume-detect interrupts if they work.
-        * Then enter Global Suspend mode, still configured.
+        * Then enter Global Suspend mode if _it_ works, still configured.
         */
+       egsm_enable = USBCMD_EGSM;
        uhci->working_RD = 1;
        int_enable = USBINTR_RESUME;
-       if (resume_detect_interrupts_are_broken(uhci)) {
+       if (remote_wakeup_is_broken(uhci))
+               egsm_enable = 0;
+       if (resume_detect_interrupts_are_broken(uhci) || !egsm_enable)
                uhci->working_RD = int_enable = 0;
-       }
+
        outw(int_enable, uhci->io_addr + USBINTR);
-       outw(USBCMD_EGSM | USBCMD_CF, uhci->io_addr + USBCMD);
+       outw(egsm_enable | USBCMD_CF, uhci->io_addr + USBCMD);
        mb();
        udelay(5);
 
@@ -252,7 +286,7 @@ __acquires(uhci->lock)
        uhci->is_stopped = UHCI_IS_STOPPED;
        uhci_to_hcd(uhci)->poll_rh = !int_enable;
 
-       uhci_scan_schedule(uhci, NULL);
+       uhci_scan_schedule(uhci);
        uhci_fsbr_off(uhci);
 }
 
@@ -309,7 +343,7 @@ __acquires(uhci->lock)
        mod_timer(&uhci_to_hcd(uhci)->rh_timer, jiffies);
 }
 
-static irqreturn_t uhci_irq(struct usb_hcd *hcd, struct pt_regs *regs)
+static irqreturn_t uhci_irq(struct usb_hcd *hcd)
 {
        struct uhci_hcd *uhci = hcd_to_uhci(hcd);
        unsigned short status;
@@ -358,7 +392,7 @@ static irqreturn_t uhci_irq(struct usb_hcd *hcd, struct pt_regs *regs)
                usb_hcd_poll_rh_status(hcd);
        else {
                spin_lock_irqsave(&uhci->lock, flags);
-               uhci_scan_schedule(uhci, regs);
+               uhci_scan_schedule(uhci);
                spin_unlock_irqrestore(&uhci->lock, flags);
        }
 
@@ -671,7 +705,7 @@ static void uhci_stop(struct usb_hcd *hcd)
        spin_lock_irq(&uhci->lock);
        if (test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags) && !uhci->dead)
                uhci_hc_died(uhci);
-       uhci_scan_schedule(uhci, NULL);
+       uhci_scan_schedule(uhci);
        spin_unlock_irq(&uhci->lock);
 
        del_timer_sync(&uhci->fsbr_timer);
index 16fb72eb6fc9213785216414293d7f27dedd8546..f8347f1a10b6633303e333233e59ef8df5dd5d51 100644 (file)
@@ -176,7 +176,7 @@ static int uhci_hub_status_data(struct usb_hcd *hcd, char *buf)
 
        spin_lock_irqsave(&uhci->lock, flags);
 
-       uhci_scan_schedule(uhci, NULL);
+       uhci_scan_schedule(uhci);
        if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags) || uhci->dead)
                goto done;
        uhci_check_ports(uhci);
index 431e8f31f1a976194bef66888af6b11be1fd62fb..06115f22a4fac7420113b7b30d134b08cf3aa6b3 100644 (file)
@@ -1244,7 +1244,7 @@ done:
  * Finish unlinking an URB and give it back
  */
 static void uhci_giveback_urb(struct uhci_hcd *uhci, struct uhci_qh *qh,
-               struct urb *urb, struct pt_regs *regs)
+               struct urb *urb)
 __releases(uhci->lock)
 __acquires(uhci->lock)
 {
@@ -1293,7 +1293,7 @@ __acquires(uhci->lock)
        }
 
        spin_unlock(&uhci->lock);
-       usb_hcd_giveback_urb(uhci_to_hcd(uhci), urb, regs);
+       usb_hcd_giveback_urb(uhci_to_hcd(uhci), urb);
        spin_lock(&uhci->lock);
 
        /* If the queue is now empty, we can unlink the QH and give up its
@@ -1313,8 +1313,7 @@ __acquires(uhci->lock)
                (qh->state == QH_STATE_UNLINKING &&     \
                uhci->frame_number + uhci->is_stopped != qh->unlink_frame)
 
-static void uhci_scan_qh(struct uhci_hcd *uhci, struct uhci_qh *qh,
-               struct pt_regs *regs)
+static void uhci_scan_qh(struct uhci_hcd *uhci, struct uhci_qh *qh)
 {
        struct urb_priv *urbp;
        struct urb *urb;
@@ -1347,7 +1346,7 @@ static void uhci_scan_qh(struct uhci_hcd *uhci, struct uhci_qh *qh,
                                return;
                }
 
-               uhci_giveback_urb(uhci, qh, urb, regs);
+               uhci_giveback_urb(uhci, qh, urb);
                if (status < 0 && qh->type != USB_ENDPOINT_XFER_ISOC)
                        break;
        }
@@ -1372,7 +1371,7 @@ restart:
                                qh->is_stopped = 0;
                                return;
                        }
-                       uhci_giveback_urb(uhci, qh, urb, regs);
+                       uhci_giveback_urb(uhci, qh, urb);
                        goto restart;
                }
        }
@@ -1487,7 +1486,7 @@ done:
 /*
  * Process events in the schedule, but only in one thread at a time
  */
-static void uhci_scan_schedule(struct uhci_hcd *uhci, struct pt_regs *regs)
+static void uhci_scan_schedule(struct uhci_hcd *uhci)
 {
        int i;
        struct uhci_qh *qh;
@@ -1515,7 +1514,7 @@ rescan:
                                        struct uhci_qh, node);
 
                        if (uhci_advance_check(uhci, qh)) {
-                               uhci_scan_qh(uhci, qh, regs);
+                               uhci_scan_qh(uhci, qh);
                                if (qh->state == QH_STATE_ACTIVE) {
                                        uhci_urbp_wants_fsbr(uhci,
        list_entry(qh->queue.next, struct urb_priv, node));
index ca6305c1d64c67ba7b529ec2b8db2fa6a1ee0f3d..63a84bbc310de32f4c3aac320e8e24663b0d0066 100644 (file)
@@ -280,7 +280,7 @@ static int mdc800_isReady (char *ch)
 /*
  * USB IRQ Handler for InputLine
  */
-static void mdc800_usb_irq (struct urb *urb, struct pt_regs *res)
+static void mdc800_usb_irq (struct urb *urb)
 {
        int data_received=0, wake_up;
        unsigned char* b=urb->transfer_buffer;
@@ -374,7 +374,7 @@ static int mdc800_usb_waitForIRQ (int mode, int msec)
 /*
  * The write_urb callback function
  */
-static void mdc800_usb_write_notify (struct urb *urb, struct pt_regs *res)
+static void mdc800_usb_write_notify (struct urb *urb)
 {
        struct mdc800_data* mdc800=urb->context;
 
@@ -394,7 +394,7 @@ static void mdc800_usb_write_notify (struct urb *urb, struct pt_regs *res)
 /*
  * The download_urb callback function
  */
-static void mdc800_usb_download_notify (struct urb *urb, struct pt_regs *res)
+static void mdc800_usb_download_notify (struct urb *urb)
 {
        struct mdc800_data* mdc800=urb->context;
 
index 5f861331932a670affdb9769f8ef32571b957269..3038ed0700d359e29be173decd1b6d7578120f8c 100644 (file)
@@ -370,7 +370,7 @@ static int
 mts_scsi_queuecommand(struct scsi_cmnd *srb, mts_scsi_cmnd_callback callback);
 
 static void mts_transfer_cleanup( struct urb *transfer );
-static void mts_do_sg(struct urb * transfer, struct pt_regs *regs);
+static void mts_do_sg(struct urb * transfer);
 
 static inline
 void mts_int_submit_urb (struct urb* transfer,
@@ -417,7 +417,7 @@ static void mts_transfer_cleanup( struct urb *transfer )
 
 }
 
-static void mts_transfer_done( struct urb *transfer, struct pt_regs *regs )
+static void mts_transfer_done( struct urb *transfer )
 {
        MTS_INT_INIT();
 
@@ -443,7 +443,7 @@ static void mts_get_status( struct urb *transfer )
                           mts_transfer_done );
 }
 
-static void mts_data_done( struct urb* transfer, struct pt_regs *regs )
+static void mts_data_done( struct urb* transfer )
 /* Interrupt context! */
 {
        MTS_INT_INIT();
@@ -460,7 +460,7 @@ static void mts_data_done( struct urb* transfer, struct pt_regs *regs )
 }
 
 
-static void mts_command_done( struct urb *transfer, struct pt_regs *regs )
+static void mts_command_done( struct urb *transfer )
 /* Interrupt context! */
 {
        MTS_INT_INIT();
@@ -501,7 +501,7 @@ static void mts_command_done( struct urb *transfer, struct pt_regs *regs )
        return;
 }
 
-static void mts_do_sg (struct urb* transfer, struct pt_regs *regs)
+static void mts_do_sg (struct urb* transfer)
 {
        struct scatterlist * sg;
        MTS_INT_INIT();
index 21cd22640080fbce6d032354409f59dc61de32a3..20db36448ab377d6c763ccbd472037c440a5eb92 100644 (file)
@@ -348,13 +348,3 @@ config USB_APPLETOUCH
 
          To compile this driver as a module, choose M here: the
          module will be called appletouch.
-
-config USB_TRANCEVIBRATOR
-       tristate "PlayStation 2 Trance Vibrator driver support"
-       depends on USB
-       help
-         Say Y here if you want to connect a PlayStation 2 Trance Vibrator
-         device to your computer's USB port.
-
-         To compile this driver as a module, choose M here: the
-         module will be called trancevibrator.
index 295f459d1079ffa4c3afe69bb38d61474f503162..d946d5213b30d0481035406caf1ada2101f178f7 100644 (file)
@@ -3,7 +3,7 @@
 #
 
 # Multipart objects.
-wacom-objs     := wacom_sys.o wacom_wac.o
+wacom-objs     := wacom_wac.o wacom_sys.o
 usbhid-objs    := hid-core.o
 
 # Optional parts of multipart objects.
@@ -48,7 +48,6 @@ obj-$(CONFIG_USB_ACECAD)      += acecad.o
 obj-$(CONFIG_USB_YEALINK)      += yealink.o
 obj-$(CONFIG_USB_XPAD)         += xpad.o
 obj-$(CONFIG_USB_APPLETOUCH)   += appletouch.o
-obj-$(CONFIG_USB_TRANCEVIBRATOR)       += trancevibrator.o
 
 ifeq ($(CONFIG_USB_DEBUG),y)
 EXTRA_CFLAGS += -DDEBUG
index d83603ba40ae257aa344b5f7774c8a926e9789b5..0096373b5f98b974f5c67c9341f67e7718c877a2 100644 (file)
@@ -58,7 +58,7 @@ struct usb_acecad {
        dma_addr_t data_dma;
 };
 
-static void usb_acecad_irq(struct urb *urb, struct pt_regs *regs)
+static void usb_acecad_irq(struct urb *urb)
 {
        struct usb_acecad *acecad = urb->context;
        unsigned char *data = acecad->data;
index b138dae2b0559dfcff4c79b6e2ccc4fb162714f5..bf428184608fe435cffbe3b15e2d7df401524f5c 100644 (file)
@@ -396,7 +396,7 @@ static int aiptek_convert_from_2s_complement(unsigned char c)
  * replaced with the input_sync() method (which emits EV_SYN.)
  */
 
-static void aiptek_irq(struct urb *urb, struct pt_regs *regs)
+static void aiptek_irq(struct urb *urb)
 {
        struct aiptek *aiptek = urb->context;
        unsigned char *data = aiptek->data;
@@ -442,8 +442,6 @@ static void aiptek_irq(struct urb *urb, struct pt_regs *regs)
                        aiptek->diagnostic =
                            AIPTEK_DIAGNOSTIC_SENDING_RELATIVE_IN_ABSOLUTE;
                } else {
-                       input_regs(inputdev, regs);
-
                        x = aiptek_convert_from_2s_complement(data[2]);
                        y = aiptek_convert_from_2s_complement(data[3]);
 
@@ -488,8 +486,6 @@ static void aiptek_irq(struct urb *urb, struct pt_regs *regs)
                            (aiptek->curSetting.pointerMode)) {
                                aiptek->diagnostic = AIPTEK_DIAGNOSTIC_TOOL_DISALLOWED;
                } else {
-                       input_regs(inputdev, regs);
-
                        x = le16_to_cpu(get_unaligned((__le16 *) (data + 1)));
                        y = le16_to_cpu(get_unaligned((__le16 *) (data + 3)));
                        z = le16_to_cpu(get_unaligned((__le16 *) (data + 6)));
@@ -568,7 +564,6 @@ static void aiptek_irq(struct urb *urb, struct pt_regs *regs)
                        (aiptek->curSetting.pointerMode)) {
                        aiptek->diagnostic = AIPTEK_DIAGNOSTIC_TOOL_DISALLOWED;
                } else {
-                       input_regs(inputdev, regs);
                        x = le16_to_cpu(get_unaligned((__le16 *) (data + 1)));
                        y = le16_to_cpu(get_unaligned((__le16 *) (data + 3)));
 
@@ -631,8 +626,6 @@ static void aiptek_irq(struct urb *urb, struct pt_regs *regs)
                z = le16_to_cpu(get_unaligned((__le16 *) (data + 4)));
 
                if (dv != 0) {
-                       input_regs(inputdev, regs);
-
                        /* If we've not already sent a tool_button_?? code, do
                         * so now. Then set FIRED_BIT so it won't be resent unless
                         * the user forces FIRED_BIT off.
@@ -681,8 +674,6 @@ static void aiptek_irq(struct urb *urb, struct pt_regs *regs)
                macro = data[3];
 
                if (dv != 0) {
-                       input_regs(inputdev, regs);
-
                        /* If we've not already sent a tool_button_?? code, do
                         * so now. Then set FIRED_BIT so it won't be resent unless
                         * the user forces FIRED_BIT off.
@@ -726,8 +717,6 @@ static void aiptek_irq(struct urb *urb, struct pt_regs *regs)
         */
        else if (data[0] == 6) {
                macro = le16_to_cpu(get_unaligned((__le16 *) (data + 1)));
-               input_regs(inputdev, regs);
-
                if (macro > 0) {
                        input_report_key(inputdev, macroKeyEvents[macro - 1],
                                         0);
index 0aa9cc2bfd69fb5a067beaeb9664aea005abf4e3..4c213513484dcb38d154220a55094e226f8dd5b5 100644 (file)
@@ -210,7 +210,7 @@ static inline void atp_report_fingers(struct input_dev *input, int fingers)
        input_report_key(input, BTN_TOOL_TRIPLETAP, fingers > 2);
 }
 
-static void atp_complete(struct urb* urb, struct pt_regs* regs)
+static void atp_complete(struct urb* urb)
 {
        int x, y, x_z, y_z, x_f, y_f;
        int retval, i, j;
index 3558d7ed99b96e9cafdce2ea5002fb74ed4292e2..f659f3028ad28edee6db90fdefb469ceb1f58aea 100644 (file)
@@ -283,9 +283,9 @@ static void ati_remote_dump         (unsigned char *data, unsigned int actual_length);
 static int ati_remote_open             (struct input_dev *inputdev);
 static void ati_remote_close           (struct input_dev *inputdev);
 static int ati_remote_sendpacket       (struct ati_remote *ati_remote, u16 cmd, unsigned char *data);
-static void ati_remote_irq_out         (struct urb *urb, struct pt_regs *regs);
-static void ati_remote_irq_in          (struct urb *urb, struct pt_regs *regs);
-static void ati_remote_input_report    (struct urb *urb, struct pt_regs *regs);
+static void ati_remote_irq_out         (struct urb *urb);
+static void ati_remote_irq_in          (struct urb *urb);
+static void ati_remote_input_report    (struct urb *urb);
 static int ati_remote_initialize       (struct ati_remote *ati_remote);
 static int ati_remote_probe            (struct usb_interface *interface, const struct usb_device_id *id);
 static void ati_remote_disconnect      (struct usb_interface *interface);
@@ -344,7 +344,7 @@ static void ati_remote_close(struct input_dev *inputdev)
 /*
  *             ati_remote_irq_out
  */
-static void ati_remote_irq_out(struct urb *urb, struct pt_regs *regs)
+static void ati_remote_irq_out(struct urb *urb)
 {
        struct ati_remote *ati_remote = urb->context;
 
@@ -453,7 +453,7 @@ static int ati_remote_compute_accel(struct ati_remote *ati_remote)
 /*
  *     ati_remote_report_input
  */
-static void ati_remote_input_report(struct urb *urb, struct pt_regs *regs)
+static void ati_remote_input_report(struct urb *urb)
 {
        struct ati_remote *ati_remote = urb->context;
        unsigned char *data= ati_remote->inbuf;
@@ -491,7 +491,6 @@ static void ati_remote_input_report(struct urb *urb, struct pt_regs *regs)
                remote_num, data[1], data[2], index, ati_remote_tbl[index].code);
 
        if (ati_remote_tbl[index].kind == KIND_LITERAL) {
-               input_regs(dev, regs);
                input_event(dev, ati_remote_tbl[index].type,
                        ati_remote_tbl[index].code,
                        ati_remote_tbl[index].value);
@@ -520,7 +519,6 @@ static void ati_remote_input_report(struct urb *urb, struct pt_regs *regs)
                        return;
 
 
-               input_regs(dev, regs);
                input_event(dev, ati_remote_tbl[index].type,
                        ati_remote_tbl[index].code, 1);
                input_sync(dev);
@@ -537,7 +535,6 @@ static void ati_remote_input_report(struct urb *urb, struct pt_regs *regs)
                 */
                acc = ati_remote_compute_accel(ati_remote);
 
-               input_regs(dev, regs);
                switch (ati_remote_tbl[index].kind) {
                case KIND_ACCEL:
                        input_event(dev, ati_remote_tbl[index].type,
@@ -575,14 +572,14 @@ static void ati_remote_input_report(struct urb *urb, struct pt_regs *regs)
 /*
  *     ati_remote_irq_in
  */
-static void ati_remote_irq_in(struct urb *urb, struct pt_regs *regs)
+static void ati_remote_irq_in(struct urb *urb)
 {
        struct ati_remote *ati_remote = urb->context;
        int retval;
 
        switch (urb->status) {
        case 0:                 /* success */
-               ati_remote_input_report(urb, regs);
+               ati_remote_input_report(urb);
                break;
        case -ECONNRESET:       /* unlink */
        case -ENOENT:
index ea71de81ca6b571290b303cd0ab0f3744b26d202..f982a2b4a7f9a9ff5723f92797003846ce2db983 100644 (file)
@@ -142,7 +142,7 @@ static void ati_remote2_close(struct input_dev *idev)
        usb_kill_urb(ar2->urb[1]);
 }
 
-static void ati_remote2_input_mouse(struct ati_remote2 *ar2, struct pt_regs *regs)
+static void ati_remote2_input_mouse(struct ati_remote2 *ar2)
 {
        struct input_dev *idev = ar2->idev;
        u8 *data = ar2->buf[0];
@@ -157,7 +157,6 @@ static void ati_remote2_input_mouse(struct ati_remote2 *ar2, struct pt_regs *reg
        if (!((1 << data[0]) & mode_mask))
                return;
 
-       input_regs(idev, regs);
        input_event(idev, EV_REL, REL_X, (s8) data[1]);
        input_event(idev, EV_REL, REL_Y, (s8) data[2]);
        input_sync(idev);
@@ -174,7 +173,7 @@ static int ati_remote2_lookup(unsigned int hw_code)
        return -1;
 }
 
-static void ati_remote2_input_key(struct ati_remote2 *ar2, struct pt_regs *regs)
+static void ati_remote2_input_key(struct ati_remote2 *ar2)
 {
        struct input_dev *idev = ar2->idev;
        u8 *data = ar2->buf[1];
@@ -245,19 +244,18 @@ static void ati_remote2_input_key(struct ati_remote2 *ar2, struct pt_regs *regs)
                return;
        }
 
-       input_regs(idev, regs);
        input_event(idev, EV_KEY, ati_remote2_key_table[index].key_code, data[1]);
        input_sync(idev);
 }
 
-static void ati_remote2_complete_mouse(struct urb *urb, struct pt_regs *regs)
+static void ati_remote2_complete_mouse(struct urb *urb)
 {
        struct ati_remote2 *ar2 = urb->context;
        int r;
 
        switch (urb->status) {
        case 0:
-               ati_remote2_input_mouse(ar2, regs);
+               ati_remote2_input_mouse(ar2);
                break;
        case -ENOENT:
        case -EILSEQ:
@@ -277,14 +275,14 @@ static void ati_remote2_complete_mouse(struct urb *urb, struct pt_regs *regs)
                        "%s(): usb_submit_urb() = %d\n", __FUNCTION__, r);
 }
 
-static void ati_remote2_complete_key(struct urb *urb, struct pt_regs *regs)
+static void ati_remote2_complete_key(struct urb *urb)
 {
        struct ati_remote2 *ar2 = urb->context;
        int r;
 
        switch (urb->status) {
        case 0:
-               ati_remote2_input_key(ar2, regs);
+               ati_remote2_input_key(ar2);
                break;
        case -ENOENT:
        case -EILSEQ:
index e0fd11605b430939fc10dbfc52111f9de3745d92..45f44fe33bfed4b1fdd419cf047820841c8e2593 100644 (file)
@@ -750,21 +750,31 @@ static __inline__ __u32 s32ton(__s32 value, unsigned n)
 }
 
 /*
- * Extract/implement a data field from/to a report.
+ * Extract/implement a data field from/to a little endian report (bit array).
  */
 
 static __inline__ __u32 extract(__u8 *report, unsigned offset, unsigned n)
 {
-       report += (offset >> 5) << 2; offset &= 31;
-       return (le64_to_cpu(get_unaligned((__le64*)report)) >> offset) & ((1ULL << n) - 1);
+       u32 x;
+
+       report += offset >> 3;  /* adjust byte index */
+       offset &= 8 - 1;
+       x = get_unaligned((u32 *) report);
+       x = le32_to_cpu(x);
+       x = (x >> offset) & ((1 << n) - 1);
+       return x;
 }
 
 static __inline__ void implement(__u8 *report, unsigned offset, unsigned n, __u32 value)
 {
-       report += (offset >> 5) << 2; offset &= 31;
-       put_unaligned((get_unaligned((__le64*)report)
-               & cpu_to_le64(~((((__u64) 1 << n) - 1) << offset)))
-               | cpu_to_le64((__u64)value << offset), (__le64*)report);
+       u32 x;
+
+       report += offset >> 3;
+       offset &= 8 - 1;
+       x = get_unaligned((u32 *)report);
+       x &= cpu_to_le32(~((((__u32) 1 << n) - 1) << offset));
+       x |= cpu_to_le32(value << offset);
+       put_unaligned(x,(u32 *)report);
 }
 
 /*
@@ -780,13 +790,13 @@ static __inline__ int search(__s32 *array, __s32 value, unsigned n)
        return -1;
 }
 
-static void hid_process_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value, int interrupt, struct pt_regs *regs)
+static void hid_process_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value, int interrupt)
 {
        hid_dump_input(usage, value);
        if (hid->claimed & HID_CLAIMED_INPUT)
-               hidinput_hid_event(hid, field, usage, value, regs);
+               hidinput_hid_event(hid, field, usage, value);
        if (hid->claimed & HID_CLAIMED_HIDDEV && interrupt)
-               hiddev_hid_event(hid, field, usage, value, regs);
+               hiddev_hid_event(hid, field, usage, value);
 }
 
 /*
@@ -795,7 +805,7 @@ static void hid_process_event(struct hid_device *hid, struct hid_field *field, s
  * reporting to the layer).
  */
 
-static void hid_input_field(struct hid_device *hid, struct hid_field *field, __u8 *data, int interrupt, struct pt_regs *regs)
+static void hid_input_field(struct hid_device *hid, struct hid_field *field, __u8 *data, int interrupt)
 {
        unsigned n;
        unsigned count = field->report_count;
@@ -822,19 +832,19 @@ static void hid_input_field(struct hid_device *hid, struct hid_field *field, __u
        for (n = 0; n < count; n++) {
 
                if (HID_MAIN_ITEM_VARIABLE & field->flags) {
-                       hid_process_event(hid, field, &field->usage[n], value[n], interrupt, regs);
+                       hid_process_event(hid, field, &field->usage[n], value[n], interrupt);
                        continue;
                }
 
                if (field->value[n] >= min && field->value[n] <= max
                        && field->usage[field->value[n] - min].hid
                        && search(value, field->value[n], count))
-                               hid_process_event(hid, field, &field->usage[field->value[n] - min], 0, interrupt, regs);
+                               hid_process_event(hid, field, &field->usage[field->value[n] - min], 0, interrupt);
 
                if (value[n] >= min && value[n] <= max
                        && field->usage[value[n] - min].hid
                        && search(field->value, value[n], count))
-                               hid_process_event(hid, field, &field->usage[value[n] - min], 1, interrupt, regs);
+                               hid_process_event(hid, field, &field->usage[value[n] - min], 1, interrupt);
        }
 
        memcpy(field->value, value, count * sizeof(__s32));
@@ -842,7 +852,7 @@ exit:
        kfree(value);
 }
 
-static int hid_input_report(int type, struct urb *urb, int interrupt, struct pt_regs *regs)
+static int hid_input_report(int type, struct urb *urb, int interrupt)
 {
        struct hid_device *hid = urb->context;
        struct hid_report_enum *report_enum = hid->report_enum + type;
@@ -892,7 +902,7 @@ static int hid_input_report(int type, struct urb *urb, int interrupt, struct pt_
                hiddev_report_event(hid, report);
 
        for (n = 0; n < report->maxfield; n++)
-               hid_input_field(hid, report->field[n], data, interrupt, regs);
+               hid_input_field(hid, report->field[n], data, interrupt);
 
        if (hid->claimed & HID_CLAIMED_INPUT)
                hidinput_report_event(hid, report);
@@ -1004,7 +1014,7 @@ done:
  * Input interrupt completion handler.
  */
 
-static void hid_irq_in(struct urb *urb, struct pt_regs *regs)
+static void hid_irq_in(struct urb *urb)
 {
        struct hid_device       *hid = urb->context;
        int                     status;
@@ -1012,7 +1022,7 @@ static void hid_irq_in(struct urb *urb, struct pt_regs *regs)
        switch (urb->status) {
                case 0:                 /* success */
                        hid->retry_delay = 0;
-                       hid_input_report(HID_INPUT_REPORT, urb, 1, regs);
+                       hid_input_report(HID_INPUT_REPORT, urb, 1);
                        break;
                case -ECONNRESET:       /* unlink */
                case -ENOENT:
@@ -1193,7 +1203,7 @@ static int hid_submit_ctrl(struct hid_device *hid)
  * Output interrupt completion handler.
  */
 
-static void hid_irq_out(struct urb *urb, struct pt_regs *regs)
+static void hid_irq_out(struct urb *urb)
 {
        struct hid_device *hid = urb->context;
        unsigned long flags;
@@ -1238,7 +1248,7 @@ static void hid_irq_out(struct urb *urb, struct pt_regs *regs)
  * Control pipe completion handler.
  */
 
-static void hid_ctrl(struct urb *urb, struct pt_regs *regs)
+static void hid_ctrl(struct urb *urb)
 {
        struct hid_device *hid = urb->context;
        unsigned long flags;
@@ -1249,7 +1259,7 @@ static void hid_ctrl(struct urb *urb, struct pt_regs *regs)
        switch (urb->status) {
                case 0:                 /* success */
                        if (hid->ctrl[hid->ctrltail].dir == USB_DIR_IN)
-                               hid_input_report(hid->ctrl[hid->ctrltail].report->type, urb, 0, regs);
+                               hid_input_report(hid->ctrl[hid->ctrltail].report->type, urb, 0);
                        break;
                case -ESHUTDOWN:        /* unplug */
                        unplug = 1;
@@ -1381,6 +1391,9 @@ void hid_close(struct hid_device *hid)
 
 #define USB_VENDOR_ID_PANJIT           0x134c
 
+#define USB_VENDOR_ID_TURBOX           0x062a
+#define USB_DEVICE_ID_TURBOX_KEYBOARD  0x0201
+
 /*
  * Initialize all reports
  */
@@ -1768,6 +1781,8 @@ static const struct hid_blacklist {
        { USB_VENDOR_ID_PANJIT, 0x0003, HID_QUIRK_IGNORE },
        { USB_VENDOR_ID_PANJIT, 0x0004, HID_QUIRK_IGNORE },
 
+       { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD, HID_QUIRK_NOGET },
+       
        { 0, 0 }
 };
 
index 4c62afbeb430a31620ff3681d6ac303b613af187..9a808a3b4d3750e1a6e4a93a3c9cac1b98c1a667 100644 (file)
@@ -613,7 +613,7 @@ ignore:
        return;
 }
 
-void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value, struct pt_regs *regs)
+void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value)
 {
        struct input_dev *input;
        int *quirks = &hid->quirks;
@@ -623,8 +623,6 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
 
        input = field->hidinput->input;
 
-       input_regs(input, regs);
-
        if (!usage->type)
                return;
 
index b03fd9b075df7cf836112f06531d199ef140c40b..9b50effef75817af9c00b3d459bf481c1c5e1d9d 100644 (file)
@@ -499,13 +499,13 @@ struct hid_descriptor {
 /* Applications from HID Usage Tables 4/8/99 Version 1.1 */
 /* We ignore a few input applications that are not widely used */
 #define IS_INPUT_APPLICATION(a) (((a >= 0x00010000) && (a <= 0x00010008)) || (a == 0x00010080) || (a == 0x000c0001))
-extern void hidinput_hid_event(struct hid_device *, struct hid_field *, struct hid_usage *, __s32, struct pt_regs *regs);
+extern void hidinput_hid_event(struct hid_device *, struct hid_field *, struct hid_usage *, __s32);
 extern void hidinput_report_event(struct hid_device *hid, struct hid_report *report);
 extern int hidinput_connect(struct hid_device *);
 extern void hidinput_disconnect(struct hid_device *);
 #else
 #define IS_INPUT_APPLICATION(a) (0)
-static inline void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value, struct pt_regs *regs) { }
+static inline void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value) { }
 static inline void hidinput_report_event(struct hid_device *hid, struct hid_report *report) { }
 static inline int hidinput_connect(struct hid_device *hid) { return -ENODEV; }
 static inline void hidinput_disconnect(struct hid_device *hid) { }
index a2b419d13740e08631c3f170c52f2a642c3a2a23..7dc14d0cacc1bd5c79298fba41a11aa33749cdaf 100644 (file)
@@ -179,7 +179,7 @@ static void hiddev_send_event(struct hid_device *hid,
  * the interrupt pipe
  */
 void hiddev_hid_event(struct hid_device *hid, struct hid_field *field,
-                     struct hid_usage *usage, __s32 value, struct pt_regs *regs)
+                     struct hid_usage *usage, __s32 value)
 {
        unsigned type = field->report_type;
        struct hiddev_usage_ref uref;
index 61966d719ca3c577e7c8f4cdbe2999da6dbac0f9..aac968aab860f839a7c573e8f08920b662e30818 100644 (file)
  *
  * 1.2.1  09/03/2005 (HCE) hc@mivu.no
  *   Code cleanup and adjusting syntax to start matching kernel standards
- *
+ * 
+ * 1.2.2  10/05/2006 (MJA) massad@gmail.com
+ *   Flag for detecting if the screen was being touch was incorrectly 
+ *   inverted, so no touch events were being detected.         
+ *   
  *****************************************************************************/
 
 #include <linux/kernel.h>
@@ -53,7 +57,7 @@
 #define USB_PRODUCT_ID_TOUCHPANEL      0xf9e9
 
 #define DRIVER_AUTHOR "Hans-Christian Egtvedt <hc@mivu.no>"
-#define DRIVER_VERSION "v1.2.1"
+#define DRIVER_VERSION "v1.2.2"
 #define DRIVER_DESC "USB ITM Inc Touch Panel Driver"
 #define DRIVER_LICENSE "GPL"
 
@@ -76,7 +80,7 @@ static struct usb_device_id itmtouch_ids [] = {
        { }
 };
 
-static void itmtouch_irq(struct urb *urb, struct pt_regs *regs)
+static void itmtouch_irq(struct urb *urb)
 {
        struct itmtouch_dev *itmtouch = urb->context;
        unsigned char *data = urb->transfer_buffer;
@@ -105,10 +109,8 @@ static void itmtouch_irq(struct urb *urb, struct pt_regs *regs)
                goto exit;
        }
 
-       input_regs(dev, regs);
-
        /* if pressure has been released, then don't report X/Y */
-       if (data[7] & 0x20) {
+       if (!(data[7] & 0x20)) {
                input_report_abs(dev, ABS_X, (data[0] & 0x1F) << 7 | (data[3] & 0x7F));
                input_report_abs(dev, ABS_Y, (data[1] & 0x1F) << 7 | (data[4] & 0x7F));
        }
index 604ade356eadd680d0851c66d151b76f596ac7f2..fedbcb127c213676e18d102af6243718019edeba 100644 (file)
@@ -41,7 +41,7 @@ struct kbtab {
        char phys[32];
 };
 
-static void kbtab_irq(struct urb *urb, struct pt_regs *regs)
+static void kbtab_irq(struct urb *urb)
 {
        struct kbtab *kbtab = urb->context;
        unsigned char *data = kbtab->data;
index a903595515759b9f9dd19203758c07a37bb2616e..50aa8108a50b27d82b6cdb95a6d3f07b7cc06c67 100644 (file)
@@ -176,7 +176,7 @@ static int keyspan_load_tester(struct usb_keyspan* dev, int bits_needed)
 /*
  * Routine that handles all the logic needed to parse out the message from the remote.
  */
-static void keyspan_check_data(struct usb_keyspan *remote, struct pt_regs *regs)
+static void keyspan_check_data(struct usb_keyspan *remote)
 {
        int i;
        int found = 0;
@@ -311,7 +311,6 @@ static void keyspan_check_data(struct usb_keyspan *remote, struct pt_regs *regs)
                        __FUNCTION__, message.system, message.button, message.toggle);
 
                if (message.toggle != remote->toggle) {
-                       input_regs(remote->input, regs);
                        input_report_key(remote->input, keyspan_key_table[message.button], 1);
                        input_report_key(remote->input, keyspan_key_table[message.button], 0);
                        input_sync(remote->input);
@@ -361,7 +360,7 @@ static int keyspan_setup(struct usb_device* dev)
 /*
  * Routine used to handle a new message that has come in.
  */
-static void keyspan_irq_recv(struct urb *urb, struct pt_regs *regs)
+static void keyspan_irq_recv(struct urb *urb)
 {
        struct usb_keyspan *dev = urb->context;
        int retval;
@@ -385,7 +384,7 @@ static void keyspan_irq_recv(struct urb *urb, struct pt_regs *regs)
        if (debug)
                keyspan_print(dev);
 
-       keyspan_check_data(dev, regs);
+       keyspan_check_data(dev);
 
 resubmit:
        retval = usb_submit_urb(urb, GFP_ATOMIC);
index 5dce951f2751a2eeb8d0a3a2bff79765d924cbca..79a85d46cb13b3f7bdd2a3ed1c783c7672ba4aa4 100644 (file)
@@ -98,7 +98,7 @@ static struct usb_device_id mtouchusb_devices[] = {
        { }
 };
 
-static void mtouchusb_irq(struct urb *urb, struct pt_regs *regs)
+static void mtouchusb_irq(struct urb *urb)
 {
        struct mtouch_usb *mtouch = urb->context;
        int retval;
@@ -125,7 +125,6 @@ static void mtouchusb_irq(struct urb *urb, struct pt_regs *regs)
                goto exit;
        }
 
-       input_regs(mtouch->input, regs);
        input_report_key(mtouch->input, BTN_TOUCH,
                         MTOUCHUSB_GET_TOUCHED(mtouch->data));
        input_report_abs(mtouch->input, ABS_X, MTOUCHUSB_GET_XC(mtouch->data));
index f0f8db6810a2900aa6160acf70d1dff75834f7f1..0bf91778c40def170820b04b41ae949dc66a8b13 100644 (file)
@@ -80,10 +80,10 @@ struct powermate_device {
 static char pm_name_powermate[] = "Griffin PowerMate";
 static char pm_name_soundknob[] = "Griffin SoundKnob";
 
-static void powermate_config_complete(struct urb *urb, struct pt_regs *regs);
+static void powermate_config_complete(struct urb *urb);
 
 /* Callback for data arriving from the PowerMate over the USB interrupt pipe */
-static void powermate_irq(struct urb *urb, struct pt_regs *regs)
+static void powermate_irq(struct urb *urb)
 {
        struct powermate_device *pm = urb->context;
        int retval;
@@ -104,7 +104,6 @@ static void powermate_irq(struct urb *urb, struct pt_regs *regs)
        }
 
        /* handle updates to device state */
-       input_regs(pm->input, regs);
        input_report_key(pm->input, BTN_0, pm->data[0] & 0x01);
        input_report_rel(pm->input, REL_DIAL, pm->data[1]);
        input_sync(pm->input);
@@ -191,7 +190,7 @@ static void powermate_sync_state(struct powermate_device *pm)
 }
 
 /* Called when our asynchronous control message completes. We may need to issue another immediately */
-static void powermate_config_complete(struct urb *urb, struct pt_regs *regs)
+static void powermate_config_complete(struct urb *urb)
 {
        struct powermate_device *pm = urb->context;
        unsigned long flags;
index 30b9f820e7a894e7b1db04ec347483b5177d3735..05c0d1ca39ab2497c72f6bc80955c36757850b24 100644 (file)
@@ -92,8 +92,7 @@ static inline int touchkit_get_y(char *data)
 
 
 /* processes one input packet. */
-static void touchkit_process_pkt(struct touchkit_usb *touchkit,
-                                 struct pt_regs *regs, char *pkt)
+static void touchkit_process_pkt(struct touchkit_usb *touchkit, char *pkt)
 {
        int x, y;
 
@@ -109,7 +108,6 @@ static void touchkit_process_pkt(struct touchkit_usb *touchkit,
                y = touchkit_get_y(pkt);
        }
 
-       input_regs(touchkit->input, regs);
        input_report_key(touchkit->input, BTN_TOUCH, touchkit_get_touched(pkt));
        input_report_abs(touchkit->input, ABS_X, x);
        input_report_abs(touchkit->input, ABS_Y, y);
@@ -130,8 +128,7 @@ static int touchkit_get_pkt_len(char *buf)
        return 0;
 }
 
-static void touchkit_process(struct touchkit_usb *touchkit, int len,
-                             struct pt_regs *regs)
+static void touchkit_process(struct touchkit_usb *touchkit, int len)
 {
        char *buffer;
        int pkt_len, buf_len, pos;
@@ -153,7 +150,7 @@ static void touchkit_process(struct touchkit_usb *touchkit, int len,
                /* append, process */
                tmp = pkt_len - touchkit->buf_len;
                memcpy(touchkit->buffer + touchkit->buf_len, touchkit->data, tmp);
-               touchkit_process_pkt(touchkit, regs, touchkit->buffer);
+               touchkit_process_pkt(touchkit, touchkit->buffer);
 
                buffer = touchkit->data + tmp;
                buf_len = len - tmp;
@@ -181,7 +178,7 @@ static void touchkit_process(struct touchkit_usb *touchkit, int len,
 
                /* full packet: process */
                if (likely(pkt_len <= buf_len)) {
-                       touchkit_process_pkt(touchkit, regs, buffer + pos);
+                       touchkit_process_pkt(touchkit, buffer + pos);
                } else {
                        /* incomplete packet: save in buffer */
                        memcpy(touchkit->buffer, buffer + pos, buf_len - pos);
@@ -192,7 +189,7 @@ static void touchkit_process(struct touchkit_usb *touchkit, int len,
 }
 
 
-static void touchkit_irq(struct urb *urb, struct pt_regs *regs)
+static void touchkit_irq(struct urb *urb)
 {
        struct touchkit_usb *touchkit = urb->context;
        int retval;
@@ -219,7 +216,7 @@ static void touchkit_irq(struct urb *urb, struct pt_regs *regs)
                goto exit;
        }
 
-       touchkit_process(touchkit, urb->actual_length, regs);
+       touchkit_process(touchkit, urb->actual_length);
 
 exit:
        retval = usb_submit_urb(urb, GFP_ATOMIC);
diff --git a/drivers/usb/input/trancevibrator.c b/drivers/usb/input/trancevibrator.c
deleted file mode 100644 (file)
index 33cd91d..0000000
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * PlayStation 2 Trance Vibrator driver
- *
- * Copyright (C) 2006 Sam Hocevar <sam@zoy.org>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/* Standard include files */
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/usb.h>
-
-/* Version Information */
-#define DRIVER_VERSION "v1.1"
-#define DRIVER_AUTHOR "Sam Hocevar, sam@zoy.org"
-#define DRIVER_DESC "PlayStation 2 Trance Vibrator driver"
-
-#define TRANCEVIBRATOR_VENDOR_ID       0x0b49  /* ASCII Corporation */
-#define TRANCEVIBRATOR_PRODUCT_ID      0x064f  /* Trance Vibrator */
-
-static struct usb_device_id id_table [] = {
-       { USB_DEVICE(TRANCEVIBRATOR_VENDOR_ID, TRANCEVIBRATOR_PRODUCT_ID) },
-       { },
-};
-MODULE_DEVICE_TABLE (usb, id_table);
-
-/* Driver-local specific stuff */
-struct trancevibrator {
-       struct usb_device *udev;
-       unsigned int speed;
-};
-
-static ssize_t show_speed(struct device *dev, struct device_attribute *attr,
-                         char *buf)
-{
-       struct usb_interface *intf = to_usb_interface(dev);
-       struct trancevibrator *tv = usb_get_intfdata(intf);
-
-       return sprintf(buf, "%d\n", tv->speed);
-}
-
-static ssize_t set_speed(struct device *dev, struct device_attribute *attr,
-                        const char *buf, size_t count)
-{
-       struct usb_interface *intf = to_usb_interface(dev);
-       struct trancevibrator *tv = usb_get_intfdata(intf);
-       int temp, retval;
-
-       temp = simple_strtoul(buf, NULL, 10);
-       if (temp > 255)
-               temp = 255;
-       else if (temp < 0)
-               temp = 0;
-       tv->speed = temp;
-
-       dev_dbg(&tv->udev->dev, "speed = %d\n", tv->speed);
-
-       /* Set speed */
-       retval = usb_control_msg(tv->udev, usb_sndctrlpipe(tv->udev, 0),
-                                0x01, /* vendor request: set speed */
-                                USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_OTHER,
-                                tv->speed, /* speed value */
-                                0, NULL, 0, USB_CTRL_GET_TIMEOUT);
-       if (retval) {
-               dev_dbg(&tv->udev->dev, "retval = %d\n", retval);
-               return retval;
-       }
-       return count;
-}
-
-static DEVICE_ATTR(speed, S_IWUGO | S_IRUGO, show_speed, set_speed);
-
-static int tv_probe(struct usb_interface *interface,
-                   const struct usb_device_id *id)
-{
-       struct usb_device *udev = interface_to_usbdev(interface);
-       struct trancevibrator *dev;
-       int retval;
-
-       dev = kzalloc(sizeof(struct trancevibrator), GFP_KERNEL);
-       if (dev == NULL) {
-               dev_err(&interface->dev, "Out of memory\n");
-               retval = -ENOMEM;
-               goto error;
-       }
-
-       dev->udev = usb_get_dev(udev);
-       usb_set_intfdata(interface, dev);
-       retval = device_create_file(&interface->dev, &dev_attr_speed);
-       if (retval)
-               goto error_create_file;
-
-       return 0;
-
-error_create_file:
-       usb_put_dev(udev);
-       usb_set_intfdata(interface, NULL);
-error:
-       kfree(dev);
-       return retval;
-}
-
-static void tv_disconnect(struct usb_interface *interface)
-{
-       struct trancevibrator *dev;
-
-       dev = usb_get_intfdata (interface);
-       usb_set_intfdata(interface, NULL);
-       device_remove_file(&interface->dev, &dev_attr_speed);
-       usb_put_dev(dev->udev);
-       kfree(dev);
-}
-
-/* USB subsystem object */
-static struct usb_driver tv_driver = {
-       .name =         "trancevibrator",
-       .probe =        tv_probe,
-       .disconnect =   tv_disconnect,
-       .id_table =     id_table,
-};
-
-static int __init tv_init(void)
-{
-       int retval = usb_register(&tv_driver);
-       if (retval) {
-               err("usb_register failed. Error number %d", retval);
-               return retval;
-       }
-
-       info(DRIVER_VERSION ":" DRIVER_DESC);
-       return 0;
-}
-
-static void __exit tv_exit(void)
-{
-       usb_deregister(&tv_driver);
-}
-
-module_init (tv_init);
-module_exit (tv_exit);
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");
index 5067a6ae650f8bfb220dc7d29e85bfcb39d66eb5..c73285cf855890935bff3c6bce2420b58aa0500f 100644 (file)
@@ -80,7 +80,7 @@ struct usb_kbd {
        dma_addr_t leds_dma;
 };
 
-static void usb_kbd_irq(struct urb *urb, struct pt_regs *regs)
+static void usb_kbd_irq(struct urb *urb)
 {
        struct usb_kbd *kbd = urb->context;
        int i;
@@ -97,8 +97,6 @@ static void usb_kbd_irq(struct urb *urb, struct pt_regs *regs)
                goto resubmit;
        }
 
-       input_regs(kbd->dev, regs);
-
        for (i = 0; i < 8; i++)
                input_report_key(kbd->dev, usb_kbd_keycode[i + 224], (kbd->new[0] >> i) & 1);
 
@@ -158,7 +156,7 @@ static int usb_kbd_event(struct input_dev *dev, unsigned int type,
        return 0;
 }
 
-static void usb_kbd_led(struct urb *urb, struct pt_regs *regs)
+static void usb_kbd_led(struct urb *urb)
 {
        struct usb_kbd *kbd = urb->context;
 
index 0fb792be95efa9edc2defe878255d29db8490e9a..cbbbea332ed730d48940a0cc72932604fa4bb55d 100644 (file)
@@ -55,7 +55,7 @@ struct usb_mouse {
        dma_addr_t data_dma;
 };
 
-static void usb_mouse_irq(struct urb *urb, struct pt_regs *regs)
+static void usb_mouse_irq(struct urb *urb)
 {
        struct usb_mouse *mouse = urb->context;
        signed char *data = mouse->data;
@@ -74,8 +74,6 @@ static void usb_mouse_irq(struct urb *urb, struct pt_regs *regs)
                goto resubmit;
        }
 
-       input_regs(dev, regs);
-
        input_report_key(dev, BTN_LEFT,   data[0] & 0x01);
        input_report_key(dev, BTN_RIGHT,  data[0] & 0x02);
        input_report_key(dev, BTN_MIDDLE, data[0] & 0x04);
index 923e22db18d4fea4d6e2346b141c935f7317ab55..2902742895ad875f71ea55c4aaea5a30af508a01 100644 (file)
@@ -61,7 +61,7 @@ struct usbtouch_device_info {
        int rept_size;
        int flags;
 
-       void (*process_pkt) (struct usbtouch_usb *usbtouch, struct pt_regs *regs, unsigned char *pkt, int len);
+       void (*process_pkt) (struct usbtouch_usb *usbtouch, unsigned char *pkt, int len);
        int  (*get_pkt_len) (unsigned char *pkt, int len);
        int  (*read_data)   (unsigned char *pkt, int *x, int *y, int *touch, int *press);
        int  (*init)        (struct usbtouch_usb *usbtouch);
@@ -91,7 +91,6 @@ struct usbtouch_usb {
 
 #ifdef MULTI_PACKET
 static void usbtouch_process_multi(struct usbtouch_usb *usbtouch,
-                                   struct pt_regs *regs,
                                    unsigned char *pkt, int len);
 #endif
 
@@ -257,10 +256,10 @@ static int itm_read_data(unsigned char *pkt, int *x, int *y, int *touch, int *pr
 {
        *x = ((pkt[0] & 0x1F) << 7) | (pkt[3] & 0x7F);
        *y = ((pkt[1] & 0x1F) << 7) | (pkt[4] & 0x7F);
-       *press = ((pkt[2] & 0x1F) << 7) | (pkt[5] & 0x7F);
+       *press = ((pkt[2] & 0x01) << 7) | (pkt[5] & 0x7F);
        *touch = ~pkt[7] & 0x20;
 
-       return 1;
+       return *touch;
 }
 #endif
 
@@ -397,7 +396,7 @@ static struct usbtouch_device_info usbtouch_dev_info[] = {
  * Generic Part
  */
 static void usbtouch_process_pkt(struct usbtouch_usb *usbtouch,
-                                 struct pt_regs *regs, unsigned char *pkt, int len)
+                                 unsigned char *pkt, int len)
 {
        int x, y, touch, press;
        struct usbtouch_device_info *type = usbtouch->type;
@@ -405,7 +404,6 @@ static void usbtouch_process_pkt(struct usbtouch_usb *usbtouch,
        if (!type->read_data(pkt, &x, &y, &touch, &press))
                        return;
 
-       input_regs(usbtouch->input, regs);
        input_report_key(usbtouch->input, BTN_TOUCH, touch);
 
        if (swap_xy) {
@@ -423,7 +421,6 @@ static void usbtouch_process_pkt(struct usbtouch_usb *usbtouch,
 
 #ifdef MULTI_PACKET
 static void usbtouch_process_multi(struct usbtouch_usb *usbtouch,
-                                   struct pt_regs *regs,
                                    unsigned char *pkt, int len)
 {
        unsigned char *buffer;
@@ -460,7 +457,7 @@ static void usbtouch_process_multi(struct usbtouch_usb *usbtouch,
                if (usbtouch->buf_len + tmp >= usbtouch->type->rept_size)
                        goto out_flush_buf;
                memcpy(usbtouch->buffer + usbtouch->buf_len, pkt, tmp);
-               usbtouch_process_pkt(usbtouch, regs, usbtouch->buffer, pkt_len);
+               usbtouch_process_pkt(usbtouch, usbtouch->buffer, pkt_len);
 
                buffer = pkt + tmp;
                buf_len = len - tmp;
@@ -481,7 +478,7 @@ static void usbtouch_process_multi(struct usbtouch_usb *usbtouch,
 
                /* full packet: process */
                if (likely((pkt_len > 0) && (pkt_len <= buf_len - pos))) {
-                       usbtouch_process_pkt(usbtouch, regs, buffer + pos, pkt_len);
+                       usbtouch_process_pkt(usbtouch, buffer + pos, pkt_len);
                } else {
                        /* incomplete packet: save in buffer */
                        memcpy(usbtouch->buffer, buffer + pos, buf_len - pos);
@@ -498,7 +495,7 @@ out_flush_buf:
 #endif
 
 
-static void usbtouch_irq(struct urb *urb, struct pt_regs *regs)
+static void usbtouch_irq(struct urb *urb)
 {
        struct usbtouch_usb *usbtouch = urb->context;
        int retval;
@@ -525,7 +522,7 @@ static void usbtouch_irq(struct urb *urb, struct pt_regs *regs)
                goto exit;
        }
 
-       usbtouch->type->process_pkt(usbtouch, regs, usbtouch->data, urb->actual_length);
+       usbtouch->type->process_pkt(usbtouch, usbtouch->data, urb->actual_length);
 
 exit:
        retval = usb_submit_urb(urb, GFP_ATOMIC);
index 832737b658cf151da4c0f87eb1fae31bf04499cf..1cf08f02c50e8a8871aff028f2ac01983627c2f1 100644 (file)
@@ -63,6 +63,7 @@
  *      v1.46 (pc) - Split wacom.c into wacom_sys.c and wacom_wac.c,
  *                - where wacom_sys.c deals with system specific code,
  *                - and wacom_wac.c deals with Wacom specific code
+ *                - Support Intuos3 4x6
  */
 
 /*
@@ -106,20 +107,19 @@ struct wacom {
 struct wacom_combo {
        struct wacom * wacom;
        struct urb * urb;
-       struct pt_regs *regs;
 };
 
 extern int wacom_wac_irq(struct wacom_wac * wacom_wac, void * wcombo);
-extern void wacom_sys_irq(struct urb *urb, struct pt_regs *regs);
+extern void wacom_sys_irq(struct urb *urb);
 extern void wacom_report_abs(void *wcombo, unsigned int abs_type, int abs_data);
 extern void wacom_report_rel(void *wcombo, unsigned int rel_type, int rel_data);
 extern void wacom_report_key(void *wcombo, unsigned int key_type, int key_data);
 extern void wacom_input_event(void *wcombo, unsigned int type, unsigned int code, int value);
-extern void wacom_input_regs(void *wcombo);
 extern void wacom_input_sync(void *wcombo);
 extern void wacom_init_input_dev(struct input_dev *input_dev, struct wacom_wac *wacom_wac);
 extern void input_dev_g4(struct input_dev *input_dev, struct wacom_wac *wacom_wac);
 extern void input_dev_g(struct input_dev *input_dev, struct wacom_wac *wacom_wac);
+extern void input_dev_i3s(struct input_dev *input_dev, struct wacom_wac *wacom_wac);
 extern void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wac);
 extern void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac);
 extern void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac);
index 7c3b52bdd9d619a2f44d4bff2fb4dd25199c85c7..3498b893b53b62b6a792ddebcceafcb0ab5e890d 100644 (file)
@@ -42,7 +42,7 @@ static struct input_dev * get_input_dev(struct wacom_combo *wcombo)
        return wcombo->wacom->dev;
 }
 
-void wacom_sys_irq(struct urb *urb, struct pt_regs *regs)
+void wacom_sys_irq(struct urb *urb)
 {
        struct wacom *wacom = urb->context;
        struct wacom_combo wcombo;
@@ -65,7 +65,6 @@ void wacom_sys_irq(struct urb *urb, struct pt_regs *regs)
 
        wcombo.wacom = wacom;
        wcombo.urb = urb;
-       wcombo.regs = regs;
 
        if (wacom_wac_irq(wacom->wacom_wac, (void *)&wcombo))
                input_sync(get_input_dev(&wcombo));
@@ -111,16 +110,10 @@ __u16 wacom_be16_to_cpu(unsigned char *data)
 __u16 wacom_le16_to_cpu(unsigned char *data)
 {
        __u16 value;
-       value = be16_to_cpu(*(__be16 *) data);
+       value = le16_to_cpu(*(__le16 *) data);
        return value;
 }
 
-void wacom_input_regs(void *wcombo)
-{
-       input_regs(get_input_dev((struct wacom_combo *)wcombo), ((struct wacom_combo *)wcombo)->regs);
-       return;
-}
-
 void wacom_input_sync(void *wcombo)
 {
        input_sync(get_input_dev((struct wacom_combo *)wcombo));
@@ -150,7 +143,7 @@ void input_dev_g4(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
        input_dev->evbit[0] |= BIT(EV_MSC);
        input_dev->mscbit[0] |= BIT(MSC_SERIAL);
        input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER);
-       input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_0) | BIT(BTN_1) | BIT(BTN_2) | BIT(BTN_3) | BIT(BTN_4) | BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7);
+       input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_0) | BIT(BTN_4);
 }
 
 void input_dev_g(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
@@ -162,11 +155,16 @@ void input_dev_g(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
        input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features->distance_max, 0, 0);
 }
 
-void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
+void input_dev_i3s(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
 {
        input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER);
-       input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_0) | BIT(BTN_1) | BIT(BTN_2) | BIT(BTN_3) | BIT(BTN_4) | BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7);
+       input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_0) | BIT(BTN_1) | BIT(BTN_2) | BIT(BTN_3);
        input_set_abs_params(input_dev, ABS_RX, 0, 4097, 0, 0);
+}
+
+void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
+{
+       input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_4) | BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7);
        input_set_abs_params(input_dev, ABS_RY, 0, 4097, 0, 0);
 }
 
@@ -225,8 +223,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
        strlcat(wacom->phys, "/input0", sizeof(wacom->phys));
 
        wacom_wac->features = get_wacom_feature(id);
-       if (wacom_wac->features->pktlen > 10)
-               BUG();
+       BUG_ON(wacom_wac->features->pktlen > 10);
 
        input_dev->name = wacom_wac->features->name;
        wacom->wacom_wac = wacom_wac;
@@ -251,7 +248,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
        usb_fill_int_urb(wacom->irq, dev,
                         usb_rcvintpipe(dev, endpoint->bEndpointAddress),
                         wacom_wac->data, wacom_wac->features->pktlen,
-                        wacom_wac->features->irq, wacom, endpoint->bInterval);
+                        wacom_sys_irq, wacom, endpoint->bInterval);
        wacom->irq->transfer_dma = wacom->data_dma;
        wacom->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 
@@ -285,8 +282,8 @@ static void wacom_disconnect(struct usb_interface *intf)
                input_unregister_device(wacom->dev);
                usb_free_urb(wacom->irq);
                usb_buffer_free(interface_to_usbdev(intf), 10, wacom->wacom_wac->data, wacom->data_dma);
-               kfree(wacom);
                kfree(wacom->wacom_wac);
+               kfree(wacom);
        }
 }
 
index 85d458c98b6e28893c54991daaeda7557b3c27c7..92726fe89379e7631f7c3bf382063ed7859c5e26 100644 (file)
@@ -20,7 +20,6 @@ static int wacom_penpartner_irq(struct wacom_wac *wacom, void *wcombo)
 
        switch (data[0]) {
                case 1:
-                       wacom_input_regs(wcombo);
                        if (data[5] & 0x80) {
                                wacom->tool[0] = (data[5] & 0x20) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN;
                                wacom->id[0] = (data[5] & 0x20) ? ERASER_DEVICE_ID : STYLUS_DEVICE_ID;
@@ -39,7 +38,6 @@ static int wacom_penpartner_irq(struct wacom_wac *wacom, void *wcombo)
                        }
                        break;
                case 2:
-                       wacom_input_regs(wcombo);
                        wacom_report_key(wcombo, BTN_TOOL_PEN, 1);
                        wacom_report_abs(wcombo, ABS_MISC, STYLUS_DEVICE_ID); /* report tool id */
                        wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[1]));
@@ -67,8 +65,6 @@ static int wacom_pl_irq(struct wacom_wac *wacom, void *wcombo)
 
        prox = data[1] & 0x40;
 
-       wacom_input_regs(wcombo);
-
        id = ERASER_DEVICE_ID;
        if (prox) {
 
@@ -138,7 +134,6 @@ static int wacom_ptu_irq(struct wacom_wac *wacom, void *wcombo)
                return 0;
        }
 
-       wacom_input_regs(wcombo);
        if (data[1] & 0x04) {
                wacom_report_key(wcombo, BTN_TOOL_RUBBER, data[1] & 0x20);
                wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x08);
@@ -167,8 +162,6 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
                return 0;
        }
 
-       wacom_input_regs(wcombo);
-
        id = STYLUS_DEVICE_ID;
        if (data[1] & 0x10) { /* in prox */
 
@@ -198,9 +191,9 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
                                wacom_report_key(wcombo, BTN_LEFT, data[1] & 0x01);
                                wacom_report_key(wcombo, BTN_RIGHT, data[1] & 0x02);
                                if (wacom->features->type == WACOM_G4)
-                                       wacom_report_abs(wcombo, ABS_DISTANCE, data[6]);
+                                       wacom_report_abs(wcombo, ABS_DISTANCE, data[6] & 0x3f);
                                else
-                                       wacom_report_abs(wcombo, ABS_DISTANCE, data[7]);
+                                       wacom_report_abs(wcombo, ABS_DISTANCE, data[7] & 0x3f);
                                break;
                }
        }
@@ -310,8 +303,9 @@ static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo)
                                wacom->tool[idx] = BTN_TOOL_PEN;
                }
                /* only large I3 support Lens Cursor */
-               if(!((wacom->tool[idx] == BTN_TOOL_LENS) &&
-                               (wacom->features->type == INTUOS3))) {
+               if(!((wacom->tool[idx] == BTN_TOOL_LENS)
+                                && ((wacom->features->type == INTUOS3)
+                                || (wacom->features->type == INTUOS3S)))) {
                        wacom_report_abs(wcombo, ABS_MISC, wacom->id[idx]); /* report tool id */
                        wacom_report_key(wcombo, wacom->tool[idx], 1);
                        wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, wacom->serial[idx]);
@@ -322,10 +316,14 @@ static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo)
 
        /* Exit report */
        if ((data[1] & 0xfe) == 0x80) {
-               wacom_report_key(wcombo, wacom->tool[idx], 0);
-               wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */
-               wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, wacom->serial[idx]);
-               return 2;
+               if(!((wacom->tool[idx] == BTN_TOOL_LENS)
+                                && ((wacom->features->type == INTUOS3)
+                                || (wacom->features->type == INTUOS3S)))) {
+                       wacom_report_key(wcombo, wacom->tool[idx], 0);
+                       wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */
+                       wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, wacom->serial[idx]);
+                       return 2;
+               }
        }
        return 0;
 }
@@ -369,8 +367,6 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo)
                 return 0;
        }
 
-       wacom_input_regs(wcombo);
-
        /* tool number */
        idx = data[1] & 0x01;
 
@@ -391,7 +387,8 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo)
                wacom_report_abs(wcombo, ABS_RX, ((data[1] & 0x1f) << 8) | data[2]);
                wacom_report_abs(wcombo, ABS_RY, ((data[3] & 0x1f) << 8) | data[4]);
 
-               if((data[5] & 0x0f) | (data[6] & 0x0f) | (data[1] & 0x1f) | data[2])
+               if((data[5] & 0x0f) | (data[6] & 0x0f) | (data[1] & 0x1f) |
+                       data[2] | (data[3] & 0x1f) | data[4])
                        wacom_report_key(wcombo, wacom->tool[1], 1);
                else
                        wacom_report_key(wcombo, wacom->tool[1], 0);
@@ -441,7 +438,7 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo)
                                        ((t - 1) / 2) : -t / 2);
                        }
 
-               } else if (!(data[1] & 0x10) && wacom->features->type < INTUOS3) {
+               } else if (!(data[1] & 0x10) && wacom->features->type < INTUOS3S) {
                        /* 4D mouse packet */
                        wacom_report_key(wcombo, BTN_LEFT,   data[8] & 0x01);
                        wacom_report_key(wcombo, BTN_MIDDLE, data[8] & 0x02);
@@ -461,12 +458,12 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo)
                                                 - ((data[8] & 0x02) >> 1));
 
                        /* I3 2D mouse side buttons */
-                       if (wacom->features->type == INTUOS3) {
+                       if (wacom->features->type >= INTUOS3S && wacom->features->type <= INTUOS3L) {
                                wacom_report_key(wcombo, BTN_SIDE,   data[8] & 0x40);
                                wacom_report_key(wcombo, BTN_EXTRA,  data[8] & 0x20);
                        }
 
-               } else if (wacom->features->type < INTUOS3) {
+               } else if (wacom->features->type < INTUOS3S || wacom->features->type == INTUOS3L) {
                        /* Lens cursor packets */
                        wacom_report_key(wcombo, BTN_LEFT,   data[8] & 0x01);
                        wacom_report_key(wcombo, BTN_MIDDLE, data[8] & 0x02);
@@ -499,6 +496,7 @@ int wacom_wac_irq(struct wacom_wac *wacom_wac, void *wcombo)
                        return (wacom_ptu_irq(wacom_wac, wcombo));
                        break;
                case INTUOS:
+               case INTUOS3S:
                case INTUOS3:
                case INTUOS3L:
                case CINTIQ:
@@ -524,6 +522,8 @@ void wacom_init_input_dev(struct input_dev *input_dev, struct wacom_wac *wacom_w
                case CINTIQ:
                        input_dev_i3(input_dev, wacom_wac);
                        /* fall through */
+               case INTUOS3S:
+                       input_dev_i3s(input_dev, wacom_wac);
                case INTUOS:
                        input_dev_i(input_dev, wacom_wac);
                        break;
@@ -539,49 +539,50 @@ void wacom_init_input_dev(struct input_dev *input_dev, struct wacom_wac *wacom_w
 }
 
 static struct wacom_features wacom_features[] = {
-       { "Wacom Penpartner",    7,   5040,  3780,  255, 32, PENPARTNER,        wacom_sys_irq },
-        { "Wacom Graphire",      8,  10206,  7422,  511, 32, GRAPHIRE, wacom_sys_irq },
-       { "Wacom Graphire2 4x5", 8,  10206,  7422,  511, 32, GRAPHIRE,  wacom_sys_irq },
-       { "Wacom Graphire2 5x7", 8,  13918, 10206,  511, 32, GRAPHIRE,  wacom_sys_irq },
-       { "Wacom Graphire3",     8,  10208,  7424,  511, 32, GRAPHIRE,  wacom_sys_irq },
-       { "Wacom Graphire3 6x8", 8,  16704, 12064,  511, 32, GRAPHIRE,  wacom_sys_irq },
-       { "Wacom Graphire4 4x5", 8,  10208,  7424,  511, 32, WACOM_G4,  wacom_sys_irq },
-       { "Wacom Graphire4 6x8", 8,  16704, 12064,  511, 32, WACOM_G4,  wacom_sys_irq },
-       { "Wacom Volito",        8,   5104,  3712,  511, 32, GRAPHIRE,  wacom_sys_irq },
-       { "Wacom PenStation2",   8,   3250,  2320,  255, 32, GRAPHIRE,  wacom_sys_irq },
-       { "Wacom Volito2 4x5",   8,   5104,  3712,  511, 32, GRAPHIRE,  wacom_sys_irq },
-       { "Wacom Volito2 2x3",   8,   3248,  2320,  511, 32, GRAPHIRE,  wacom_sys_irq },
-       { "Wacom PenPartner2",   8,   3250,  2320,  255, 32, GRAPHIRE,  wacom_sys_irq },
-       { "Wacom Intuos 4x5",   10,  12700, 10600, 1023, 15, INTUOS,    wacom_sys_irq},
-       { "Wacom Intuos 6x8",   10,  20320, 16240, 1023, 15, INTUOS,    wacom_sys_irq },
-       { "Wacom Intuos 9x12",  10,  30480, 24060, 1023, 15, INTUOS,    wacom_sys_irq },
-       { "Wacom Intuos 12x12", 10,  30480, 31680, 1023, 15, INTUOS,    wacom_sys_irq },
-       { "Wacom Intuos 12x18", 10,  45720, 31680, 1023, 15, INTUOS,    wacom_sys_irq},
-       { "Wacom PL400",         8,   5408,  4056,  255, 32, PL,        wacom_sys_irq },
-       { "Wacom PL500",         8,   6144,  4608,  255, 32, PL,        wacom_sys_irq },
-       { "Wacom PL600",         8,   6126,  4604,  255, 32, PL,        wacom_sys_irq },
-       { "Wacom PL600SX",       8,   6260,  5016,  255, 32, PL,        wacom_sys_irq },
-       { "Wacom PL550",         8,   6144,  4608,  511, 32, PL,        wacom_sys_irq },
-       { "Wacom PL800",         8,   7220,  5780,  511, 32, PL,        wacom_sys_irq },
-       { "Wacom PL700",         8,   6758,  5406,  511, 32, PL,        wacom_sys_irq },
-       { "Wacom PL510",         8,   6282,  4762,  511, 32, PL,        wacom_sys_irq },
-       { "Wacom DTU710",        8,  34080, 27660,  511, 32, PL,        wacom_sys_irq },
-       { "Wacom DTF521",        8,   6282,  4762,  511, 32, PL,        wacom_sys_irq },
-       { "Wacom DTF720",        8,   6858,  5506,  511, 32, PL,        wacom_sys_irq },
-       { "Wacom Cintiq Partner",8,  20480, 15360,  511, 32, PTU,       wacom_sys_irq },
-       { "Wacom Intuos2 4x5",   10, 12700, 10600, 1023, 15, INTUOS,    wacom_sys_irq },
-       { "Wacom Intuos2 6x8",   10, 20320, 16240, 1023, 15, INTUOS,    wacom_sys_irq },
-       { "Wacom Intuos2 9x12",  10, 30480, 24060, 1023, 15, INTUOS,    wacom_sys_irq },
-       { "Wacom Intuos2 12x12", 10, 30480, 31680, 1023, 15, INTUOS,    wacom_sys_irq },
-       { "Wacom Intuos2 12x18", 10, 45720, 31680, 1023, 15, INTUOS,    wacom_sys_irq },
-       { "Wacom Intuos3 4x5",   10, 25400, 20320, 1023, 15, INTUOS3,   wacom_sys_irq },
-       { "Wacom Intuos3 6x8",   10, 40640, 30480, 1023, 15, INTUOS3,   wacom_sys_irq },
-       { "Wacom Intuos3 9x12",  10, 60960, 45720, 1023, 15, INTUOS3,   wacom_sys_irq },
-       { "Wacom Intuos3 12x12", 10, 60960, 60960, 1023, 15, INTUOS3L,  wacom_sys_irq },
-       { "Wacom Intuos3 12x19", 10, 97536, 60960, 1023, 15, INTUOS3L,  wacom_sys_irq },
-       { "Wacom Intuos3 6x11",  10, 54204, 31750, 1023, 15, INTUOS3,   wacom_sys_irq },
-       { "Wacom Cintiq 21UX",   10, 87200, 65600, 1023, 15, CINTIQ,    wacom_sys_irq },
-       { "Wacom Intuos2 6x8",   10, 20320, 16240, 1023, 15, INTUOS,    wacom_sys_irq },
+       { "Wacom Penpartner",    7,   5040,  3780,  255,  0, PENPARTNER },
+        { "Wacom Graphire",      8,  10206,  7422,  511, 63, GRAPHIRE },
+       { "Wacom Graphire2 4x5", 8,  10206,  7422,  511, 63, GRAPHIRE },
+       { "Wacom Graphire2 5x7", 8,  13918, 10206,  511, 63, GRAPHIRE },
+       { "Wacom Graphire3",     8,  10208,  7424,  511, 63, GRAPHIRE },
+       { "Wacom Graphire3 6x8", 8,  16704, 12064,  511, 63, GRAPHIRE },
+       { "Wacom Graphire4 4x5", 8,  10208,  7424,  511, 63, WACOM_G4 },
+       { "Wacom Graphire4 6x8", 8,  16704, 12064,  511, 63, WACOM_G4 },
+       { "Wacom Volito",        8,   5104,  3712,  511,  0, GRAPHIRE },
+       { "Wacom PenStation2",   8,   3250,  2320,  255,  0, GRAPHIRE },
+       { "Wacom Volito2 4x5",   8,   5104,  3712,  511,  0, GRAPHIRE },
+       { "Wacom Volito2 2x3",   8,   3248,  2320,  511,  0, GRAPHIRE },
+       { "Wacom PenPartner2",   8,   3250,  2320,  255,  0, GRAPHIRE },
+       { "Wacom Intuos 4x5",   10,  12700, 10600, 1023, 63, INTUOS },
+       { "Wacom Intuos 6x8",   10,  20320, 16240, 1023, 63, INTUOS },
+       { "Wacom Intuos 9x12",  10,  30480, 24060, 1023, 63, INTUOS },
+       { "Wacom Intuos 12x12", 10,  30480, 31680, 1023, 63, INTUOS },
+       { "Wacom Intuos 12x18", 10,  45720, 31680, 1023, 63, INTUOS },
+       { "Wacom PL400",         8,   5408,  4056,  255,  0, PL },
+       { "Wacom PL500",         8,   6144,  4608,  255,  0, PL },
+       { "Wacom PL600",         8,   6126,  4604,  255,  0, PL },
+       { "Wacom PL600SX",       8,   6260,  5016,  255,  0, PL },
+       { "Wacom PL550",         8,   6144,  4608,  511,  0, PL },
+       { "Wacom PL800",         8,   7220,  5780,  511,  0, PL },
+       { "Wacom PL700",         8,   6758,  5406,  511,  0, PL },
+       { "Wacom PL510",         8,   6282,  4762,  511,  0, PL },
+       { "Wacom DTU710",        8,  34080, 27660,  511,  0, PL },
+       { "Wacom DTF521",        8,   6282,  4762,  511,  0, PL },
+       { "Wacom DTF720",        8,   6858,  5506,  511,  0, PL },
+       { "Wacom Cintiq Partner",8,  20480, 15360,  511,  0, PTU },
+       { "Wacom Intuos2 4x5",   10, 12700, 10600, 1023, 63, INTUOS },
+       { "Wacom Intuos2 6x8",   10, 20320, 16240, 1023, 63, INTUOS },
+       { "Wacom Intuos2 9x12",  10, 30480, 24060, 1023, 63, INTUOS },
+       { "Wacom Intuos2 12x12", 10, 30480, 31680, 1023, 63, INTUOS },
+       { "Wacom Intuos2 12x18", 10, 45720, 31680, 1023, 63, INTUOS },
+       { "Wacom Intuos3 4x5",   10, 25400, 20320, 1023, 63, INTUOS3S },
+       { "Wacom Intuos3 6x8",   10, 40640, 30480, 1023, 63, INTUOS3 },
+       { "Wacom Intuos3 9x12",  10, 60960, 45720, 1023, 63, INTUOS3 },
+       { "Wacom Intuos3 12x12", 10, 60960, 60960, 1023, 63, INTUOS3L },
+       { "Wacom Intuos3 12x19", 10, 97536, 60960, 1023, 63, INTUOS3L },
+       { "Wacom Intuos3 6x11",  10, 54204, 31750, 1023, 63, INTUOS3 },
+       { "Wacom Intuos3 4x6",   10, 31496, 19685, 1023, 15, INTUOS3S },
+       { "Wacom Cintiq 21UX",   10, 87200, 65600, 1023, 63, CINTIQ },
+       { "Wacom Intuos2 6x8",   10, 20320, 16240, 1023, 63, INTUOS },
        { }
 };
 
@@ -627,6 +628,7 @@ static struct usb_device_id wacom_ids[] = {
        { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB3) },
        { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB4) },
        { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB5) },
+       { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB7) },
        { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x3F) },
        { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x47) },
        { }
index ceae7bf59d9f8b13a19c26403a5cf3661aa6e1cd..a1d9ce007970b12084c78c81e51cd0551541d3d1 100644 (file)
@@ -20,6 +20,7 @@ enum {
        PTU,
        PL,
        INTUOS,
+       INTUOS3S,
        INTUOS3,
        INTUOS3L,
        CINTIQ,
@@ -34,7 +35,6 @@ struct wacom_features {
        int pressure_max;
        int distance_max;
        int type;
-       usb_complete_t irq;
 };
 
 struct wacom_wac {
index 9889b1cda05b8600a181bb946698b054ecceb0e6..6a12a943b938a189424b12526cb1ed28fa03ebd4 100644 (file)
@@ -1,8 +1,9 @@
 /*
- * X-Box gamepad - v0.0.5
+ * X-Box gamepad - v0.0.6
  *
  * Copyright (c) 2002 Marko Friedemann <mfr@bmx-chemnitz.de>
- *
+ *               2005 Dominic Cerquetti <binary1230@yahoo.com>
+ *               2006 Adam Buchbinder <adam.buchbinder@gmail.com>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
  *  - Greg Kroah-Hartman - usb-skeleton driver
  *
  * TODO:
- *  - fine tune axes
+ *  - fine tune axes (especially trigger axes)
  *  - fix "analog" buttons (reported as digital now)
  *  - get rumble working
+ *  - need USB IDs for other dance pads
  *
  * History:
  *
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/slab.h>
+#include <linux/stat.h>
 #include <linux/module.h>
+#include <linux/moduleparam.h>
 #include <linux/smp_lock.h>
 #include <linux/usb/input.h>
 
-#define DRIVER_VERSION "v0.0.5"
+#define DRIVER_VERSION "v0.0.6"
 #define DRIVER_AUTHOR "Marko Friedemann <mfr@bmx-chemnitz.de>"
 #define DRIVER_DESC "X-Box pad driver"
 
 #define XPAD_PKT_LEN 32
 
+/* xbox d-pads should map to buttons, as is required for DDR pads
+   but we map them to axes when possible to simplify things */
+#define MAP_DPAD_TO_BUTTONS    0
+#define MAP_DPAD_TO_AXES       1
+#define MAP_DPAD_UNKNOWN       -1
+
+static int dpad_to_buttons;
+module_param(dpad_to_buttons, bool, S_IRUGO);
+MODULE_PARM_DESC(dpad_to_buttons, "Map D-PAD to buttons rather than axes for unknown pads");
+
 static const struct xpad_device {
        u16 idVendor;
        u16 idProduct;
        char *name;
+       u8 dpad_mapping;
 } xpad_device[] = {
-       { 0x045e, 0x0202, "Microsoft X-Box pad (US)" },
-       { 0x045e, 0x0285, "Microsoft X-Box pad (Japan)" },
-       { 0x05fd, 0x107a, "InterAct 'PowerPad Pro' X-Box pad (Germany)" },
-       { 0x0000, 0x0000, "X-Box pad" }
+       { 0x045e, 0x0202, "Microsoft X-Box pad v1 (US)", MAP_DPAD_TO_AXES },
+       { 0x045e, 0x0289, "Microsoft X-Box pad v2 (US)", MAP_DPAD_TO_AXES },
+       { 0x045e, 0x0285, "Microsoft X-Box pad (Japan)", MAP_DPAD_TO_AXES },
+       { 0x05fd, 0x107a, "InterAct 'PowerPad Pro' X-Box pad (Germany)", MAP_DPAD_TO_AXES },
+       { 0x0c12, 0x8809, "RedOctane Xbox Dance Pad", MAP_DPAD_TO_BUTTONS },
+       { 0x0000, 0x0000, "Generic X-Box pad", MAP_DPAD_UNKNOWN }
 };
 
 static const signed short xpad_btn[] = {
@@ -84,11 +101,23 @@ static const signed short xpad_btn[] = {
        -1                                              /* terminating entry */
 };
 
+/* only used if MAP_DPAD_TO_BUTTONS */
+static const signed short xpad_btn_pad[] = {
+       BTN_LEFT, BTN_RIGHT,            /* d-pad left, right */
+       BTN_0, BTN_1,                   /* d-pad up, down (XXX names??) */
+       -1                              /* terminating entry */
+};
+
 static const signed short xpad_abs[] = {
        ABS_X, ABS_Y,           /* left stick */
        ABS_RX, ABS_RY,         /* right stick */
        ABS_Z, ABS_RZ,          /* triggers left/right */
-       ABS_HAT0X, ABS_HAT0Y,   /* digital pad */
+       -1                      /* terminating entry */
+};
+
+/* only used if MAP_DPAD_TO_AXES */
+static const signed short xpad_abs_pad[] = {
+       ABS_HAT0X, ABS_HAT0Y,   /* d-pad axes */
        -1                      /* terminating entry */
 };
 
@@ -100,14 +129,16 @@ static struct usb_device_id xpad_table [] = {
 MODULE_DEVICE_TABLE (usb, xpad_table);
 
 struct usb_xpad {
-       struct input_dev *dev;                  /* input device interface */
-       struct usb_device *udev;                /* usb device */
+       struct input_dev *dev;          /* input device interface */
+       struct usb_device *udev;        /* usb device */
 
-       struct urb *irq_in;                     /* urb for interrupt in report */
-       unsigned char *idata;                   /* input data */
+       struct urb *irq_in;             /* urb for interrupt in report */
+       unsigned char *idata;           /* input data */
        dma_addr_t idata_dma;
 
-       char phys[65];                          /* physical device path */
+       char phys[65];                  /* physical device path */
+
+       int dpad_mapping;               /* map d-pad to buttons or to axes */
 };
 
 /*
@@ -120,12 +151,10 @@ struct usb_xpad {
  *      http://euc.jp/periphs/xbox-controller.ja.html
  */
 
-static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *data, struct pt_regs *regs)
+static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *data)
 {
        struct input_dev *dev = xpad->dev;
 
-       input_regs(dev, regs);
-
        /* left stick */
        input_report_abs(dev, ABS_X, (__s16) (((__s16)data[13] << 8) | data[12]));
        input_report_abs(dev, ABS_Y, (__s16) (((__s16)data[15] << 8) | data[14]));
@@ -139,14 +168,21 @@ static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *d
        input_report_abs(dev, ABS_RZ, data[11]);
 
        /* digital pad */
-       input_report_abs(dev, ABS_HAT0X, !!(data[2] & 0x08) - !!(data[2] & 0x04));
-       input_report_abs(dev, ABS_HAT0Y, !!(data[2] & 0x02) - !!(data[2] & 0x01));
+       if (xpad->dpad_mapping == MAP_DPAD_TO_AXES) {
+               input_report_abs(dev, ABS_HAT0X, !!(data[2] & 0x08) - !!(data[2] & 0x04));
+               input_report_abs(dev, ABS_HAT0Y, !!(data[2] & 0x02) - !!(data[2] & 0x01));
+       } else /* xpad->dpad_mapping == MAP_DPAD_TO_BUTTONS */ {
+               input_report_key(dev, BTN_LEFT,  data[2] & 0x04);
+               input_report_key(dev, BTN_RIGHT, data[2] & 0x08);
+               input_report_key(dev, BTN_0,     data[2] & 0x01); // up
+               input_report_key(dev, BTN_1,     data[2] & 0x02); // down
+       }
 
        /* start/back buttons and stick press left/right */
-       input_report_key(dev, BTN_START, (data[2] & 0x10) >> 4);
-       input_report_key(dev, BTN_BACK, (data[2] & 0x20) >> 5);
-       input_report_key(dev, BTN_THUMBL, (data[2] & 0x40) >> 6);
-       input_report_key(dev, BTN_THUMBR, data[2] >> 7);
+       input_report_key(dev, BTN_START,  data[2] & 0x10);
+       input_report_key(dev, BTN_BACK,   data[2] & 0x20);
+       input_report_key(dev, BTN_THUMBL, data[2] & 0x40);
+       input_report_key(dev, BTN_THUMBR, data[2] & 0x80);
 
        /* "analog" buttons A, B, X, Y */
        input_report_key(dev, BTN_A, data[4]);
@@ -161,7 +197,7 @@ static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *d
        input_sync(dev);
 }
 
-static void xpad_irq_in(struct urb *urb, struct pt_regs *regs)
+static void xpad_irq_in(struct urb *urb)
 {
        struct usb_xpad *xpad = urb->context;
        int retval;
@@ -181,7 +217,7 @@ static void xpad_irq_in(struct urb *urb, struct pt_regs *regs)
                goto exit;
        }
 
-       xpad_process_packet(xpad, 0, xpad->idata, regs);
+       xpad_process_packet(xpad, 0, xpad->idata);
 
 exit:
        retval = usb_submit_urb (urb, GFP_ATOMIC);
@@ -208,6 +244,28 @@ static void xpad_close (struct input_dev *dev)
        usb_kill_urb(xpad->irq_in);
 }
 
+static void xpad_set_up_abs(struct input_dev *input_dev, signed short abs)
+{
+       set_bit(abs, input_dev->absbit);
+
+       switch (abs) {
+       case ABS_X:
+       case ABS_Y:
+       case ABS_RX:
+       case ABS_RY:    /* the two sticks */
+               input_set_abs_params(input_dev, abs, -32768, 32767, 16, 128);
+               break;
+       case ABS_Z:
+       case ABS_RZ:    /* the triggers */
+               input_set_abs_params(input_dev, abs, 0, 255, 0, 0);
+               break;
+       case ABS_HAT0X:
+       case ABS_HAT0Y: /* the d-pad (only if MAP_DPAD_TO_AXES) */
+               input_set_abs_params(input_dev, abs, -1, 1, 0, 0);
+               break;
+       }
+}
+
 static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id)
 {
        struct usb_device *udev = interface_to_usbdev (intf);
@@ -237,6 +295,9 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
                goto fail2;
 
        xpad->udev = udev;
+       xpad->dpad_mapping = xpad_device[i].dpad_mapping;
+       if (xpad->dpad_mapping == MAP_DPAD_UNKNOWN)
+               xpad->dpad_mapping = dpad_to_buttons;
        xpad->dev = input_dev;
        usb_make_path(udev, xpad->phys, sizeof(xpad->phys));
        strlcat(xpad->phys, "/input0", sizeof(xpad->phys));
@@ -251,32 +312,19 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
 
        input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
 
+       /* set up buttons */
        for (i = 0; xpad_btn[i] >= 0; i++)
                set_bit(xpad_btn[i], input_dev->keybit);
+       if (xpad->dpad_mapping == MAP_DPAD_TO_BUTTONS)
+               for (i = 0; xpad_btn_pad[i] >= 0; i++)
+                       set_bit(xpad_btn_pad[i], input_dev->keybit);
 
-       for (i = 0; xpad_abs[i] >= 0; i++) {
-
-               signed short t = xpad_abs[i];
-
-               set_bit(t, input_dev->absbit);
-
-               switch (t) {
-                       case ABS_X:
-                       case ABS_Y:
-                       case ABS_RX:
-                       case ABS_RY:    /* the two sticks */
-                               input_set_abs_params(input_dev, t, -32768, 32767, 16, 128);
-                               break;
-                       case ABS_Z:
-                       case ABS_RZ:    /* the triggers */
-                               input_set_abs_params(input_dev, t, 0, 255, 0, 0);
-                               break;
-                       case ABS_HAT0X:
-                       case ABS_HAT0Y: /* the d-pad */
-                               input_set_abs_params(input_dev, t, -1, 1, 0, 0);
-                               break;
-               }
-       }
+       /* set up axes */
+       for (i = 0; xpad_abs[i] >= 0; i++)
+               xpad_set_up_abs(input_dev, xpad_abs[i]);
+       if (xpad->dpad_mapping == MAP_DPAD_TO_AXES)
+               for (i = 0; xpad_abs_pad[i] >= 0; i++)
+                   xpad_set_up_abs(input_dev, xpad_abs_pad[i]);
 
        ep_irq_in = &intf->cur_altsetting->endpoint[0].desc;
        usb_fill_int_urb(xpad->irq_in, udev,
@@ -307,7 +355,8 @@ static void xpad_disconnect(struct usb_interface *intf)
                usb_kill_urb(xpad->irq_in);
                input_unregister_device(xpad->dev);
                usb_free_urb(xpad->irq_in);
-               usb_buffer_free(interface_to_usbdev(intf), XPAD_PKT_LEN, xpad->idata, xpad->idata_dma);
+               usb_buffer_free(interface_to_usbdev(intf), XPAD_PKT_LEN,
+                               xpad->idata, xpad->idata_dma);
                kfree(xpad);
        }
 }
index 7291e7a2717b4ade9a3a0530ddc2e908cd9fde35..905bf6398257b763c199475d5461d0ff37a71bf7 100644 (file)
@@ -233,11 +233,10 @@ static int map_p1k_to_key(int scancode)
  *
  * The key parameter can be cascaded: key2 << 8 | key1
  */
-static void report_key(struct yealink_dev *yld, int key, struct pt_regs *regs)
+static void report_key(struct yealink_dev *yld, int key)
 {
        struct input_dev *idev = yld->idev;
 
-       input_regs(idev, regs);
        if (yld->key_code >= 0) {
                /* old key up */
                input_report_key(idev, yld->key_code & 0xff, 0);
@@ -422,7 +421,7 @@ send_update:
  * error,start
  *
  */
-static void urb_irq_callback(struct urb *urb, struct pt_regs *regs)
+static void urb_irq_callback(struct urb *urb)
 {
        struct yealink_dev *yld = urb->context;
        int ret;
@@ -439,7 +438,7 @@ static void urb_irq_callback(struct urb *urb, struct pt_regs *regs)
        case CMD_SCANCODE:
                dbg("get scancode %x", yld->irq_data->data[0]);
 
-               report_key(yld, map_p1k_to_key(yld->irq_data->data[0]), regs);
+               report_key(yld, map_p1k_to_key(yld->irq_data->data[0]));
                break;
 
        default:
@@ -453,7 +452,7 @@ static void urb_irq_callback(struct urb *urb, struct pt_regs *regs)
                err("%s - usb_submit_urb failed %d", __FUNCTION__, ret);
 }
 
-static void urb_ctl_callback(struct urb *urb, struct pt_regs *regs)
+static void urb_ctl_callback(struct urb *urb)
 {
        struct yealink_dev *yld = urb->context;
        int ret;
index c29658f69e2a8c0db81dc26a9d1fe9addb1bb96a..a74bf8617e7f3f11cbb67397e0bd6cef9b160483 100644 (file)
@@ -223,6 +223,16 @@ config USB_LD
          To compile this driver as a module, choose M here: the
          module will be called ldusb.
 
+config USB_TRANCEVIBRATOR
+       tristate "PlayStation 2 Trance Vibrator driver support"
+       depends on USB
+       help
+         Say Y here if you want to connect a PlayStation 2 Trance Vibrator
+         device to your computer's USB port.
+
+         To compile this driver as a module, choose M here: the
+         module will be called trancevibrator.
+
 config USB_TEST
        tristate "USB testing driver (DEVELOPMENT)"
        depends on USB && USB_DEVICEFS && EXPERIMENTAL
index 2be70fa259bfe16cc45ebbdcae5db57dd33dcd9d..11dc59540cda11eaf501427ae43242bfe4c5e742 100644 (file)
@@ -21,6 +21,7 @@ obj-$(CONFIG_USB_PHIDGETMOTORCONTROL) += phidgetmotorcontrol.o
 obj-$(CONFIG_USB_PHIDGETSERVO) += phidgetservo.o
 obj-$(CONFIG_USB_RIO500)       += rio500.o
 obj-$(CONFIG_USB_TEST)         += usbtest.o
+obj-$(CONFIG_USB_TRANCEVIBRATOR)       += trancevibrator.o
 obj-$(CONFIG_USB_USS720)       += uss720.o
 
 obj-$(CONFIG_USB_SISUSBVGA)    += sisusbvga/
index d3963199b6eceeb8683fc312016cd72159eeac85..af2934e016a7e76313816ba480e81a060de5a4b4 100644 (file)
@@ -177,7 +177,7 @@ static void adu_delete(struct adu_device *dev)
        dbg(2, "%s : leave", __FUNCTION__);
 }
 
-static void adu_interrupt_in_callback(struct urb *urb, struct pt_regs *regs)
+static void adu_interrupt_in_callback(struct urb *urb)
 {
        struct adu_device *dev = urb->context;
 
@@ -221,7 +221,7 @@ exit:
        dbg(4," %s : leave, status %d", __FUNCTION__, urb->status);
 }
 
-static void adu_interrupt_out_callback(struct urb *urb, struct pt_regs *regs)
+static void adu_interrupt_out_callback(struct urb *urb)
 {
        struct adu_device *dev = urb->context;
 
@@ -370,7 +370,8 @@ static int adu_release(struct inode *inode, struct file *file)
        retval = adu_release_internal(dev);
 
 exit:
-       up(&dev->sem);
+       if (dev)
+               up(&dev->sem);
        dbg(2," %s : leave, return value %d", __FUNCTION__, retval);
        return retval;
 }
index fc6cc147996f9562cc632d462bd512462374d3a6..6b23a1def9fe9e12d9a36a6a6c3316fc44d38f06 100644 (file)
@@ -84,7 +84,7 @@ struct appledisplay {
 static atomic_t count_displays = ATOMIC_INIT(0);
 static struct workqueue_struct *wq;
 
-static void appledisplay_complete(struct urb *urb, struct pt_regs *regs)
+static void appledisplay_complete(struct urb *urb)
 {
        struct appledisplay *pdata = urb->context;
        unsigned long flags;
index 4fd2110b34110066606726197e966eb271b00846..0be9d62d62aeda0d096456a88fa5aa09557af0b6 100644 (file)
@@ -267,7 +267,7 @@ typedef struct
 
 /*-------------------------------------------------------------------*/
 /* Forwards */
-static void auerswald_ctrlread_complete (struct urb * urb, struct pt_regs *regs);
+static void auerswald_ctrlread_complete (struct urb * urb);
 static void auerswald_removeservice (pauerswald_t cp, pauerscon_t scp);
 static struct usb_driver auerswald_driver;
 
@@ -277,7 +277,7 @@ static struct usb_driver auerswald_driver;
 /* --------------------------                                        */
 
 /* completion function for chained urbs */
-static void auerchain_complete (struct urb * urb, struct pt_regs *regs)
+static void auerchain_complete (struct urb * urb)
 {
        unsigned long flags;
         int result;
@@ -296,7 +296,7 @@ static void auerchain_complete (struct urb * urb, struct pt_regs *regs)
            NOTE: this function may lead to more urbs submitted into the chain.
                  (no chain lock at calling complete()!)
                  acp->active != NULL is protecting us against recursion.*/
-        urb->complete (urb, regs);
+        urb->complete (urb);
 
         /* detach element from chain data structure */
        spin_lock_irqsave (&acp->lock, flags);
@@ -331,7 +331,7 @@ static void auerchain_complete (struct urb * urb, struct pt_regs *regs)
                         urb->status = result;
                         dbg("auerchain_complete: usb_submit_urb with error code %d", result);
                         /* and do error handling via *this* completion function (recursive) */
-                        auerchain_complete( urb, NULL);
+                        auerchain_complete( urb);
                 }
         } else {
                 /* simple return without submitting a new urb.
@@ -408,7 +408,7 @@ static int auerchain_submit_urb_list (pauerchain_t acp, struct urb * urb, int ea
                         urb->status = result;
                         dbg("auerchain_submit_urb: usb_submit_urb with error code %d", result);
                         /* and do error handling via completion function */
-                        auerchain_complete( urb, NULL);
+                        auerchain_complete( urb);
                 }
         }
 
@@ -448,7 +448,7 @@ static int auerchain_unlink_urb (pauerchain_t acp, struct urb * urb)
                         spin_unlock_irqrestore (&acp->lock, flags);
                         dbg ("unlink waiting urb");
                         urb->status = -ENOENT;
-                        urb->complete (urb, NULL);
+                        urb->complete (urb);
                         return 0;
                 }
         }
@@ -505,7 +505,7 @@ static void auerchain_unlink_all (pauerchain_t acp)
                 spin_unlock_irqrestore (&acp->lock, flags);
                 dbg ("unlink waiting urb");
                 urbp->status = -ENOENT;
-                urbp->complete (urbp, NULL);
+                urbp->complete (urbp);
                 spin_lock_irqsave (&acp->lock, flags);
         }
         spin_unlock_irqrestore (&acp->lock, flags);
@@ -591,7 +591,7 @@ ac_fail:/* free the elements */
 
 
 /* completion handler for synchronous chained URBs */
-static void auerchain_blocking_completion (struct urb *urb, struct pt_regs *regs)
+static void auerchain_blocking_completion (struct urb *urb)
 {
        pauerchain_chs_t pchs = (pauerchain_chs_t)urb->context;
        pchs->done = 1;
@@ -846,7 +846,7 @@ static int auerswald_status_retry (int status)
 }
 
 /* Completion of asynchronous write block */
-static void auerchar_ctrlwrite_complete (struct urb * urb, struct pt_regs *regs)
+static void auerchar_ctrlwrite_complete (struct urb * urb)
 {
        pauerbuf_t bp = (pauerbuf_t) urb->context;
        pauerswald_t cp = ((pauerswald_t)((char *)(bp->list)-(unsigned long)(&((pauerswald_t)0)->bufctl)));
@@ -859,7 +859,7 @@ static void auerchar_ctrlwrite_complete (struct urb * urb, struct pt_regs *regs)
 }
 
 /* Completion handler for dummy retry packet */
-static void auerswald_ctrlread_wretcomplete (struct urb * urb, struct pt_regs *regs)
+static void auerswald_ctrlread_wretcomplete (struct urb * urb)
 {
         pauerbuf_t bp = (pauerbuf_t) urb->context;
         pauerswald_t cp;
@@ -893,12 +893,12 @@ static void auerswald_ctrlread_wretcomplete (struct urb * urb, struct pt_regs *r
         if (ret) {
                dbg ("auerswald_ctrlread_complete: nonzero result of auerchain_submit_urb_list %d", ret);
                bp->urbp->status = ret;
-               auerswald_ctrlread_complete (bp->urbp, NULL);
+               auerswald_ctrlread_complete (bp->urbp);
        }
 }
 
 /* completion handler for receiving of control messages */
-static void auerswald_ctrlread_complete (struct urb * urb, struct pt_regs *regs)
+static void auerswald_ctrlread_complete (struct urb * urb)
 {
         unsigned int  serviceid;
         pauerswald_t  cp;
@@ -941,7 +941,7 @@ static void auerswald_ctrlread_complete (struct urb * urb, struct pt_regs *regs)
                        if (ret) {
                                dbg ("auerswald_ctrlread_complete: nonzero result of auerchain_submit_urb_list %d", ret);
                                bp->urbp->status = ret;
-                               auerswald_ctrlread_wretcomplete (bp->urbp, regs);
+                               auerswald_ctrlread_wretcomplete (bp->urbp);
                }
                 return;
         }
@@ -970,7 +970,7 @@ static void auerswald_ctrlread_complete (struct urb * urb, struct pt_regs *regs)
    messages from the USB device.
 */
 /* int completion handler. */
-static void auerswald_int_complete (struct urb * urb, struct pt_regs *regs)
+static void auerswald_int_complete (struct urb * urb)
 {
         unsigned long flags;
         unsigned  int channelid;
@@ -1070,7 +1070,7 @@ static void auerswald_int_complete (struct urb * urb, struct pt_regs *regs)
         if (ret) {
                 dbg ("auerswald_int_complete: nonzero result of auerchain_submit_urb %d", ret);
                 bp->urbp->status = ret;
-                auerswald_ctrlread_complete( bp->urbp, NULL);
+                auerswald_ctrlread_complete( bp->urbp);
                /* here applies the same problem as above: device locking! */
         }
 exit:
index c6f2f488a40feee4795ff728434f80467c82444c..9b591b8b9369b2e67708ffb79cd01cd997451838 100644 (file)
@@ -513,8 +513,6 @@ static void ftdi_elan_respond_work(void *data)
                         ftdi->disconnected += 1;
                 } else if (retval == -ENODEV) {
                         ftdi->disconnected += 1;
-                } else if (retval == -ENODEV) {
-                        ftdi->disconnected += 1;
                 } else if (retval == -EILSEQ) {
                         ftdi->disconnected += 1;
                 } else {
@@ -758,7 +756,7 @@ static ssize_t ftdi_elan_read(struct file *file, char __user *buffer,
                 return bytes_read;
 }
 
-static void ftdi_elan_write_bulk_callback(struct urb *urb, struct pt_regs *regs)
+static void ftdi_elan_write_bulk_callback(struct urb *urb)
 {
         struct usb_ftdi *ftdi = (struct usb_ftdi *)urb->context;
         if (urb->status && !(urb->status == -ENOENT || urb->status ==
@@ -1186,11 +1184,8 @@ static ssize_t ftdi_elan_write(struct file *file,
         int retval = 0;
         struct urb *urb;
         char *buf;
-        char data[30 *3 + 4];
-        char *d = data;
-        const char __user *s = user_buffer;
-        int m = (sizeof(data) - 1) / 3;
-        struct usb_ftdi *ftdi = (struct usb_ftdi *)file->private_data;
+        struct usb_ftdi *ftdi = file->private_data;
+
         if (ftdi->disconnected > 0) {
                 return -ENODEV;
         }
@@ -1220,27 +1215,18 @@ static ssize_t ftdi_elan_write(struct file *file,
         if (retval) {
                 dev_err(&ftdi->udev->dev, "failed submitting write urb, error %"
                         "d\n", retval);
-                goto error_4;
+                goto error_3;
         }
         usb_free_urb(urb);
-      exit:;
-        if (count > m) {
-                int I = m - 1;
-                while (I-- > 0) {
-                        d += sprintf(d, " %02X", 0x000000FF & *s++);
-                }
-                d += sprintf(d, " ..");
-        } else {
-                int I = count;
-                while (I-- > 0) {
-                        d += sprintf(d, " %02X", 0x000000FF & *s++);
-                }
-        }
+
+exit:
         return count;
-      error_4: error_3:usb_buffer_free(ftdi->udev, count, buf,
-              urb->transfer_dma);
-      error_2:usb_free_urb(urb);
-      error_1:return retval;
+error_3:
+       usb_buffer_free(ftdi->udev, count, buf, urb->transfer_dma);
+error_2:
+       usb_free_urb(urb);
+error_1:
+       return retval;
 }
 
 static struct file_operations ftdi_elan_fops = {
index 10b640339d8dc6e832a1c20cabdb272ebe0c323a..788a11e6772f121968b7944ef58d16701e97182f 100644 (file)
@@ -212,7 +212,7 @@ static void ld_usb_delete(struct ld_usb *dev)
 /**
  *     ld_usb_interrupt_in_callback
  */
-static void ld_usb_interrupt_in_callback(struct urb *urb, struct pt_regs *regs)
+static void ld_usb_interrupt_in_callback(struct urb *urb)
 {
        struct ld_usb *dev = urb->context;
        size_t *actual_buffer;
@@ -264,7 +264,7 @@ exit:
 /**
  *     ld_usb_interrupt_out_callback
  */
-static void ld_usb_interrupt_out_callback(struct urb *urb, struct pt_regs *regs)
+static void ld_usb_interrupt_out_callback(struct urb *urb)
 {
        struct ld_usb *dev = urb->context;
 
index 77c36e63c7bff169c405357bbec5270565ab80bb..27089497e717975c0543d537aa22562061ac9d56 100644 (file)
@@ -248,8 +248,8 @@ static loff_t tower_llseek  (struct file *file, loff_t off, int whence);
 
 static void tower_abort_transfers (struct lego_usb_tower *dev);
 static void tower_check_for_read_packet (struct lego_usb_tower *dev);
-static void tower_interrupt_in_callback (struct urb *urb, struct pt_regs *regs);
-static void tower_interrupt_out_callback (struct urb *urb, struct pt_regs *regs);
+static void tower_interrupt_in_callback (struct urb *urb);
+static void tower_interrupt_out_callback (struct urb *urb);
 
 static int  tower_probe        (struct usb_interface *interface, const struct usb_device_id *id);
 static void tower_disconnect   (struct usb_interface *interface);
@@ -755,7 +755,7 @@ exit:
 /**
  *     tower_interrupt_in_callback
  */
-static void tower_interrupt_in_callback (struct urb *urb, struct pt_regs *regs)
+static void tower_interrupt_in_callback (struct urb *urb)
 {
        struct lego_usb_tower *dev = (struct lego_usb_tower *)urb->context;
        int retval;
@@ -811,7 +811,7 @@ exit:
 /**
  *     tower_interrupt_out_callback
  */
-static void tower_interrupt_out_callback (struct urb *urb, struct pt_regs *regs)
+static void tower_interrupt_out_callback (struct urb *urb)
 {
        struct lego_usb_tower *dev = (struct lego_usb_tower *)urb->context;
 
index 78e419904abf361d3463abc625d29fe6c7b32ae3..abb4dcd811ac1394d6de4ff48acc6baed489c3e1 100644 (file)
@@ -300,7 +300,7 @@ out:
 
 static DEVICE_ATTR(lcd, S_IWUGO, NULL, enable_lcd_files);
 
-static void interfacekit_irq(struct urb *urb, struct pt_regs *regs)
+static void interfacekit_irq(struct urb *urb)
 {
        struct interfacekit *kit = urb->context;
        unsigned char *buffer = kit->data;
index 6b59b620d616b9848d59ba1bf78a91a054f697f5..5c780cab92e0c2056ae1c78699b410ef9a9105f3 100644 (file)
@@ -90,7 +90,7 @@ static int set_motor(struct motorcontrol *mc, int motor)
        return retval < 0 ? retval : 0;
 }
 
-static void motorcontrol_irq(struct urb *urb, struct pt_regs *regs)
+static void motorcontrol_irq(struct urb *urb)
 {
        struct motorcontrol *mc = urb->context;
        unsigned char *buffer = mc->data;
index a287836e39f19178d3b62ee2ccc208ec94e22863..b99ca9c798218d2a713999b5033b1730966a09d3 100644 (file)
@@ -209,7 +209,7 @@ sisusb_free_outbuf(struct sisusb_usb_data *sisusb, int index)
 /* completion callback */
 
 static void
-sisusb_bulk_completeout(struct urb *urb, struct pt_regs *regs)
+sisusb_bulk_completeout(struct urb *urb)
 {
        struct sisusb_urb_context *context = urb->context;
        struct sisusb_usb_data *sisusb;
@@ -288,7 +288,7 @@ sisusb_bulkout_msg(struct sisusb_usb_data *sisusb, int index, unsigned int pipe,
 /* completion callback */
 
 static void
-sisusb_bulk_completein(struct urb *urb, struct pt_regs *regs)
+sisusb_bulk_completein(struct urb *urb)
 {
        struct sisusb_usb_data *sisusb = urb->context;
 
diff --git a/drivers/usb/misc/trancevibrator.c b/drivers/usb/misc/trancevibrator.c
new file mode 100644 (file)
index 0000000..33cd91d
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+ * PlayStation 2 Trance Vibrator driver
+ *
+ * Copyright (C) 2006 Sam Hocevar <sam@zoy.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* Standard include files */
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+
+/* Version Information */
+#define DRIVER_VERSION "v1.1"
+#define DRIVER_AUTHOR "Sam Hocevar, sam@zoy.org"
+#define DRIVER_DESC "PlayStation 2 Trance Vibrator driver"
+
+#define TRANCEVIBRATOR_VENDOR_ID       0x0b49  /* ASCII Corporation */
+#define TRANCEVIBRATOR_PRODUCT_ID      0x064f  /* Trance Vibrator */
+
+static struct usb_device_id id_table [] = {
+       { USB_DEVICE(TRANCEVIBRATOR_VENDOR_ID, TRANCEVIBRATOR_PRODUCT_ID) },
+       { },
+};
+MODULE_DEVICE_TABLE (usb, id_table);
+
+/* Driver-local specific stuff */
+struct trancevibrator {
+       struct usb_device *udev;
+       unsigned int speed;
+};
+
+static ssize_t show_speed(struct device *dev, struct device_attribute *attr,
+                         char *buf)
+{
+       struct usb_interface *intf = to_usb_interface(dev);
+       struct trancevibrator *tv = usb_get_intfdata(intf);
+
+       return sprintf(buf, "%d\n", tv->speed);
+}
+
+static ssize_t set_speed(struct device *dev, struct device_attribute *attr,
+                        const char *buf, size_t count)
+{
+       struct usb_interface *intf = to_usb_interface(dev);
+       struct trancevibrator *tv = usb_get_intfdata(intf);
+       int temp, retval;
+
+       temp = simple_strtoul(buf, NULL, 10);
+       if (temp > 255)
+               temp = 255;
+       else if (temp < 0)
+               temp = 0;
+       tv->speed = temp;
+
+       dev_dbg(&tv->udev->dev, "speed = %d\n", tv->speed);
+
+       /* Set speed */
+       retval = usb_control_msg(tv->udev, usb_sndctrlpipe(tv->udev, 0),
+                                0x01, /* vendor request: set speed */
+                                USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_OTHER,
+                                tv->speed, /* speed value */
+                                0, NULL, 0, USB_CTRL_GET_TIMEOUT);
+       if (retval) {
+               dev_dbg(&tv->udev->dev, "retval = %d\n", retval);
+               return retval;
+       }
+       return count;
+}
+
+static DEVICE_ATTR(speed, S_IWUGO | S_IRUGO, show_speed, set_speed);
+
+static int tv_probe(struct usb_interface *interface,
+                   const struct usb_device_id *id)
+{
+       struct usb_device *udev = interface_to_usbdev(interface);
+       struct trancevibrator *dev;
+       int retval;
+
+       dev = kzalloc(sizeof(struct trancevibrator), GFP_KERNEL);
+       if (dev == NULL) {
+               dev_err(&interface->dev, "Out of memory\n");
+               retval = -ENOMEM;
+               goto error;
+       }
+
+       dev->udev = usb_get_dev(udev);
+       usb_set_intfdata(interface, dev);
+       retval = device_create_file(&interface->dev, &dev_attr_speed);
+       if (retval)
+               goto error_create_file;
+
+       return 0;
+
+error_create_file:
+       usb_put_dev(udev);
+       usb_set_intfdata(interface, NULL);
+error:
+       kfree(dev);
+       return retval;
+}
+
+static void tv_disconnect(struct usb_interface *interface)
+{
+       struct trancevibrator *dev;
+
+       dev = usb_get_intfdata (interface);
+       usb_set_intfdata(interface, NULL);
+       device_remove_file(&interface->dev, &dev_attr_speed);
+       usb_put_dev(dev->udev);
+       kfree(dev);
+}
+
+/* USB subsystem object */
+static struct usb_driver tv_driver = {
+       .name =         "trancevibrator",
+       .probe =        tv_probe,
+       .disconnect =   tv_disconnect,
+       .id_table =     id_table,
+};
+
+static int __init tv_init(void)
+{
+       int retval = usb_register(&tv_driver);
+       if (retval) {
+               err("usb_register failed. Error number %d", retval);
+               return retval;
+       }
+
+       info(DRIVER_VERSION ":" DRIVER_DESC);
+       return 0;
+}
+
+static void __exit tv_exit(void)
+{
+       usb_deregister(&tv_driver);
+}
+
+module_init (tv_init);
+module_exit (tv_exit);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
index dbaca9f1efadc02de7d6544523e75a039f26a104..ada2ebc464ae2bd0eb9bdd5a03e1424caad3c42d 100644 (file)
@@ -165,7 +165,7 @@ static int lcd_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
        return 0;
 }
 
-static void lcd_write_bulk_callback(struct urb *urb, struct pt_regs *regs)
+static void lcd_write_bulk_callback(struct urb *urb)
 {
        struct usb_lcd *dev;
 
index 983e104dd4520653baa6f61c4ca2ccff10a16ba5..7c2cbdf81d200be6831a0c7baa5b7286ed54ca06 100644 (file)
@@ -198,7 +198,7 @@ found:
  * them with non-zero test data (or test for it) when appropriate.
  */
 
-static void simple_callback (struct urb *urb, struct pt_regs *regs)
+static void simple_callback (struct urb *urb)
 {
        complete ((struct completion *) urb->context);
 }
@@ -730,7 +730,7 @@ struct subcase {
        int                     expected;
 };
 
-static void ctrl_complete (struct urb *urb, struct pt_regs *regs)
+static void ctrl_complete (struct urb *urb)
 {
        struct ctrl_ctx         *ctx = urb->context;
        struct usb_ctrlrequest  *reqp;
@@ -1035,7 +1035,7 @@ cleanup:
 
 /*-------------------------------------------------------------------------*/
 
-static void unlink1_callback (struct urb *urb, struct pt_regs *regs)
+static void unlink1_callback (struct urb *urb)
 {
        int     status = urb->status;
 
@@ -1343,7 +1343,7 @@ struct iso_context {
        struct usbtest_dev      *dev;
 };
 
-static void iso_callback (struct urb *urb, struct pt_regs *regs)
+static void iso_callback (struct urb *urb)
 {
        struct iso_context      *ctx = urb->context;
 
index 4081990b7d1a97626bb937fa6ae03f8f3dcf9e4d..7e8a0acd52eea2a6b77c66ac6aff9f19883ef2b5 100644 (file)
@@ -106,7 +106,7 @@ static void destroy_async(struct kref *kref)
 
 /* --------------------------------------------------------------------- */
 
-static void async_complete(struct urb *urb, struct pt_regs *ptregs)
+static void async_complete(struct urb *urb)
 {
        struct uss720_async_request *rq;
        struct parport *pp;
@@ -127,7 +127,7 @@ static void async_complete(struct urb *urb, struct pt_regs *ptregs)
 #endif
                /* if nAck interrupts are enabled and we have an interrupt, call the interrupt procedure */
                if (rq->reg[2] & rq->reg[1] & 0x10 && pp)
-                       parport_generic_irq(0, pp, NULL);
+                       parport_generic_irq(0, pp);
        }
        complete(&rq->compl);
        kref_put(&rq->ref_count, destroy_async);
index 054059632a219e54d2217486df8da039a7a0bff9..454a186b64ad1bafdd3b09738c1d787fd8d44415 100644 (file)
@@ -207,6 +207,14 @@ config USB_NET_PLUSB
          Choose this option if you're using a host-to-host cable
          with one of these chips.
 
+config USB_NET_MCS7830
+       tristate "MosChip MCS7830 based Ethernet adapters"
+       depends on USB_USBNET
+       help
+         Choose this option if you're using a 10/100 Ethernet USB2
+         adapter based on the MosChip 7830 controller. This includes
+         adapters marketed under the DeLOCK brand.
+
 config USB_NET_RNDIS_HOST
        tristate "Host for RNDIS devices (EXPERIMENTAL)"
        depends on USB_USBNET && EXPERIMENTAL
index 160f19dbdf121253ad360e8d64313aff8253d25d..7b51964de171416cc614c99c80b97f3494cdf841 100644 (file)
@@ -14,6 +14,7 @@ obj-$(CONFIG_USB_NET_PLUSB)   += plusb.o
 obj-$(CONFIG_USB_NET_RNDIS_HOST)       += rndis_host.o
 obj-$(CONFIG_USB_NET_CDC_SUBSET)       += cdc_subset.o
 obj-$(CONFIG_USB_NET_ZAURUS)   += zaurus.o
+obj-$(CONFIG_USB_NET_MCS7830)  += mcs7830.o
 obj-$(CONFIG_USB_USBNET)       += usbnet.o
 
 ifeq ($(CONFIG_USB_DEBUG),y)
index 9c0eacf7055c1d65169ad536fc4d21450da74eae..881841e600def9f680f58109b30bfb175e4d2118 100644 (file)
@@ -214,7 +214,7 @@ static int asix_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index,
                USB_CTRL_SET_TIMEOUT);
 }
 
-static void asix_async_cmd_callback(struct urb *urb, struct pt_regs *regs)
+static void asix_async_cmd_callback(struct urb *urb)
 {
        struct usb_ctrlrequest *req = (struct usb_ctrlrequest *)urb->context;
 
@@ -569,10 +569,12 @@ static int asix_mdio_read(struct net_device *netdev, int phy_id, int loc)
        struct usbnet *dev = netdev_priv(netdev);
        u16 res;
 
+       mutex_lock(&dev->phy_mutex);
        asix_set_sw_mii(dev);
        asix_read_cmd(dev, AX_CMD_READ_MII_REG, phy_id,
                                (__u16)loc, 2, (u16 *)&res);
        asix_set_hw_mii(dev);
+       mutex_unlock(&dev->phy_mutex);
 
        devdbg(dev, "asix_mdio_read() phy_id=0x%02x, loc=0x%02x, returns=0x%04x", phy_id, loc, le16_to_cpu(res & 0xffff));
 
@@ -586,10 +588,12 @@ asix_mdio_write(struct net_device *netdev, int phy_id, int loc, int val)
        u16 res = cpu_to_le16(val);
 
        devdbg(dev, "asix_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x", phy_id, loc, val);
+       mutex_lock(&dev->phy_mutex);
        asix_set_sw_mii(dev);
        asix_write_cmd(dev, AX_CMD_WRITE_MII_REG, phy_id,
                                (__u16)loc, 2, (u16 *)&res);
        asix_set_hw_mii(dev);
+       mutex_unlock(&dev->phy_mutex);
 }
 
 /* Get the PHY Identifier from the PHYSID1 & PHYSID2 MII registers */
@@ -700,32 +704,6 @@ static void asix_get_drvinfo (struct net_device *net,
        info->eedump_len = data->eeprom_len;
 }
 
-static int asix_get_settings(struct net_device *net, struct ethtool_cmd *cmd)
-{
-       struct usbnet *dev = netdev_priv(net);
-
-       return mii_ethtool_gset(&dev->mii,cmd);
-}
-
-static int asix_set_settings(struct net_device *net, struct ethtool_cmd *cmd)
-{
-       struct usbnet *dev = netdev_priv(net);
-       int res = mii_ethtool_sset(&dev->mii,cmd);
-
-       /* link speed/duplex might have changed */
-       if (dev->driver_info->link_reset)
-               dev->driver_info->link_reset(dev);
-
-       return res;
-}
-
-static int asix_nway_reset(struct net_device *net)
-{
-       struct usbnet *dev = netdev_priv(net);
-
-       return mii_nway_restart(&dev->mii);
-}
-
 static u32 asix_get_link(struct net_device *net)
 {
        struct usbnet *dev = netdev_priv(net);
@@ -746,15 +724,15 @@ static int asix_ioctl (struct net_device *net, struct ifreq *rq, int cmd)
 static struct ethtool_ops ax88172_ethtool_ops = {
        .get_drvinfo            = asix_get_drvinfo,
        .get_link               = asix_get_link,
-       .nway_reset             = asix_nway_reset,
        .get_msglevel           = usbnet_get_msglevel,
        .set_msglevel           = usbnet_set_msglevel,
        .get_wol                = asix_get_wol,
        .set_wol                = asix_set_wol,
        .get_eeprom_len         = asix_get_eeprom_len,
        .get_eeprom             = asix_get_eeprom,
-       .get_settings           = asix_get_settings,
-       .set_settings           = asix_set_settings,
+       .get_settings           = usbnet_get_settings,
+       .set_settings           = usbnet_set_settings,
+       .nway_reset             = usbnet_nway_reset,
 };
 
 static void ax88172_set_multicast(struct net_device *net)
@@ -885,15 +863,15 @@ out1:
 static struct ethtool_ops ax88772_ethtool_ops = {
        .get_drvinfo            = asix_get_drvinfo,
        .get_link               = asix_get_link,
-       .nway_reset             = asix_nway_reset,
        .get_msglevel           = usbnet_get_msglevel,
        .set_msglevel           = usbnet_set_msglevel,
        .get_wol                = asix_get_wol,
        .set_wol                = asix_set_wol,
        .get_eeprom_len         = asix_get_eeprom_len,
        .get_eeprom             = asix_get_eeprom,
-       .get_settings           = asix_get_settings,
-       .set_settings           = asix_set_settings,
+       .get_settings           = usbnet_get_settings,
+       .set_settings           = usbnet_set_settings,
+       .nway_reset             = usbnet_nway_reset,
 };
 
 static int ax88772_link_reset(struct usbnet *dev)
@@ -1046,15 +1024,15 @@ out1:
 static struct ethtool_ops ax88178_ethtool_ops = {
        .get_drvinfo            = asix_get_drvinfo,
        .get_link               = asix_get_link,
-       .nway_reset             = asix_nway_reset,
        .get_msglevel           = usbnet_get_msglevel,
        .set_msglevel           = usbnet_set_msglevel,
        .get_wol                = asix_get_wol,
        .set_wol                = asix_set_wol,
        .get_eeprom_len         = asix_get_eeprom_len,
        .get_eeprom             = asix_get_eeprom,
-       .get_settings           = asix_get_settings,
-       .set_settings           = asix_set_settings,
+       .get_settings           = usbnet_get_settings,
+       .set_settings           = usbnet_set_settings,
+       .nway_reset             = usbnet_nway_reset,
 };
 
 static int marvell_phy_init(struct usbnet *dev)
index be5f5e142dd0d9427d14c82eca0b51ea56e23aba..f740325abac42bbd762148b6c81a31be94ce4882 100644 (file)
@@ -223,7 +223,7 @@ struct catc {
  * Receive routines.
  */
 
-static void catc_rx_done(struct urb *urb, struct pt_regs *regs)
+static void catc_rx_done(struct urb *urb)
 {
        struct catc *catc = urb->context;
        u8 *pkt_start = urb->transfer_buffer;
@@ -289,7 +289,7 @@ static void catc_rx_done(struct urb *urb, struct pt_regs *regs)
        }
 }
 
-static void catc_irq_done(struct urb *urb, struct pt_regs *regs)
+static void catc_irq_done(struct urb *urb)
 {
        struct catc *catc = urb->context;
        u8 *data = urb->transfer_buffer;
@@ -376,7 +376,7 @@ static void catc_tx_run(struct catc *catc)
        catc->netdev->trans_start = jiffies;
 }
 
-static void catc_tx_done(struct urb *urb, struct pt_regs *regs)
+static void catc_tx_done(struct urb *urb)
 {
        struct catc *catc = urb->context;
        unsigned long flags;
@@ -486,7 +486,7 @@ static void catc_ctrl_run(struct catc *catc)
                err("submit(ctrl_urb) status %d", status);
 }
 
-static void catc_ctrl_done(struct urb *urb, struct pt_regs *regs)
+static void catc_ctrl_done(struct urb *urb)
 {
        struct catc *catc = urb->context;
        struct ctrl_queue *q;
index 82ce0358d9a3e5f13e44a76089c319e28622b662..f6971b88349d8b8a3e5c4eec357ce2ed1063166b 100644 (file)
@@ -498,7 +498,7 @@ static struct usb_driver cdc_driver = {
 
 static int __init cdc_init(void)
 {
-       BUG_ON((sizeof(((struct usbnet *)0)->data)
+       BUILD_BUG_ON((sizeof(((struct usbnet *)0)->data)
                        < sizeof(struct cdc_state)));
 
        return usb_register(&cdc_driver);
index 3155f25f1d48ba82a4abfe40c096441f8d230ff1..a3242be21959561504431d9004415d25ff37b2cc 100644 (file)
@@ -106,7 +106,7 @@ static inline int gl_control_write(struct usbnet *dev, u8 request, u16 value)
        return retval;
 }
 
-static void gl_interrupt_complete(struct urb *urb, struct pt_regs *regs)
+static void gl_interrupt_complete(struct urb *urb)
 {
        int status = urb->status;
 
index 544d41fe9b9261fb5ad2740e3ecba447cd662bf1..7c906a43e4973b081b9cdd20d068913e43a930bd 100644 (file)
 
 #undef DEBUG
 
-#ifdef DEBUG
-#define kaweth_dbg(format, arg...) printk(KERN_DEBUG __FILE__ ": " format "\n" ,##arg)
-#else
-#define kaweth_dbg(format, arg...) do {} while (0)
-#endif
-#define kaweth_err(format, arg...) printk(KERN_ERR __FILE__ ": " format "\n" ,##arg)
-#define kaweth_info(format, arg...) printk(KERN_INFO __FILE__ ": " format "\n" , ##arg)
-#define kaweth_warn(format, arg...) printk(KERN_WARNING __FILE__ ": " format "\n" , ##arg)
-
-
 #include "kawethfw.h"
 
 #define KAWETH_MTU                     1514
@@ -86,6 +76,9 @@
 
 #define KAWETH_STATUS_BROKEN           0x0000001
 #define KAWETH_STATUS_CLOSING          0x0000002
+#define KAWETH_STATUS_SUSPENDING       0x0000004
+
+#define KAWETH_STATUS_BLOCKED (KAWETH_STATUS_CLOSING | KAWETH_STATUS_SUSPENDING)
 
 #define KAWETH_PACKET_FILTER_PROMISCUOUS       0x01
 #define KAWETH_PACKET_FILTER_ALL_MULTICAST     0x02
 #define STATE_MASK                             0x40
 #define        STATE_SHIFT                             5
 
+#define IS_BLOCKED(s) (s & KAWETH_STATUS_BLOCKED)
+
 
 MODULE_AUTHOR("Michael Zappe <zapman@interlan.net>, Stephane Alnet <stephane@u-picardie.fr>, Brad Hards <bhards@bigpond.net.au> and Oliver Neukum <oliver@neukum.org>");
 MODULE_DESCRIPTION("KL5USB101 USB Ethernet driver");
@@ -128,6 +123,8 @@ static int kaweth_internal_control_msg(struct usb_device *usb_dev,
                                       unsigned int pipe,
                                       struct usb_ctrlrequest *cmd, void *data,
                                       int len, int timeout);
+static int kaweth_suspend(struct usb_interface *intf, pm_message_t message);
+static int kaweth_resume(struct usb_interface *intf);
 
 /****************************************************************
  *     usb_device_id
@@ -179,6 +176,8 @@ static struct usb_driver kaweth_driver = {
        .name =         driver_name,
        .probe =        kaweth_probe,
        .disconnect =   kaweth_disconnect,
+       .suspend =      kaweth_suspend,
+       .resume =       kaweth_resume,
        .id_table =     usb_klsi_table,
 };
 
@@ -222,6 +221,7 @@ struct kaweth_device
        int suspend_lowmem_rx;
        int suspend_lowmem_ctrl;
        int linkstate;
+       int opened;
        struct work_struct lowmem_work;
 
        struct usb_device *dev;
@@ -265,17 +265,17 @@ static int kaweth_control(struct kaweth_device *kaweth,
 {
        struct usb_ctrlrequest *dr;
 
-       kaweth_dbg("kaweth_control()");
+       dbg("kaweth_control()");
 
        if(in_interrupt()) {
-               kaweth_dbg("in_interrupt()");
+               dbg("in_interrupt()");
                return -EBUSY;
        }
 
        dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_ATOMIC);
 
        if (!dr) {
-               kaweth_dbg("kmalloc() failed");
+               dbg("kmalloc() failed");
                return -ENOMEM;
        }
 
@@ -300,7 +300,7 @@ static int kaweth_read_configuration(struct kaweth_device *kaweth)
 {
        int retval;
 
-       kaweth_dbg("Reading kaweth configuration");
+       dbg("Reading kaweth configuration");
 
        retval = kaweth_control(kaweth,
                                usb_rcvctrlpipe(kaweth->dev, 0),
@@ -322,7 +322,7 @@ static int kaweth_set_urb_size(struct kaweth_device *kaweth, __u16 urb_size)
 {
        int retval;
 
-       kaweth_dbg("Setting URB size to %d", (unsigned)urb_size);
+       dbg("Setting URB size to %d", (unsigned)urb_size);
 
        retval = kaweth_control(kaweth,
                                usb_sndctrlpipe(kaweth->dev, 0),
@@ -344,7 +344,7 @@ static int kaweth_set_sofs_wait(struct kaweth_device *kaweth, __u16 sofs_wait)
 {
        int retval;
 
-       kaweth_dbg("Set SOFS wait to %d", (unsigned)sofs_wait);
+       dbg("Set SOFS wait to %d", (unsigned)sofs_wait);
 
        retval = kaweth_control(kaweth,
                                usb_sndctrlpipe(kaweth->dev, 0),
@@ -367,7 +367,7 @@ static int kaweth_set_receive_filter(struct kaweth_device *kaweth,
 {
        int retval;
 
-       kaweth_dbg("Set receive filter to %d", (unsigned)receive_filter);
+       dbg("Set receive filter to %d", (unsigned)receive_filter);
 
        retval = kaweth_control(kaweth,
                                usb_sndctrlpipe(kaweth->dev, 0),
@@ -392,7 +392,7 @@ static int kaweth_download_firmware(struct kaweth_device *kaweth,
                                    __u8 type)
 {
        if(data_len > KAWETH_FIRMWARE_BUF_SIZE) {
-               kaweth_err("Firmware too big: %d", data_len);
+               err("Firmware too big: %d", data_len);
                return -ENOSPC;
        }
 
@@ -403,13 +403,13 @@ static int kaweth_download_firmware(struct kaweth_device *kaweth,
        kaweth->firmware_buf[4] = type;
        kaweth->firmware_buf[5] = interrupt;
 
-       kaweth_dbg("High: %i, Low:%i", kaweth->firmware_buf[3],
+       dbg("High: %i, Low:%i", kaweth->firmware_buf[3],
                   kaweth->firmware_buf[2]);
 
-       kaweth_dbg("Downloading firmware at %p to kaweth device at %p",
+       dbg("Downloading firmware at %p to kaweth device at %p",
            data,
            kaweth);
-       kaweth_dbg("Firmware length: %d", data_len);
+       dbg("Firmware length: %d", data_len);
 
        return kaweth_control(kaweth,
                              usb_sndctrlpipe(kaweth->dev, 0),
@@ -437,7 +437,7 @@ static int kaweth_trigger_firmware(struct kaweth_device *kaweth,
        kaweth->firmware_buf[6] = 0x00;
        kaweth->firmware_buf[7] = 0x00;
 
-       kaweth_dbg("Triggering firmware");
+       dbg("Triggering firmware");
 
        return kaweth_control(kaweth,
                              usb_sndctrlpipe(kaweth->dev, 0),
@@ -457,7 +457,7 @@ static int kaweth_reset(struct kaweth_device *kaweth)
 {
        int result;
 
-       kaweth_dbg("kaweth_reset(%p)", kaweth);
+       dbg("kaweth_reset(%p)", kaweth);
        result = kaweth_control(kaweth,
                                usb_sndctrlpipe(kaweth->dev, 0),
                                USB_REQ_SET_CONFIGURATION,
@@ -470,12 +470,12 @@ static int kaweth_reset(struct kaweth_device *kaweth)
 
        mdelay(10);
 
-       kaweth_dbg("kaweth_reset() returns %d.",result);
+       dbg("kaweth_reset() returns %d.",result);
 
        return result;
 }
 
-static void kaweth_usb_receive(struct urb *, struct pt_regs *regs);
+static void kaweth_usb_receive(struct urb *);
 static int kaweth_resubmit_rx_urb(struct kaweth_device *, gfp_t);
 
 /****************************************************************
@@ -500,7 +500,7 @@ static void kaweth_resubmit_int_urb(struct kaweth_device *kaweth, gfp_t mf)
                                kaweth->dev->devpath, status);
 }
 
-static void int_callback(struct urb *u, struct pt_regs *regs)
+static void int_callback(struct urb *u)
 {
        struct kaweth_device *kaweth = u->context;
        int act_state;
@@ -534,7 +534,7 @@ static void kaweth_resubmit_tl(void *d)
 {
        struct kaweth_device *kaweth = (struct kaweth_device *)d;
 
-       if (kaweth->status | KAWETH_STATUS_CLOSING)
+       if (IS_BLOCKED(kaweth->status))
                return;
 
        if (kaweth->suspend_lowmem_rx)
@@ -568,7 +568,7 @@ static int kaweth_resubmit_rx_urb(struct kaweth_device *kaweth,
                        kaweth->suspend_lowmem_rx = 1;
                        schedule_delayed_work(&kaweth->lowmem_work, HZ/4);
                }
-               kaweth_err("resubmitting rx_urb %d failed", result);
+               err("resubmitting rx_urb %d failed", result);
        } else {
                kaweth->suspend_lowmem_rx = 0;
        }
@@ -581,7 +581,7 @@ static void kaweth_async_set_rx_mode(struct kaweth_device *kaweth);
 /****************************************************************
  *     kaweth_usb_receive
  ****************************************************************/
-static void kaweth_usb_receive(struct urb *urb, struct pt_regs *regs)
+static void kaweth_usb_receive(struct urb *urb)
 {
        struct kaweth_device *kaweth = urb->context;
        struct net_device *net = kaweth->net;
@@ -601,11 +601,15 @@ static void kaweth_usb_receive(struct urb *urb, struct pt_regs *regs)
                return;
        }
 
-       if (kaweth->status & KAWETH_STATUS_CLOSING)
+       spin_lock(&kaweth->device_lock);
+       if (IS_BLOCKED(kaweth->status)) {
+               spin_unlock(&kaweth->device_lock);
                return;
+       }
+       spin_unlock(&kaweth->device_lock);
 
        if(urb->status && urb->status != -EREMOTEIO && count != 1) {
-               kaweth_err("%s RX status: %d count: %d packet_len: %d",
+               err("%s RX status: %d count: %d packet_len: %d",
                            net->name,
                           urb->status,
                           count,
@@ -616,9 +620,9 @@ static void kaweth_usb_receive(struct urb *urb, struct pt_regs *regs)
 
        if(kaweth->net && (count > 2)) {
                if(pkt_len > (count - 2)) {
-                       kaweth_err("Packet length too long for USB frame (pkt_len: %x, count: %x)",pkt_len, count);
-                       kaweth_err("Packet len & 2047: %x", pkt_len & 2047);
-                       kaweth_err("Count 2: %x", count2);
+                       err("Packet length too long for USB frame (pkt_len: %x, count: %x)",pkt_len, count);
+                       err("Packet len & 2047: %x", pkt_len & 2047);
+                       err("Count 2: %x", count2);
                        kaweth_resubmit_rx_urb(kaweth, GFP_ATOMIC);
                         return;
                 }
@@ -655,7 +659,7 @@ static int kaweth_open(struct net_device *net)
        struct kaweth_device *kaweth = netdev_priv(net);
        int res;
 
-       kaweth_dbg("Opening network device.");
+       dbg("Opening network device.");
 
        res = kaweth_resubmit_rx_urb(kaweth, GFP_KERNEL);
        if (res)
@@ -678,6 +682,7 @@ static int kaweth_open(struct net_device *net)
                usb_kill_urb(kaweth->rx_urb);
                return -EIO;
        }
+       kaweth->opened = 1;
 
        netif_start_queue(net);
 
@@ -688,14 +693,8 @@ static int kaweth_open(struct net_device *net)
 /****************************************************************
  *     kaweth_close
  ****************************************************************/
-static int kaweth_close(struct net_device *net)
+static void kaweth_kill_urbs(struct kaweth_device *kaweth)
 {
-       struct kaweth_device *kaweth = netdev_priv(net);
-
-       netif_stop_queue(net);
-
-       kaweth->status |= KAWETH_STATUS_CLOSING;
-
        usb_kill_urb(kaweth->irq_urb);
        usb_kill_urb(kaweth->rx_urb);
        usb_kill_urb(kaweth->tx_urb);
@@ -706,6 +705,21 @@ static int kaweth_close(struct net_device *net)
           we hit them again */
        usb_kill_urb(kaweth->irq_urb);
        usb_kill_urb(kaweth->rx_urb);
+}
+
+/****************************************************************
+ *     kaweth_close
+ ****************************************************************/
+static int kaweth_close(struct net_device *net)
+{
+       struct kaweth_device *kaweth = netdev_priv(net);
+
+       netif_stop_queue(net);
+       kaweth->opened = 0;
+
+       kaweth->status |= KAWETH_STATUS_CLOSING;
+
+       kaweth_kill_urbs(kaweth);
 
        kaweth->status &= ~KAWETH_STATUS_CLOSING;
 
@@ -725,14 +739,14 @@ static struct ethtool_ops ops = {
 /****************************************************************
  *     kaweth_usb_transmit_complete
  ****************************************************************/
-static void kaweth_usb_transmit_complete(struct urb *urb, struct pt_regs *regs)
+static void kaweth_usb_transmit_complete(struct urb *urb)
 {
        struct kaweth_device *kaweth = urb->context;
        struct sk_buff *skb = kaweth->tx_skb;
 
        if (unlikely(urb->status != 0))
                if (urb->status != -ENOENT)
-                       kaweth_dbg("%s: TX status %d.", kaweth->net->name, urb->status);
+                       dbg("%s: TX status %d.", kaweth->net->name, urb->status);
 
        netif_wake_queue(kaweth->net);
        dev_kfree_skb_irq(skb);
@@ -752,6 +766,9 @@ static int kaweth_start_xmit(struct sk_buff *skb, struct net_device *net)
 
        kaweth_async_set_rx_mode(kaweth);
        netif_stop_queue(net);
+       if (IS_BLOCKED(kaweth->status)) {
+               goto skip;
+       }
 
        /* We now decide whether we can put our special header into the sk_buff */
        if (skb_cloned(skb) || skb_headroom(skb) < 2) {
@@ -783,7 +800,8 @@ static int kaweth_start_xmit(struct sk_buff *skb, struct net_device *net)
 
        if((res = usb_submit_urb(kaweth->tx_urb, GFP_ATOMIC)))
        {
-               kaweth_warn("kaweth failed tx_urb %d", res);
+               warn("kaweth failed tx_urb %d", res);
+skip:
                kaweth->stats.tx_errors++;
 
                netif_start_queue(net);
@@ -812,7 +830,7 @@ static void kaweth_set_rx_mode(struct net_device *net)
                                      KAWETH_PACKET_FILTER_BROADCAST |
                                     KAWETH_PACKET_FILTER_MULTICAST;
 
-       kaweth_dbg("Setting Rx mode to %d", packet_filter_bitmap);
+       dbg("Setting Rx mode to %d", packet_filter_bitmap);
 
        netif_stop_queue(net);
 
@@ -850,10 +868,10 @@ static void kaweth_async_set_rx_mode(struct kaweth_device *kaweth)
                                KAWETH_CONTROL_TIMEOUT);
 
        if(result < 0) {
-               kaweth_err("Failed to set Rx mode: %d", result);
+               err("Failed to set Rx mode: %d", result);
        }
        else {
-               kaweth_dbg("Set Rx mode to %d", packet_filter_bitmap);
+               dbg("Set Rx mode to %d", packet_filter_bitmap);
        }
        }
 }
@@ -874,13 +892,49 @@ static void kaweth_tx_timeout(struct net_device *net)
 {
        struct kaweth_device *kaweth = netdev_priv(net);
 
-       kaweth_warn("%s: Tx timed out. Resetting.", net->name);
+       warn("%s: Tx timed out. Resetting.", net->name);
        kaweth->stats.tx_errors++;
        net->trans_start = jiffies;
 
        usb_unlink_urb(kaweth->tx_urb);
 }
 
+/****************************************************************
+ *     kaweth_suspend
+ ****************************************************************/
+static int kaweth_suspend(struct usb_interface *intf, pm_message_t message)
+{
+       struct kaweth_device *kaweth = usb_get_intfdata(intf);
+       unsigned long flags;
+
+       spin_lock_irqsave(&kaweth->device_lock, flags);
+       kaweth->status |= KAWETH_STATUS_SUSPENDING;
+       spin_unlock_irqrestore(&kaweth->device_lock, flags);
+
+       kaweth_kill_urbs(kaweth);
+       return 0;
+}
+
+/****************************************************************
+ *     kaweth_resume
+ ****************************************************************/
+static int kaweth_resume(struct usb_interface *intf)
+{
+       struct kaweth_device *kaweth = usb_get_intfdata(intf);
+       unsigned long flags;
+
+       spin_lock_irqsave(&kaweth->device_lock, flags);
+       kaweth->status &= ~KAWETH_STATUS_SUSPENDING;
+       spin_unlock_irqrestore(&kaweth->device_lock, flags);
+
+       if (!kaweth->opened)
+               return 0;
+       kaweth_resubmit_rx_urb(kaweth, GFP_NOIO);
+       kaweth_resubmit_int_urb(kaweth, GFP_NOIO);
+
+       return 0;
+}
+
 /****************************************************************
  *     kaweth_probe
  ****************************************************************/
@@ -895,15 +949,15 @@ static int kaweth_probe(
        const eth_addr_t bcast_addr = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
        int result = 0;
 
-       kaweth_dbg("Kawasaki Device Probe (Device number:%d): 0x%4.4x:0x%4.4x:0x%4.4x",
+       dbg("Kawasaki Device Probe (Device number:%d): 0x%4.4x:0x%4.4x:0x%4.4x",
                 dev->devnum,
                 le16_to_cpu(dev->descriptor.idVendor),
                 le16_to_cpu(dev->descriptor.idProduct),
                 le16_to_cpu(dev->descriptor.bcdDevice));
 
-       kaweth_dbg("Device at %p", dev);
+       dbg("Device at %p", dev);
 
-       kaweth_dbg("Descriptor length: %x type: %x",
+       dbg("Descriptor length: %x type: %x",
                 (int)dev->descriptor.bLength,
                 (int)dev->descriptor.bDescriptorType);
 
@@ -918,7 +972,7 @@ static int kaweth_probe(
        spin_lock_init(&kaweth->device_lock);
        init_waitqueue_head(&kaweth->term_wait);
 
-       kaweth_dbg("Resetting.");
+       dbg("Resetting.");
 
        kaweth_reset(kaweth);
 
@@ -928,17 +982,17 @@ static int kaweth_probe(
         */
 
        if (le16_to_cpu(dev->descriptor.bcdDevice) >> 8) {
-               kaweth_info("Firmware present in device.");
+               info("Firmware present in device.");
        } else {
                /* Download the firmware */
-               kaweth_info("Downloading firmware...");
+               info("Downloading firmware...");
                kaweth->firmware_buf = (__u8 *)__get_free_page(GFP_KERNEL);
                if ((result = kaweth_download_firmware(kaweth,
                                                      kaweth_new_code,
                                                      len_kaweth_new_code,
                                                      100,
                                                      2)) < 0) {
-                       kaweth_err("Error downloading firmware (%d)", result);
+                       err("Error downloading firmware (%d)", result);
                        goto err_fw;
                }
 
@@ -947,7 +1001,7 @@ static int kaweth_probe(
                                                      len_kaweth_new_code_fix,
                                                      100,
                                                      3)) < 0) {
-                       kaweth_err("Error downloading firmware fix (%d)", result);
+                       err("Error downloading firmware fix (%d)", result);
                        goto err_fw;
                }
 
@@ -956,7 +1010,7 @@ static int kaweth_probe(
                                                      len_kaweth_trigger_code,
                                                      126,
                                                      2)) < 0) {
-                       kaweth_err("Error downloading trigger code (%d)", result);
+                       err("Error downloading trigger code (%d)", result);
                        goto err_fw;
 
                }
@@ -966,18 +1020,18 @@ static int kaweth_probe(
                                                      len_kaweth_trigger_code_fix,
                                                      126,
                                                      3)) < 0) {
-                       kaweth_err("Error downloading trigger code fix (%d)", result);
+                       err("Error downloading trigger code fix (%d)", result);
                        goto err_fw;
                }
 
 
                if ((result = kaweth_trigger_firmware(kaweth, 126)) < 0) {
-                       kaweth_err("Error triggering firmware (%d)", result);
+                       err("Error triggering firmware (%d)", result);
                        goto err_fw;
                }
 
                /* Device will now disappear for a moment...  */
-               kaweth_info("Firmware loaded.  I'll be back...");
+               info("Firmware loaded.  I'll be back...");
 err_fw:
                free_page((unsigned long)kaweth->firmware_buf);
                free_netdev(netdev);
@@ -987,14 +1041,14 @@ err_fw:
        result = kaweth_read_configuration(kaweth);
 
        if(result < 0) {
-               kaweth_err("Error reading configuration (%d), no net device created", result);
+               err("Error reading configuration (%d), no net device created", result);
                goto err_free_netdev;
        }
 
-       kaweth_info("Statistics collection: %x", kaweth->configuration.statistics_mask);
-       kaweth_info("Multicast filter limit: %x", kaweth->configuration.max_multicast_filters & ((1 << 15) - 1));
-       kaweth_info("MTU: %d", le16_to_cpu(kaweth->configuration.segment_size));
-       kaweth_info("Read MAC address %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x",
+       info("Statistics collection: %x", kaweth->configuration.statistics_mask);
+       info("Multicast filter limit: %x", kaweth->configuration.max_multicast_filters & ((1 << 15) - 1));
+       info("MTU: %d", le16_to_cpu(kaweth->configuration.segment_size));
+       info("Read MAC address %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x",
                 (int)kaweth->configuration.hw_addr[0],
                 (int)kaweth->configuration.hw_addr[1],
                 (int)kaweth->configuration.hw_addr[2],
@@ -1005,17 +1059,17 @@ err_fw:
        if(!memcmp(&kaweth->configuration.hw_addr,
                    &bcast_addr,
                   sizeof(bcast_addr))) {
-               kaweth_err("Firmware not functioning properly, no net device created");
+               err("Firmware not functioning properly, no net device created");
                goto err_free_netdev;
        }
 
        if(kaweth_set_urb_size(kaweth, KAWETH_BUF_SIZE) < 0) {
-               kaweth_dbg("Error setting URB size");
+               dbg("Error setting URB size");
                goto err_free_netdev;
        }
 
        if(kaweth_set_sofs_wait(kaweth, KAWETH_SOFS_TO_WAIT) < 0) {
-               kaweth_err("Error setting SOFS wait");
+               err("Error setting SOFS wait");
                goto err_free_netdev;
        }
 
@@ -1025,11 +1079,11 @@ err_fw:
                                            KAWETH_PACKET_FILTER_MULTICAST);
 
        if(result < 0) {
-               kaweth_err("Error setting receive filter");
+               err("Error setting receive filter");
                goto err_free_netdev;
        }
 
-       kaweth_dbg("Initializing net device.");
+       dbg("Initializing net device.");
 
        kaweth->tx_urb = usb_alloc_urb(0, GFP_KERNEL);
        if (!kaweth->tx_urb)
@@ -1086,13 +1140,13 @@ err_fw:
 
        SET_NETDEV_DEV(netdev, &intf->dev);
        if (register_netdev(netdev) != 0) {
-               kaweth_err("Error registering netdev.");
+               err("Error registering netdev.");
                goto err_intfdata;
        }
 
-       kaweth_info("kaweth interface created at %s", kaweth->net->name);
+       info("kaweth interface created at %s", kaweth->net->name);
 
-       kaweth_dbg("Kaweth probe returning.");
+       dbg("Kaweth probe returning.");
 
        return 0;
 
@@ -1121,16 +1175,16 @@ static void kaweth_disconnect(struct usb_interface *intf)
        struct kaweth_device *kaweth = usb_get_intfdata(intf);
        struct net_device *netdev;
 
-       kaweth_info("Unregistering");
+       info("Unregistering");
 
        usb_set_intfdata(intf, NULL);
        if (!kaweth) {
-               kaweth_warn("unregistering non-existant device");
+               warn("unregistering non-existant device");
                return;
        }
        netdev = kaweth->net;
 
-       kaweth_dbg("Unregistering net device");
+       dbg("Unregistering net device");
        unregister_netdev(netdev);
 
        usb_free_urb(kaweth->rx_urb);
@@ -1154,7 +1208,7 @@ struct usb_api_data {
 /*-------------------------------------------------------------------*
  * completion handler for compatibility wrappers (sync control/bulk) *
  *-------------------------------------------------------------------*/
-static void usb_api_blocking_completion(struct urb *urb, struct pt_regs *regs)
+static void usb_api_blocking_completion(struct urb *urb)
 {
         struct usb_api_data *awd = (struct usb_api_data *)urb->context;
 
@@ -1185,7 +1239,7 @@ static int usb_start_wait_urb(struct urb *urb, int timeout, int* actual_length)
 
        if (!wait_event_timeout(awd.wqh, awd.done, timeout)) {
                 // timeout
-                kaweth_warn("usb_control/bulk_msg: timeout");
+                warn("usb_control/bulk_msg: timeout");
                 usb_kill_urb(urb);  // remove urb safely
                 status = -ETIMEDOUT;
         }
@@ -1234,7 +1288,7 @@ static int kaweth_internal_control_msg(struct usb_device *usb_dev,
  ****************************************************************/
 static int __init kaweth_init(void)
 {
-       kaweth_dbg("Driver loading");
+       dbg("Driver loading");
        return usb_register(&kaweth_driver);
 }
 
diff --git a/drivers/usb/net/mcs7830.c b/drivers/usb/net/mcs7830.c
new file mode 100644 (file)
index 0000000..6240b97
--- /dev/null
@@ -0,0 +1,534 @@
+/*
+ * MosChips MCS7830 based USB 2.0 Ethernet Devices
+ *
+ * based on usbnet.c, asix.c and the vendor provided mcs7830 driver
+ *
+ * Copyright (C) 2006 Arnd Bergmann <arnd@arndb.de>
+ * Copyright (C) 2003-2005 David Hollis <dhollis@davehollis.com>
+ * Copyright (C) 2005 Phil Chang <pchang23@sbcglobal.net>
+ * Copyright (c) 2002-2003 TiVo Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/crc32.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/init.h>
+#include <linux/mii.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/usb.h>
+
+#include "usbnet.h"
+
+/* requests */
+#define MCS7830_RD_BMREQ       (USB_DIR_IN  | USB_TYPE_VENDOR | \
+                                USB_RECIP_DEVICE)
+#define MCS7830_WR_BMREQ       (USB_DIR_OUT | USB_TYPE_VENDOR | \
+                                USB_RECIP_DEVICE)
+#define MCS7830_RD_BREQ                0x0E
+#define MCS7830_WR_BREQ                0x0D
+
+#define MCS7830_CTRL_TIMEOUT   1000
+#define MCS7830_MAX_MCAST      64
+
+#define MCS7830_VENDOR_ID      0x9710
+#define MCS7830_PRODUCT_ID     0x7830
+
+#define MCS7830_MII_ADVERTISE  (ADVERTISE_PAUSE_CAP | ADVERTISE_100FULL | \
+                                ADVERTISE_100HALF | ADVERTISE_10FULL | \
+                                ADVERTISE_10HALF | ADVERTISE_CSMA)
+
+/* HIF_REG_XX coressponding index value */
+enum {
+       HIF_REG_MULTICAST_HASH                  = 0x00,
+       HIF_REG_PACKET_GAP1                     = 0x08,
+       HIF_REG_PACKET_GAP2                     = 0x09,
+       HIF_REG_PHY_DATA                        = 0x0a,
+       HIF_REG_PHY_CMD1                        = 0x0c,
+          HIF_REG_PHY_CMD1_READ                = 0x40,
+          HIF_REG_PHY_CMD1_WRITE               = 0x20,
+          HIF_REG_PHY_CMD1_PHYADDR             = 0x01,
+       HIF_REG_PHY_CMD2                        = 0x0d,
+          HIF_REG_PHY_CMD2_PEND_FLAG_BIT       = 0x80,
+          HIF_REG_PHY_CMD2_READY_FLAG_BIT      = 0x40,
+       HIF_REG_CONFIG                          = 0x0e,
+          HIF_REG_CONFIG_CFG                   = 0x80,
+          HIF_REG_CONFIG_SPEED100              = 0x40,
+          HIF_REG_CONFIG_FULLDUPLEX_ENABLE     = 0x20,
+          HIF_REG_CONFIG_RXENABLE              = 0x10,
+          HIF_REG_CONFIG_TXENABLE              = 0x08,
+          HIF_REG_CONFIG_SLEEPMODE             = 0x04,
+          HIF_REG_CONFIG_ALLMULTICAST          = 0x02,
+          HIF_REG_CONFIG_PROMISCIOUS           = 0x01,
+       HIF_REG_ETHERNET_ADDR                   = 0x0f,
+       HIF_REG_22                              = 0x15,
+       HIF_REG_PAUSE_THRESHOLD                 = 0x16,
+          HIF_REG_PAUSE_THRESHOLD_DEFAULT      = 0,
+};
+
+struct mcs7830_data {
+       u8 multi_filter[8];
+       u8 config;
+};
+
+static const char driver_name[] = "MOSCHIP usb-ethernet driver";
+
+static int mcs7830_get_reg(struct usbnet *dev, u16 index, u16 size, void *data)
+{
+       struct usb_device *xdev = dev->udev;
+       int ret;
+
+       ret = usb_control_msg(xdev, usb_rcvctrlpipe(xdev, 0), MCS7830_RD_BREQ,
+                             MCS7830_RD_BMREQ, 0x0000, index, data,
+                             size, msecs_to_jiffies(MCS7830_CTRL_TIMEOUT));
+       return ret;
+}
+
+static int mcs7830_set_reg(struct usbnet *dev, u16 index, u16 size, void *data)
+{
+       struct usb_device *xdev = dev->udev;
+       int ret;
+
+       ret = usb_control_msg(xdev, usb_sndctrlpipe(xdev, 0), MCS7830_WR_BREQ,
+                             MCS7830_WR_BMREQ, 0x0000, index, data,
+                             size, msecs_to_jiffies(MCS7830_CTRL_TIMEOUT));
+       return ret;
+}
+
+static void mcs7830_async_cmd_callback(struct urb *urb)
+{
+       struct usb_ctrlrequest *req = (struct usb_ctrlrequest *)urb->context;
+
+       if (urb->status < 0)
+               printk(KERN_DEBUG "mcs7830_async_cmd_callback() failed with %d",
+                       urb->status);
+
+       kfree(req);
+       usb_free_urb(urb);
+}
+
+static void mcs7830_set_reg_async(struct usbnet *dev, u16 index, u16 size, void *data)
+{
+       struct usb_ctrlrequest *req;
+       int ret;
+       struct urb *urb;
+
+       urb = usb_alloc_urb(0, GFP_ATOMIC);
+       if (!urb) {
+               dev_dbg(&dev->udev->dev, "Error allocating URB "
+                               "in write_cmd_async!");
+               return;
+       }
+
+       req = kmalloc(sizeof *req, GFP_ATOMIC);
+       if (!req) {
+               dev_err(&dev->udev->dev, "Failed to allocate memory for "
+                               "control request");
+               goto out;
+       }
+       req->bRequestType = MCS7830_WR_BMREQ;
+       req->bRequest = MCS7830_WR_BREQ;
+       req->wValue = 0;
+       req->wIndex = cpu_to_le16(index);
+       req->wLength = cpu_to_le16(size);
+
+       usb_fill_control_urb(urb, dev->udev,
+                            usb_sndctrlpipe(dev->udev, 0),
+                            (void *)req, data, size,
+                            mcs7830_async_cmd_callback, req);
+
+       ret = usb_submit_urb(urb, GFP_ATOMIC);
+       if (ret < 0) {
+               dev_err(&dev->udev->dev, "Error submitting the control "
+                               "message: ret=%d", ret);
+               goto out;
+       }
+       return;
+out:
+       kfree(req);
+       usb_free_urb(urb);
+}
+
+static int mcs7830_get_address(struct usbnet *dev)
+{
+       int ret;
+       ret = mcs7830_get_reg(dev, HIF_REG_ETHERNET_ADDR, ETH_ALEN,
+                                  dev->net->dev_addr);
+       if (ret < 0)
+               return ret;
+       return 0;
+}
+
+static int mcs7830_read_phy(struct usbnet *dev, u8 index)
+{
+       int ret;
+       int i;
+       __le16 val;
+
+       u8 cmd[2] = {
+               HIF_REG_PHY_CMD1_READ | HIF_REG_PHY_CMD1_PHYADDR,
+               HIF_REG_PHY_CMD2_PEND_FLAG_BIT | index,
+       };
+
+       mutex_lock(&dev->phy_mutex);
+       /* write the MII command */
+       ret = mcs7830_set_reg(dev, HIF_REG_PHY_CMD1, 2, cmd);
+       if (ret < 0)
+               goto out;
+
+       /* wait for the data to become valid, should be within < 1ms */
+       for (i = 0; i < 10; i++) {
+               ret = mcs7830_get_reg(dev, HIF_REG_PHY_CMD1, 2, cmd);
+               if ((ret < 0) || (cmd[1] & HIF_REG_PHY_CMD2_READY_FLAG_BIT))
+                       break;
+               ret = -EIO;
+               msleep(1);
+       }
+       if (ret < 0)
+               goto out;
+
+       /* read actual register contents */
+       ret = mcs7830_get_reg(dev, HIF_REG_PHY_DATA, 2, &val);
+       if (ret < 0)
+               goto out;
+       ret = le16_to_cpu(val);
+       dev_dbg(&dev->udev->dev, "read PHY reg %02x: %04x (%d tries)\n",
+               index, val, i);
+out:
+       mutex_unlock(&dev->phy_mutex);
+       return ret;
+}
+
+static int mcs7830_write_phy(struct usbnet *dev, u8 index, u16 val)
+{
+       int ret;
+       int i;
+       __le16 le_val;
+
+       u8 cmd[2] = {
+               HIF_REG_PHY_CMD1_WRITE | HIF_REG_PHY_CMD1_PHYADDR,
+               HIF_REG_PHY_CMD2_PEND_FLAG_BIT | (index & 0x1F),
+       };
+
+       mutex_lock(&dev->phy_mutex);
+
+       /* write the new register contents */
+       le_val = cpu_to_le16(val);
+       ret = mcs7830_set_reg(dev, HIF_REG_PHY_DATA, 2, &le_val);
+       if (ret < 0)
+               goto out;
+
+       /* write the MII command */
+       ret = mcs7830_set_reg(dev, HIF_REG_PHY_CMD1, 2, cmd);
+       if (ret < 0)
+               goto out;
+
+       /* wait for the command to be accepted by the PHY */
+       for (i = 0; i < 10; i++) {
+               ret = mcs7830_get_reg(dev, HIF_REG_PHY_CMD1, 2, cmd);
+               if ((ret < 0) || (cmd[1] & HIF_REG_PHY_CMD2_READY_FLAG_BIT))
+                       break;
+               ret = -EIO;
+               msleep(1);
+       }
+       if (ret < 0)
+               goto out;
+
+       ret = 0;
+       dev_dbg(&dev->udev->dev, "write PHY reg %02x: %04x (%d tries)\n",
+               index, val, i);
+out:
+       mutex_unlock(&dev->phy_mutex);
+       return ret;
+}
+
+/*
+ * This algorithm comes from the original mcs7830 version 1.4 driver,
+ * not sure if it is needed.
+ */
+static int mcs7830_set_autoneg(struct usbnet *dev, int ptrUserPhyMode)
+{
+       int ret;
+       /* Enable all media types */
+       ret = mcs7830_write_phy(dev, MII_ADVERTISE, MCS7830_MII_ADVERTISE);
+
+       /* First reset BMCR */
+       if (!ret)
+               ret = mcs7830_write_phy(dev, MII_BMCR, 0x0000);
+       /* Enable Auto Neg */
+       if (!ret)
+               ret = mcs7830_write_phy(dev, MII_BMCR, BMCR_ANENABLE);
+       /* Restart Auto Neg (Keep the Enable Auto Neg Bit Set) */
+       if (!ret)
+               ret = mcs7830_write_phy(dev, MII_BMCR,
+                               BMCR_ANENABLE | BMCR_ANRESTART  );
+       return ret < 0 ? : 0;
+}
+
+
+/*
+ * if we can read register 22, the chip revision is C or higher
+ */
+static int mcs7830_get_rev(struct usbnet *dev)
+{
+       u8 dummy[2];
+       int ret;
+       ret = mcs7830_get_reg(dev, HIF_REG_22, 2, dummy);
+       if (ret > 0)
+               return 2; /* Rev C or later */
+       return 1; /* earlier revision */
+}
+
+/*
+ * On rev. C we need to set the pause threshold
+ */
+static void mcs7830_rev_C_fixup(struct usbnet *dev)
+{
+       u8 pause_threshold = HIF_REG_PAUSE_THRESHOLD_DEFAULT;
+       int retry;
+
+       for (retry = 0; retry < 2; retry++) {
+               if (mcs7830_get_rev(dev) == 2) {
+                       dev_info(&dev->udev->dev, "applying rev.C fixup\n");
+                       mcs7830_set_reg(dev, HIF_REG_PAUSE_THRESHOLD,
+                                       1, &pause_threshold);
+               }
+               msleep(1);
+       }
+}
+
+static int mcs7830_init_dev(struct usbnet *dev)
+{
+       int ret;
+       int retry;
+
+       /* Read MAC address from EEPROM */
+       ret = -EINVAL;
+       for (retry = 0; retry < 5 && ret; retry++)
+               ret = mcs7830_get_address(dev);
+       if (ret) {
+               dev_warn(&dev->udev->dev, "Cannot read MAC address\n");
+               goto out;
+       }
+
+       /* Set up PHY */
+       ret = mcs7830_set_autoneg(dev, 0);
+       if (ret) {
+               dev_info(&dev->udev->dev, "Cannot set autoneg\n");
+               goto out;
+       }
+
+       mcs7830_rev_C_fixup(dev);
+       ret = 0;
+out:
+       return ret;
+}
+
+static int mcs7830_mdio_read(struct net_device *netdev, int phy_id,
+                            int location)
+{
+       struct usbnet *dev = netdev->priv;
+       return mcs7830_read_phy(dev, location);
+}
+
+static void mcs7830_mdio_write(struct net_device *netdev, int phy_id,
+                               int location, int val)
+{
+       struct usbnet *dev = netdev->priv;
+       mcs7830_write_phy(dev, location, val);
+}
+
+static int mcs7830_ioctl(struct net_device *net, struct ifreq *rq, int cmd)
+{
+       struct usbnet *dev = netdev_priv(net);
+       return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL);
+}
+
+/* credits go to asix_set_multicast */
+static void mcs7830_set_multicast(struct net_device *net)
+{
+       struct usbnet *dev = netdev_priv(net);
+       struct mcs7830_data *data = (struct mcs7830_data *)&dev->data;
+
+       data->config = HIF_REG_CONFIG_TXENABLE;
+
+       /* this should not be needed, but it doesn't work otherwise */
+       data->config |= HIF_REG_CONFIG_ALLMULTICAST;
+
+       if (net->flags & IFF_PROMISC) {
+               data->config |= HIF_REG_CONFIG_PROMISCIOUS;
+       } else if (net->flags & IFF_ALLMULTI
+                  || net->mc_count > MCS7830_MAX_MCAST) {
+               data->config |= HIF_REG_CONFIG_ALLMULTICAST;
+       } else if (net->mc_count == 0) {
+               /* just broadcast and directed */
+       } else {
+               /* We use the 20 byte dev->data
+                * for our 8 byte filter buffer
+                * to avoid allocating memory that
+                * is tricky to free later */
+               struct dev_mc_list *mc_list = net->mc_list;
+               u32 crc_bits;
+               int i;
+
+               memset(data->multi_filter, 0, sizeof data->multi_filter);
+
+               /* Build the multicast hash filter. */
+               for (i = 0; i < net->mc_count; i++) {
+                       crc_bits = ether_crc(ETH_ALEN, mc_list->dmi_addr) >> 26;
+                       data->multi_filter[crc_bits >> 3] |= 1 << (crc_bits & 7);
+                       mc_list = mc_list->next;
+               }
+
+               mcs7830_set_reg_async(dev, HIF_REG_MULTICAST_HASH,
+                               sizeof data->multi_filter,
+                               data->multi_filter);
+       }
+
+       mcs7830_set_reg_async(dev, HIF_REG_CONFIG, 1, &data->config);
+}
+
+static int mcs7830_get_regs_len(struct net_device *net)
+{
+       struct usbnet *dev = netdev_priv(net);
+
+       switch (mcs7830_get_rev(dev)) {
+       case 1:
+               return 21;
+       case 2:
+               return 32;
+       }
+       return 0;
+}
+
+static void mcs7830_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *drvinfo)
+{
+       usbnet_get_drvinfo(net, drvinfo);
+       drvinfo->regdump_len = mcs7830_get_regs_len(net);
+}
+
+static void mcs7830_get_regs(struct net_device *net, struct ethtool_regs *regs, void *data)
+{
+       struct usbnet *dev = netdev_priv(net);
+
+       regs->version = mcs7830_get_rev(dev);
+       mcs7830_get_reg(dev, 0, regs->len, data);
+}
+
+static struct ethtool_ops mcs7830_ethtool_ops = {
+       .get_drvinfo            = mcs7830_get_drvinfo,
+       .get_regs_len           = mcs7830_get_regs_len,
+       .get_regs               = mcs7830_get_regs,
+
+       /* common usbnet calls */
+       .get_link               = usbnet_get_link,
+       .get_msglevel           = usbnet_get_msglevel,
+       .set_msglevel           = usbnet_set_msglevel,
+       .get_settings           = usbnet_get_settings,
+       .set_settings           = usbnet_set_settings,
+       .nway_reset             = usbnet_nway_reset,
+};
+
+static int mcs7830_bind(struct usbnet *dev, struct usb_interface *udev)
+{
+       struct net_device *net = dev->net;
+       int ret;
+
+       ret = mcs7830_init_dev(dev);
+       if (ret)
+               goto out;
+
+       net->do_ioctl = mcs7830_ioctl;
+       net->ethtool_ops = &mcs7830_ethtool_ops;
+       net->set_multicast_list = mcs7830_set_multicast;
+       mcs7830_set_multicast(net);
+
+       /* reserve space for the status byte on rx */
+       dev->rx_urb_size = ETH_FRAME_LEN + 1;
+
+       dev->mii.mdio_read = mcs7830_mdio_read;
+       dev->mii.mdio_write = mcs7830_mdio_write;
+       dev->mii.dev = net;
+       dev->mii.phy_id_mask = 0x3f;
+       dev->mii.reg_num_mask = 0x1f;
+       dev->mii.phy_id = *((u8 *) net->dev_addr + 1);
+
+       ret = usbnet_get_endpoints(dev, udev);
+out:
+       return ret;
+}
+
+/* The chip always appends a status bytes that we need to strip */
+static int mcs7830_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
+{
+       u8 status;
+
+       if (skb->len == 0) {
+               dev_err(&dev->udev->dev, "unexpected empty rx frame\n");
+               return 0;
+       }
+
+       skb_trim(skb, skb->len - 1);
+       status = skb->data[skb->len];
+
+       if (status != 0x20)
+               dev_dbg(&dev->udev->dev, "rx fixup status %x\n", status);
+
+       return skb->len > 0;
+}
+
+static const struct driver_info moschip_info = {
+       .description    = "MOSCHIP 7830 usb-NET adapter",
+       .bind           = mcs7830_bind,
+       .rx_fixup       = mcs7830_rx_fixup,
+       .flags          = FLAG_ETHER,
+       .in             = 1,
+       .out            = 2,
+};
+
+static const struct usb_device_id products[] = {
+       {
+               USB_DEVICE(MCS7830_VENDOR_ID, MCS7830_PRODUCT_ID),
+               .driver_info = (unsigned long) &moschip_info,
+       },
+       {},
+};
+MODULE_DEVICE_TABLE(usb, products);
+
+static struct usb_driver mcs7830_driver = {
+       .name = driver_name,
+       .id_table = products,
+       .probe = usbnet_probe,
+       .disconnect = usbnet_disconnect,
+       .suspend = usbnet_suspend,
+       .resume = usbnet_resume,
+};
+
+static int __init mcs7830_init(void)
+{
+       return usb_register(&mcs7830_driver);
+}
+module_init(mcs7830_init);
+
+static void __exit mcs7830_exit(void)
+{
+       usb_deregister(&mcs7830_driver);
+}
+module_exit(mcs7830_exit);
+
+MODULE_DESCRIPTION("USB to network adapter MCS7830)");
+MODULE_LICENSE("GPL");
index 301baa72bac7b4ed20859a4fe64b97dfd545a9b4..ce00de8f13a101c36d9dc66daf2fbff6ead17291 100644 (file)
@@ -368,7 +368,7 @@ static int net1080_check_connect(struct usbnet *dev)
        return 0;
 }
 
-static void nc_flush_complete(struct urb *urb, struct pt_regs *regs)
+static void nc_flush_complete(struct urb *urb)
 {
        kfree(urb->context);
        usb_free_urb(urb);
index 918cf5a77c08208f99e89aeede993397413d2129..33abbd2176b63f27cd8cea5b28b419fedd202f6c 100644 (file)
@@ -96,7 +96,7 @@ MODULE_DEVICE_TABLE(usb, pegasus_ids);
 
 static int update_eth_regs_async(pegasus_t *);
 /* Aargh!!! I _really_ hate such tweaks */
-static void ctrl_callback(struct urb *urb, struct pt_regs *regs)
+static void ctrl_callback(struct urb *urb)
 {
        pegasus_t *pegasus = urb->context;
 
@@ -605,7 +605,7 @@ static inline struct sk_buff *pull_skb(pegasus_t * pegasus)
        return NULL;
 }
 
-static void read_bulk_callback(struct urb *urb, struct pt_regs *regs)
+static void read_bulk_callback(struct urb *urb)
 {
        pegasus_t *pegasus = urb->context;
        struct net_device *net;
@@ -764,7 +764,7 @@ done:
        spin_unlock_irqrestore(&pegasus->rx_pool_lock, flags);
 }
 
-static void write_bulk_callback(struct urb *urb, struct pt_regs *regs)
+static void write_bulk_callback(struct urb *urb)
 {
        pegasus_t *pegasus = urb->context;
        struct net_device *net = pegasus->net;
@@ -801,7 +801,7 @@ static void write_bulk_callback(struct urb *urb, struct pt_regs *regs)
        netif_wake_queue(net);
 }
 
-static void intr_callback(struct urb *urb, struct pt_regs *regs)
+static void intr_callback(struct urb *urb)
 {
        pegasus_t *pegasus = urb->context;
        struct net_device *net;
@@ -1226,7 +1226,7 @@ static void pegasus_set_multicast(struct net_device *net)
        }
 
        pegasus->flags |= ETH_REGS_CHANGE;
-       ctrl_callback(pegasus->ctrl_urb, NULL);
+       ctrl_callback(pegasus->ctrl_urb);
 }
 
 static __u8 mii_phy_probe(pegasus_t * pegasus)
@@ -1433,11 +1433,11 @@ static int pegasus_resume (struct usb_interface *intf)
        if (netif_running(pegasus->net)) {
                pegasus->rx_urb->status = 0;
                pegasus->rx_urb->actual_length = 0;
-               read_bulk_callback(pegasus->rx_urb, NULL);
+               read_bulk_callback(pegasus->rx_urb);
 
                pegasus->intr_urb->status = 0;
                pegasus->intr_urb->actual_length = 0;
-               intr_callback(pegasus->intr_urb, NULL);
+               intr_callback(pegasus->intr_urb);
        }
        queue_delayed_work(pegasus_workqueue, &pegasus->carrier_check,
                                CARRIER_CHECK_DELAY);
index 2364c20993874f381c4975430000a56fb8a4a9a4..72171f94ded48eb648c061b92f648bda8f2600b4 100644 (file)
@@ -208,7 +208,7 @@ static int set_registers(rtl8150_t * dev, u16 indx, u16 size, void *data)
                               indx, 0, data, size, 500);
 }
 
-static void ctrl_callback(struct urb *urb, struct pt_regs *regs)
+static void ctrl_callback(struct urb *urb)
 {
        rtl8150_t *dev;
 
@@ -415,7 +415,7 @@ static inline struct sk_buff *pull_skb(rtl8150_t *dev)
        return NULL;
 }
 
-static void read_bulk_callback(struct urb *urb, struct pt_regs *regs)
+static void read_bulk_callback(struct urb *urb)
 {
        rtl8150_t *dev;
        unsigned pkt_len, res;
@@ -525,7 +525,7 @@ tlsched:
        tasklet_schedule(&dev->tl);
 }
 
-static void write_bulk_callback(struct urb *urb, struct pt_regs *regs)
+static void write_bulk_callback(struct urb *urb)
 {
        rtl8150_t *dev;
 
@@ -541,7 +541,7 @@ static void write_bulk_callback(struct urb *urb, struct pt_regs *regs)
        netif_wake_queue(dev->netdev);
 }
 
-static void intr_callback(struct urb *urb, struct pt_regs *regs)
+static void intr_callback(struct urb *urb)
 {
        rtl8150_t *dev;
        __u8 *d;
@@ -617,11 +617,11 @@ static int rtl8150_resume(struct usb_interface *intf)
        if (netif_running(dev->netdev)) {
                dev->rx_urb->status = 0;
                dev->rx_urb->actual_length = 0;
-               read_bulk_callback(dev->rx_urb, NULL);
+               read_bulk_callback(dev->rx_urb);
 
                dev->intr_urb->status = 0;
                dev->intr_urb->actual_length = 0;
-               intr_callback(dev->intr_urb, NULL);
+               intr_callback(dev->intr_urb);
        }
        return 0;
 }
index 98a522f1e264412bc7b15971aee924125930eedd..cf3d20eb781cde127e53f1af4c553bea198fa13a 100644 (file)
@@ -158,7 +158,7 @@ int usbnet_get_endpoints(struct usbnet *dev, struct usb_interface *intf)
 }
 EXPORT_SYMBOL_GPL(usbnet_get_endpoints);
 
-static void intr_complete (struct urb *urb, struct pt_regs *regs);
+static void intr_complete (struct urb *urb);
 
 static int init_status (struct usbnet *dev, struct usb_interface *intf)
 {
@@ -295,7 +295,7 @@ EXPORT_SYMBOL_GPL(usbnet_defer_kevent);
 
 /*-------------------------------------------------------------------------*/
 
-static void rx_complete (struct urb *urb, struct pt_regs *regs);
+static void rx_complete (struct urb *urb);
 
 static void rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags)
 {
@@ -383,7 +383,7 @@ error:
 
 /*-------------------------------------------------------------------------*/
 
-static void rx_complete (struct urb *urb, struct pt_regs *regs)
+static void rx_complete (struct urb *urb)
 {
        struct sk_buff          *skb = (struct sk_buff *) urb->context;
        struct skb_data         *entry = (struct skb_data *) skb->cb;
@@ -467,7 +467,7 @@ block:
                devdbg (dev, "no read resubmitted");
 }
 
-static void intr_complete (struct urb *urb, struct pt_regs *regs)
+static void intr_complete (struct urb *urb)
 {
        struct usbnet   *dev = urb->context;
        int             status = urb->status;
@@ -669,6 +669,37 @@ done:
  * they'll probably want to use this base set.
  */
 
+int usbnet_get_settings (struct net_device *net, struct ethtool_cmd *cmd)
+{
+       struct usbnet *dev = netdev_priv(net);
+
+       if (!dev->mii.mdio_read)
+               return -EOPNOTSUPP;
+
+       return mii_ethtool_gset(&dev->mii, cmd);
+}
+EXPORT_SYMBOL_GPL(usbnet_get_settings);
+
+int usbnet_set_settings (struct net_device *net, struct ethtool_cmd *cmd)
+{
+       struct usbnet *dev = netdev_priv(net);
+       int retval;
+
+       if (!dev->mii.mdio_write)
+               return -EOPNOTSUPP;
+
+       retval = mii_ethtool_sset(&dev->mii, cmd);
+
+       /* link speed/duplex might have changed */
+       if (dev->driver_info->link_reset)
+               dev->driver_info->link_reset(dev);
+
+       return retval;
+
+}
+EXPORT_SYMBOL_GPL(usbnet_set_settings);
+
+
 void usbnet_get_drvinfo (struct net_device *net, struct ethtool_drvinfo *info)
 {
        struct usbnet *dev = netdev_priv(net);
@@ -682,7 +713,7 @@ void usbnet_get_drvinfo (struct net_device *net, struct ethtool_drvinfo *info)
 }
 EXPORT_SYMBOL_GPL(usbnet_get_drvinfo);
 
-static u32 usbnet_get_link (struct net_device *net)
+u32 usbnet_get_link (struct net_device *net)
 {
        struct usbnet *dev = netdev_priv(net);
 
@@ -690,9 +721,14 @@ static u32 usbnet_get_link (struct net_device *net)
        if (dev->driver_info->check_connect)
                return dev->driver_info->check_connect (dev) == 0;
 
+       /* if the device has mii operations, use those */
+       if (dev->mii.mdio_read)
+               return mii_link_ok(&dev->mii);
+
        /* Otherwise, say we're up (to avoid breaking scripts) */
        return 1;
 }
+EXPORT_SYMBOL_GPL(usbnet_get_link);
 
 u32 usbnet_get_msglevel (struct net_device *net)
 {
@@ -710,10 +746,24 @@ void usbnet_set_msglevel (struct net_device *net, u32 level)
 }
 EXPORT_SYMBOL_GPL(usbnet_set_msglevel);
 
+int usbnet_nway_reset(struct net_device *net)
+{
+       struct usbnet *dev = netdev_priv(net);
+
+       if (!dev->mii.mdio_write)
+               return -EOPNOTSUPP;
+
+       return mii_nway_restart(&dev->mii);
+}
+EXPORT_SYMBOL_GPL(usbnet_nway_reset);
+
 /* drivers may override default ethtool_ops in their bind() routine */
 static struct ethtool_ops usbnet_ethtool_ops = {
+       .get_settings           = usbnet_get_settings,
+       .set_settings           = usbnet_set_settings,
        .get_drvinfo            = usbnet_get_drvinfo,
        .get_link               = usbnet_get_link,
+       .nway_reset             = usbnet_nway_reset,
        .get_msglevel           = usbnet_get_msglevel,
        .set_msglevel           = usbnet_set_msglevel,
 };
@@ -797,7 +847,7 @@ kevent (void *data)
 
 /*-------------------------------------------------------------------------*/
 
-static void tx_complete (struct urb *urb, struct pt_regs *regs)
+static void tx_complete (struct urb *urb)
 {
        struct sk_buff          *skb = (struct sk_buff *) urb->context;
        struct skb_data         *entry = (struct skb_data *) skb->cb;
@@ -1094,6 +1144,7 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
        dev->delay.function = usbnet_bh;
        dev->delay.data = (unsigned long) dev;
        init_timer (&dev->delay);
+       mutex_init (&dev->phy_mutex);
 
        SET_MODULE_OWNER (net);
        dev->net = net;
@@ -1225,7 +1276,7 @@ EXPORT_SYMBOL_GPL(usbnet_resume);
 static int __init usbnet_init(void)
 {
        /* compiler should optimize this out */
-       BUG_ON (sizeof (((struct sk_buff *)0)->cb)
+       BUILD_BUG_ON (sizeof (((struct sk_buff *)0)->cb)
                        < sizeof (struct skb_data));
 
        random_ether_addr(node_id);
index c0746f0454afe277e4d970e81f6f36ea48305b25..07c70abbe0ecaa5c3df76e488239e79e0f7ebbcf 100644 (file)
@@ -30,6 +30,7 @@ struct usbnet {
        struct usb_device       *udev;
        struct driver_info      *driver_info;
        wait_queue_head_t       *wait;
+       struct mutex            phy_mutex;
 
        /* i/o info: pipes etc */
        unsigned                in, out;
@@ -168,9 +169,13 @@ extern void usbnet_defer_kevent (struct usbnet *, int);
 extern void usbnet_skb_return (struct usbnet *, struct sk_buff *);
 extern void usbnet_unlink_rx_urbs(struct usbnet *);
 
+extern int usbnet_get_settings (struct net_device *net, struct ethtool_cmd *cmd);
+extern int usbnet_set_settings (struct net_device *net, struct ethtool_cmd *cmd);
+extern u32 usbnet_get_link (struct net_device *net);
 extern u32 usbnet_get_msglevel (struct net_device *);
 extern void usbnet_set_msglevel (struct net_device *, u32);
 extern void usbnet_get_drvinfo (struct net_device *, struct ethtool_drvinfo *);
+extern int usbnet_nway_reset(struct net_device *net);
 
 /* messaging support includes the interface name, so it must not be
  * used before it has one ... notably, in minidriver bind() calls.
index 5076b9d97057aee810faf064414485eec2f475e9..9a6ec1b5e3d5d1c1eca4dbbb3d70e56eb1ac4361 100644 (file)
@@ -422,6 +422,16 @@ config USB_SERIAL_MCT_U232
          To compile this driver as a module, choose M here: the
          module will be called mct_u232.
 
+config USB_SERIAL_MOS7720
+       tristate "USB Moschip 7720 Single Port Serial Driver"
+       depends on USB_SERIAL
+       ---help---
+         Say Y here if you want to use a USB Serial single port adapter from
+         Moschip Semiconductor Tech.
+
+         To compile this driver as a module, choose M here: the
+         module will be called mos7720.
+
 config USB_SERIAL_MOS7840
        tristate "USB Moschip 7840/7820 USB Serial Driver"
        depends on USB_SERIAL
@@ -527,8 +537,7 @@ config USB_SERIAL_OPTION
          The USB bus on these cards is not accessible externally.
 
          Supported devices include (some of?) those made by:
-         Option, Huawei, Audiovox, Sierra Wireless, Novatel Wireless, or
-         Anydata.
+         Option, Huawei, Audiovox, Novatel Wireless, or Anydata.
 
          To compile this driver as a module, choose M here: the
          module will be called option.
index 8dce83340e3109aa655d84512524f82510fe48cf..a5047dc599bbf738cbbb4a87352bf7bb638f25d3 100644 (file)
@@ -34,6 +34,7 @@ obj-$(CONFIG_USB_SERIAL_KEYSPAN_PDA)          += keyspan_pda.o
 obj-$(CONFIG_USB_SERIAL_KLSI)                  += kl5kusb105.o
 obj-$(CONFIG_USB_SERIAL_KOBIL_SCT)             += kobil_sct.o
 obj-$(CONFIG_USB_SERIAL_MCT_U232)              += mct_u232.o
+obj-$(CONFIG_USB_SERIAL_MOS7720)               += mos7720.o
 obj-$(CONFIG_USB_SERIAL_MOS7840)               += mos7840.o
 obj-$(CONFIG_USB_SERIAL_NAVMAN)                        += navman.o
 obj-$(CONFIG_USB_SERIAL_OMNINET)               += omninet.o
index 2ccd9ded52a5020e9b215092d6dd4548ed255fc8..8122755091376ce8d840683853d1f8d7c700e71e 100644 (file)
@@ -403,7 +403,7 @@ static int aircable_write(struct usb_serial_port *port,
 
 }
 
-static void aircable_write_bulk_callback(struct urb *urb, struct pt_regs *regs)
+static void aircable_write_bulk_callback(struct urb *urb)
 {
        struct usb_serial_port *port = urb->context;
        int result;
@@ -444,7 +444,7 @@ static void aircable_write_bulk_callback(struct urb *urb, struct pt_regs *regs)
        aircable_send(port);
 }
 
-static void aircable_read_bulk_callback(struct urb *urb, struct pt_regs *regs)
+static void aircable_read_bulk_callback(struct urb *urb)
 {
        struct usb_serial_port *port = urb->context;
        struct aircable_private *priv = usb_get_serial_port_data(port);
index 6e1a84a858d4df72eb6cf99ff4397d12aa23f9a2..7f5d546da39af963b57123b9b35e58e714a88cd0 100644 (file)
 
 static struct usb_device_id id_table [] = {
        { USB_DEVICE(0x0c88, 0x17da) }, /* Kyocera Wireless KPC650/Passport */
-       { USB_DEVICE(0x0f3d, 0x0112) }, /* AirPrime CDMA Wireless PC Card */
-       { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */
-       { USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */
-       { USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless Aircard 580 */
-       { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */
        { USB_DEVICE(0x1410, 0x1110) }, /* Novatel Wireless Merlin CDMA */
+       { USB_DEVICE(0x1410, 0x1100) }, /* ExpressCard34 Qualcomm 3G CDMA */
        { },
 };
 MODULE_DEVICE_TABLE(usb, id_table);
@@ -46,7 +42,7 @@ struct airprime_private {
        struct urb *read_urbp[NUM_READ_URBS];
 };
 
-static void airprime_read_bulk_callback(struct urb *urb, struct pt_regs *regs)
+static void airprime_read_bulk_callback(struct urb *urb)
 {
        struct usb_serial_port *port = urb->context;
        unsigned char *data = urb->transfer_buffer;
@@ -80,7 +76,7 @@ static void airprime_read_bulk_callback(struct urb *urb, struct pt_regs *regs)
        return;
 }
 
-static void airprime_write_bulk_callback(struct urb *urb, struct pt_regs *regs)
+static void airprime_write_bulk_callback(struct urb *urb)
 {
        struct usb_serial_port *port = urb->context;
        struct airprime_private *priv = usb_get_serial_port_data(port);
@@ -133,6 +129,7 @@ static int airprime_open(struct usb_serial_port *port, struct file *filp)
                }
                urb = usb_alloc_urb(0, GFP_KERNEL);
                if (!urb) {
+                       kfree(buffer);
                        dev_err(&port->dev, "%s - no more urbs?\n",
                                __FUNCTION__);
                        result = -ENOMEM;
index 70ece9e01ce4a9372f48947889237a0e42891468..8835bb58ca9bfa5ec7d9a873dba1972275ad34ac 100644 (file)
@@ -91,7 +91,7 @@ static int  belkin_sa_startup         (struct usb_serial *serial);
 static void belkin_sa_shutdown         (struct usb_serial *serial);
 static int  belkin_sa_open             (struct usb_serial_port *port, struct file *filp);
 static void belkin_sa_close            (struct usb_serial_port *port, struct file *filp);
-static void belkin_sa_read_int_callback (struct urb *urb, struct pt_regs *regs);
+static void belkin_sa_read_int_callback (struct urb *urb);
 static void belkin_sa_set_termios      (struct usb_serial_port *port, struct termios * old);
 static int  belkin_sa_ioctl            (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg);
 static void belkin_sa_break_ctl                (struct usb_serial_port *port, int break_state );
@@ -248,7 +248,7 @@ static void belkin_sa_close (struct usb_serial_port *port, struct file *filp)
 } /* belkin_sa_close */
 
 
-static void belkin_sa_read_int_callback (struct urb *urb, struct pt_regs *regs)
+static void belkin_sa_read_int_callback (struct urb *urb)
 {
        struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
        struct belkin_sa_private *priv;
index 486c7411b9a7572f3e573e494d2f903cd935e342..bbf6532c26e5328b43ce4abb7a4de319ce86fbb3 100644 (file)
@@ -65,6 +65,7 @@ static struct usb_device_id id_table [] = {
        { USB_DEVICE(0x10C4, 0x813D) }, /* Burnside Telecom Deskmobile */
        { USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */
        { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */
+       { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */
        { USB_DEVICE(0x16D6, 0x0001) }, /* Jablotron serial interface */
        { } /* Terminating Entry */
 };
index d954ec34b018504b0cde6706030e3a29fac46ea9..a63c3286caa052b2e886d4ec6fe883a4344feeb1 100644 (file)
@@ -63,9 +63,9 @@ static int  cyberjack_open (struct usb_serial_port *port, struct file *filp);
 static void cyberjack_close (struct usb_serial_port *port, struct file *filp);
 static int cyberjack_write (struct usb_serial_port *port, const unsigned char *buf, int count);
 static int cyberjack_write_room( struct usb_serial_port *port );
-static void cyberjack_read_int_callback (struct urb *urb, struct pt_regs *regs);
-static void cyberjack_read_bulk_callback (struct urb *urb, struct pt_regs *regs);
-static void cyberjack_write_bulk_callback (struct urb *urb, struct pt_regs *regs);
+static void cyberjack_read_int_callback (struct urb *urb);
+static void cyberjack_read_bulk_callback (struct urb *urb);
+static void cyberjack_write_bulk_callback (struct urb *urb);
 
 static struct usb_device_id id_table [] = {
        { USB_DEVICE(CYBERJACK_VENDOR_ID, CYBERJACK_PRODUCT_ID) },
@@ -299,7 +299,7 @@ static int cyberjack_write_room( struct usb_serial_port *port )
        return CYBERJACK_LOCAL_BUF_SIZE;
 }
 
-static void cyberjack_read_int_callback( struct urb *urb, struct pt_regs *regs )
+static void cyberjack_read_int_callback( struct urb *urb )
 {
        struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
        struct cyberjack_private *priv = usb_get_serial_port_data(port);
@@ -356,7 +356,7 @@ resubmit:
        dbg("%s - usb_submit_urb(int urb)", __FUNCTION__);
 }
 
-static void cyberjack_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
+static void cyberjack_read_bulk_callback (struct urb *urb)
 {
        struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
        struct cyberjack_private *priv = usb_get_serial_port_data(port);
@@ -406,7 +406,7 @@ static void cyberjack_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
        }
 }
 
-static void cyberjack_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
+static void cyberjack_write_bulk_callback (struct urb *urb)
 {
        struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
        struct cyberjack_private *priv = usb_get_serial_port_data(port);
index e1173c1aee37c1280931cf7e32b17589d833480d..f2e89a083659c21374407a1e7f23e0fa1e17e0a6 100644 (file)
@@ -172,8 +172,8 @@ static int  cypress_chars_in_buffer (struct usb_serial_port *port);
 static void cypress_throttle           (struct usb_serial_port *port);
 static void cypress_unthrottle         (struct usb_serial_port *port);
 static void cypress_set_dead           (struct usb_serial_port *port);
-static void cypress_read_int_callback  (struct urb *urb, struct pt_regs *regs);
-static void cypress_write_int_callback (struct urb *urb, struct pt_regs *regs);
+static void cypress_read_int_callback  (struct urb *urb);
+static void cypress_write_int_callback (struct urb *urb);
 /* baud helper functions */
 static int      mask_to_rate           (unsigned mask);
 static unsigned  rate_to_mask          (int rate);
@@ -1275,7 +1275,7 @@ static void cypress_unthrottle (struct usb_serial_port *port)
 }
 
 
-static void cypress_read_int_callback(struct urb *urb, struct pt_regs *regs)
+static void cypress_read_int_callback(struct urb *urb)
 {
        struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
        struct cypress_private *priv = usb_get_serial_port_data(port);
@@ -1426,7 +1426,7 @@ continue_read:
 } /* cypress_read_int_callback */
 
 
-static void cypress_write_int_callback(struct urb *urb, struct pt_regs *regs)
+static void cypress_write_int_callback(struct urb *urb)
 {
        struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
        struct cypress_private *priv = usb_get_serial_port_data(port);
index 9b225183fc7a4ccc091b2b463a514b4a3b89baf7..bdb58100fc1dd11fdfaed773326b795b4014858b 100644 (file)
@@ -456,7 +456,7 @@ static int digi_tiocmget( struct usb_serial_port *port, struct file *file );
 static int digi_tiocmset( struct usb_serial_port *port, struct file *file,
        unsigned int set, unsigned int clear );
 static int digi_write( struct usb_serial_port *port, const unsigned char *buf, int count );
-static void digi_write_bulk_callback( struct urb *urb, struct pt_regs *regs );
+static void digi_write_bulk_callback( struct urb *urb );
 static int digi_write_room( struct usb_serial_port *port );
 static int digi_chars_in_buffer( struct usb_serial_port *port );
 static int digi_open( struct usb_serial_port *port, struct file *filp );
@@ -464,7 +464,7 @@ static void digi_close( struct usb_serial_port *port, struct file *filp );
 static int digi_startup_device( struct usb_serial *serial );
 static int digi_startup( struct usb_serial *serial );
 static void digi_shutdown( struct usb_serial *serial );
-static void digi_read_bulk_callback( struct urb *urb, struct pt_regs *regs );
+static void digi_read_bulk_callback( struct urb *urb );
 static int digi_read_inb_callback( struct urb *urb );
 static int digi_read_oob_callback( struct urb *urb );
 
@@ -1336,7 +1336,7 @@ dbg( "digi_write: returning %d", ret );
 } 
 
 
-static void digi_write_bulk_callback( struct urb *urb, struct pt_regs *regs )
+static void digi_write_bulk_callback( struct urb *urb )
 {
 
        struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
@@ -1754,7 +1754,7 @@ dbg( "digi_shutdown: TOP, in_interrupt()=%ld", in_interrupt() );
 }
 
 
-static void digi_read_bulk_callback( struct urb *urb, struct pt_regs *regs )
+static void digi_read_bulk_callback( struct urb *urb )
 {
 
        struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
index daafe405d86d628a956836c288b4bf8bd67f2c37..4ce10a8319539f56187034ecfa611c4b7b663a05 100644 (file)
@@ -93,8 +93,8 @@ static int  empeg_ioctl                       (struct usb_serial_port *port,
                                        unsigned int cmd,
                                        unsigned long arg);
 static void empeg_set_termios          (struct usb_serial_port *port, struct termios *old_termios);
-static void empeg_write_bulk_callback  (struct urb *urb, struct pt_regs *regs);
-static void empeg_read_bulk_callback   (struct urb *urb, struct pt_regs *regs);
+static void empeg_write_bulk_callback  (struct urb *urb);
+static void empeg_read_bulk_callback   (struct urb *urb);
 
 static struct usb_device_id id_table [] = {
        { USB_DEVICE(EMPEG_VENDOR_ID, EMPEG_PRODUCT_ID) },
@@ -323,7 +323,7 @@ static int empeg_chars_in_buffer (struct usb_serial_port *port)
 }
 
 
-static void empeg_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
+static void empeg_write_bulk_callback (struct urb *urb)
 {
        struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
 
@@ -338,7 +338,7 @@ static void empeg_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
 }
 
 
-static void empeg_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
+static void empeg_read_bulk_callback (struct urb *urb)
 {
        struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
        struct tty_struct *tty;
index e774a27c6c9857bf9677d166f55f5d55e6271866..bd76b4c11fcc1dc12c3a8515002d7847f179d91e 100644 (file)
@@ -1,16 +1,16 @@
 /*
  * USB FTDI SIO driver
  *
- *     Copyright (C) 1999 - 2001
- *         Greg Kroah-Hartman (greg@kroah.com)
+ *     Copyright (C) 1999 - 2001
+ *         Greg Kroah-Hartman (greg@kroah.com)
  *          Bill Ryder (bryder@sgi.com)
  *     Copyright (C) 2002
  *         Kuba Ober (kuba@mareimbrium.org)
  *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
+ *     This program is 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.
  *
  * See Documentation/usb/usb-serial.txt for more information on using this driver
  *
@@ -32,7 +32,7 @@
  *      Changed full name of USB-UIRT device to avoid "/" character.
  *      Added FTDI's alternate PID (0x6006) for FT232/245 devices.
  *      Added PID for "ELV USB Module UO100" from Stefan Frings.
- * 
+ *
  * (21/Oct/2003) Ian Abbott
  *      Renamed some VID/PID macros for Matrix Orbital and Perle Systems
  *      devices.  Removed Matrix Orbital and Perle Systems devices from the
@@ -69,7 +69,7 @@
  *     does not incure any measurable overhead.  This also relies on the fact
  *     that we have proper reference counting logic for urbs.  I nicked this
  *     from Greg KH's Visor driver.
- *      
+ *
  * (23/Jun/2003) Ian Abbott
  *      Reduced flip buffer pushes and corrected a data length test in
  *      ftdi_read_bulk_callback.
@@ -77,7 +77,7 @@
  *
  * (21/Jun/2003) Erik Nygren
  *      Added support for Home Electronics Tira-1 IR transceiver using FT232BM chip.
- *      See <http://www.home-electro.com/tira1.htm>.  Only operates properly 
+ *      See <http://www.home-electro.com/tira1.htm>.  Only operates properly
  *      at 100000 and RTS-CTS, so set custom divisor mode on startup.
  *      Also force the Tira-1 and USB-UIRT to only use their custom baud rates.
  *
  * (17/Feb/2003) Bill Ryder
  *      Added write urb buffer pool on a per device basis
  *      Added more checking for open file on callbacks (fixed OOPS)
- *      Added CrystalFontz 632 and 634 PIDs 
+ *      Added CrystalFontz 632 and 634 PIDs
  *         (thanx to CrystalFontz for the sample devices - they flushed out
  *           some driver bugs)
  *      Minor debugging message changes
  *      Added throttle, unthrottle and chars_in_buffer functions
  *      Fixed FTDI_SIO (the original device) bug
  *      Fixed some shutdown handling
- *      
- * 
- * 
- * 
+ *
+ *
+ *
+ *
  * (07/Jun/2002) Kuba Ober
  *     Changed FTDI_SIO_BASE_BAUD_TO_DIVISOR macro into ftdi_baud_to_divisor
  *     function. It was getting too complex.
  *
  * (25/Jul/2002) Bill Ryder inserted Dmitri's TIOCMIWAIT patch
  *      Not tested by me but it doesn't break anything I use.
- * 
+ *
  * (04/Jan/2002) Kuba Ober
  *     Implemented 38400 baudrate kludge, where it can be substituted with other
  *       values. That's the only way to set custom baudrates.
  *        (the previous version caused panics)
  *     Removed port iteration code since the device only has one I/O port and it
  *       was wrong anyway.
- * 
+ *
  * (31/May/2001) gkh
  *     Switched from using spinlock to a semaphore, which fixes lots of problems.
  *
  *     Cleaned up comments for 8U232
  *     Added parity, framing and overrun error handling
  *     Added receive break handling.
- * 
+ *
  * (04/08/2001) gb
  *     Identify version on module load.
- *       
+ *
  * (18/March/2001) Bill Ryder
  *     (Not released)
  *     Added send break handling. (requires kernel patch too)
  *     Fixed 8U232AM hardware RTS/CTS etc status reporting.
  *     Added flipbuf fix copied from generic device
- * 
+ *
  * (12/3/2000) Bill Ryder
  *     Added support for 8U232AM device.
  *     Moved PID and VIDs into header file only.
  *     Cleaned up comments. Removed multiple PID/VID definitions.
  *     Factorised cts/dtr code
  *     Made use of __FUNCTION__ in dbg's
- *      
+ *
  * (11/01/2000) Adam J. Richter
  *     usb_device_id table support
- * 
+ *
  * (10/05/2000) gkh
  *     Fixed bug with urb->dev not being set properly, now that the usb
  *     core needs it.
- * 
+ *
  * (09/11/2000) gkh
  *     Removed DEBUG #ifdefs with call to usb_serial_debug_data
  *
  *     Added module_init and module_exit functions to handle the fact that this
  *     driver is a loadable module now.
  *
- * (04/04/2000) Bill Ryder 
+ * (04/04/2000) Bill Ryder
  *     Fixed bugs in TCGET/TCSET ioctls (by removing them - they are
  *        handled elsewhere in the tty io driver chain).
  *
- * (03/30/2000) Bill Ryder 
+ * (03/30/2000) Bill Ryder
  *     Implemented lots of ioctls
  *     Fixed a race condition in write
  *     Changed some dbg's to errs
@@ -444,13 +444,13 @@ static struct usb_device_id id_table_combined [] = {
        /* { USB_DEVICE(FTDI_VID, FTDI_ELV_WS300PC_PID) }, */
        /* { USB_DEVICE(FTDI_VID, FTDI_ELV_FHZ1300PC_PID) }, */
        /* { USB_DEVICE(FTDI_VID, FTDI_ELV_WS500_PID) }, */
-       { USB_DEVICE(FTDI_VID, LINX_SDMUSBQSS_PID) },
-       { USB_DEVICE(FTDI_VID, LINX_MASTERDEVEL2_PID) },
-       { USB_DEVICE(FTDI_VID, LINX_FUTURE_0_PID) },
-       { USB_DEVICE(FTDI_VID, LINX_FUTURE_1_PID) },
-       { USB_DEVICE(FTDI_VID, LINX_FUTURE_2_PID) },
-       { USB_DEVICE(FTDI_VID, FTDI_CCSICDU20_0_PID) },
-       { USB_DEVICE(FTDI_VID, FTDI_CCSICDU40_1_PID) },
+       { USB_DEVICE(FTDI_VID, LINX_SDMUSBQSS_PID) },
+       { USB_DEVICE(FTDI_VID, LINX_MASTERDEVEL2_PID) },
+       { USB_DEVICE(FTDI_VID, LINX_FUTURE_0_PID) },
+       { USB_DEVICE(FTDI_VID, LINX_FUTURE_1_PID) },
+       { USB_DEVICE(FTDI_VID, LINX_FUTURE_2_PID) },
+       { USB_DEVICE(FTDI_VID, FTDI_CCSICDU20_0_PID) },
+       { USB_DEVICE(FTDI_VID, FTDI_CCSICDU40_1_PID) },
        { USB_DEVICE(FTDI_VID, INSIDE_ACCESSO) },
        { USB_DEVICE(INTREPID_VID, INTREPID_VALUECAN_PID) },
        { USB_DEVICE(INTREPID_VID, INTREPID_NEOVI_PID) },
@@ -522,7 +522,7 @@ static struct usb_driver ftdi_driver = {
        .probe =        usb_serial_probe,
        .disconnect =   usb_serial_disconnect,
        .id_table =     id_table_combined,
-       .no_dynamic_id =        1,
+       .no_dynamic_id =        1,
 };
 
 static const char *ftdi_chip_name[] = {
@@ -548,13 +548,13 @@ struct ftdi_private {
        int custom_divisor;     /* custom_divisor kludge, this is for baud_base (different from what goes to the chip!) */
        __u16 last_set_data_urb_value ;
                                /* the last data state set - needed for doing a break */
-        int write_offset;       /* This is the offset in the usb data block to write the serial data - 
+        int write_offset;       /* This is the offset in the usb data block to write the serial data -
                                 * it is different between devices
                                 */
        int flags;              /* some ASYNC_xxxx flags are supported */
        unsigned long last_dtr_rts;     /* saved modem control outputs */
         wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */
-       char prev_status, diff_status;        /* Used for TIOCMIWAIT */
+       char prev_status, diff_status;        /* Used for TIOCMIWAIT */
        __u8 rx_flags;          /* receive state flags (throttling) */
        spinlock_t rx_lock;     /* spinlock for receive state */
        struct work_struct rx_work;
@@ -589,8 +589,8 @@ static void ftdi_close                      (struct usb_serial_port *port, struct file *filp);
 static int  ftdi_write                 (struct usb_serial_port *port, const unsigned char *buf, int count);
 static int  ftdi_write_room            (struct usb_serial_port *port);
 static int  ftdi_chars_in_buffer       (struct usb_serial_port *port);
-static void ftdi_write_bulk_callback   (struct urb *urb, struct pt_regs *regs);
-static void ftdi_read_bulk_callback    (struct urb *urb, struct pt_regs *regs);
+static void ftdi_write_bulk_callback   (struct urb *urb);
+static void ftdi_read_bulk_callback    (struct urb *urb);
 static void ftdi_process_read          (void *param);
 static void ftdi_set_termios           (struct usb_serial_port *port, struct termios * old);
 static int  ftdi_tiocmget               (struct usb_serial_port *port, struct file *file);
@@ -721,7 +721,7 @@ static int update_mctrl(struct usb_serial_port *port, unsigned int set, unsigned
                urb_value |= FTDI_SIO_SET_RTS_HIGH;
        rv = usb_control_msg(port->serial->dev,
                               usb_sndctrlpipe(port->serial->dev, 0),
-                              FTDI_SIO_SET_MODEM_CTRL_REQUEST, 
+                              FTDI_SIO_SET_MODEM_CTRL_REQUEST,
                               FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE,
                               urb_value, priv->interface,
                               buf, 0, WDR_TIMEOUT);
@@ -768,7 +768,7 @@ static int change_speed(struct usb_serial_port *port)
        if (priv->interface) {  /* FT2232C */
                urb_index = (__u16)((urb_index << 8) | priv->interface);
        }
-       
+
        rv = usb_control_msg(port->serial->dev,
                            usb_sndctrlpipe(port->serial->dev, 0),
                            FTDI_SIO_SET_BAUDRATE_REQUEST,
@@ -827,7 +827,7 @@ static __u32 get_ftdi_divisor(struct usb_serial_port * port)
 
        /* 3. Convert baudrate to device-specific divisor */
 
-       if (!baud) baud = 9600; 
+       if (!baud) baud = 9600;
        switch(priv->chip_type) {
        case SIO: /* SIO chip */
                switch(baud) {
@@ -843,7 +843,7 @@ static __u32 get_ftdi_divisor(struct usb_serial_port * port)
                case 115200: div_value = ftdi_sio_b115200; break;
                } /* baud */
                if (div_value == 0) {
-                       dbg("%s - Baudrate (%d) requested is not supported", __FUNCTION__,  baud);
+                       dbg("%s - Baudrate (%d) requested is not supported", __FUNCTION__,  baud);
                        div_value = ftdi_sio_b9600;
                        div_okay = 0;
                }
@@ -925,7 +925,7 @@ static int set_serial_info(struct usb_serial_port * port, struct serial_struct _
        /* Make the changes - these are privileged changes! */
 
        priv->flags = ((priv->flags & ~ASYNC_FLAGS) |
-                      (new_serial.flags & ASYNC_FLAGS));       
+                      (new_serial.flags & ASYNC_FLAGS));
        priv->custom_divisor = new_serial.custom_divisor;
 
        port->tty->low_latency = (priv->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
@@ -950,7 +950,7 @@ check_and_exit:
             (old_priv.custom_divisor != priv->custom_divisor))) {
                change_speed(port);
        }
-       
+
        return (0);
 
 } /* set_serial_info */
@@ -1022,18 +1022,18 @@ static ssize_t show_latency_timer(struct device *dev, struct device_attribute *a
        struct usb_device *udev;
        unsigned short latency = 0;
        int rv = 0;
-       
+
        udev = to_usb_device(dev);
-       
+
        dbg("%s",__FUNCTION__);
-       
+
        rv = usb_control_msg(udev,
                             usb_rcvctrlpipe(udev, 0),
                             FTDI_SIO_GET_LATENCY_TIMER_REQUEST,
                             FTDI_SIO_GET_LATENCY_TIMER_REQUEST_TYPE,
-                            0, priv->interface, 
+                            0, priv->interface,
                             (char*) &latency, 1, WDR_TIMEOUT);
-       
+
        if (rv < 0) {
                dev_err(dev, "Unable to read latency timer: %i", rv);
                return -EIO;
@@ -1051,23 +1051,23 @@ static ssize_t store_latency_timer(struct device *dev, struct device_attribute *
        char buf[1];
        int v = simple_strtoul(valbuf, NULL, 10);
        int rv = 0;
-       
+
        udev = to_usb_device(dev);
-       
+
        dbg("%s: setting latency timer = %i", __FUNCTION__, v);
-       
+
        rv = usb_control_msg(udev,
                             usb_sndctrlpipe(udev, 0),
                             FTDI_SIO_SET_LATENCY_TIMER_REQUEST,
                             FTDI_SIO_SET_LATENCY_TIMER_REQUEST_TYPE,
-                            v, priv->interface, 
+                            v, priv->interface,
                             buf, 0, WDR_TIMEOUT);
-       
+
        if (rv < 0) {
                dev_err(dev, "Unable to write latency timer: %i", rv);
                return -EIO;
        }
-       
+
        return count;
 }
 
@@ -1082,23 +1082,23 @@ static ssize_t store_event_char(struct device *dev, struct device_attribute *att
        char buf[1];
        int v = simple_strtoul(valbuf, NULL, 10);
        int rv = 0;
-       
+
        udev = to_usb_device(dev);
-       
+
        dbg("%s: setting event char = %i", __FUNCTION__, v);
-       
+
        rv = usb_control_msg(udev,
                             usb_sndctrlpipe(udev, 0),
                             FTDI_SIO_SET_EVENT_CHAR_REQUEST,
                             FTDI_SIO_SET_EVENT_CHAR_REQUEST_TYPE,
-                            v, priv->interface, 
+                            v, priv->interface,
                             buf, 0, WDR_TIMEOUT);
-       
+
        if (rv < 0) {
                dbg("Unable to write event character: %i", rv);
                return -EIO;
        }
-       
+
        return count;
 }
 
@@ -1135,11 +1135,11 @@ static void remove_sysfs_attrs(struct usb_serial *serial)
        struct ftdi_private *priv;
        struct usb_device *udev;
 
-       dbg("%s",__FUNCTION__); 
+       dbg("%s",__FUNCTION__);
 
        priv = usb_get_serial_port_data(serial->port[0]);
        udev = serial->dev;
-       
+
        /* XXX see create_sysfs_attrs */
        if (priv->chip_type != SIO) {
                device_remove_file(&udev->dev, &dev_attr_event_char);
@@ -1147,7 +1147,7 @@ static void remove_sysfs_attrs(struct usb_serial *serial)
                        device_remove_file(&udev->dev, &dev_attr_latency_timer);
                }
        }
-       
+
 }
 
 /*
@@ -1258,7 +1258,7 @@ static void ftdi_HE_TIRA1_setup (struct usb_serial *serial)
 } /* ftdi_HE_TIRA1_setup */
 
 
-/* ftdi_shutdown is called from usbserial:usb_serial_disconnect 
+/* ftdi_shutdown is called from usbserial:usb_serial_disconnect
  *   it is called when the usb device is disconnected
  *
  *   usbserial:usb_serial_disconnect
@@ -1269,16 +1269,16 @@ static void ftdi_HE_TIRA1_setup (struct usb_serial *serial)
 
 static void ftdi_shutdown (struct usb_serial *serial)
 { /* ftdi_shutdown */
-       
+
        struct usb_serial_port *port = serial->port[0];
        struct ftdi_private *priv = usb_get_serial_port_data(port);
 
        dbg("%s", __FUNCTION__);
 
        remove_sysfs_attrs(serial);
-       
-       /* all open ports are closed at this point 
-         *    (by usbserial.c:__serial_close, which calls ftdi_close)  
+
+       /* all open ports are closed at this point
+         *    (by usbserial.c:__serial_close, which calls ftdi_close)
         */
 
        if (priv) {
@@ -1293,7 +1293,7 @@ static int  ftdi_open (struct usb_serial_port *port, struct file *filp)
        struct usb_device *dev = port->serial->dev;
        struct ftdi_private *priv = usb_get_serial_port_data(port);
        unsigned long flags;
-       
+
        int result = 0;
        char buf[1]; /* Needed for the usb_control_msg I think */
 
@@ -1312,8 +1312,8 @@ static int  ftdi_open (struct usb_serial_port *port, struct file *filp)
        /* No error checking for this (will get errors later anyway) */
        /* See ftdi_sio.h for description of what is reset */
        usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
-                       FTDI_SIO_RESET_REQUEST, FTDI_SIO_RESET_REQUEST_TYPE, 
-                       FTDI_SIO_RESET_SIO, 
+                       FTDI_SIO_RESET_REQUEST, FTDI_SIO_RESET_REQUEST_TYPE,
+                       FTDI_SIO_RESET_SIO,
                        priv->interface, buf, 0, WDR_TIMEOUT);
 
        /* Termios defaults are set by usb_serial_init. We don't change
@@ -1350,12 +1350,12 @@ static int  ftdi_open (struct usb_serial_port *port, struct file *filp)
 
 
 
-/* 
+/*
  * usbserial:__serial_close  only calls ftdi_close if the point is open
  *
  *   This only gets called when it is the last close
- *   
- *   
+ *
+ *
  */
 
 static void ftdi_close (struct usb_serial_port *port, struct file *filp)
@@ -1368,14 +1368,14 @@ static void ftdi_close (struct usb_serial_port *port, struct file *filp)
 
        if (c_cflag & HUPCL){
                /* Disable flow control */
-               if (usb_control_msg(port->serial->dev, 
+               if (usb_control_msg(port->serial->dev,
                                    usb_sndctrlpipe(port->serial->dev, 0),
                                    FTDI_SIO_SET_FLOW_CTRL_REQUEST,
                                    FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE,
                                    0, priv->interface, buf, 0,
                                    WDR_TIMEOUT) < 0) {
                        err("error from flowcontrol urb");
-               }           
+               }
 
                /* drop RTS and DTR */
                clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
@@ -1384,14 +1384,14 @@ static void ftdi_close (struct usb_serial_port *port, struct file *filp)
        /* cancel any scheduled reading */
        cancel_delayed_work(&priv->rx_work);
        flush_scheduled_work();
-       
+
        /* shutdown our bulk read */
        if (port->read_urb)
                usb_kill_urb(port->read_urb);
 } /* ftdi_close */
 
 
-  
+
 /* The SIO requires the first byte to have:
  *  B0 1
  *  B1 0
@@ -1423,7 +1423,7 @@ static int ftdi_write (struct usb_serial_port *port,
                return 0;
        }
        spin_unlock_irqrestore(&priv->tx_lock, flags);
-       
+
        data_offset = priv->write_offset;
         dbg("data_offset set to %d",data_offset);
 
@@ -1462,7 +1462,7 @@ static int ftdi_write (struct usb_serial_port *port,
                                user_pktsz = todo;
                        }
                        /* Write the control byte at the front of the packet*/
-                       *first_byte = 1 | ((user_pktsz) << 2); 
+                       *first_byte = 1 | ((user_pktsz) << 2);
                        /* Copy data for packet */
                        memcpy (first_byte + data_offset,
                                current_position, user_pktsz);
@@ -1479,7 +1479,7 @@ static int ftdi_write (struct usb_serial_port *port,
        usb_serial_debug_data(debug, &port->dev, __FUNCTION__, transfer_size, buffer);
 
        /* fill the buffer and send it */
-       usb_fill_bulk_urb(urb, port->serial->dev, 
+       usb_fill_bulk_urb(urb, port->serial->dev,
                      usb_sndbulkpipe(port->serial->dev, port->bulk_out_endpointAddress),
                      buffer, transfer_size,
                      ftdi_write_bulk_callback, port);
@@ -1508,7 +1508,7 @@ static int ftdi_write (struct usb_serial_port *port,
 
 /* This function may get called when the device is closed */
 
-static void ftdi_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
+static void ftdi_write_bulk_callback (struct urb *urb)
 {
        unsigned long flags;
        struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
@@ -1520,7 +1520,7 @@ static void ftdi_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
        kfree (urb->transfer_buffer);
 
        dbg("%s - port %d", __FUNCTION__, port->number);
-       
+
        if (urb->status) {
                dbg("nonzero write bulk status received: %d", urb->status);
                return;
@@ -1591,7 +1591,7 @@ static int ftdi_chars_in_buffer (struct usb_serial_port *port)
 
 
 
-static void ftdi_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
+static void ftdi_read_bulk_callback (struct urb *urb)
 { /* ftdi_read_bulk_callback */
        struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
        struct tty_struct *tty;
@@ -1651,7 +1651,7 @@ static void ftdi_process_read (void *param)
        struct tty_struct *tty;
        struct ftdi_private *priv;
        char error_flag;
-               unsigned char *data;
+       unsigned char *data;
 
        int i;
        int result;
@@ -1759,7 +1759,7 @@ static void ftdi_process_read (void *param)
                }
                if (length > 0) {
                        for (i = 2; i < length+2; i++) {
-                               /* Note that the error flag is duplicated for 
+                               /* Note that the error flag is duplicated for
                                   every character received since we don't know
                                   which character it applied to */
                                tty_insert_flip_char(tty, data[packet_offset+i], error_flag);
@@ -1773,7 +1773,7 @@ static void ftdi_process_read (void *param)
                   This doesn't work well since the application receives a never
                   ending stream of bad data - even though new data hasn't been sent.
                   Therefore I (bill) have taken this out.
-                  However - this might make sense for framing errors and so on 
+                  However - this might make sense for framing errors and so on
                   so I am leaving the code in for now.
                */
                else {
@@ -1827,7 +1827,7 @@ static void ftdi_process_read (void *param)
        /* if the port is closed stop trying to read */
        if (port->open_count > 0){
                /* Continue trying to always read  */
-               usb_fill_bulk_urb(port->read_urb, port->serial->dev, 
+               usb_fill_bulk_urb(port->read_urb, port->serial->dev,
                              usb_rcvbulkpipe(port->serial->dev, port->bulk_in_endpointAddress),
                              port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length,
                              ftdi_read_bulk_callback, port);
@@ -1844,9 +1844,9 @@ static void ftdi_process_read (void *param)
 static void ftdi_break_ctl( struct usb_serial_port *port, int break_state )
 {
        struct ftdi_private *priv = usb_get_serial_port_data(port);
-       __u16 urb_value = 0; 
+       __u16 urb_value = 0;
        char buf[1];
-       
+
        /* break_state = -1 to turn on break, and 0 to turn off break */
        /* see drivers/char/tty_io.c to see it used */
        /* last_set_data_urb_value NEVER has the break bit set in it */
@@ -1854,20 +1854,20 @@ static void ftdi_break_ctl( struct usb_serial_port *port, int break_state )
        if (break_state) {
                urb_value = priv->last_set_data_urb_value | FTDI_SIO_SET_BREAK;
        } else {
-               urb_value = priv->last_set_data_urb_value; 
+               urb_value = priv->last_set_data_urb_value;
        }
 
-       
+
        if (usb_control_msg(port->serial->dev, usb_sndctrlpipe(port->serial->dev, 0),
-                           FTDI_SIO_SET_DATA_REQUEST, 
+                           FTDI_SIO_SET_DATA_REQUEST,
                            FTDI_SIO_SET_DATA_REQUEST_TYPE,
                            urb_value , priv->interface,
                            buf, 0, WDR_TIMEOUT) < 0) {
                err("%s FAILED to enable/disable break state (state was %d)", __FUNCTION__,break_state);
-       }          
+       }
 
        dbg("%s break state is %d - urb is %d", __FUNCTION__,break_state, urb_value);
-       
+
 }
 
 
@@ -1883,12 +1883,12 @@ static void ftdi_set_termios (struct usb_serial_port *port, struct termios *old_
        struct ftdi_private *priv = usb_get_serial_port_data(port);
        __u16 urb_value; /* will hold the new flags */
        char buf[1]; /* Perhaps I should dynamically alloc this? */
-       
+
        // Added for xon/xoff support
        unsigned int iflag = port->tty->termios->c_iflag;
        unsigned char vstop;
        unsigned char vstart;
-       
+
        dbg("%s", __FUNCTION__);
 
        /* Force baud rate if this device requires it, unless it is set to B0. */
@@ -1906,20 +1906,20 @@ static void ftdi_set_termios (struct usb_serial_port *port, struct termios *old_
 
        cflag = port->tty->termios->c_cflag;
 
-       /* FIXME -For this cut I don't care if the line is really changing or 
-          not  - so just do the change regardless  - should be able to 
+       /* FIXME -For this cut I don't care if the line is really changing or
+          not  - so just do the change regardless  - should be able to
           compare old_termios and tty->termios */
-       /* NOTE These routines can get interrupted by 
-          ftdi_sio_read_bulk_callback  - need to examine what this 
+       /* NOTE These routines can get interrupted by
+          ftdi_sio_read_bulk_callback  - need to examine what this
            means - don't see any problems yet */
-       
+
        /* Set number of data bits, parity, stop bits */
-       
+
        urb_value = 0;
        urb_value |= (cflag & CSTOPB ? FTDI_SIO_SET_DATA_STOP_BITS_2 :
                      FTDI_SIO_SET_DATA_STOP_BITS_1);
-       urb_value |= (cflag & PARENB ? 
-                     (cflag & PARODD ? FTDI_SIO_SET_DATA_PARITY_ODD : 
+       urb_value |= (cflag & PARENB ?
+                     (cflag & PARODD ? FTDI_SIO_SET_DATA_PARITY_ODD :
                       FTDI_SIO_SET_DATA_PARITY_EVEN) :
                      FTDI_SIO_SET_DATA_PARITY_NONE);
        if (cflag & CSIZE) {
@@ -1936,25 +1936,25 @@ static void ftdi_set_termios (struct usb_serial_port *port, struct termios *old_
        /* This is needed by the break command since it uses the same command - but is
         *  or'ed with this value  */
        priv->last_set_data_urb_value = urb_value;
-       
+
        if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
-                           FTDI_SIO_SET_DATA_REQUEST, 
+                           FTDI_SIO_SET_DATA_REQUEST,
                            FTDI_SIO_SET_DATA_REQUEST_TYPE,
                            urb_value , priv->interface,
                            buf, 0, WDR_SHORT_TIMEOUT) < 0) {
                err("%s FAILED to set databits/stopbits/parity", __FUNCTION__);
-       }          
+       }
 
        /* Now do the baudrate */
        if ((cflag & CBAUD) == B0 ) {
                /* Disable flow control */
                if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
-                                   FTDI_SIO_SET_FLOW_CTRL_REQUEST, 
+                                   FTDI_SIO_SET_FLOW_CTRL_REQUEST,
                                    FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE,
-                                   0, priv->interface, 
+                                   0, priv->interface,
                                    buf, 0, WDR_TIMEOUT) < 0) {
                        err("%s error from disable flowcontrol urb", __FUNCTION__);
-               }           
+               }
                /* Drop RTS and DTR */
                clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
        } else {
@@ -1972,16 +1972,16 @@ static void ftdi_set_termios (struct usb_serial_port *port, struct termios *old_
        /* Note device also supports DTR/CD (ugh) and Xon/Xoff in hardware */
        if (cflag & CRTSCTS) {
                dbg("%s Setting to CRTSCTS flow control", __FUNCTION__);
-               if (usb_control_msg(dev, 
+               if (usb_control_msg(dev,
                                    usb_sndctrlpipe(dev, 0),
-                                   FTDI_SIO_SET_FLOW_CTRL_REQUEST, 
+                                   FTDI_SIO_SET_FLOW_CTRL_REQUEST,
                                    FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE,
                                    0 , (FTDI_SIO_RTS_CTS_HS | priv->interface),
                                    buf, 0, WDR_TIMEOUT) < 0) {
                        err("urb failed to set to rts/cts flow control");
-               }               
-               
-       } else { 
+               }
+
+       } else {
                /*
                 * Xon/Xoff code
                 *
@@ -2011,16 +2011,16 @@ static void ftdi_set_termios (struct usb_serial_port *port, struct termios *old_
                        /* else clause to only run if cfag ! CRTSCTS and iflag ! XOFF */
                        /* CHECKME Assuming XON/XOFF handled by tty stack - not by device */
                        dbg("%s Turning off hardware flow control", __FUNCTION__);
-                       if (usb_control_msg(dev, 
+                       if (usb_control_msg(dev,
                                            usb_sndctrlpipe(dev, 0),
-                                           FTDI_SIO_SET_FLOW_CTRL_REQUEST, 
+                                           FTDI_SIO_SET_FLOW_CTRL_REQUEST,
                                            FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE,
-                                           0, priv->interface, 
+                                           0, priv->interface,
                                            buf, 0, WDR_TIMEOUT) < 0) {
                                err("urb failed to clear flow control");
-                       }                               
+                       }
                }
-               
+
        }
        return;
 } /* ftdi_termios */
@@ -2036,11 +2036,11 @@ static int ftdi_tiocmget (struct usb_serial_port *port, struct file *file)
        switch (priv->chip_type) {
        case SIO:
                /* Request the status from the device */
-               if ((ret = usb_control_msg(port->serial->dev, 
+               if ((ret = usb_control_msg(port->serial->dev,
                                           usb_rcvctrlpipe(port->serial->dev, 0),
-                                          FTDI_SIO_GET_MODEM_STATUS_REQUEST, 
+                                          FTDI_SIO_GET_MODEM_STATUS_REQUEST,
                                           FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE,
-                                          0, 0, 
+                                          0, 0,
                                           buf, 1, WDR_TIMEOUT)) < 0 ) {
                        err("%s Could not get modem status of device - err: %d", __FUNCTION__,
                            ret);
@@ -2052,11 +2052,11 @@ static int ftdi_tiocmget (struct usb_serial_port *port, struct file *file)
        case FT2232C:
                /* the 8U232AM returns a two byte value (the sio is a 1 byte value) - in the same
                   format as the data returned from the in point */
-               if ((ret = usb_control_msg(port->serial->dev, 
+               if ((ret = usb_control_msg(port->serial->dev,
                                           usb_rcvctrlpipe(port->serial->dev, 0),
-                                          FTDI_SIO_GET_MODEM_STATUS_REQUEST, 
+                                          FTDI_SIO_GET_MODEM_STATUS_REQUEST,
                                           FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE,
-                                          0, priv->interface, 
+                                          0, priv->interface,
                                           buf, 2, WDR_TIMEOUT)) < 0 ) {
                        err("%s Could not get modem status of device - err: %d", __FUNCTION__,
                            ret);
@@ -2067,12 +2067,12 @@ static int ftdi_tiocmget (struct usb_serial_port *port, struct file *file)
                return -EFAULT;
                break;
        }
-       
+
        return  (buf[0] & FTDI_SIO_DSR_MASK ? TIOCM_DSR : 0) |
                (buf[0] & FTDI_SIO_CTS_MASK ? TIOCM_CTS : 0) |
                (buf[0]  & FTDI_SIO_RI_MASK  ? TIOCM_RI  : 0) |
                (buf[0]  & FTDI_SIO_RLSD_MASK ? TIOCM_CD  : 0) |
-               priv->last_dtr_rts;                     
+               priv->last_dtr_rts;
 }
 
 static int ftdi_tiocmset(struct usb_serial_port *port, struct file * file, unsigned int set, unsigned int clear)
@@ -2138,11 +2138,11 @@ static int ftdi_ioctl (struct usb_serial_port *port, struct file * file, unsigne
                break;
        default:
                break;
-               
+
        }
 
 
-       /* This is not necessarily an error - turns out the higher layers will do 
+       /* This is not necessarily an error - turns out the higher layers will do
         *  some ioctls itself (see comment above)
         */
        dbg("%s arg not supported - it was 0x%04x - check /usr/include/asm/ioctls.h", __FUNCTION__, cmd);
@@ -2199,7 +2199,7 @@ static int __init ftdi_init (void)
        if (retval)
                goto failed_sio_register;
        retval = usb_register(&ftdi_driver);
-       if (retval) 
+       if (retval)
                goto failed_usb_register;
 
        info(DRIVER_VERSION ":" DRIVER_DESC);
index 4b1196a8b09e946364fb28e8fdcb625900b78e9a..4543152a9966690dee64d8b19b6efef79aacb6db 100644 (file)
@@ -1031,7 +1031,7 @@ static void garmin_close (struct usb_serial_port *port, struct file * filp)
 }
 
 
-static void garmin_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
+static void garmin_write_bulk_callback (struct urb *urb)
 {
        unsigned long flags;
        struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
@@ -1274,7 +1274,7 @@ static void garmin_read_process(struct garmin_data * garmin_data_p,
 }
 
 
-static void garmin_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
+static void garmin_read_bulk_callback (struct urb *urb)
 {
        unsigned long flags;
        struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
@@ -1330,7 +1330,7 @@ static void garmin_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
 }
 
 
-static void garmin_read_int_callback (struct urb *urb, struct pt_regs *regs)
+static void garmin_read_int_callback (struct urb *urb)
 {
        unsigned long flags;
        int status;
index 21cbaa0fb96b998e99084ac3bc3ed6db1ac2f3dc..36042937e77f80f3c536e3f1aea64e99d161d949 100644 (file)
@@ -248,7 +248,7 @@ int usb_serial_generic_chars_in_buffer (struct usb_serial_port *port)
        return (chars);
 }
 
-void usb_serial_generic_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
+void usb_serial_generic_read_bulk_callback (struct urb *urb)
 {
        struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
        struct usb_serial *serial = port->serial;
@@ -287,7 +287,7 @@ void usb_serial_generic_read_bulk_callback (struct urb *urb, struct pt_regs *reg
 }
 EXPORT_SYMBOL_GPL(usb_serial_generic_read_bulk_callback);
 
-void usb_serial_generic_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
+void usb_serial_generic_write_bulk_callback (struct urb *urb)
 {
        struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
 
index c49976c3ad52cf7924aaf07ac3f208a5005dfc98..91bd3014ef1eb6b1a6d9060aecd05946d588d90f 100644 (file)
@@ -216,10 +216,10 @@ static int CmdUrbs = 0;           /* Number of outstanding Command Write Urbs */
 /* local function prototypes */
 
 /* function prototypes for all URB callbacks */
-static void edge_interrupt_callback    (struct urb *urb, struct pt_regs *regs);
-static void edge_bulk_in_callback      (struct urb *urb, struct pt_regs *regs);
-static void edge_bulk_out_data_callback        (struct urb *urb, struct pt_regs *regs);
-static void edge_bulk_out_cmd_callback (struct urb *urb, struct pt_regs *regs);
+static void edge_interrupt_callback    (struct urb *urb);
+static void edge_bulk_in_callback      (struct urb *urb);
+static void edge_bulk_out_data_callback        (struct urb *urb);
+static void edge_bulk_out_cmd_callback (struct urb *urb);
 
 /* function prototypes for the usbserial callbacks */
 static int  edge_open                  (struct usb_serial_port *port, struct file *filp);
@@ -534,7 +534,7 @@ static void get_product_info(struct edgeport_serial *edge_serial)
  *     this is the callback function for when we have received data on the 
  *     interrupt endpoint.
  *****************************************************************************/
-static void edge_interrupt_callback (struct urb *urb, struct pt_regs *regs)
+static void edge_interrupt_callback (struct urb *urb)
 {
        struct edgeport_serial  *edge_serial = (struct edgeport_serial *)urb->context;
        struct edgeport_port *edge_port;
@@ -631,7 +631,7 @@ exit:
  *     this is the callback function for when we have received data on the 
  *     bulk in endpoint.
  *****************************************************************************/
-static void edge_bulk_in_callback (struct urb *urb, struct pt_regs *regs)
+static void edge_bulk_in_callback (struct urb *urb)
 {
        struct edgeport_serial  *edge_serial = (struct edgeport_serial *)urb->context;
        unsigned char           *data = urb->transfer_buffer;
@@ -687,7 +687,7 @@ static void edge_bulk_in_callback (struct urb *urb, struct pt_regs *regs)
  *     this is the callback function for when we have finished sending serial data
  *     on the bulk out endpoint.
  *****************************************************************************/
-static void edge_bulk_out_data_callback (struct urb *urb, struct pt_regs *regs)
+static void edge_bulk_out_data_callback (struct urb *urb)
 {
        struct edgeport_port *edge_port = (struct edgeport_port *)urb->context;
        struct tty_struct *tty;
@@ -718,7 +718,7 @@ static void edge_bulk_out_data_callback (struct urb *urb, struct pt_regs *regs)
  *     this is the callback function for when we have finished sending a command
  *     on the bulk out endpoint.
  *****************************************************************************/
-static void edge_bulk_out_cmd_callback (struct urb *urb, struct pt_regs *regs)
+static void edge_bulk_out_cmd_callback (struct urb *urb)
 {
        struct edgeport_port *edge_port = (struct edgeport_port *)urb->context;
        struct tty_struct *tty;
index 17c5b1d2311a83e22cc09f30ef4d5b60d3c25244..ee0c921e15206458516409617ca1c648d1cfdf2d 100644 (file)
@@ -1697,7 +1697,7 @@ static void handle_new_lsr (struct edgeport_port *edge_port, int lsr_data, __u8
 }
 
 
-static void edge_interrupt_callback (struct urb *urb, struct pt_regs *regs)
+static void edge_interrupt_callback (struct urb *urb)
 {
        struct edgeport_serial *edge_serial = (struct edgeport_serial *)urb->context;
        struct usb_serial_port *port;
@@ -1787,7 +1787,7 @@ exit:
                         __FUNCTION__, status);
 }
 
-static void edge_bulk_in_callback (struct urb *urb, struct pt_regs *regs)
+static void edge_bulk_in_callback (struct urb *urb)
 {
        struct edgeport_port *edge_port = (struct edgeport_port *)urb->context;
        unsigned char *data = urb->transfer_buffer;
@@ -1879,7 +1879,7 @@ static void edge_tty_recv(struct device *dev, struct tty_struct *tty, unsigned c
        tty_flip_buffer_push(tty);
 }
 
-static void edge_bulk_out_callback (struct urb *urb, struct pt_regs *regs)
+static void edge_bulk_out_callback (struct urb *urb)
 {
        struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
        struct edgeport_port *edge_port = usb_get_serial_port_data(port);
index cbc725a6c58eb15aa606f6e40a37b6e3404493bf..6238aff1e772c71bf81deb62298be7d79ce770d0 100644 (file)
@@ -83,8 +83,8 @@ static int ipaq_write(struct usb_serial_port *port, const unsigned char *buf,
 static int ipaq_write_bulk(struct usb_serial_port *port, const unsigned char *buf,
                           int count);
 static void ipaq_write_gather(struct usb_serial_port *port);
-static void ipaq_read_bulk_callback (struct urb *urb, struct pt_regs *regs);
-static void ipaq_write_bulk_callback(struct urb *urb, struct pt_regs *regs);
+static void ipaq_read_bulk_callback (struct urb *urb);
+static void ipaq_write_bulk_callback(struct urb *urb);
 static int ipaq_write_room(struct usb_serial_port *port);
 static int ipaq_chars_in_buffer(struct usb_serial_port *port);
 static void ipaq_destroy_lists(struct usb_serial_port *port);
@@ -721,7 +721,7 @@ static void ipaq_close(struct usb_serial_port *port, struct file *filp)
        /* info ("Bytes In = %d  Bytes Out = %d", bytes_in, bytes_out); */
 }
 
-static void ipaq_read_bulk_callback(struct urb *urb, struct pt_regs *regs)
+static void ipaq_read_bulk_callback(struct urb *urb)
 {
        struct usb_serial_port  *port = (struct usb_serial_port *)urb->context;
        struct tty_struct       *tty;
@@ -859,7 +859,7 @@ static void ipaq_write_gather(struct usb_serial_port *port)
        return;
 }
 
-static void ipaq_write_bulk_callback(struct urb *urb, struct pt_regs *regs)
+static void ipaq_write_bulk_callback(struct urb *urb)
 {
        struct usb_serial_port  *port = (struct usb_serial_port *)urb->context;
        struct ipaq_private     *priv = usb_get_serial_port_data(port);
index 812bc213a963349643b0e974cdf8b47629b57fef..2a4bb66691ad4ae90cebe8b7b6201b0f4a82d404 100644 (file)
@@ -161,7 +161,7 @@ static struct usb_driver usb_ipw_driver = {
 
 static int debug;
 
-static void ipw_read_bulk_callback(struct urb *urb, struct pt_regs *regs)
+static void ipw_read_bulk_callback(struct urb *urb)
 {
        struct usb_serial_port *port = urb->context;
        unsigned char *data = urb->transfer_buffer;
@@ -367,7 +367,7 @@ static void ipw_close(struct usb_serial_port *port, struct file * filp)
        usb_kill_urb(port->write_urb);
 }
 
-static void ipw_write_bulk_callback(struct urb *urb, struct pt_regs *regs)
+static void ipw_write_bulk_callback(struct urb *urb)
 {
        struct usb_serial_port *port = urb->context;
 
index 1b348df388ed2586a2ce0937c3f4af9e3b61c934..331bf81556fcca1978b4bd4e2cac6ad358356f7a 100644 (file)
@@ -105,8 +105,8 @@ static int  ir_startup (struct usb_serial *serial);
 static int  ir_open (struct usb_serial_port *port, struct file *filep);
 static void ir_close (struct usb_serial_port *port, struct file *filep);
 static int  ir_write (struct usb_serial_port *port, const unsigned char *buf, int count);
-static void ir_write_bulk_callback (struct urb *urb, struct pt_regs *regs);
-static void ir_read_bulk_callback (struct urb *urb, struct pt_regs *regs);
+static void ir_write_bulk_callback (struct urb *urb);
+static void ir_read_bulk_callback (struct urb *urb);
 static void ir_set_termios (struct usb_serial_port *port, struct termios *old_termios);
 
 static u8 ir_baud = 0;
@@ -388,7 +388,7 @@ static int ir_write (struct usb_serial_port *port, const unsigned char *buf, int
        return result;
 }
 
-static void ir_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
+static void ir_write_bulk_callback (struct urb *urb)
 {
        struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
 
@@ -410,7 +410,7 @@ static void ir_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
        usb_serial_port_softint(port);
 }
 
-static void ir_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
+static void ir_read_bulk_callback (struct urb *urb)
 {
        struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
        struct tty_struct *tty;
index 015ad6cc1bbb6418613d8fed60992bf49e8157c4..53be824eb1bf2070e0e666ea67313de07de035c8 100644 (file)
@@ -412,7 +412,7 @@ static int keyspan_write(struct usb_serial_port *port,
        return count - left;
 }
 
-static void    usa26_indat_callback(struct urb *urb, struct pt_regs *regs)
+static void    usa26_indat_callback(struct urb *urb)
 {
        int                     i, err;
        int                     endpoint;
@@ -470,7 +470,7 @@ static void usa26_indat_callback(struct urb *urb, struct pt_regs *regs)
 }
 
        /* Outdat handling is common for all devices */
-static void    usa2x_outdat_callback(struct urb *urb, struct pt_regs *regs)
+static void    usa2x_outdat_callback(struct urb *urb)
 {
        struct usb_serial_port *port;
        struct keyspan_port_private *p_priv;
@@ -483,13 +483,13 @@ static void       usa2x_outdat_callback(struct urb *urb, struct pt_regs *regs)
                usb_serial_port_softint(port);
 }
 
-static void    usa26_inack_callback(struct urb *urb, struct pt_regs *regs)
+static void    usa26_inack_callback(struct urb *urb)
 {
        dbg ("%s", __FUNCTION__); 
        
 }
 
-static void    usa26_outcont_callback(struct urb *urb, struct pt_regs *regs)
+static void    usa26_outcont_callback(struct urb *urb)
 {
        struct usb_serial_port *port;
        struct keyspan_port_private *p_priv;
@@ -503,7 +503,7 @@ static void usa26_outcont_callback(struct urb *urb, struct pt_regs *regs)
        }
 }
 
-static void    usa26_instat_callback(struct urb *urb, struct pt_regs *regs)
+static void    usa26_instat_callback(struct urb *urb)
 {
        unsigned char                           *data = urb->transfer_buffer;
        struct keyspan_usa26_portStatusMessage  *msg;
@@ -565,14 +565,14 @@ static void       usa26_instat_callback(struct urb *urb, struct pt_regs *regs)
 exit: ;
 }
 
-static void    usa26_glocont_callback(struct urb *urb, struct pt_regs *regs)
+static void    usa26_glocont_callback(struct urb *urb)
 {
        dbg ("%s", __FUNCTION__);
        
 }
 
 
-static void usa28_indat_callback(struct urb *urb, struct pt_regs *regs)
+static void usa28_indat_callback(struct urb *urb)
 {
        int                     i, err;
        struct usb_serial_port  *port;
@@ -620,12 +620,12 @@ static void usa28_indat_callback(struct urb *urb, struct pt_regs *regs)
        } while (urb->status != -EINPROGRESS);
 }
 
-static void    usa28_inack_callback(struct urb *urb, struct pt_regs *regs)
+static void    usa28_inack_callback(struct urb *urb)
 {
        dbg ("%s", __FUNCTION__);
 }
 
-static void    usa28_outcont_callback(struct urb *urb, struct pt_regs *regs)
+static void    usa28_outcont_callback(struct urb *urb)
 {
        struct usb_serial_port *port;
        struct keyspan_port_private *p_priv;
@@ -639,7 +639,7 @@ static void usa28_outcont_callback(struct urb *urb, struct pt_regs *regs)
        }
 }
 
-static void    usa28_instat_callback(struct urb *urb, struct pt_regs *regs)
+static void    usa28_instat_callback(struct urb *urb)
 {
        int                                     err;
        unsigned char                           *data = urb->transfer_buffer;
@@ -700,13 +700,13 @@ static void       usa28_instat_callback(struct urb *urb, struct pt_regs *regs)
 exit: ;
 }
 
-static void    usa28_glocont_callback(struct urb *urb, struct pt_regs *regs)
+static void    usa28_glocont_callback(struct urb *urb)
 {
        dbg ("%s", __FUNCTION__);
 }
 
 
-static void    usa49_glocont_callback(struct urb *urb, struct pt_regs *regs)
+static void    usa49_glocont_callback(struct urb *urb)
 {
        struct usb_serial *serial;
        struct usb_serial_port *port;
@@ -730,7 +730,7 @@ static void usa49_glocont_callback(struct urb *urb, struct pt_regs *regs)
 
        /* This is actually called glostat in the Keyspan
           doco */
-static void    usa49_instat_callback(struct urb *urb, struct pt_regs *regs)
+static void    usa49_instat_callback(struct urb *urb)
 {
        int                                     err;
        unsigned char                           *data = urb->transfer_buffer;
@@ -793,12 +793,12 @@ static void       usa49_instat_callback(struct urb *urb, struct pt_regs *regs)
 exit:  ;
 }
 
-static void    usa49_inack_callback(struct urb *urb, struct pt_regs *regs)
+static void    usa49_inack_callback(struct urb *urb)
 {
        dbg ("%s", __FUNCTION__);
 }
 
-static void    usa49_indat_callback(struct urb *urb, struct pt_regs *regs)
+static void    usa49_indat_callback(struct urb *urb)
 {
        int                     i, err;
        int                     endpoint;
@@ -851,12 +851,12 @@ static void       usa49_indat_callback(struct urb *urb, struct pt_regs *regs)
 }
 
 /* not used, usa-49 doesn't have per-port control endpoints */
-static void    usa49_outcont_callback(struct urb *urb, struct pt_regs *regs)
+static void    usa49_outcont_callback(struct urb *urb)
 {
        dbg ("%s", __FUNCTION__);
 }
 
-static void    usa90_indat_callback(struct urb *urb, struct pt_regs *regs)
+static void    usa90_indat_callback(struct urb *urb)
 {
        int                     i, err;
        int                     endpoint;
@@ -930,7 +930,7 @@ static void usa90_indat_callback(struct urb *urb, struct pt_regs *regs)
 }
 
 
-static void    usa90_instat_callback(struct urb *urb, struct pt_regs *regs)
+static void    usa90_instat_callback(struct urb *urb)
 {
        unsigned char                           *data = urb->transfer_buffer;
        struct keyspan_usa90_portStatusMessage  *msg;
@@ -981,7 +981,7 @@ exit:
        ;
 }
 
-static void    usa90_outcont_callback(struct urb *urb, struct pt_regs *regs)
+static void    usa90_outcont_callback(struct urb *urb)
 {
        struct usb_serial_port *port;
        struct keyspan_port_private *p_priv;
@@ -1277,7 +1277,7 @@ static int keyspan_fake_startup (struct usb_serial *serial)
 /* Helper functions used by keyspan_setup_urbs */
 static struct urb *keyspan_setup_urb (struct usb_serial *serial, int endpoint,
                                      int dir, void *ctx, char *buf, int len,
-                                     void (*callback)(struct urb *, struct pt_regs *regs))
+                                     void (*callback)(struct urb *))
 {
        struct urb *urb;
 
@@ -1300,12 +1300,12 @@ static struct urb *keyspan_setup_urb (struct usb_serial *serial, int endpoint,
 }
 
 static struct callbacks {
-       void    (*instat_callback)(struct urb *, struct pt_regs *regs);
-       void    (*glocont_callback)(struct urb *, struct pt_regs *regs);
-       void    (*indat_callback)(struct urb *, struct pt_regs *regs);
-       void    (*outdat_callback)(struct urb *, struct pt_regs *regs);
-       void    (*inack_callback)(struct urb *, struct pt_regs *regs);
-       void    (*outcont_callback)(struct urb *, struct pt_regs *regs);
+       void    (*instat_callback)(struct urb *);
+       void    (*glocont_callback)(struct urb *);
+       void    (*indat_callback)(struct urb *);
+       void    (*outdat_callback)(struct urb *);
+       void    (*inack_callback)(struct urb *);
+       void    (*outcont_callback)(struct urb *);
 } keyspan_callbacks[] = {
        {
                /* msg_usa26 callbacks */
index 59e777f1e8fdd3502eafab416be7d84bdc15d7ee..909005107ea2465285f133ca1a0db5b82c2033fc 100644 (file)
@@ -210,7 +210,7 @@ static void keyspan_pda_request_unthrottle( struct usb_serial *serial )
 }
 
 
-static void keyspan_pda_rx_interrupt (struct urb *urb, struct pt_regs *regs)
+static void keyspan_pda_rx_interrupt (struct urb *urb)
 {
        struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
                struct tty_struct *tty = port->tty;
@@ -601,7 +601,7 @@ exit:
 }
 
 
-static void keyspan_pda_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
+static void keyspan_pda_write_bulk_callback (struct urb *urb)
 {
        struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
        struct keyspan_pda_private *priv;
index 2a2f3e2da0553a3b3488fcb0a196a3a13953efb8..17e205699c2bca32970e0c2b26e79095ea7e91ae 100644 (file)
@@ -80,11 +80,11 @@ static void klsi_105_close           (struct usb_serial_port *port,
 static int  klsi_105_write              (struct usb_serial_port *port,
                                          const unsigned char *buf,
                                          int count);
-static void klsi_105_write_bulk_callback (struct urb *urb, struct pt_regs *regs);
+static void klsi_105_write_bulk_callback (struct urb *urb);
 static int  klsi_105_chars_in_buffer     (struct usb_serial_port *port);
 static int  klsi_105_write_room          (struct usb_serial_port *port);
 
-static void klsi_105_read_bulk_callback  (struct urb *urb, struct pt_regs *regs);
+static void klsi_105_read_bulk_callback  (struct urb *urb);
 static void klsi_105_set_termios         (struct usb_serial_port *port,
                                          struct termios * old);
 static int  klsi_105_ioctl              (struct usb_serial_port *port,
@@ -556,7 +556,7 @@ exit:
        return bytes_sent;      /* that's how much we wrote */
 } /* klsi_105_write */
 
-static void klsi_105_write_bulk_callback ( struct urb *urb, struct pt_regs *regs)
+static void klsi_105_write_bulk_callback ( struct urb *urb)
 {
        struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
 
@@ -616,7 +616,7 @@ static int klsi_105_write_room (struct usb_serial_port *port)
 
 
 
-static void klsi_105_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
+static void klsi_105_read_bulk_callback (struct urb *urb)
 {
        struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
        struct klsi_105_private *priv = usb_get_serial_port_data(port);
index d50dce03495819f4280f815285a89214be2a3e88..ff03331e0bcf0d97241d468856b3531f6caa5c6c 100644 (file)
@@ -80,8 +80,8 @@ static int  kobil_ioctl(struct usb_serial_port *port, struct file *file,
 static int  kobil_tiocmget(struct usb_serial_port *port, struct file *file);
 static int  kobil_tiocmset(struct usb_serial_port *port, struct file *file,
                           unsigned int set, unsigned int clear);
-static void kobil_read_int_callback( struct urb *urb, struct pt_regs *regs );
-static void kobil_write_callback( struct urb *purb, struct pt_regs *regs );
+static void kobil_read_int_callback( struct urb *urb );
+static void kobil_write_callback( struct urb *purb );
 
 
 static struct usb_device_id id_table [] = {
@@ -360,7 +360,7 @@ static void kobil_close (struct usb_serial_port *port, struct file *filp)
 }
 
 
-static void kobil_read_int_callback( struct urb *purb, struct pt_regs *regs)
+static void kobil_read_int_callback( struct urb *purb)
 {
        int result;
        struct usb_serial_port *port = (struct usb_serial_port *) purb->context;
@@ -405,7 +405,7 @@ static void kobil_read_int_callback( struct urb *purb, struct pt_regs *regs)
 }
 
 
-static void kobil_write_callback( struct urb *purb, struct pt_regs *regs )
+static void kobil_write_callback( struct urb *purb )
 {
 }
 
index f4d4305c2c026fa2099faaef26c5ae80d30a8884..b7582cc496dc3fa598860ca18ad810526345f0f2 100644 (file)
@@ -96,7 +96,7 @@ static int  mct_u232_open              (struct usb_serial_port *port,
                                          struct file *filp);
 static void mct_u232_close              (struct usb_serial_port *port,
                                          struct file *filp);
-static void mct_u232_read_int_callback   (struct urb *urb, struct pt_regs *regs);
+static void mct_u232_read_int_callback   (struct urb *urb);
 static void mct_u232_set_termios         (struct usb_serial_port *port,
                                          struct termios * old);
 static int  mct_u232_ioctl              (struct usb_serial_port *port,
@@ -466,7 +466,7 @@ static void mct_u232_close (struct usb_serial_port *port, struct file *filp)
 } /* mct_u232_close */
 
 
-static void mct_u232_read_int_callback (struct urb *urb, struct pt_regs *regs)
+static void mct_u232_read_int_callback (struct urb *urb)
 {
        struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
        struct mct_u232_private *priv = usb_get_serial_port_data(port);
diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c
new file mode 100644 (file)
index 0000000..82cd15b
--- /dev/null
@@ -0,0 +1,1683 @@
+/*
+ * mos7720.c
+ *   Controls the Moschip 7720 usb to dual port serial convertor
+ *
+ * Copyright 2006 Moschip Semiconductor Tech. 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, version 2 of the License.
+ *
+ * Developed by:
+ *     VijayaKumar.G.N. <vijaykumar@aspirecom.net>
+ *     AjayKumar <ajay@aspirecom.net>
+ *     Gurudeva.N. <gurudev@aspirecom.net>
+ *
+ * Cleaned up from the original by:
+ *     Greg Kroah-Hartman <gregkh@suse.de>
+ *
+ * Originally based on drivers/usb/serial/io_edgeport.c which is:
+ *     Copyright (C) 2000 Inside Out Networks, All rights reserved.
+ *     Copyright (C) 2001-2002 Greg Kroah-Hartman <greg@kroah.com>
+ */
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/tty.h>
+#include <linux/tty_driver.h>
+#include <linux/tty_flip.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/serial.h>
+#include <linux/serial_reg.h>
+#include <linux/usb.h>
+#include <linux/usb/serial.h>
+#include <asm/uaccess.h>
+
+
+/*
+ * Version Information
+ */
+#define DRIVER_VERSION "1.0.0.4F"
+#define DRIVER_AUTHOR "Aspire Communications pvt Ltd."
+#define DRIVER_DESC "Moschip USB Serial Driver"
+
+/* default urb timeout */
+#define MOS_WDR_TIMEOUT        (HZ * 5)
+
+#define MOS_PORT1      0x0200
+#define MOS_PORT2      0x0300
+#define MOS_VENREG     0x0000
+#define MOS_MAX_PORT   0x02
+#define MOS_WRITE      0x0E
+#define MOS_READ       0x0D
+
+/* Interrupt Rotinue Defines   */
+#define SERIAL_IIR_RLS 0x06
+#define SERIAL_IIR_RDA 0x04
+#define SERIAL_IIR_CTI 0x0c
+#define SERIAL_IIR_THR 0x02
+#define SERIAL_IIR_MS  0x00
+
+#define NUM_URBS                       16      /* URB Count */
+#define URB_TRANSFER_BUFFER_SIZE       32      /* URB Size */
+
+/* This structure holds all of the local port information */
+struct moschip_port
+{
+       __u8    shadowLCR;              /* last LCR value received */
+       __u8    shadowMCR;              /* last MCR value received */
+       __u8    shadowMSR;              /* last MSR value received */
+       char                    open;
+       struct async_icount     icount;
+       struct usb_serial_port  *port;  /* loop back to the owner */
+       struct urb              *write_urb_pool[NUM_URBS];
+};
+
+/* This structure holds all of the individual serial device information */
+struct moschip_serial
+{
+       int interrupt_started;
+};
+
+static int debug;
+
+#define USB_VENDOR_ID_MOSCHIP          0x9710
+#define MOSCHIP_DEVICE_ID_7720         0x7720
+#define MOSCHIP_DEVICE_ID_7715         0x7715
+
+static struct usb_device_id moschip_port_id_table [] = {
+       { USB_DEVICE(USB_VENDOR_ID_MOSCHIP,MOSCHIP_DEVICE_ID_7720) },
+       { } /* terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, moschip_port_id_table);
+
+
+/*
+ * mos7720_interrupt_callback
+ *     this is the callback function for when we have received data on the
+ *     interrupt endpoint.
+ */
+static void mos7720_interrupt_callback(struct urb *urb)
+{
+       int result;
+       int length;
+       __u32 *data;
+       unsigned int status;
+       __u8 sp1;
+       __u8 sp2;
+       __u8 st;
+
+       dbg("%s"," : Entering\n");
+
+       if (!urb) {
+               dbg("%s","Invalid Pointer !!!!:\n");
+               return;
+       }
+
+       switch (urb->status) {
+       case 0:
+               /* success */
+               break;
+       case -ECONNRESET:
+       case -ENOENT:
+       case -ESHUTDOWN:
+               /* this urb is terminated, clean up */
+               dbg("%s - urb shutting down with status: %d", __FUNCTION__,
+                   urb->status);
+               return;
+       default:
+               dbg("%s - nonzero urb status received: %d", __FUNCTION__,
+                   urb->status);
+               goto exit;
+       }
+
+       length = urb->actual_length;
+       data = urb->transfer_buffer;
+
+       /* Moschip get 4 bytes
+        * Byte 1 IIR Port 1 (port.number is 0)
+        * Byte 2 IIR Port 2 (port.number is 1)
+        * Byte 3 --------------
+        * Byte 4 FIFO status for both */
+       if (length && length > 4) {
+               dbg("Wrong data !!!");
+               return;
+       }
+
+       status = *data;
+
+       sp1 = (status & 0xff000000)>>24;
+       sp2 = (status & 0x00ff0000)>>16;
+       st = status & 0x000000ff;
+
+       if ((sp1 & 0x01) || (sp2 & 0x01)) {
+               /* No Interrupt Pending in both the ports */
+               dbg("No Interrupt !!!");
+       } else {
+               switch (sp1 & 0x0f) {
+               case SERIAL_IIR_RLS:
+                       dbg("Serial Port 1: Receiver status error or address "
+                           "bit detected in 9-bit mode\n");
+                       break;
+               case SERIAL_IIR_CTI:
+                       dbg("Serial Port 1: Receiver time out");
+                       break;
+               case SERIAL_IIR_MS:
+                       dbg("Serial Port 1: Modem status change");
+                       break;
+               }
+
+               switch (sp2 & 0x0f) {
+               case SERIAL_IIR_RLS:
+                       dbg("Serial Port 2: Receiver status error or address "
+                           "bit detected in 9-bit mode");
+                       break;
+               case SERIAL_IIR_CTI:
+                       dbg("Serial Port 2: Receiver time out");
+                       break;
+               case SERIAL_IIR_MS:
+                       dbg("Serial Port 2: Modem status change");
+                       break;
+               }
+       }
+
+exit:
+       result = usb_submit_urb(urb, GFP_ATOMIC);
+       if (result)
+               dev_err(&urb->dev->dev,
+                       "%s - Error %d submitting control urb\n",
+                       __FUNCTION__, result);
+       return;
+}
+
+/*
+ * mos7720_bulk_in_callback
+ *     this is the callback function for when we have received data on the
+ *     bulk in endpoint.
+ */
+static void mos7720_bulk_in_callback(struct urb *urb)
+{
+       int status;
+       unsigned char *data ;
+       struct usb_serial_port *port;
+       struct moschip_port *mos7720_port;
+       struct tty_struct *tty;
+
+       if (urb->status) {
+               dbg("nonzero read bulk status received: %d",urb->status);
+               return;
+       }
+
+       mos7720_port = urb->context;
+       if (!mos7720_port) {
+               dbg("%s","NULL mos7720_port pointer \n");
+               return ;
+       }
+
+       port = mos7720_port->port;
+
+       dbg("Entering...%s", __FUNCTION__);
+
+       data = urb->transfer_buffer;
+
+       tty = port->tty;
+       if (tty && urb->actual_length) {
+               tty_buffer_request_room(tty, urb->actual_length);
+               tty_insert_flip_string(tty, data, urb->actual_length);
+               tty_flip_buffer_push(tty);
+       }
+
+       if (!port->read_urb) {
+               dbg("URB KILLED !!!");
+               return;
+       }
+
+       if (port->read_urb->status != -EINPROGRESS) {
+               port->read_urb->dev = port->serial->dev;
+
+               status = usb_submit_urb(port->read_urb, GFP_ATOMIC);
+               if (status)
+                       dbg("usb_submit_urb(read bulk) failed, status = %d",
+                           status);
+       }
+}
+
+/*
+ * mos7720_bulk_out_data_callback
+ *     this is the callback function for when we have finished sending serial
+ *     data on the bulk out endpoint.
+ */
+static void mos7720_bulk_out_data_callback(struct urb *urb)
+{
+       struct moschip_port *mos7720_port;
+       struct tty_struct *tty;
+
+       if (urb->status) {
+               dbg("nonzero write bulk status received:%d", urb->status);
+               return;
+       }
+
+       mos7720_port = urb->context;
+       if (!mos7720_port) {
+               dbg("NULL mos7720_port pointer");
+               return ;
+       }
+
+       dbg("Entering .........");
+
+       tty = mos7720_port->port->tty;
+
+       if (tty && mos7720_port->open) {
+               /* let the tty driver wakeup if it has a special *
+                * write_wakeup function */
+               if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+                    tty->ldisc.write_wakeup)
+                       (tty->ldisc.write_wakeup)(tty);
+
+               /* tell the tty driver that something has changed */
+               wake_up_interruptible(&tty->write_wait);
+       }
+
+       /* schedule_work(&mos7720_port->port->work); */
+}
+
+/*
+ * send_mos_cmd
+ *     this function will be used for sending command to device
+ */
+static int send_mos_cmd(struct usb_serial *serial, __u8 request, __u16 value,
+                       __u16 index, void *data)
+{
+       int status;
+       unsigned int pipe;
+       u16 product = le16_to_cpu(serial->dev->descriptor.idProduct);
+       __u8 requesttype;
+       __u16 size = 0x0000;
+
+       if (value < MOS_MAX_PORT) {
+               if (product == MOSCHIP_DEVICE_ID_7715) {
+                       value = value*0x100+0x100;
+               } else {
+                       value = value*0x100+0x200;
+               }
+       } else {
+               value = 0x0000;
+               if ((product == MOSCHIP_DEVICE_ID_7715) &&
+                   (index != 0x08)) {
+                       dbg("serial->product== MOSCHIP_DEVICE_ID_7715");
+                       //index = 0x01 ;
+               }
+       }
+
+       if (request == MOS_WRITE) {
+               request = (__u8)MOS_WRITE;
+               requesttype = (__u8)0x40;
+               value  = value + (__u16)*((unsigned char *)data);
+               data = NULL;
+               pipe = usb_sndctrlpipe(serial->dev, 0);
+       } else {
+               request = (__u8)MOS_READ;
+               requesttype = (__u8)0xC0;
+               size = 0x01;
+               pipe = usb_rcvctrlpipe(serial->dev,0);
+       }
+
+       status = usb_control_msg(serial->dev, pipe, request, requesttype,
+                                value, index, data, size, MOS_WDR_TIMEOUT);
+
+       if (status < 0)
+               dbg("Command Write failed Value %x index %x\n",value,index);
+
+       return status;
+}
+
+static int mos7720_open(struct usb_serial_port *port, struct file * filp)
+{
+       struct usb_serial *serial;
+       struct usb_serial_port *port0;
+       struct urb *urb;
+       struct moschip_serial *mos7720_serial;
+       struct moschip_port *mos7720_port;
+       int response;
+       int port_number;
+       char data;
+       int j;
+
+       serial = port->serial;
+
+       mos7720_port = usb_get_serial_port_data(port);
+       if (mos7720_port == NULL)
+               return -ENODEV;
+
+       port0 = serial->port[0];
+
+       mos7720_serial = usb_get_serial_data(serial);
+
+       if (mos7720_serial == NULL || port0 == NULL)
+               return -ENODEV;
+
+       usb_clear_halt(serial->dev, port->write_urb->pipe);
+       usb_clear_halt(serial->dev, port->read_urb->pipe);
+
+       /* Initialising the write urb pool */
+       for (j = 0; j < NUM_URBS; ++j) {
+               urb = usb_alloc_urb(0,SLAB_ATOMIC);
+               mos7720_port->write_urb_pool[j] = urb;
+
+               if (urb == NULL) {
+                       err("No more urbs???");
+                       continue;
+               }
+
+               urb->transfer_buffer = kmalloc(URB_TRANSFER_BUFFER_SIZE,
+                                              GFP_KERNEL);
+               if (!urb->transfer_buffer) {
+                       err("%s-out of memory for urb buffers.", __FUNCTION__);
+                       continue;
+               }
+       }
+
+        /* Initialize MCS7720 -- Write Init values to corresponding Registers
+         *
+         * Register Index
+         * 1 : IER
+         * 2 : FCR
+         * 3 : LCR
+         * 4 : MCR
+         *
+         * 0x08 : SP1/2 Control Reg
+         */
+       port_number = port->number - port->serial->minor;
+       send_mos_cmd(port->serial, MOS_READ, port_number, UART_LSR, &data);
+       dbg("SS::%p LSR:%x\n",mos7720_port, data);
+
+       dbg("Check:Sending Command ..........");
+
+       data = 0x02;
+       send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, 0x01, &data);
+       data = 0x02;
+       send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, 0x02, &data);
+
+       data = 0x00;
+       send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data);
+       data = 0x00;
+       send_mos_cmd(serial, MOS_WRITE, port_number, 0x02, &data);
+
+       data = 0xCF;
+       send_mos_cmd(serial, MOS_WRITE, port_number, 0x02, &data);
+       data = 0x03;
+        mos7720_port->shadowLCR  = data;
+       send_mos_cmd(serial, MOS_WRITE, port_number, 0x03, &data);
+       data = 0x0b;
+        mos7720_port->shadowMCR  = data;
+       send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data);
+       data = 0x0b;
+       send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data);
+
+       data = 0x00;
+       send_mos_cmd(serial, MOS_READ, MOS_MAX_PORT, 0x08, &data);
+       data = 0x00;
+       send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, 0x08, &data);
+
+/*     data = 0x00;
+       send_mos_cmd(serial, MOS_READ, MOS_MAX_PORT, port_number + 1, &data);
+       data = 0x03;
+       send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, port_number + 1, &data);
+       data = 0x00;
+       send_mos_cmd(port->serial, MOS_WRITE, MOS_MAX_PORT, port_number + 1, &data);
+*/
+       data = 0x00;
+       send_mos_cmd(serial, MOS_READ, MOS_MAX_PORT, 0x08, &data);
+
+       data = data | (port->number - port->serial->minor + 1);
+       send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, 0x08, &data);
+
+       data = 0x83;
+        mos7720_port->shadowLCR  = data;
+       send_mos_cmd(serial, MOS_WRITE, port_number, 0x03, &data);
+       data = 0x0c;
+       send_mos_cmd(serial, MOS_WRITE, port_number, 0x00, &data);
+       data = 0x00;
+       send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data);
+       data = 0x03;
+        mos7720_port->shadowLCR  = data;
+       send_mos_cmd(serial, MOS_WRITE, port_number, 0x03, &data);
+       data = 0x0c;
+       send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data);
+       data = 0x0c;
+       send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data);
+
+//Matrix
+
+       /* force low_latency on so that our tty_push actually forces *
+        * the data through,otherwise it is scheduled, and with      *
+        * high data rates (like with OHCI) data can get lost.       */
+
+       if (port->tty)
+               port->tty->low_latency = 1;
+
+       /* see if we've set up our endpoint info yet   *
+        * (can't set it up in mos7720_startup as the  *
+        * structures were not set up at that time.)   */
+       if (!mos7720_serial->interrupt_started) {
+               dbg("Interrupt buffer NULL !!!");
+
+               /* not set up yet, so do it now */
+               mos7720_serial->interrupt_started = 1;
+
+               dbg("To Submit URB !!!");
+
+               /* set up our interrupt urb */
+               usb_fill_int_urb(port0->interrupt_in_urb, serial->dev,
+                                usb_rcvintpipe(serial->dev,
+                                               port->interrupt_in_endpointAddress),
+                                port0->interrupt_in_buffer,
+                                port0->interrupt_in_urb->transfer_buffer_length,
+                                mos7720_interrupt_callback, mos7720_port,
+                                port0->interrupt_in_urb->interval);
+
+               /* start interrupt read for this mos7720 this interrupt *
+                * will continue as long as the mos7720 is connected    */
+               dbg("Submit URB over !!!");
+               response = usb_submit_urb(port0->interrupt_in_urb, GFP_KERNEL);
+               if (response)
+                       dev_err(&port->dev,
+                               "%s - Error %d submitting control urb",
+                               __FUNCTION__, response);
+       }
+
+       /* set up our bulk in urb */
+       usb_fill_bulk_urb(port->read_urb, serial->dev,
+                         usb_rcvbulkpipe(serial->dev,
+                                         port->bulk_in_endpointAddress),
+                         port->bulk_in_buffer,
+                         port->read_urb->transfer_buffer_length,
+                         mos7720_bulk_in_callback, mos7720_port);
+       response = usb_submit_urb(port->read_urb, GFP_KERNEL);
+       if (response)
+               dev_err(&port->dev,
+                       "%s - Error %d submitting read urb", __FUNCTION__, response);
+
+       /* initialize our icount structure */
+       memset(&(mos7720_port->icount), 0x00, sizeof(mos7720_port->icount));
+
+       /* initialize our port settings */
+       mos7720_port->shadowMCR = UART_MCR_OUT2; /* Must set to enable ints! */
+
+       /* send a open port command */
+       mos7720_port->open = 1;
+
+       return 0;
+}
+
+/*
+ * mos7720_chars_in_buffer
+ *     this function is called by the tty driver when it wants to know how many
+ *     bytes of data we currently have outstanding in the port (data that has
+ *     been written, but hasn't made it out the port yet)
+ *     If successful, we return the number of bytes left to be written in the
+ *     system,
+ *     Otherwise we return a negative error number.
+ */
+static int mos7720_chars_in_buffer(struct usb_serial_port *port)
+{
+       int i;
+       int chars = 0;
+       struct moschip_port *mos7720_port;
+
+       dbg("%s:entering ...........", __FUNCTION__);
+
+       mos7720_port = usb_get_serial_port_data(port);
+       if (mos7720_port == NULL) {
+               dbg("%s:leaving ...........", __FUNCTION__);
+               return -ENODEV;
+       }
+
+       for (i = 0; i < NUM_URBS; ++i) {
+               if (mos7720_port->write_urb_pool[i]->status == -EINPROGRESS)
+                       chars += URB_TRANSFER_BUFFER_SIZE;
+       }
+       dbg("%s - returns %d", __FUNCTION__, chars);
+       return chars;
+}
+
+static void mos7720_close(struct usb_serial_port *port, struct file *filp)
+{
+       struct usb_serial *serial;
+       struct moschip_port *mos7720_port;
+       char data;
+       int j;
+
+       dbg("mos7720_close:entering...");
+
+       serial = port->serial;
+
+       mos7720_port = usb_get_serial_port_data(port);
+       if (mos7720_port == NULL)
+               return;
+
+       for (j = 0; j < NUM_URBS; ++j)
+               usb_kill_urb(mos7720_port->write_urb_pool[j]);
+
+       /* Freeing Write URBs */
+       for (j = 0; j < NUM_URBS; ++j) {
+               if (mos7720_port->write_urb_pool[j]) {
+                       kfree(mos7720_port->write_urb_pool[j]->transfer_buffer);
+                       usb_free_urb(mos7720_port->write_urb_pool[j]);
+               }
+       }
+
+       /* While closing port, shutdown all bulk read, write  *
+        * and interrupt read if they exists                  */
+       if (serial->dev) {
+               dbg("Shutdown bulk write");
+               usb_kill_urb(port->write_urb);
+               dbg("Shutdown bulk read");
+               usb_kill_urb(port->read_urb);
+       }
+
+       data = 0x00;
+       send_mos_cmd(serial, MOS_WRITE, port->number - port->serial->minor,
+                    0x04, &data);
+
+       data = 0x00;
+       send_mos_cmd(serial, MOS_WRITE, port->number - port->serial->minor,
+                    0x01, &data);
+
+       mos7720_port->open = 0;
+
+       dbg("Leaving %s", __FUNCTION__);
+}
+
+static void mos7720_break(struct usb_serial_port *port, int break_state)
+{
+        unsigned char data;
+       struct usb_serial *serial;
+       struct moschip_port *mos7720_port;
+
+       dbg("Entering %s", __FUNCTION__);
+
+       serial = port->serial;
+
+       mos7720_port = usb_get_serial_port_data(port);
+       if (mos7720_port == NULL)
+               return;
+
+       if (break_state == -1)
+               data = mos7720_port->shadowLCR | UART_LCR_SBC;
+       else
+               data = mos7720_port->shadowLCR & ~UART_LCR_SBC;
+
+       mos7720_port->shadowLCR  = data;
+       send_mos_cmd(serial, MOS_WRITE, port->number - port->serial->minor,
+                    0x03, &data);
+
+       return;
+}
+
+/*
+ * mos7720_write_room
+ *     this function is called by the tty driver when it wants to know how many
+ *     bytes of data we can accept for a specific port.
+ *     If successful, we return the amount of room that we have for this port
+ *     Otherwise we return a negative error number.
+ */
+static int mos7720_write_room(struct usb_serial_port *port)
+{
+       struct moschip_port *mos7720_port;
+       int room = 0;
+       int i;
+
+       dbg("%s:entering ...........", __FUNCTION__);
+
+       mos7720_port = usb_get_serial_port_data(port);
+       if (mos7720_port == NULL) {
+               dbg("%s:leaving ...........", __FUNCTION__);
+               return -ENODEV;
+       }
+
+       for (i = 0; i < NUM_URBS; ++i) {
+               if (mos7720_port->write_urb_pool[i]->status != -EINPROGRESS)
+                       room += URB_TRANSFER_BUFFER_SIZE;
+       }
+
+       dbg("%s - returns %d", __FUNCTION__, room);
+       return room;
+}
+
+static int mos7720_write(struct usb_serial_port *port,
+                        const unsigned char *data, int count)
+{
+       int status;
+       int i;
+       int bytes_sent = 0;
+       int transfer_size;
+
+       struct moschip_port *mos7720_port;
+       struct usb_serial *serial;
+       struct urb    *urb;
+       const unsigned char *current_position = data;
+
+       dbg("%s:entering ...........", __FUNCTION__);
+
+       serial = port->serial;
+
+       mos7720_port = usb_get_serial_port_data(port);
+       if (mos7720_port == NULL) {
+               dbg("mos7720_port is NULL");
+               return -ENODEV;
+       }
+
+       /* try to find a free urb in the list */
+       urb = NULL;
+
+       for (i = 0; i < NUM_URBS; ++i) {
+               if (mos7720_port->write_urb_pool[i]->status != -EINPROGRESS) {
+                       urb = mos7720_port->write_urb_pool[i];
+                       dbg("URB:%d",i);
+                       break;
+               }
+       }
+
+       if (urb == NULL) {
+               dbg("%s - no more free urbs", __FUNCTION__);
+               goto exit;
+       }
+
+       if (urb->transfer_buffer == NULL) {
+               urb->transfer_buffer = kmalloc(URB_TRANSFER_BUFFER_SIZE,
+                                              GFP_KERNEL);
+               if (urb->transfer_buffer == NULL) {
+                       err("%s no more kernel memory...", __FUNCTION__);
+                       goto exit;
+               }
+       }
+       transfer_size = min (count, URB_TRANSFER_BUFFER_SIZE);
+
+       memcpy(urb->transfer_buffer, current_position, transfer_size);
+       usb_serial_debug_data(debug, &port->dev, __FUNCTION__, transfer_size,
+                             urb->transfer_buffer);
+
+       /* fill urb with data and submit  */
+       usb_fill_bulk_urb(urb, serial->dev,
+                         usb_sndbulkpipe(serial->dev,
+                                         port->bulk_out_endpointAddress),
+                         urb->transfer_buffer, transfer_size,
+                         mos7720_bulk_out_data_callback, mos7720_port);
+
+       /* send it down the pipe */
+       status = usb_submit_urb(urb,GFP_ATOMIC);
+       if (status) {
+               err("%s - usb_submit_urb(write bulk) failed with status = %d",
+                   __FUNCTION__, status);
+               bytes_sent = status;
+               goto exit;
+       }
+       bytes_sent = transfer_size;
+
+exit:
+       return bytes_sent;
+}
+
+static void mos7720_throttle(struct usb_serial_port *port)
+{
+       struct moschip_port *mos7720_port;
+       struct tty_struct *tty;
+       int status;
+
+       dbg("%s- port %d\n", __FUNCTION__, port->number);
+
+       mos7720_port = usb_get_serial_port_data(port);
+
+       if (mos7720_port == NULL)
+               return;
+
+       if (!mos7720_port->open) {
+               dbg("port not opened");
+               return;
+       }
+
+       dbg("%s: Entering ..........", __FUNCTION__);
+
+       tty = port->tty;
+       if (!tty) {
+               dbg("%s - no tty available", __FUNCTION__);
+               return;
+       }
+
+       /* if we are implementing XON/XOFF, send the stop character */
+       if (I_IXOFF(tty)) {
+               unsigned char stop_char = STOP_CHAR(tty);
+               status = mos7720_write(port, &stop_char, 1);
+               if (status <= 0)
+                       return;
+       }
+
+       /* if we are implementing RTS/CTS, toggle that line */
+       if (tty->termios->c_cflag & CRTSCTS) {
+               mos7720_port->shadowMCR &= ~UART_MCR_RTS;
+               status = send_mos_cmd(port->serial, MOS_WRITE,
+                                     port->number - port->serial->minor,
+                                     UART_MCR, &mos7720_port->shadowMCR);
+               if (status != 0)
+                       return;
+       }
+}
+
+static void mos7720_unthrottle(struct usb_serial_port *port)
+{
+       struct tty_struct *tty;
+       int status;
+       struct moschip_port *mos7720_port = usb_get_serial_port_data(port);
+
+       if (mos7720_port == NULL)
+               return;
+
+       if (!mos7720_port->open) {
+               dbg("%s - port not opened", __FUNCTION__);
+               return;
+       }
+
+       dbg("%s: Entering ..........", __FUNCTION__);
+
+       tty = port->tty;
+       if (!tty) {
+               dbg("%s - no tty available", __FUNCTION__);
+               return;
+       }
+
+       /* if we are implementing XON/XOFF, send the start character */
+       if (I_IXOFF(tty)) {
+               unsigned char start_char = START_CHAR(tty);
+               status = mos7720_write(port, &start_char, 1);
+               if (status <= 0)
+                       return;
+       }
+
+       /* if we are implementing RTS/CTS, toggle that line */
+       if (tty->termios->c_cflag & CRTSCTS) {
+               mos7720_port->shadowMCR |= UART_MCR_RTS;
+               status = send_mos_cmd(port->serial, MOS_WRITE,
+                                     port->number - port->serial->minor,
+                                     UART_MCR, &mos7720_port->shadowMCR);
+               if (status != 0)
+                       return;
+       }
+}
+
+static int set_higher_rates(struct moschip_port *mos7720_port,
+                           unsigned int baud)
+{
+       unsigned char data;
+       struct usb_serial_port *port;
+       struct usb_serial *serial;
+       int port_number;
+
+       if (mos7720_port == NULL)
+               return -EINVAL;
+
+       port = mos7720_port->port;
+       serial = port->serial;
+
+        /***********************************************
+         *      Init Sequence for higher rates
+         ***********************************************/
+       dbg("Sending Setting Commands ..........");
+       port_number = port->number - port->serial->minor;
+
+       data = 0x000;
+       send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data);
+       data = 0x000;
+       send_mos_cmd(serial, MOS_WRITE, port_number, 0x02, &data);
+       data = 0x0CF;
+       send_mos_cmd(serial, MOS_WRITE, port->number, 0x02, &data);
+       data = 0x00b;
+        mos7720_port->shadowMCR  = data;
+       send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data);
+       data = 0x00b;
+       send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data);
+
+       data = 0x000;
+       send_mos_cmd(serial, MOS_READ, MOS_MAX_PORT, 0x08, &data);
+       data = 0x000;
+       send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, 0x08, &data);
+
+
+        /***********************************************
+         *              Set for higher rates           *
+         ***********************************************/
+
+       data = baud * 0x10;
+       send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, port_number + 1,&data);
+
+       data = 0x003;
+       send_mos_cmd(serial, MOS_READ, MOS_MAX_PORT, 0x08, &data);
+       data = 0x003;
+       send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT, 0x08, &data);
+
+       data = 0x02b;
+        mos7720_port->shadowMCR  = data;
+       send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data);
+       data = 0x02b;
+       send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data);
+
+        /***********************************************
+         *              Set DLL/DLM
+         ***********************************************/
+
+       data = mos7720_port->shadowLCR | UART_LCR_DLAB;
+        mos7720_port->shadowLCR  = data;
+       send_mos_cmd(serial, MOS_WRITE, port_number, 0x03, &data);
+
+       data =  0x001; /* DLL */
+        send_mos_cmd(serial, MOS_WRITE, port_number, 0x00, &data);
+       data =  0x000; /* DLM */
+        send_mos_cmd(serial, MOS_WRITE, port_number, 0x01, &data);
+
+       data = mos7720_port->shadowLCR & ~UART_LCR_DLAB;
+        mos7720_port->shadowLCR  = data;
+       send_mos_cmd(serial, MOS_WRITE, port_number, 0x03, &data);
+
+       return 0;
+}
+
+/* baud rate information */
+struct divisor_table_entry
+{
+       __u32  baudrate;
+       __u16  divisor;
+};
+
+/* Define table of divisors for moschip 7720 hardware     *
+ * These assume a 3.6864MHz crystal, the standard /16, and *
+ * MCR.7 = 0.                                             */
+static struct divisor_table_entry divisor_table[] = {
+       {   50,         2304},
+       {   110,        1047},  /* 2094.545455 => 230450   => .0217 % over */
+       {   134,        857},   /* 1713.011152 => 230398.5 => .00065% under */
+       {   150,        768},
+       {   300,        384},
+       {   600,        192},
+       {   1200,       96},
+       {   1800,       64},
+       {   2400,       48},
+       {   4800,       24},
+       {   7200,       16},
+       {   9600,       12},
+       {   19200,      6},
+       {   38400,      3},
+       {   57600,      2},
+       {   115200,     1},
+};
+
+/*****************************************************************************
+ * calc_baud_rate_divisor
+ *     this function calculates the proper baud rate divisor for the specified
+ *     baud rate.
+ *****************************************************************************/
+static int calc_baud_rate_divisor(int baudrate, int *divisor)
+{
+       int i;
+       __u16 custom;
+       __u16 round1;
+       __u16 round;
+
+
+       dbg("%s - %d", __FUNCTION__, baudrate);
+
+       for (i = 0; i < ARRAY_SIZE(divisor_table); i++) {
+               if (divisor_table[i].baudrate == baudrate) {
+                       *divisor = divisor_table[i].divisor;
+                       return 0;
+               }
+       }
+
+        /* After trying for all the standard baud rates    *
+         * Try calculating the divisor for this baud rate  */
+       if (baudrate > 75 &&  baudrate < 230400) {
+               /* get the divisor */
+               custom = (__u16)(230400L  / baudrate);
+
+               /* Check for round off */
+               round1 = (__u16)(2304000L / baudrate);
+               round = (__u16)(round1 - (custom * 10));
+               if (round > 4)
+                       custom++;
+               *divisor = custom;
+
+               dbg("Baud %d = %d",baudrate, custom);
+               return 0;
+       }
+
+       dbg("Baud calculation Failed...");
+       return -EINVAL;
+}
+
+/*
+ * send_cmd_write_baud_rate
+ *     this function sends the proper command to change the baud rate of the
+ *     specified port.
+ */
+static int send_cmd_write_baud_rate(struct moschip_port *mos7720_port,
+                                   int baudrate)
+{
+       struct usb_serial_port *port;
+       struct usb_serial *serial;
+       int divisor;
+       int status;
+       unsigned char data;
+       unsigned char number;
+
+       if (mos7720_port == NULL)
+               return -1;
+
+       port = mos7720_port->port;
+       serial = port->serial;
+
+       dbg("%s: Entering ..........", __FUNCTION__);
+
+       number = port->number - port->serial->minor;
+       dbg("%s - port = %d, baud = %d", __FUNCTION__, port->number, baudrate);
+
+        /* Calculate the Divisor */
+       status = calc_baud_rate_divisor(baudrate, &divisor);
+       if (status) {
+               err("%s - bad baud rate", __FUNCTION__);
+               return status;
+       }
+
+        /* Enable access to divisor latch */
+        data = mos7720_port->shadowLCR | UART_LCR_DLAB;
+        mos7720_port->shadowLCR  = data;
+        send_mos_cmd(serial, MOS_WRITE, number, UART_LCR, &data);
+
+       /* Write the divisor */
+       data = ((unsigned char)(divisor & 0xff));
+        send_mos_cmd(serial, MOS_WRITE, number, 0x00, &data);
+
+       data = ((unsigned char)((divisor & 0xff00) >> 8));
+        send_mos_cmd(serial, MOS_WRITE, number, 0x01, &data);
+
+        /* Disable access to divisor latch */
+        data = mos7720_port->shadowLCR & ~UART_LCR_DLAB;
+        mos7720_port->shadowLCR = data;
+        send_mos_cmd(serial, MOS_WRITE, number, 0x03, &data);
+
+       return status;
+}
+
+/*
+ * change_port_settings
+ *     This routine is called to set the UART on the device to match
+ *      the specified new settings.
+ */
+static void change_port_settings(struct moschip_port *mos7720_port,
+                                struct termios *old_termios)
+{
+       struct usb_serial_port *port;
+       struct usb_serial *serial;
+       struct tty_struct *tty;
+       int baud;
+       unsigned cflag;
+       unsigned iflag;
+       __u8 mask = 0xff;
+       __u8 lData;
+       __u8 lParity;
+       __u8 lStop;
+       int status;
+       int port_number;
+       char data;
+
+       if (mos7720_port == NULL)
+               return ;
+
+       port = mos7720_port->port;
+       serial = port->serial;
+       port_number = port->number - port->serial->minor;
+
+       dbg("%s - port %d", __FUNCTION__, port->number);
+
+       if (!mos7720_port->open) {
+               dbg("%s - port not opened", __FUNCTION__);
+               return;
+       }
+
+       tty = mos7720_port->port->tty;
+
+       if ((!tty) || (!tty->termios)) {
+               dbg("%s - no tty structures", __FUNCTION__);
+               return;
+       }
+
+       dbg("%s: Entering ..........", __FUNCTION__);
+
+       lData = UART_LCR_WLEN8;
+       lStop = 0x00;   /* 1 stop bit */
+       lParity = 0x00; /* No parity */
+
+       cflag = tty->termios->c_cflag;
+       iflag = tty->termios->c_iflag;
+
+       /* Change the number of bits */
+       switch (cflag & CSIZE) {
+       case CS5:
+               lData = UART_LCR_WLEN5;
+               mask = 0x1f;
+               break;
+
+       case CS6:
+               lData = UART_LCR_WLEN6;
+               mask = 0x3f;
+               break;
+
+       case CS7:
+               lData = UART_LCR_WLEN7;
+               mask = 0x7f;
+               break;
+       default:
+       case CS8:
+               lData = UART_LCR_WLEN8;
+               break;
+       }
+
+       /* Change the Parity bit */
+       if (cflag & PARENB) {
+               if (cflag & PARODD) {
+                       lParity = UART_LCR_PARITY;
+                       dbg("%s - parity = odd", __FUNCTION__);
+               } else {
+                       lParity = (UART_LCR_EPAR | UART_LCR_PARITY);
+                       dbg("%s - parity = even", __FUNCTION__);
+               }
+
+       } else {
+               dbg("%s - parity = none", __FUNCTION__);
+       }
+
+       if (cflag & CMSPAR)
+               lParity = lParity | 0x20;
+
+       /* Change the Stop bit */
+       if (cflag & CSTOPB) {
+               lStop = UART_LCR_STOP;
+               dbg("%s - stop bits = 2", __FUNCTION__);
+       } else {
+               lStop = 0x00;
+               dbg("%s - stop bits = 1", __FUNCTION__);
+       }
+
+#define LCR_BITS_MASK          0x03    /* Mask for bits/char field */
+#define LCR_STOP_MASK          0x04    /* Mask for stop bits field */
+#define LCR_PAR_MASK           0x38    /* Mask for parity field */
+
+       /* Update the LCR with the correct value */
+       mos7720_port->shadowLCR &= ~(LCR_BITS_MASK | LCR_STOP_MASK | LCR_PAR_MASK);
+       mos7720_port->shadowLCR |= (lData | lParity | lStop);
+
+
+       /* Disable Interrupts */
+       data = 0x00;
+        send_mos_cmd(serial,MOS_WRITE,port->number - port->serial->minor, UART_IER, &data);
+
+       data = 0x00;
+        send_mos_cmd(serial, MOS_WRITE, port_number, UART_FCR, &data);
+
+       data = 0xcf;
+        send_mos_cmd(serial, MOS_WRITE, port_number, UART_FCR, &data);
+
+       /* Send the updated LCR value to the mos7720 */
+       data = mos7720_port->shadowLCR;
+        send_mos_cmd(serial, MOS_WRITE, port_number, UART_LCR, &data);
+
+        data = 0x00b;
+        mos7720_port->shadowMCR = data;
+        send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data);
+        data = 0x00b;
+        send_mos_cmd(serial, MOS_WRITE, port_number, 0x04, &data);
+
+       /* set up the MCR register and send it to the mos7720 */
+       mos7720_port->shadowMCR = UART_MCR_OUT2;
+       if (cflag & CBAUD)
+               mos7720_port->shadowMCR |= (UART_MCR_DTR | UART_MCR_RTS);
+
+       if (cflag & CRTSCTS) {
+               mos7720_port->shadowMCR |= (UART_MCR_XONANY);
+
+                /* To set hardware flow control to the specified *
+                 * serial port, in SP1/2_CONTROL_REG             */
+               if (port->number) {
+                       data = 0x001;
+                       send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT,
+                                    0x08, &data);
+               } else {
+                       data = 0x002;
+                       send_mos_cmd(serial, MOS_WRITE, MOS_MAX_PORT,
+                                    0x08, &data);
+               }
+       } else {
+               mos7720_port->shadowMCR &= ~(UART_MCR_XONANY);
+       }
+
+       data = mos7720_port->shadowMCR;
+       send_mos_cmd(serial, MOS_WRITE, port_number, UART_MCR, &data);
+
+       /* Determine divisor based on baud rate */
+       baud = tty_get_baud_rate(tty);
+       if (!baud) {
+               /* pick a default, any default... */
+               dbg("Picked default baud...");
+               baud = 9600;
+       }
+
+       if (baud >= 230400) {
+               set_higher_rates(mos7720_port, baud);
+               /* Enable Interrupts */
+               data = 0x0c;
+               send_mos_cmd(serial, MOS_WRITE, port_number, UART_IER, &data);
+               return;
+       }
+
+       dbg("%s - baud rate = %d", __FUNCTION__, baud);
+       status = send_cmd_write_baud_rate(mos7720_port, baud);
+
+       /* Enable Interrupts */
+       data = 0x0c;
+       send_mos_cmd(serial, MOS_WRITE, port_number, UART_IER, &data);
+
+       if (port->read_urb->status != -EINPROGRESS) {
+               port->read_urb->dev = serial->dev;
+
+               status = usb_submit_urb(port->read_urb, GFP_ATOMIC);
+               if (status)
+                       dbg("usb_submit_urb(read bulk) failed, status = %d",
+                           status);
+       }
+       return;
+}
+
+/*
+ * mos7720_set_termios
+ *     this function is called by the tty driver when it wants to change the
+ *     termios structure.
+ */
+static void mos7720_set_termios(struct usb_serial_port *port,
+                               struct termios *old_termios)
+{
+       int status;
+       unsigned int cflag;
+       struct usb_serial *serial;
+       struct moschip_port *mos7720_port;
+       struct tty_struct *tty;
+
+       serial = port->serial;
+
+       mos7720_port = usb_get_serial_port_data(port);
+
+       if (mos7720_port == NULL)
+               return;
+
+       tty = port->tty;
+
+       if (!port->tty || !port->tty->termios) {
+               dbg("%s - no tty or termios", __FUNCTION__);
+               return;
+       }
+
+       if (!mos7720_port->open) {
+               dbg("%s - port not opened", __FUNCTION__);
+               return;
+       }
+
+       dbg("%s\n","setting termios - ASPIRE");
+
+       cflag = tty->termios->c_cflag;
+
+       if (!cflag) {
+               printk("%s %s\n",__FUNCTION__,"cflag is NULL");
+               return;
+       }
+
+       /* check that they really want us to change something */
+       if (old_termios) {
+               if ((cflag == old_termios->c_cflag) &&
+                   (RELEVANT_IFLAG(tty->termios->c_iflag) ==
+                    RELEVANT_IFLAG(old_termios->c_iflag))) {
+                       dbg("Nothing to change");
+                       return;
+               }
+       }
+
+       dbg("%s - clfag %08x iflag %08x", __FUNCTION__,
+           tty->termios->c_cflag,
+           RELEVANT_IFLAG(tty->termios->c_iflag));
+
+       if (old_termios)
+               dbg("%s - old clfag %08x old iflag %08x", __FUNCTION__,
+                   old_termios->c_cflag,
+                   RELEVANT_IFLAG(old_termios->c_iflag));
+
+       dbg("%s - port %d", __FUNCTION__, port->number);
+
+       /* change the port settings to the new ones specified */
+       change_port_settings(mos7720_port, old_termios);
+
+       if(!port->read_urb) {
+               dbg("%s","URB KILLED !!!!!\n");
+               return;
+       }
+
+       if(port->read_urb->status != -EINPROGRESS) {
+               port->read_urb->dev = serial->dev;
+               status = usb_submit_urb(port->read_urb, GFP_ATOMIC);
+               if (status)
+                       dbg("usb_submit_urb(read bulk) failed, status = %d",
+                           status);
+       }
+       return;
+}
+
+/*
+ * get_lsr_info - get line status register info
+ *
+ * Purpose: Let user call ioctl() to get info when the UART physically
+ *         is emptied.  On bus types like RS485, the transmitter must
+ *         release the bus after transmitting. This must be done when
+ *         the transmit shift register is empty, not be done when the
+ *         transmit holding register is empty.  This functionality
+ *         allows an RS485 driver to be written in user space.
+ */
+static int get_lsr_info(struct moschip_port *mos7720_port,
+                       unsigned int __user *value)
+{
+       int count;
+       unsigned int result = 0;
+
+       count = mos7720_chars_in_buffer(mos7720_port->port);
+       if (count == 0) {
+               dbg("%s -- Empty", __FUNCTION__);
+               result = TIOCSER_TEMT;
+       }
+
+       if (copy_to_user(value, &result, sizeof(int)))
+               return -EFAULT;
+       return 0;
+}
+
+/*
+ * get_number_bytes_avail - get number of bytes available
+ *
+ * Purpose: Let user call ioctl to get the count of number of bytes available.
+ */
+static int get_number_bytes_avail(struct moschip_port *mos7720_port,
+                                 unsigned int __user *value)
+{
+       unsigned int result = 0;
+       struct tty_struct *tty = mos7720_port->port->tty;
+
+       if (!tty)
+               return -ENOIOCTLCMD;
+
+       result = tty->read_cnt;
+
+       dbg("%s(%d) = %d", __FUNCTION__,  mos7720_port->port->number, result);
+       if (copy_to_user(value, &result, sizeof(int)))
+               return -EFAULT;
+
+       return -ENOIOCTLCMD;
+}
+
+static int set_modem_info(struct moschip_port *mos7720_port, unsigned int cmd,
+                         unsigned int __user *value)
+{
+       unsigned int mcr ;
+       unsigned int arg;
+       unsigned char data;
+
+       struct usb_serial_port *port;
+
+       if (mos7720_port == NULL)
+               return -1;
+
+       port = (struct usb_serial_port*)mos7720_port->port;
+       mcr = mos7720_port->shadowMCR;
+
+       if (copy_from_user(&arg, value, sizeof(int)))
+               return -EFAULT;
+
+       switch (cmd) {
+       case TIOCMBIS:
+               if (arg & TIOCM_RTS)
+                       mcr |= UART_MCR_RTS;
+               if (arg & TIOCM_DTR)
+                       mcr |= UART_MCR_RTS;
+               if (arg & TIOCM_LOOP)
+                       mcr |= UART_MCR_LOOP;
+               break;
+
+       case TIOCMBIC:
+               if (arg & TIOCM_RTS)
+                       mcr &= ~UART_MCR_RTS;
+               if (arg & TIOCM_DTR)
+                       mcr &= ~UART_MCR_RTS;
+               if (arg & TIOCM_LOOP)
+                       mcr &= ~UART_MCR_LOOP;
+               break;
+
+       case TIOCMSET:
+               /* turn off the RTS and DTR and LOOPBACK
+                * and then only turn on what was asked to */
+               mcr &=  ~(UART_MCR_RTS | UART_MCR_DTR | UART_MCR_LOOP);
+               mcr |= ((arg & TIOCM_RTS) ? UART_MCR_RTS : 0);
+               mcr |= ((arg & TIOCM_DTR) ? UART_MCR_DTR : 0);
+               mcr |= ((arg & TIOCM_LOOP) ? UART_MCR_LOOP : 0);
+               break;
+       }
+
+       mos7720_port->shadowMCR = mcr;
+
+       data = mos7720_port->shadowMCR;
+       send_mos_cmd(port->serial, MOS_WRITE,
+                    port->number - port->serial->minor, UART_MCR, &data);
+
+       return 0;
+}
+
+static int get_modem_info(struct moschip_port *mos7720_port,
+                         unsigned int __user *value)
+{
+       unsigned int result = 0;
+       unsigned int msr = mos7720_port->shadowMSR;
+       unsigned int mcr = mos7720_port->shadowMCR;
+
+       result = ((mcr & UART_MCR_DTR)  ? TIOCM_DTR: 0)   /* 0x002 */
+                 | ((mcr & UART_MCR_RTS)       ? TIOCM_RTS: 0)   /* 0x004 */
+                 | ((msr & UART_MSR_CTS)       ? TIOCM_CTS: 0)   /* 0x020 */
+                 | ((msr & UART_MSR_DCD)       ? TIOCM_CAR: 0)   /* 0x040 */
+                 | ((msr & UART_MSR_RI)        ? TIOCM_RI:  0)   /* 0x080 */
+                 | ((msr & UART_MSR_DSR)       ? TIOCM_DSR: 0);  /* 0x100 */
+
+
+       dbg("%s -- %x", __FUNCTION__, result);
+
+       if (copy_to_user(value, &result, sizeof(int)))
+               return -EFAULT;
+       return 0;
+}
+
+static int get_serial_info(struct moschip_port *mos7720_port,
+                          struct serial_struct __user *retinfo)
+{
+       struct serial_struct tmp;
+
+       if (!retinfo)
+               return -EFAULT;
+
+       memset(&tmp, 0, sizeof(tmp));
+
+       tmp.type                = PORT_16550A;
+       tmp.line                = mos7720_port->port->serial->minor;
+       tmp.port                = mos7720_port->port->number;
+       tmp.irq                 = 0;
+       tmp.flags               = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ;
+        tmp.xmit_fifo_size     = NUM_URBS * URB_TRANSFER_BUFFER_SIZE;
+       tmp.baud_base           = 9600;
+       tmp.close_delay         = 5*HZ;
+       tmp.closing_wait        = 30*HZ;
+
+       if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
+               return -EFAULT;
+       return 0;
+}
+
+static int mos7720_ioctl(struct usb_serial_port *port, struct file *file,
+                        unsigned int cmd, unsigned long arg)
+{
+       struct moschip_port *mos7720_port;
+       struct async_icount cnow;
+       struct async_icount cprev;
+       struct serial_icounter_struct icount;
+
+       mos7720_port = usb_get_serial_port_data(port);
+       if (mos7720_port == NULL)
+               return -ENODEV;
+
+       dbg("%s - port %d, cmd = 0x%x", __FUNCTION__, port->number, cmd);
+
+       switch (cmd) {
+       case TIOCINQ:
+               /* return number of bytes available */
+               dbg("%s (%d) TIOCINQ", __FUNCTION__,  port->number);
+               return get_number_bytes_avail(mos7720_port,
+                                             (unsigned int __user *)arg);
+               break;
+
+       case TIOCSERGETLSR:
+               dbg("%s (%d) TIOCSERGETLSR", __FUNCTION__,  port->number);
+               return get_lsr_info(mos7720_port, (unsigned int __user *)arg);
+               return 0;
+
+       case TIOCMBIS:
+       case TIOCMBIC:
+       case TIOCMSET:
+               dbg("%s (%d) TIOCMSET/TIOCMBIC/TIOCMSET", __FUNCTION__,
+                   port->number);
+               return set_modem_info(mos7720_port, cmd,
+                                     (unsigned int __user *)arg);
+
+       case TIOCMGET:
+               dbg("%s (%d) TIOCMGET", __FUNCTION__,  port->number);
+               return get_modem_info(mos7720_port,
+                                     (unsigned int __user *)arg);
+
+       case TIOCGSERIAL:
+               dbg("%s (%d) TIOCGSERIAL", __FUNCTION__,  port->number);
+               return get_serial_info(mos7720_port,
+                                      (struct serial_struct __user *)arg);
+
+       case TIOCSSERIAL:
+               dbg("%s (%d) TIOCSSERIAL", __FUNCTION__,  port->number);
+               break;
+
+       case TIOCMIWAIT:
+               dbg("%s (%d) TIOCMIWAIT", __FUNCTION__,  port->number);
+               cprev = mos7720_port->icount;
+               while (1) {
+                       if (signal_pending(current))
+                               return -ERESTARTSYS;
+                       cnow = mos7720_port->icount;
+                       if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
+                           cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
+                               return -EIO; /* no change => error */
+                       if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
+                           ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
+                           ((arg & TIOCM_CD)  && (cnow.dcd != cprev.dcd)) ||
+                           ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)) ) {
+                               return 0;
+                       }
+                       cprev = cnow;
+               }
+               /* NOTREACHED */
+               break;
+
+       case TIOCGICOUNT:
+               cnow = mos7720_port->icount;
+               icount.cts = cnow.cts;
+               icount.dsr = cnow.dsr;
+               icount.rng = cnow.rng;
+               icount.dcd = cnow.dcd;
+               icount.rx = cnow.rx;
+               icount.tx = cnow.tx;
+               icount.frame = cnow.frame;
+               icount.overrun = cnow.overrun;
+               icount.parity = cnow.parity;
+               icount.brk = cnow.brk;
+               icount.buf_overrun = cnow.buf_overrun;
+
+               dbg("%s (%d) TIOCGICOUNT RX=%d, TX=%d", __FUNCTION__,
+                   port->number, icount.rx, icount.tx );
+               if (copy_to_user((void __user *)arg, &icount, sizeof(icount)))
+                       return -EFAULT;
+               return 0;
+       }
+
+       return -ENOIOCTLCMD;
+}
+
+static int mos7720_startup(struct usb_serial *serial)
+{
+       struct moschip_serial *mos7720_serial;
+       struct moschip_port *mos7720_port;
+       struct usb_device *dev;
+       int i;
+       char data;
+
+       dbg("%s: Entering ..........", __FUNCTION__);
+
+       if (!serial) {
+               dbg("Invalid Handler");
+               return -ENODEV;
+       }
+
+       dev = serial->dev;
+
+       /* create our private serial structure */
+       mos7720_serial = kzalloc(sizeof(struct moschip_serial), GFP_KERNEL);
+       if (mos7720_serial == NULL) {
+               err("%s - Out of memory", __FUNCTION__);
+               return -ENOMEM;
+       }
+
+       usb_set_serial_data(serial, mos7720_serial);
+
+       /* we set up the pointers to the endpoints in the mos7720_open *
+        * function, as the structures aren't created yet.             */
+
+       /* set up port private structures */
+       for (i = 0; i < serial->num_ports; ++i) {
+               mos7720_port = kzalloc(sizeof(struct moschip_port), GFP_KERNEL);
+               if (mos7720_port == NULL) {
+                       err("%s - Out of memory", __FUNCTION__);
+                       usb_set_serial_data(serial, NULL);
+                       kfree(mos7720_serial);
+                       return -ENOMEM;
+               }
+
+               /* Initialize all port interrupt end point to port 0 int
+                * endpoint.  Our device has only one interrupt endpoint
+                * comman to all ports */
+               serial->port[i]->interrupt_in_endpointAddress = serial->port[0]->interrupt_in_endpointAddress;
+
+               mos7720_port->port = serial->port[i];
+               usb_set_serial_port_data(serial->port[i], mos7720_port);
+
+               dbg("port number is %d", serial->port[i]->number);
+               dbg("serial number is %d", serial->minor);
+       }
+
+
+       /* setting configuration feature to one */
+       usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+                       (__u8)0x03, 0x00,0x01,0x00, NULL, 0x00, 5*HZ);
+
+       send_mos_cmd(serial,MOS_READ,0x00, UART_LSR, &data);  // LSR For Port 1
+       dbg("LSR:%x",data);
+
+       send_mos_cmd(serial,MOS_READ,0x01, UART_LSR, &data);  // LSR For Port 2
+       dbg("LSR:%x",data);
+
+       return 0;
+}
+
+static void mos7720_shutdown(struct usb_serial *serial)
+{
+       int i;
+
+       /* free private structure allocated for serial port */
+       for (i=0; i < serial->num_ports; ++i) {
+               kfree(usb_get_serial_port_data(serial->port[i]));
+               usb_set_serial_port_data(serial->port[i], NULL);
+       }
+
+       /* free private structure allocated for serial device */
+       kfree(usb_get_serial_data(serial));
+       usb_set_serial_data(serial, NULL);
+}
+
+static struct usb_serial_driver moschip7720_2port_driver = {
+       .driver = {
+               .owner =        THIS_MODULE,
+               .name =         "moschip7720",
+       },
+       .description            = "Moschip 2 port adapter",
+       .id_table               = moschip_port_id_table,
+       .num_interrupt_in       = 1,
+       .num_bulk_in            = 2,
+       .num_bulk_out           = 2,
+       .num_ports              = 2,
+       .open                   = mos7720_open,
+       .close                  = mos7720_close,
+       .throttle               = mos7720_throttle,
+       .unthrottle             = mos7720_unthrottle,
+       .attach                 = mos7720_startup,
+       .shutdown               = mos7720_shutdown,
+       .ioctl                  = mos7720_ioctl,
+       .set_termios            = mos7720_set_termios,
+       .write                  = mos7720_write,
+       .write_room             = mos7720_write_room,
+       .chars_in_buffer        = mos7720_chars_in_buffer,
+       .break_ctl              = mos7720_break,
+       .read_bulk_callback     = mos7720_bulk_in_callback,
+};
+
+static struct usb_driver usb_driver = {
+       .name =         "moschip7720",
+       .probe =        usb_serial_probe,
+       .disconnect =   usb_serial_disconnect,
+       .id_table =     moschip_port_id_table,
+};
+
+static int __init moschip7720_init(void)
+{
+       int retval;
+
+       dbg("%s: Entering ..........", __FUNCTION__);
+
+       /* Register with the usb serial */
+       retval = usb_serial_register(&moschip7720_2port_driver);
+       if (retval)
+               goto failed_port_device_register;
+
+       info(DRIVER_DESC " " DRIVER_VERSION);
+
+       /* Register with the usb */
+       retval = usb_register(&usb_driver);
+       if (retval)
+               goto failed_usb_register;
+
+       return 0;
+
+failed_usb_register:
+       usb_serial_deregister(&moschip7720_2port_driver);
+
+failed_port_device_register:
+       return retval;
+}
+
+static void __exit moschip7720_exit(void)
+{
+       usb_deregister(&usb_driver);
+       usb_serial_deregister(&moschip7720_2port_driver);
+}
+
+module_init(moschip7720_init);
+module_exit(moschip7720_exit);
+
+/* Module information */
+MODULE_AUTHOR( DRIVER_AUTHOR );
+MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_LICENSE("GPL");
+
+module_param(debug, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(debug, "Debug enabled or not");
index 95bf57166c5920970c2289fd6bef6678d8b219c4..5b71962d0351d3a740be7d8a1d3e3aecef0a070d 100644 (file)
@@ -421,7 +421,7 @@ static int mos7840_handle_new_lsr(struct moschip_port *port, __u8 new_lsr)
 /************************************************************************/
 /************************************************************************/
 
-static void mos7840_control_callback(struct urb *urb, struct pt_regs *regs)
+static void mos7840_control_callback(struct urb *urb)
 {
        unsigned char *data;
        struct moschip_port *mos7840_port;
@@ -497,7 +497,7 @@ static int mos7840_get_reg(struct moschip_port *mcs, __u16 Wval, __u16 reg,
  *     interrupt endpoint.
  *****************************************************************************/
 
-static void mos7840_interrupt_callback(struct urb *urb, struct pt_regs *regs)
+static void mos7840_interrupt_callback(struct urb *urb)
 {
        int result;
        int length;
@@ -647,7 +647,7 @@ static struct usb_serial *mos7840_get_usb_serial(struct usb_serial_port *port,
  *     bulk in endpoint.
  *****************************************************************************/
 
-static void mos7840_bulk_in_callback(struct urb *urb, struct pt_regs *regs)
+static void mos7840_bulk_in_callback(struct urb *urb)
 {
        int status;
        unsigned char *data;
@@ -726,8 +726,7 @@ static void mos7840_bulk_in_callback(struct urb *urb, struct pt_regs *regs)
  *     on the bulk out endpoint.
  *****************************************************************************/
 
-static void mos7840_bulk_out_data_callback(struct urb *urb,
-                                          struct pt_regs *regs)
+static void mos7840_bulk_out_data_callback(struct urb *urb)
 {
        struct moschip_port *mos7840_port;
        struct tty_struct *tty;
@@ -1088,7 +1087,7 @@ static int mos7840_open(struct usb_serial_port *port, struct file *filp)
        mos7840_port->icount.tx = 0;
        mos7840_port->icount.rx = 0;
 
-       dbg("\n\nusb_serial serial:%x       mos7840_port:%x\n      usb_serial_port port:%x\n\n", (unsigned int)serial, (unsigned int)mos7840_port, (unsigned int)port);
+       dbg("\n\nusb_serial serial:%p       mos7840_port:%p\n      usb_serial_port port:%p\n\n", serial, mos7840_port, port);
 
        return 0;
 
@@ -1421,7 +1420,6 @@ static int mos7840_write(struct usb_serial_port *port,
        int i;
        int bytes_sent = 0;
        int transfer_size;
-       int from_user = 0;
 
        struct moschip_port *mos7840_port;
        struct usb_serial *serial;
@@ -1512,15 +1510,7 @@ static int mos7840_write(struct usb_serial_port *port,
        }
        transfer_size = min(count, URB_TRANSFER_BUFFER_SIZE);
 
-       if (from_user) {
-               if (copy_from_user
-                   (urb->transfer_buffer, current_position, transfer_size)) {
-                       bytes_sent = -EFAULT;
-                       goto exit;
-               }
-       } else {
-               memcpy(urb->transfer_buffer, current_position, transfer_size);
-       }
+       memcpy(urb->transfer_buffer, current_position, transfer_size);
 
        /* fill urb with data and submit  */
        usb_fill_bulk_urb(urb,
@@ -2226,7 +2216,7 @@ static void mos7840_set_termios(struct usb_serial_port *port,
  *****************************************************************************/
 
 static int mos7840_get_lsr_info(struct moschip_port *mos7840_port,
-                               unsigned int *value)
+                               unsigned int __user *value)
 {
        int count;
        unsigned int result = 0;
@@ -2249,7 +2239,7 @@ static int mos7840_get_lsr_info(struct moschip_port *mos7840_port,
  *****************************************************************************/
 
 static int mos7840_get_bytes_avail(struct moschip_port *mos7840_port,
-                                  unsigned int *value)
+                                  unsigned int __user *value)
 {
        unsigned int result = 0;
        struct tty_struct *tty = mos7840_port->port->tty;
@@ -2272,7 +2262,7 @@ static int mos7840_get_bytes_avail(struct moschip_port *mos7840_port,
  *****************************************************************************/
 
 static int mos7840_set_modem_info(struct moschip_port *mos7840_port,
-                                 unsigned int cmd, unsigned int *value)
+                                 unsigned int cmd, unsigned int __user *value)
 {
        unsigned int mcr;
        unsigned int arg;
@@ -2342,7 +2332,7 @@ static int mos7840_set_modem_info(struct moschip_port *mos7840_port,
  *****************************************************************************/
 
 static int mos7840_get_modem_info(struct moschip_port *mos7840_port,
-                                 unsigned int *value)
+                                 unsigned int __user *value)
 {
        unsigned int result = 0;
        __u16 msr;
@@ -2371,7 +2361,7 @@ static int mos7840_get_modem_info(struct moschip_port *mos7840_port,
  *****************************************************************************/
 
 static int mos7840_get_serial_info(struct moschip_port *mos7840_port,
-                                  struct serial_struct *retinfo)
+                                  struct serial_struct __user *retinfo)
 {
        struct serial_struct tmp;
 
@@ -2406,6 +2396,7 @@ static int mos7840_get_serial_info(struct moschip_port *mos7840_port,
 static int mos7840_ioctl(struct usb_serial_port *port, struct file *file,
                         unsigned int cmd, unsigned long arg)
 {
+       void __user *argp = (void __user *)arg;
        struct moschip_port *mos7840_port;
        struct tty_struct *tty;
 
@@ -2422,11 +2413,12 @@ static int mos7840_ioctl(struct usb_serial_port *port, struct file *file,
        }
 
        mos7840_port = mos7840_get_port_private(port);
-       tty = mos7840_port->port->tty;
 
        if (mos7840_port == NULL)
                return -1;
 
+       tty = mos7840_port->port->tty;
+
        dbg("%s - port %d, cmd = 0x%x", __FUNCTION__, port->number, cmd);
 
        switch (cmd) {
@@ -2434,16 +2426,13 @@ static int mos7840_ioctl(struct usb_serial_port *port, struct file *file,
 
        case TIOCINQ:
                dbg("%s (%d) TIOCINQ", __FUNCTION__, port->number);
-               return mos7840_get_bytes_avail(mos7840_port,
-                                              (unsigned int *)arg);
-               break;
+               return mos7840_get_bytes_avail(mos7840_port, argp);
 
        case TIOCOUTQ:
                dbg("%s (%d) TIOCOUTQ", __FUNCTION__, port->number);
                return put_user(tty->driver->chars_in_buffer ?
                                tty->driver->chars_in_buffer(tty) : 0,
                                (int __user *)arg);
-               break;
 
        case TCFLSH:
                retval = tty_check_change(tty);
@@ -2473,13 +2462,13 @@ static int mos7840_ioctl(struct usb_serial_port *port, struct file *file,
 
        case TCGETS:
                if (kernel_termios_to_user_termios
-                   ((struct termios __user *)arg, tty->termios))
+                   ((struct termios __user *)argp, tty->termios))
                        return -EFAULT;
                return 0;
 
        case TIOCSERGETLSR:
                dbg("%s (%d) TIOCSERGETLSR", __FUNCTION__, port->number);
-               return mos7840_get_lsr_info(mos7840_port, (unsigned int *)arg);
+               return mos7840_get_lsr_info(mos7840_port, argp);
                return 0;
 
        case TIOCMBIS:
@@ -2488,19 +2477,16 @@ static int mos7840_ioctl(struct usb_serial_port *port, struct file *file,
                dbg("%s (%d) TIOCMSET/TIOCMBIC/TIOCMSET", __FUNCTION__,
                    port->number);
                mosret =
-                   mos7840_set_modem_info(mos7840_port, cmd,
-                                          (unsigned int *)arg);
+                   mos7840_set_modem_info(mos7840_port, cmd, argp);
                return mosret;
 
        case TIOCMGET:
                dbg("%s (%d) TIOCMGET", __FUNCTION__, port->number);
-               return mos7840_get_modem_info(mos7840_port,
-                                             (unsigned int *)arg);
+               return mos7840_get_modem_info(mos7840_port, argp);
 
        case TIOCGSERIAL:
                dbg("%s (%d) TIOCGSERIAL", __FUNCTION__, port->number);
-               return mos7840_get_serial_info(mos7840_port,
-                                              (struct serial_struct *)arg);
+               return mos7840_get_serial_info(mos7840_port, argp);
 
        case TIOCSSERIAL:
                dbg("%s (%d) TIOCSSERIAL", __FUNCTION__, port->number);
@@ -2550,7 +2536,7 @@ static int mos7840_ioctl(struct usb_serial_port *port, struct file *file,
 
                dbg("%s (%d) TIOCGICOUNT RX=%d, TX=%d", __FUNCTION__,
                    port->number, icount.rx, icount.tx);
-               if (copy_to_user((void *)arg, &icount, sizeof(icount)))
+               if (copy_to_user(argp, &icount, sizeof(icount)))
                        return -EFAULT;
                return 0;
 
@@ -2818,7 +2804,7 @@ static int mos7840_startup(struct usb_serial *serial)
 
        /* setting configuration feature to one */
        usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
-                       (__u8) 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 5 * HZ);
+                       (__u8) 0x03, 0x00, 0x01, 0x00, NULL, 0x00, 5 * HZ);
        return 0;
 }
 
index ac3f8b5d2c495f931739eee3ee9d3509c694f44a..0610409a6568f8bbae67a45e68d21d47cd5cf934 100644 (file)
@@ -32,7 +32,7 @@ static struct usb_driver navman_driver = {
        .no_dynamic_id =        1,
 };
 
-static void navman_read_int_callback(struct urb *urb, struct pt_regs *regs)
+static void navman_read_int_callback(struct urb *urb)
 {
        struct usb_serial_port *port = urb->context;
        unsigned char *data = urb->transfer_buffer;
index a764ff4e326cfb2c6695af4e226b9389a3a5e866..bc91d3b726fc05015baec092d210feab74bcf8c3 100644 (file)
@@ -64,8 +64,8 @@ static int debug;
 /* function prototypes */
 static int  omninet_open               (struct usb_serial_port *port, struct file *filp);
 static void omninet_close              (struct usb_serial_port *port, struct file *filp);
-static void omninet_read_bulk_callback (struct urb *urb, struct pt_regs *regs);
-static void omninet_write_bulk_callback        (struct urb *urb, struct pt_regs *regs);
+static void omninet_read_bulk_callback (struct urb *urb);
+static void omninet_write_bulk_callback        (struct urb *urb);
 static int  omninet_write              (struct usb_serial_port *port, const unsigned char *buf, int count);
 static int  omninet_write_room         (struct usb_serial_port *port);
 static void omninet_shutdown           (struct usb_serial *serial);
@@ -194,7 +194,7 @@ static void omninet_close (struct usb_serial_port *port, struct file * filp)
 #define OMNINET_HEADERLEN      sizeof(struct omninet_header)
 #define OMNINET_BULKOUTSIZE    (64 - OMNINET_HEADERLEN)
 
-static void omninet_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
+static void omninet_read_bulk_callback (struct urb *urb)
 {
        struct usb_serial_port  *port   = (struct usb_serial_port *)urb->context;
        unsigned char           *data   = urb->transfer_buffer;
@@ -306,7 +306,7 @@ static int omninet_write_room (struct usb_serial_port *port)
        return (room);
 }
 
-static void omninet_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
+static void omninet_write_bulk_callback (struct urb *urb)
 {
 /*     struct omninet_header   *header = (struct omninet_header  *) urb->transfer_buffer; */
        struct usb_serial_port  *port   = (struct usb_serial_port *) urb->context;
index c856e6f40e22c5ff7716e5d01f18c50a9c2b1bc0..130afbbd3fca6c97b9e8c9400961b1583eca6c72 100644 (file)
@@ -50,7 +50,7 @@ static void option_rx_throttle(struct usb_serial_port *port);
 static void option_rx_unthrottle(struct usb_serial_port *port);
 static int  option_write_room(struct usb_serial_port *port);
 
-static void option_instat_callback(struct urb *urb, struct pt_regs *regs);
+static void option_instat_callback(struct urb *urb);
 
 static int option_write(struct usb_serial_port *port,
                        const unsigned char *buf, int count);
@@ -337,7 +337,7 @@ static int option_write(struct usb_serial_port *port,
        return count;
 }
 
-static void option_indat_callback(struct urb *urb, struct pt_regs *regs)
+static void option_indat_callback(struct urb *urb)
 {
        int err;
        int endpoint;
@@ -374,7 +374,7 @@ static void option_indat_callback(struct urb *urb, struct pt_regs *regs)
        return;
 }
 
-static void option_outdat_callback(struct urb *urb, struct pt_regs *regs)
+static void option_outdat_callback(struct urb *urb)
 {
        struct usb_serial_port *port;
 
@@ -385,7 +385,7 @@ static void option_outdat_callback(struct urb *urb, struct pt_regs *regs)
        usb_serial_port_softint(port);
 }
 
-static void option_instat_callback(struct urb *urb, struct pt_regs *regs)
+static void option_instat_callback(struct urb *urb)
 {
        int err;
        struct usb_serial_port *port = (struct usb_serial_port *) urb->context;
@@ -565,7 +565,7 @@ static void option_close(struct usb_serial_port *port, struct file *filp)
 /* Helper functions used by option_setup_urbs */
 static struct urb *option_setup_urb(struct usb_serial *serial, int endpoint,
                int dir, void *ctx, char *buf, int len,
-               void (*callback)(struct urb *, struct pt_regs *regs))
+               void (*callback)(struct urb *))
 {
        struct urb *urb;
 
index 9c18173e33fb90710fdda8e3161625eb2cde0e19..bc800c8787a87a1bc048ae225abd2e695ee3e07b 100644 (file)
@@ -948,7 +948,7 @@ static void pl2303_update_line_status(struct usb_serial_port *port,
        wake_up_interruptible(&priv->delta_msr_wait);
 }
 
-static void pl2303_read_int_callback(struct urb *urb, struct pt_regs *regs)
+static void pl2303_read_int_callback(struct urb *urb)
 {
        struct usb_serial_port *port = (struct usb_serial_port *) urb->context;
        unsigned char *data = urb->transfer_buffer;
@@ -987,7 +987,7 @@ exit:
                        __FUNCTION__, status);
 }
 
-static void pl2303_read_bulk_callback(struct urb *urb, struct pt_regs *regs)
+static void pl2303_read_bulk_callback(struct urb *urb)
 {
        struct usb_serial_port *port = (struct usb_serial_port *) urb->context;
        struct pl2303_private *priv = usb_get_serial_port_data(port);
@@ -1070,7 +1070,7 @@ static void pl2303_read_bulk_callback(struct urb *urb, struct pt_regs *regs)
        return;
 }
 
-static void pl2303_write_bulk_callback(struct urb *urb, struct pt_regs *regs)
+static void pl2303_write_bulk_callback(struct urb *urb)
 {
        struct usb_serial_port *port = (struct usb_serial_port *) urb->context;
        struct pl2303_private *priv = usb_get_serial_port_data(port);
index 1e07dfad68535b54a80a8860f9fc8b71e1f6f615..30b7ebc8d45d660043dd37a5b879496871c5b816 100644 (file)
@@ -204,7 +204,7 @@ static __u16 __inline__ fcs_compute10 (unsigned char *sp, int len, __u16 fcs)
        return fcs;
 }
 
-static void safe_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
+static void safe_read_bulk_callback (struct urb *urb)
 {
        struct usb_serial_port *port = (struct usb_serial_port *) urb->context;
        unsigned char *data = urb->transfer_buffer;
index d29638daa987fb9a2f37f58a23caccf1a1b4f587..ea16572d19f89219b013dc2f81af344f534e38bb 100644 (file)
@@ -1,21 +1,35 @@
 /*
- * Sierra Wireless CDMA Wireless Serial USB driver
- *
- * Current Copy modified by: Kevin Lloyd <linux@sierrawireless.com>
- * Original Copyright (C) 2005-2006 Greg Kroah-Hartman <gregkh@suse.de>
- *
- *     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.
- */
+  USB Driver for Sierra Wireless
+
+  Copyright (C) 2006  Kevin Lloyd <linux@sierrawireless.com>
+
+  IMPORTANT DISCLAIMER: This driver is not commercially supported by
+  Sierra Wireless. Use at your own risk.
+
+  This driver 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.
+
+  Portions based on the option driver by Matthias Urlichs <smurf@smurf.noris.de>
+  Whom based his on the Keyspan driver by Hugh Blemings <hugh@blemings.org>
+
+  History:
+*/
+
+#define DRIVER_VERSION "v.1.0.5"
+#define DRIVER_AUTHOR "Kevin Lloyd <linux@sierrawireless.com>"
+#define DRIVER_DESC "USB Driver for Sierra Wireless USB modems"
 
 #include <linux/kernel.h>
-#include <linux/init.h>
+#include <linux/jiffies.h>
+#include <linux/errno.h>
 #include <linux/tty.h>
+#include <linux/tty_flip.h>
 #include <linux/module.h>
 #include <linux/usb.h>
 #include <linux/usb/serial.h>
 
+
 static struct usb_device_id id_table [] = {
        { USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */
        { USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */
@@ -23,53 +37,674 @@ static struct usb_device_id id_table [] = {
        { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */
        { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */
        { USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */
+       { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 for Europe */
        { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 */
        { USB_DEVICE(0x1199, 0x6820) }, /* Sierra Wireless AirCard 875 */
-       /* Following devices are supported in the airprime.c driver */
-       /* { USB_DEVICE(0x1199, 0x0112) }, */   /* Sierra Wireless AirCard 580 */
-       /* { USB_DEVICE(0x0F3D, 0x0112) }, */   /* AirPrime/Sierra PC 5220 */
+
+       { USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless AirCard 580 */
+       { USB_DEVICE(0x0F3D, 0x0112) }, /* AirPrime/Sierra PC 5220 */
        { }
 };
 MODULE_DEVICE_TABLE(usb, id_table);
 
+static struct usb_device_id id_table_1port [] = {
+       { USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless AirCard 580 */
+       { USB_DEVICE(0x0F3D, 0x0112) }, /* AirPrime/Sierra PC 5220 */
+       { }
+};
+
+static struct usb_device_id id_table_3port [] = {
+       { USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */
+       { USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */
+       { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */
+       { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */
+       { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */
+       { USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */
+       { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 */
+       { USB_DEVICE(0x1199, 0x6820) }, /* Sierra Wireless AirCard 875 */
+       { }
+};
+
 static struct usb_driver sierra_driver = {
-       .name =         "sierra_wireless",
-       .probe =        usb_serial_probe,
-       .disconnect =   usb_serial_disconnect,
-       .id_table =     id_table,
+       .name       = "sierra",
+       .probe      = usb_serial_probe,
+       .disconnect = usb_serial_disconnect,
+       .id_table   = id_table,
+       .no_dynamic_id =        1,
+};
+
+
+static int debug;
+
+/* per port private data */
+#define N_IN_URB       4
+#define N_OUT_URB      1
+#define IN_BUFLEN      4096
+#define OUT_BUFLEN     128
+
+struct sierra_port_private {
+       /* Input endpoints and buffer for this port */
+       struct urb *in_urbs[N_IN_URB];
+       char in_buffer[N_IN_URB][IN_BUFLEN];
+       /* Output endpoints and buffer for this port */
+       struct urb *out_urbs[N_OUT_URB];
+       char out_buffer[N_OUT_URB][OUT_BUFLEN];
+
+       /* Settings for the port */
+       int rts_state;  /* Handshaking pins (outputs) */
+       int dtr_state;
+       int cts_state;  /* Handshaking pins (inputs) */
+       int dsr_state;
+       int dcd_state;
+       int ri_state;
+
+       unsigned long tx_start_time[N_OUT_URB];
+};
+
+static int sierra_send_setup(struct usb_serial_port *port)
+{
+       struct usb_serial *serial = port->serial;
+       struct sierra_port_private *portdata;
+
+       dbg("%s", __FUNCTION__);
+
+       portdata = usb_get_serial_port_data(port);
+
+       if (port->tty) {
+               int val = 0;
+               if (portdata->dtr_state)
+                       val |= 0x01;
+               if (portdata->rts_state)
+                       val |= 0x02;
+
+               return usb_control_msg(serial->dev,
+                               usb_rcvctrlpipe(serial->dev, 0),
+                               0x22,0x21,val,0,NULL,0,USB_CTRL_SET_TIMEOUT);
+       }
+
+       return 0;
+}
+
+static void sierra_rx_throttle(struct usb_serial_port *port)
+{
+       dbg("%s", __FUNCTION__);
+}
+
+static void sierra_rx_unthrottle(struct usb_serial_port *port)
+{
+       dbg("%s", __FUNCTION__);
+}
+
+static void sierra_break_ctl(struct usb_serial_port *port, int break_state)
+{
+       /* Unfortunately, I don't know how to send a break */
+       dbg("%s", __FUNCTION__);
+}
+
+static void sierra_set_termios(struct usb_serial_port *port,
+                       struct termios *old_termios)
+{
+       dbg("%s", __FUNCTION__);
+
+       sierra_send_setup(port);
+}
+
+static int sierra_tiocmget(struct usb_serial_port *port, struct file *file)
+{
+       unsigned int value;
+       struct sierra_port_private *portdata;
+
+       portdata = usb_get_serial_port_data(port);
+
+       value = ((portdata->rts_state) ? TIOCM_RTS : 0) |
+               ((portdata->dtr_state) ? TIOCM_DTR : 0) |
+               ((portdata->cts_state) ? TIOCM_CTS : 0) |
+               ((portdata->dsr_state) ? TIOCM_DSR : 0) |
+               ((portdata->dcd_state) ? TIOCM_CAR : 0) |
+               ((portdata->ri_state) ? TIOCM_RNG : 0);
+
+       return value;
+}
+
+static int sierra_tiocmset(struct usb_serial_port *port, struct file *file,
+                       unsigned int set, unsigned int clear)
+{
+       struct sierra_port_private *portdata;
+
+       portdata = usb_get_serial_port_data(port);
+
+       if (set & TIOCM_RTS)
+               portdata->rts_state = 1;
+       if (set & TIOCM_DTR)
+               portdata->dtr_state = 1;
+
+       if (clear & TIOCM_RTS)
+               portdata->rts_state = 0;
+       if (clear & TIOCM_DTR)
+               portdata->dtr_state = 0;
+       return sierra_send_setup(port);
+}
+
+static int sierra_ioctl(struct usb_serial_port *port, struct file *file,
+                       unsigned int cmd, unsigned long arg)
+{
+       return -ENOIOCTLCMD;
+}
+
+/* Write */
+static int sierra_write(struct usb_serial_port *port,
+                       const unsigned char *buf, int count)
+{
+       struct sierra_port_private *portdata;
+       int i;
+       int left, todo;
+       struct urb *this_urb = NULL; /* spurious */
+       int err;
+
+       portdata = usb_get_serial_port_data(port);
+
+       dbg("%s: write (%d chars)", __FUNCTION__, count);
+
+       i = 0;
+       left = count;
+       for (i=0; left > 0 && i < N_OUT_URB; i++) {
+               todo = left;
+               if (todo > OUT_BUFLEN)
+                       todo = OUT_BUFLEN;
+
+               this_urb = portdata->out_urbs[i];
+               if (this_urb->status == -EINPROGRESS) {
+                       if (time_before(jiffies,
+                                       portdata->tx_start_time[i] + 10 * HZ))
+                               continue;
+                       usb_unlink_urb(this_urb);
+                       continue;
+               }
+               if (this_urb->status != 0)
+                       dbg("usb_write %p failed (err=%d)",
+                               this_urb, this_urb->status);
+
+               dbg("%s: endpoint %d buf %d", __FUNCTION__,
+                       usb_pipeendpoint(this_urb->pipe), i);
+
+               /* send the data */
+               memcpy (this_urb->transfer_buffer, buf, todo);
+               this_urb->transfer_buffer_length = todo;
+
+               this_urb->dev = port->serial->dev;
+               err = usb_submit_urb(this_urb, GFP_ATOMIC);
+               if (err) {
+                       dbg("usb_submit_urb %p (write bulk) failed "
+                               "(%d, has %d)", this_urb,
+                               err, this_urb->status);
+                       continue;
+               }
+               portdata->tx_start_time[i] = jiffies;
+               buf += todo;
+               left -= todo;
+       }
+
+       count -= left;
+       dbg("%s: wrote (did %d)", __FUNCTION__, count);
+       return count;
+}
+
+static void sierra_indat_callback(struct urb *urb)
+{
+       int err;
+       int endpoint;
+       struct usb_serial_port *port;
+       struct tty_struct *tty;
+       unsigned char *data = urb->transfer_buffer;
+
+       dbg("%s: %p", __FUNCTION__, urb);
+
+       endpoint = usb_pipeendpoint(urb->pipe);
+       port = (struct usb_serial_port *) urb->context;
+
+       if (urb->status) {
+               dbg("%s: nonzero status: %d on endpoint %02x.",
+                   __FUNCTION__, urb->status, endpoint);
+       } else {
+               tty = port->tty;
+               if (urb->actual_length) {
+                       tty_buffer_request_room(tty, urb->actual_length);
+                       tty_insert_flip_string(tty, data, urb->actual_length);
+                       tty_flip_buffer_push(tty);
+               } else {
+                       dbg("%s: empty read urb received", __FUNCTION__);
+               }
+
+               /* Resubmit urb so we continue receiving */
+               if (port->open_count && urb->status != -ESHUTDOWN) {
+                       err = usb_submit_urb(urb, GFP_ATOMIC);
+                       if (err)
+                               printk(KERN_ERR "%s: resubmit read urb failed. "
+                                       "(%d)", __FUNCTION__, err);
+               }
+       }
+       return;
+}
+
+static void sierra_outdat_callback(struct urb *urb)
+{
+       struct usb_serial_port *port;
+
+       dbg("%s", __FUNCTION__);
+
+       port = (struct usb_serial_port *) urb->context;
+
+       usb_serial_port_softint(port);
+}
+
+static void sierra_instat_callback(struct urb *urb)
+{
+       int err;
+       struct usb_serial_port *port = (struct usb_serial_port *) urb->context;
+       struct sierra_port_private *portdata = usb_get_serial_port_data(port);
+       struct usb_serial *serial = port->serial;
+
+       dbg("%s", __FUNCTION__);
+       dbg("%s: urb %p port %p has data %p", __FUNCTION__,urb,port,portdata);
+
+       if (urb->status == 0) {
+               struct usb_ctrlrequest *req_pkt =
+                               (struct usb_ctrlrequest *)urb->transfer_buffer;
+
+               if (!req_pkt) {
+                       dbg("%s: NULL req_pkt\n", __FUNCTION__);
+                       return;
+               }
+               if ((req_pkt->bRequestType == 0xA1) &&
+                               (req_pkt->bRequest == 0x20)) {
+                       int old_dcd_state;
+                       unsigned char signals = *((unsigned char *)
+                                       urb->transfer_buffer +
+                                       sizeof(struct usb_ctrlrequest));
+
+                       dbg("%s: signal x%x", __FUNCTION__, signals);
+
+                       old_dcd_state = portdata->dcd_state;
+                       portdata->cts_state = 1;
+                       portdata->dcd_state = ((signals & 0x01) ? 1 : 0);
+                       portdata->dsr_state = ((signals & 0x02) ? 1 : 0);
+                       portdata->ri_state = ((signals & 0x08) ? 1 : 0);
+
+                       if (port->tty && !C_CLOCAL(port->tty) &&
+                                       old_dcd_state && !portdata->dcd_state)
+                               tty_hangup(port->tty);
+               } else {
+                       dbg("%s: type %x req %x", __FUNCTION__,
+                               req_pkt->bRequestType,req_pkt->bRequest);
+               }
+       } else
+               dbg("%s: error %d", __FUNCTION__, urb->status);
+
+       /* Resubmit urb so we continue receiving IRQ data */
+       if (urb->status != -ESHUTDOWN) {
+               urb->dev = serial->dev;
+               err = usb_submit_urb(urb, GFP_ATOMIC);
+               if (err)
+                       dbg("%s: resubmit intr urb failed. (%d)",
+                               __FUNCTION__, err);
+       }
+}
+
+static int sierra_write_room(struct usb_serial_port *port)
+{
+       struct sierra_port_private *portdata;
+       int i;
+       int data_len = 0;
+       struct urb *this_urb;
+
+       portdata = usb_get_serial_port_data(port);
+
+       for (i=0; i < N_OUT_URB; i++) {
+               this_urb = portdata->out_urbs[i];
+               if (this_urb && this_urb->status != -EINPROGRESS)
+                       data_len += OUT_BUFLEN;
+       }
+
+       dbg("%s: %d", __FUNCTION__, data_len);
+       return data_len;
+}
+
+static int sierra_chars_in_buffer(struct usb_serial_port *port)
+{
+       struct sierra_port_private *portdata;
+       int i;
+       int data_len = 0;
+       struct urb *this_urb;
+
+       portdata = usb_get_serial_port_data(port);
+
+       for (i=0; i < N_OUT_URB; i++) {
+               this_urb = portdata->out_urbs[i];
+               if (this_urb && this_urb->status == -EINPROGRESS)
+                       data_len += this_urb->transfer_buffer_length;
+       }
+       dbg("%s: %d", __FUNCTION__, data_len);
+       return data_len;
+}
+
+static int sierra_open(struct usb_serial_port *port, struct file *filp)
+{
+       struct sierra_port_private *portdata;
+       struct usb_serial *serial = port->serial;
+       int i, err;
+       struct urb *urb;
+
+       portdata = usb_get_serial_port_data(port);
+
+       dbg("%s", __FUNCTION__);
+
+       /* Set some sane defaults */
+       portdata->rts_state = 1;
+       portdata->dtr_state = 1;
+
+       /* Reset low level data toggle and start reading from endpoints */
+       for (i = 0; i < N_IN_URB; i++) {
+               urb = portdata->in_urbs[i];
+               if (! urb)
+                       continue;
+               if (urb->dev != serial->dev) {
+                       dbg("%s: dev %p != %p", __FUNCTION__,
+                               urb->dev, serial->dev);
+                       continue;
+               }
+
+               /*
+                * make sure endpoint data toggle is synchronized with the
+                * device
+                */
+               usb_clear_halt(urb->dev, urb->pipe);
+
+               err = usb_submit_urb(urb, GFP_KERNEL);
+               if (err) {
+                       dbg("%s: submit urb %d failed (%d) %d",
+                               __FUNCTION__, i, err,
+                               urb->transfer_buffer_length);
+               }
+       }
+
+       /* Reset low level data toggle on out endpoints */
+       for (i = 0; i < N_OUT_URB; i++) {
+               urb = portdata->out_urbs[i];
+               if (! urb)
+                       continue;
+               urb->dev = serial->dev;
+               /* usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe),
+                               usb_pipeout(urb->pipe), 0); */
+       }
+
+       port->tty->low_latency = 1;
+
+       sierra_send_setup(port);
+
+       return (0);
+}
+
+static inline void stop_urb(struct urb *urb)
+{
+       if (urb && urb->status == -EINPROGRESS)
+               usb_kill_urb(urb);
+}
+
+static void sierra_close(struct usb_serial_port *port, struct file *filp)
+{
+       int i;
+       struct usb_serial *serial = port->serial;
+       struct sierra_port_private *portdata;
+
+       dbg("%s", __FUNCTION__);
+       portdata = usb_get_serial_port_data(port);
+
+       portdata->rts_state = 0;
+       portdata->dtr_state = 0;
+
+       if (serial->dev) {
+               sierra_send_setup(port);
+
+               /* Stop reading/writing urbs */
+               for (i = 0; i < N_IN_URB; i++)
+                       stop_urb(portdata->in_urbs[i]);
+               for (i = 0; i < N_OUT_URB; i++)
+                       stop_urb(portdata->out_urbs[i]);
+       }
+       port->tty = NULL;
+}
+
+/* Helper functions used by sierra_setup_urbs */
+static struct urb *sierra_setup_urb(struct usb_serial *serial, int endpoint,
+                                   int dir, void *ctx, char *buf, int len,
+                                   usb_complete_t callback)
+{
+       struct urb *urb;
+
+       if (endpoint == -1)
+               return NULL;            /* endpoint not needed */
+
+       urb = usb_alloc_urb(0, GFP_KERNEL);             /* No ISO */
+       if (urb == NULL) {
+               dbg("%s: alloc for endpoint %d failed.", __FUNCTION__, endpoint);
+               return NULL;
+       }
+
+               /* Fill URB using supplied data. */
+       usb_fill_bulk_urb(urb, serial->dev,
+                     usb_sndbulkpipe(serial->dev, endpoint) | dir,
+                     buf, len, callback, ctx);
+
+       return urb;
+}
+
+/* Setup urbs */
+static void sierra_setup_urbs(struct usb_serial *serial)
+{
+       int i,j;
+       struct usb_serial_port *port;
+       struct sierra_port_private *portdata;
+
+       dbg("%s", __FUNCTION__);
+
+       for (i = 0; i < serial->num_ports; i++) {
+               port = serial->port[i];
+               portdata = usb_get_serial_port_data(port);
+
+       /* Do indat endpoints first */
+               for (j = 0; j < N_IN_URB; ++j) {
+                       portdata->in_urbs[j] = sierra_setup_urb (serial,
+                       port->bulk_in_endpointAddress, USB_DIR_IN, port,
+                       portdata->in_buffer[j], IN_BUFLEN, sierra_indat_callback);
+               }
+
+               /* outdat endpoints */
+               for (j = 0; j < N_OUT_URB; ++j) {
+                       portdata->out_urbs[j] = sierra_setup_urb (serial,
+                       port->bulk_out_endpointAddress, USB_DIR_OUT, port,
+                       portdata->out_buffer[j], OUT_BUFLEN, sierra_outdat_callback);
+               }
+       }
+}
+
+static int sierra_startup(struct usb_serial *serial)
+{
+       int i, err;
+       struct usb_serial_port *port;
+       struct sierra_port_private *portdata;
+
+       dbg("%s", __FUNCTION__);
+
+       /* Now setup per port private data */
+       for (i = 0; i < serial->num_ports; i++) {
+               port = serial->port[i];
+               portdata = kzalloc(sizeof(*portdata), GFP_KERNEL);
+               if (!portdata) {
+                       dbg("%s: kmalloc for sierra_port_private (%d) failed!.",
+                                       __FUNCTION__, i);
+                       return (1);
+               }
+
+               usb_set_serial_port_data(port, portdata);
+
+               if (! port->interrupt_in_urb)
+                       continue;
+               err = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
+               if (err)
+                       dbg("%s: submit irq_in urb failed %d",
+                               __FUNCTION__, err);
+       }
+
+       sierra_setup_urbs(serial);
+
+       return (0);
+}
+
+static void sierra_shutdown(struct usb_serial *serial)
+{
+       int i, j;
+       struct usb_serial_port *port;
+       struct sierra_port_private *portdata;
+
+       dbg("%s", __FUNCTION__);
+
+       /* Stop reading/writing urbs */
+       for (i = 0; i < serial->num_ports; ++i) {
+               port = serial->port[i];
+               portdata = usb_get_serial_port_data(port);
+               for (j = 0; j < N_IN_URB; j++)
+                       stop_urb(portdata->in_urbs[j]);
+               for (j = 0; j < N_OUT_URB; j++)
+                       stop_urb(portdata->out_urbs[j]);
+       }
+
+       /* Now free them */
+       for (i = 0; i < serial->num_ports; ++i) {
+               port = serial->port[i];
+               portdata = usb_get_serial_port_data(port);
+
+               for (j = 0; j < N_IN_URB; j++) {
+                       if (portdata->in_urbs[j]) {
+                               usb_free_urb(portdata->in_urbs[j]);
+                               portdata->in_urbs[j] = NULL;
+                       }
+               }
+               for (j = 0; j < N_OUT_URB; j++) {
+                       if (portdata->out_urbs[j]) {
+                               usb_free_urb(portdata->out_urbs[j]);
+                               portdata->out_urbs[j] = NULL;
+                       }
+               }
+       }
+
+       /* Now free per port private data */
+       for (i = 0; i < serial->num_ports; i++) {
+               port = serial->port[i];
+               kfree(usb_get_serial_port_data(port));
+       }
+}
+
+static struct usb_serial_driver sierra_1port_device = {
+       .driver = {
+               .owner =        THIS_MODULE,
+               .name =         "sierra1",
+       },
+       .description       = "Sierra USB modem (1 port)",
+       .id_table          = id_table_1port,
+       .num_interrupt_in  = NUM_DONT_CARE,
+       .num_bulk_in       = 1,
+       .num_bulk_out      = 1,
+       .num_ports         = 1,
+       .open              = sierra_open,
+       .close             = sierra_close,
+       .write             = sierra_write,
+       .write_room        = sierra_write_room,
+       .chars_in_buffer   = sierra_chars_in_buffer,
+       .throttle          = sierra_rx_throttle,
+       .unthrottle        = sierra_rx_unthrottle,
+       .ioctl             = sierra_ioctl,
+       .set_termios       = sierra_set_termios,
+       .break_ctl         = sierra_break_ctl,
+       .tiocmget          = sierra_tiocmget,
+       .tiocmset          = sierra_tiocmset,
+       .attach            = sierra_startup,
+       .shutdown          = sierra_shutdown,
+       .read_int_callback = sierra_instat_callback,
 };
 
-static struct usb_serial_driver sierra_device = {
+static struct usb_serial_driver sierra_3port_device = {
        .driver = {
-       .owner =                THIS_MODULE,
-       .name =                 "Sierra_Wireless",
+               .owner =        THIS_MODULE,
+               .name =         "sierra3",
        },
-       .id_table =             id_table,
-       .num_interrupt_in =     NUM_DONT_CARE,
-       .num_bulk_in =          NUM_DONT_CARE,
-       .num_bulk_out =         NUM_DONT_CARE,
-       .num_ports =            3,
+       .description       = "Sierra USB modem (3 port)",
+       .id_table          = id_table_3port,
+       .num_interrupt_in  = NUM_DONT_CARE,
+       .num_bulk_in       = 3,
+       .num_bulk_out      = 3,
+       .num_ports         = 3,
+       .open              = sierra_open,
+       .close             = sierra_close,
+       .write             = sierra_write,
+       .write_room        = sierra_write_room,
+       .chars_in_buffer   = sierra_chars_in_buffer,
+       .throttle          = sierra_rx_throttle,
+       .unthrottle        = sierra_rx_unthrottle,
+       .ioctl             = sierra_ioctl,
+       .set_termios       = sierra_set_termios,
+       .break_ctl         = sierra_break_ctl,
+       .tiocmget          = sierra_tiocmget,
+       .tiocmset          = sierra_tiocmset,
+       .attach            = sierra_startup,
+       .shutdown          = sierra_shutdown,
+       .read_int_callback = sierra_instat_callback,
 };
 
+/* Functions used by new usb-serial code. */
 static int __init sierra_init(void)
 {
        int retval;
-
-       retval = usb_serial_register(&sierra_device);
+       retval = usb_serial_register(&sierra_1port_device);
+       if (retval)
+               goto failed_1port_device_register;
+       retval = usb_serial_register(&sierra_3port_device);
        if (retval)
-               return retval;
+               goto failed_3port_device_register;
+
+
        retval = usb_register(&sierra_driver);
        if (retval)
-               usb_serial_deregister(&sierra_device);
+               goto failed_driver_register;
+
+       info(DRIVER_DESC ": " DRIVER_VERSION);
+
+       return 0;
+
+failed_driver_register:
+       usb_serial_deregister(&sierra_3port_device);
+failed_3port_device_register:
+       usb_serial_deregister(&sierra_1port_device);
+failed_1port_device_register:
        return retval;
 }
 
 static void __exit sierra_exit(void)
 {
-       usb_deregister(&sierra_driver);
-       usb_serial_deregister(&sierra_device);
+       usb_deregister (&sierra_driver);
+       usb_serial_deregister(&sierra_1port_device);
+       usb_serial_deregister(&sierra_3port_device);
 }
 
 module_init(sierra_init);
 module_exit(sierra_exit);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_VERSION(DRIVER_VERSION);
 MODULE_LICENSE("GPL");
+
+#ifdef CONFIG_USB_DEBUG
+module_param(debug, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(debug, "Debug messages");
+#endif
+
index ac9b8ee52d4406b67761be94bff26efaa9d4ab87..07400c0c8a8cec3768bef909ddae68989c39f4a1 100644 (file)
@@ -166,9 +166,9 @@ static int ti_tiocmget(struct usb_serial_port *port, struct file *file);
 static int ti_tiocmset(struct usb_serial_port *port, struct file *file,
        unsigned int set, unsigned int clear);
 static void ti_break(struct usb_serial_port *port, int break_state);
-static void ti_interrupt_callback(struct urb *urb, struct pt_regs *regs);
-static void ti_bulk_in_callback(struct urb *urb, struct pt_regs *regs);
-static void ti_bulk_out_callback(struct urb *urb, struct pt_regs *regs);
+static void ti_interrupt_callback(struct urb *urb);
+static void ti_bulk_in_callback(struct urb *urb);
+static void ti_bulk_out_callback(struct urb *urb);
 
 static void ti_recv(struct device *dev, struct tty_struct *tty,
        unsigned char *data, int length);
@@ -1098,7 +1098,7 @@ static void ti_break(struct usb_serial_port *port, int break_state)
 }
 
 
-static void ti_interrupt_callback(struct urb *urb, struct pt_regs *regs)
+static void ti_interrupt_callback(struct urb *urb)
 {
        struct ti_device *tdev = (struct ti_device *)urb->context;
        struct usb_serial_port *port;
@@ -1178,7 +1178,7 @@ exit:
 }
 
 
-static void ti_bulk_in_callback(struct urb *urb, struct pt_regs *regs)
+static void ti_bulk_in_callback(struct urb *urb)
 {
        struct ti_port *tport = (struct ti_port *)urb->context;
        struct usb_serial_port *port = tport->tp_port;
@@ -1241,7 +1241,7 @@ exit:
 }
 
 
-static void ti_bulk_out_callback(struct urb *urb, struct pt_regs *regs)
+static void ti_bulk_out_callback(struct urb *urb)
 {
        struct ti_port *tport = (struct ti_port *)urb->context;
        struct usb_serial_port *port = tport->tp_port;
index 88949f7884ca112ded81315d1e11cda8dcb261f2..befe2e11a041043fd7f66b8715678f6caf16132f 100644 (file)
@@ -47,9 +47,9 @@ static int  visor_calc_num_ports(struct usb_serial *serial);
 static void visor_shutdown     (struct usb_serial *serial);
 static int  visor_ioctl                (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg);
 static void visor_set_termios  (struct usb_serial_port *port, struct termios *old_termios);
-static void visor_write_bulk_callback  (struct urb *urb, struct pt_regs *regs);
-static void visor_read_bulk_callback   (struct urb *urb, struct pt_regs *regs);
-static void visor_read_int_callback    (struct urb *urb, struct pt_regs *regs);
+static void visor_write_bulk_callback  (struct urb *urb);
+static void visor_read_bulk_callback   (struct urb *urb);
+static void visor_read_int_callback    (struct urb *urb);
 static int  clie_3_5_startup   (struct usb_serial *serial);
 static int  treo_attach                (struct usb_serial *serial);
 static int clie_5_attach (struct usb_serial *serial);
@@ -471,7 +471,7 @@ static int visor_chars_in_buffer (struct usb_serial_port *port)
 }
 
 
-static void visor_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
+static void visor_write_bulk_callback (struct urb *urb)
 {
        struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
        struct visor_private *priv = usb_get_serial_port_data(port);
@@ -494,7 +494,7 @@ static void visor_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
 }
 
 
-static void visor_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
+static void visor_read_bulk_callback (struct urb *urb)
 {
        struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
        struct visor_private *priv = usb_get_serial_port_data(port);
@@ -539,7 +539,7 @@ static void visor_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
        return;
 }
 
-static void visor_read_int_callback (struct urb *urb, struct pt_regs *regs)
+static void visor_read_int_callback (struct urb *urb)
 {
        struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
        int result;
index 6e6c7934be32f819a08286e474e5ec31bd98fd4e..4d1cd7aeccd38c5493bef4e3b09caedeaa663080 100644 (file)
@@ -152,8 +152,8 @@ static void whiteheat_break_ctl             (struct usb_serial_port *port, int break_state)
 static int  whiteheat_chars_in_buffer  (struct usb_serial_port *port);
 static void whiteheat_throttle         (struct usb_serial_port *port);
 static void whiteheat_unthrottle       (struct usb_serial_port *port);
-static void whiteheat_read_callback    (struct urb *urb, struct pt_regs *regs);
-static void whiteheat_write_callback   (struct urb *urb, struct pt_regs *regs);
+static void whiteheat_read_callback    (struct urb *urb);
+static void whiteheat_write_callback   (struct urb *urb);
 
 static struct usb_serial_driver whiteheat_fake_device = {
        .driver = {
@@ -235,8 +235,8 @@ struct whiteheat_private {
 /* local function prototypes */
 static int start_command_port(struct usb_serial *serial);
 static void stop_command_port(struct usb_serial *serial);
-static void command_port_write_callback(struct urb *urb, struct pt_regs *regs);
-static void command_port_read_callback(struct urb *urb, struct pt_regs *regs);
+static void command_port_write_callback(struct urb *urb);
+static void command_port_read_callback(struct urb *urb);
 
 static int start_port_read(struct usb_serial_port *port);
 static struct whiteheat_urb_wrap *urb_to_wrap(struct urb *urb, struct list_head *head);
@@ -958,7 +958,7 @@ static void whiteheat_unthrottle (struct usb_serial_port *port)
 /*****************************************************************************
  * Connect Tech's White Heat callback routines
  *****************************************************************************/
-static void command_port_write_callback (struct urb *urb, struct pt_regs *regs)
+static void command_port_write_callback (struct urb *urb)
 {
        dbg("%s", __FUNCTION__);
 
@@ -969,7 +969,7 @@ static void command_port_write_callback (struct urb *urb, struct pt_regs *regs)
 }
 
 
-static void command_port_read_callback (struct urb *urb, struct pt_regs *regs)
+static void command_port_read_callback (struct urb *urb)
 {
        struct usb_serial_port *command_port = (struct usb_serial_port *)urb->context;
        struct whiteheat_command_private *command_info;
@@ -1019,7 +1019,7 @@ static void command_port_read_callback (struct urb *urb, struct pt_regs *regs)
 }
 
 
-static void whiteheat_read_callback(struct urb *urb, struct pt_regs *regs)
+static void whiteheat_read_callback(struct urb *urb)
 {
        struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
        struct whiteheat_urb_wrap *wrap;
@@ -1061,7 +1061,7 @@ static void whiteheat_read_callback(struct urb *urb, struct pt_regs *regs)
 }
 
 
-static void whiteheat_write_callback(struct urb *urb, struct pt_regs *regs)
+static void whiteheat_write_callback(struct urb *urb)
 {
        struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
        struct whiteheat_private *info = usb_get_serial_port_data(port);
index f843a0bcf107a55b2d3f65a65be2875519357fc9..3baf448e300d6125bee994de038baa2e0d70e9e2 100644 (file)
@@ -53,7 +53,7 @@ struct usb_onetouch {
        unsigned int is_open:1;
 };
 
-static void usb_onetouch_irq(struct urb *urb, struct pt_regs *regs)
+static void usb_onetouch_irq(struct urb *urb)
 {
        struct usb_onetouch *onetouch = urb->context;
        signed char *data = onetouch->data;
@@ -72,7 +72,6 @@ static void usb_onetouch_irq(struct urb *urb, struct pt_regs *regs)
                goto resubmit;
        }
 
-       input_regs(dev, regs);
        input_report_key(dev, ONETOUCH_BUTTON, data[0] & 0x02);
        input_sync(dev);
 
index f23514c4e649bdd6947ce0301cf730e2344ef540..47644b5b61553c4082257aa8cd4763587375c197 100644 (file)
 /* This is the completion handler which will wake us up when an URB
  * completes.
  */
-static void usb_stor_blocking_completion(struct urb *urb, struct pt_regs *regs)
+static void usb_stor_blocking_completion(struct urb *urb)
 {
        struct completion *urb_done_ptr = (struct completion *)urb->context;
 
index c9a8d50106d1a3bef5b9f1359baad58d015f1725..37ed8e0f2dc8fd4015f09a2c1a52e70f3bff36f7 100644 (file)
@@ -55,7 +55,8 @@ UNUSUAL_DEV(  0x03eb, 0x2002, 0x0100, 0x0100,
                 US_SC_DEVICE, US_PR_DEVICE, NULL,
                 US_FL_IGNORE_RESIDUE),
 
-UNUSUAL_DEV(  0x03ee, 0x6901, 0x0000, 0x0100,
+/* modified by Tobias Lorenz <tobias.lorenz@gmx.net> */
+UNUSUAL_DEV(  0x03ee, 0x6901, 0x0000, 0x0200,
                "Mitsumi",
                "USB FDD",
                US_SC_DEVICE, US_PR_DEVICE, NULL,
@@ -182,6 +183,20 @@ UNUSUAL_DEV(  0x0421, 0x044e, 0x0100, 0x0100,
                US_SC_DEVICE, US_PR_DEVICE, NULL,
                US_FL_IGNORE_RESIDUE | US_FL_FIX_CAPACITY ),
 
+/* Reported by Bardur Arantsson <bardur@scientician.net> */
+UNUSUAL_DEV(  0x0421, 0x047c, 0x0370, 0x0370,
+               "Nokia",
+               "6131",
+               US_SC_DEVICE, US_PR_DEVICE, NULL,
+               US_FL_MAX_SECTORS_64 ),
+
+/* Reported by Alex Corcoles <alex@corcoles.net> */
+UNUSUAL_DEV(  0x0421, 0x0495, 0x0370, 0x0370,
+               "Nokia",
+               "6234",
+               US_SC_DEVICE, US_PR_DEVICE, NULL,
+               US_FL_MAX_SECTORS_64 ),
+
 /* Reported by Olaf Hering <olh@suse.de> from novell bug #105878 */
 UNUSUAL_DEV(  0x0424, 0x0fdc, 0x0210, 0x0210,
                "SMSC",
@@ -1291,6 +1306,13 @@ UNUSUAL_DEV(  0x0fce, 0xe030, 0x0000, 0x0000,
                US_SC_DEVICE, US_PR_DEVICE, NULL,
                US_FL_FIX_CAPACITY ),
 
+/* Reported by Jan Mate <mate@fiit.stuba.sk> */
+UNUSUAL_DEV(  0x0fce, 0xe030, 0x0000, 0x0000,
+               "Sony Ericsson",
+               "P990i",
+               US_SC_DEVICE, US_PR_DEVICE, NULL,
+               US_FL_FIX_CAPACITY ),
+
 /* Reported by Kevin Cernekee <kpc-usbdev@gelato.uiuc.edu>
  * Tested on hardware version 1.10.
  * Entry is needed only for the initializer function override.
index 1b51d3187a95c8d99c87de153de5afed4a9831ea..296b091cf168c7e460ec70db19ac7dcc18a777c1 100644 (file)
@@ -158,7 +158,7 @@ exit:
        return retval;
 }
 
-static void skel_write_bulk_callback(struct urb *urb, struct pt_regs *regs)
+static void skel_write_bulk_callback(struct urb *urb)
 {
        struct usb_skel *dev;
 
index daaa486159cf37ae64d5329150466bf839272bdc..7a43020fa5835136ced2b4826ac3cffdd7823efb 100644 (file)
@@ -701,7 +701,6 @@ config FB_NVIDIA
        depends on FB && PCI
        select I2C_ALGOBIT if FB_NVIDIA_I2C
        select I2C if FB_NVIDIA_I2C
-       select FB_DDC if FB_NVIDIA_I2C
        select FB_MODE_HELPERS
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
index f1ba54f4fc3921ee1ee4816048bcd97c56e54be0..a4e3fca058919ba2373e449d8910e6c2a1724984 100644 (file)
@@ -1144,7 +1144,7 @@ static void amifb_deinit(void);
         */
 
 static int flash_cursor(void);
-static irqreturn_t amifb_interrupt(int irq, void *dev_id, struct pt_regs *fp);
+static irqreturn_t amifb_interrupt(int irq, void *dev_id);
 static u_long chipalloc(u_long size);
 static void chipfree(void);
 
@@ -2492,7 +2492,7 @@ static int flash_cursor(void)
         * VBlank Display Interrupt
         */
 
-static irqreturn_t amifb_interrupt(int irq, void *dev_id, struct pt_regs *fp)
+static irqreturn_t amifb_interrupt(int irq, void *dev_id)
 {
        if (do_vmode_pan || do_vmode_full)
                ami_update_display();
index 70dd8115a4d8883d47a23120189620f8f8fb29a7..ab34b96acc317b659b32616e09e228911f0638a3 100644 (file)
@@ -218,8 +218,7 @@ static int arcfb_pan_display(struct fb_var_screeninfo *var,
        return -EINVAL;
 }
 
-static irqreturn_t arcfb_interrupt(int vec, void *dev_instance,
-               struct pt_regs *regs)
+static irqreturn_t arcfb_interrupt(int vec, void *dev_instance)
 {
        struct fb_info *info = dev_instance;
        unsigned char ctl2status;
index 5831893bf7a0d3256cf2e620fcd783102a0a0d2d..02c41a626fa25c2fa5d280e527fb3f8e6236ff71 100644 (file)
@@ -1521,7 +1521,7 @@ static void falcon_set_par( struct atafb_par *par )
 }
 
 
-static irqreturn_t falcon_vbl_switcher( int irq, void *dummy, struct pt_regs *fp )
+static irqreturn_t falcon_vbl_switcher( int irq, void *dummy )
 {
        struct falcon_hw *hw = &f_new_mode;
 
index b45c9fd1b3307af0c712edd78fe32011f9e3d485..b77b30923928bd0cc3d9916927a32b7f91191b5f 100644 (file)
@@ -1532,7 +1532,7 @@ static int atyfb_open(struct fb_info *info, int user)
        return (0);
 }
 
-static irqreturn_t aty_irq(int irq, void *dev_id, struct pt_regs *fp)
+static irqreturn_t aty_irq(int irq, void *dev_id)
 {
        struct atyfb_par *par = dev_id;
        int handled = 0;
index c6a5f0ccc107232ff8ac7bd866abeccd57dea69b..dbf4ec3f6d57e8a58753ab0871620dc6979e7920 100644 (file)
@@ -1545,7 +1545,7 @@ static struct fb_ops au1200fb_fb_ops = {
 
 /*-------------------------------------------------------------------------*/
 
-static irqreturn_t au1200fb_handle_irq(int irq, void* dev_id, struct pt_regs *regs)
+static irqreturn_t au1200fb_handle_irq(int irq, void* dev_id)
 {
        /* Nothing to do for now, just clear any pending interrupt */
        lcd->intstatus = lcd->intstatus;
index 8c041daa3a15b264b5825141a5382f92a526fa4c..302174b8e477df2eec923f51abe69bc7ab7a4e2e 100644 (file)
@@ -204,7 +204,7 @@ static struct class_device *fbcon_class_device;
  */
 static int vbl_detected;
 
-static irqreturn_t fb_vbl_detect(int irq, void *dummy, struct pt_regs *fp)
+static irqreturn_t fb_vbl_detect(int irq, void *dummy)
 {
        vbl_detected++;
        return IRQ_HANDLED;
@@ -414,7 +414,7 @@ static void fb_flashcursor(void *private)
 
 #if defined(CONFIG_ATARI) || defined(CONFIG_MAC)
 static int cursor_blink_rate;
-static irqreturn_t fb_vbl_handler(int irq, void *dev_id, struct pt_regs *fp)
+static irqreturn_t fb_vbl_handler(int irq, void *dev_id)
 {
        struct fb_info *info = dev_id;
 
index 8cc6c0e2d27aa74935776168562aa5b1f0d26f1c..04c6d928189b82b1c761fafb5ea408267c187958 100644 (file)
@@ -415,13 +415,15 @@ static int __init init_control(struct fb_info_control *p)
        full = p->total_vram == 0x400000;
 
        /* Try to pick a video mode out of NVRAM if we have one. */
+#ifdef CONFIG_NVRAM
        if (default_cmode == CMODE_NVRAM){
                cmode = nvram_read_byte(NV_CMODE);
                if(cmode < CMODE_8 || cmode > CMODE_32)
                        cmode = CMODE_8;
        } else
+#endif
                cmode=default_cmode;
-
+#ifdef CONFIG_NVRAM
        if (default_vmode == VMODE_NVRAM) {
                vmode = nvram_read_byte(NV_VMODE);
                if (vmode < 1 || vmode > VMODE_MAX ||
@@ -432,7 +434,9 @@ static int __init init_control(struct fb_info_control *p)
                        if (control_mac_modes[vmode - 1].m[full] < cmode)
                                vmode = VMODE_640_480_60;
                }
-       } else {
+       } else
+#endif
+       {
                vmode=default_vmode;
                if (control_mac_modes[vmode - 1].m[full] < cmode) {
                        if (cmode > CMODE_8)
index 3afb472763c0488fddcd1dd5a4c0e3bb5817c1f8..3dc49424dc75b43e6cc5d2860c5c258011d3162a 100644 (file)
@@ -29,7 +29,6 @@
 #include <asm/io.h>
 #include <asm/hd64461.h>
 #include <asm/cpu/dac.h>
-#include <asm/hp6xx/hp6xx.h>
 
 #define        WIDTH 640
 
index 67f384f867580d638e2c17501f344d803a9a19f7..e6df492c22a506ba1cec0d49ba1e227c23ab3578 100644 (file)
@@ -573,3 +573,10 @@ int __init igafb_setup(char *options)
 
 module_init(igafb_init);
 MODULE_LICENSE("GPL");
+static struct pci_device_id igafb_pci_tbl[] __devinitdata = {
+       { PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_1682,
+         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+       { }
+};
+
+MODULE_DEVICE_TABLE(pci, igafb_pci_tbl);
index f887f1efd3fef1676201321665651c147668fda7..eeeeff9a09eb6180709773d4e99dddb4549437d8 100644 (file)
@@ -1952,7 +1952,7 @@ intelfbhw_cursor_reset(struct intelfb_info *dinfo) {
 }
 
 static irqreturn_t
-intelfbhw_irq(int irq, void *dev_id, struct pt_regs *fp) {
+intelfbhw_irq(int irq, void *dev_id) {
        int handled = 0;
        u16 tmp;
        struct intelfb_info *dinfo = (struct intelfb_info *)dev_id;
index 7acf01c181eeb6d622efa8d2f1615240089e4272..e9b4115fcad0208891bfe672159453e40f3db1ea 100644 (file)
@@ -198,7 +198,7 @@ static void matroxfb_crtc1_panpos(WPMINFO2) {
        }
 }
 
-static irqreturn_t matrox_irq(int irq, void *dev_id, struct pt_regs *fp)
+static irqreturn_t matrox_irq(int irq, void *dev_id)
 {
        u_int32_t status;
        int handled = 0;
index e48de3c9fd13ff0ee1f35df67a85281a719e26fd..19eef3a090232854860ad993365993dc7e5f68f6 100644 (file)
@@ -160,12 +160,51 @@ void nvidia_delete_i2c_busses(struct nvidia_par *par)
 
 }
 
+static u8 *nvidia_do_probe_i2c_edid(struct nvidia_i2c_chan *chan)
+{
+       u8 start = 0x0;
+       struct i2c_msg msgs[] = {
+               {
+                .addr = 0x50,
+                .len = 1,
+                .buf = &start,
+                }, {
+                    .addr = 0x50,
+                    .flags = I2C_M_RD,
+                    .len = EDID_LENGTH,
+                    },
+       };
+       u8 *buf;
+
+       if (!chan->par)
+               return NULL;
+
+       buf = kmalloc(EDID_LENGTH, GFP_KERNEL);
+       if (!buf) {
+               dev_warn(&chan->par->pci_dev->dev, "Out of memory!\n");
+               return NULL;
+       }
+       msgs[1].buf = buf;
+
+       if (i2c_transfer(&chan->adapter, msgs, 2) == 2)
+               return buf;
+       dev_dbg(&chan->par->pci_dev->dev, "Unable to read EDID block.\n");
+       kfree(buf);
+       return NULL;
+}
+
 int nvidia_probe_i2c_connector(struct fb_info *info, int conn, u8 **out_edid)
 {
        struct nvidia_par *par = info->par;
-       u8 *edid;
-
-       edid = fb_ddc_read(&par->chan[conn - 1].adapter);
+       u8 *edid = NULL;
+       int i;
+
+       for (i = 0; i < 3; i++) {
+               /* Do the real work */
+               edid = nvidia_do_probe_i2c_edid(&par->chan[conn - 1]);
+               if (edid)
+                       break;
+       }
 
        if (!edid && conn == 1) {
                /* try to get from firmware */
index 983be3ec23459affb6ce021dc644ceca48138776..fdb33cd21a27211e1d78ba7ec778124c584885c7 100644 (file)
@@ -339,11 +339,12 @@ static int __devinit platinum_init_fb(struct fb_info *info)
 
        sense = read_platinum_sense(pinfo);
        printk(KERN_INFO "platinumfb: Monitor sense value = 0x%x, ", sense);
-
        if (default_vmode == VMODE_NVRAM) {
+#ifdef CONFIG_NVRAM
                default_vmode = nvram_read_byte(NV_VMODE);
                if (default_vmode <= 0 || default_vmode > VMODE_MAX ||
                    !platinum_reg_init[default_vmode-1])
+#endif
                        default_vmode = VMODE_CHOOSE;
        }
        if (default_vmode == VMODE_CHOOSE) {
@@ -351,8 +352,10 @@ static int __devinit platinum_init_fb(struct fb_info *info)
        }
        if (default_vmode <= 0 || default_vmode > VMODE_MAX)
                default_vmode = VMODE_640_480_60;
+#ifdef CONFIG_NVRAM
        if (default_cmode == CMODE_NVRAM)
                default_cmode = nvram_read_byte(NV_CMODE);
+#endif
        if (default_cmode < CMODE_8 || default_cmode > CMODE_32)
                default_cmode = CMODE_8;
        /*
index 78dc59a1751bfcf43a9f96952959d09b20643070..c7bc80921f1613196deeca432f015451184b4c87 100644 (file)
@@ -209,7 +209,7 @@ static int pvr2fb_set_par(struct fb_info *info);
 static void pvr2_update_display(struct fb_info *info);
 static void pvr2_init_display(struct fb_info *info);
 static void pvr2_do_blank(void);
-static irqreturn_t pvr2fb_interrupt(int irq, void *dev_id, struct pt_regs *fp);
+static irqreturn_t pvr2fb_interrupt(int irq, void *dev_id);
 static int pvr2_init_cable(void);
 static int pvr2_get_param(const struct pvr2_params *p, const char *s,
                             int val, int size);
@@ -626,7 +626,7 @@ static void pvr2_do_blank(void)
        is_blanked = do_blank > 0 ? do_blank : 0;
 }
 
-static irqreturn_t pvr2fb_interrupt(int irq, void *dev_id, struct pt_regs *fp)
+static irqreturn_t pvr2fb_interrupt(int irq, void *dev_id)
 {
        struct fb_info *info = dev_id;
 
index 3bc5da4a57ca5caeca7046b89cb7b1dbd412a5e0..8a8ae55a7403fbe745a3981ef816575fd25b20b3 100644 (file)
@@ -846,7 +846,7 @@ static void pxafb_disable_controller(struct pxafb_info *fbi)
 /*
  *  pxafb_handle_irq: Handle 'LCD DONE' interrupts.
  */
-static irqreturn_t pxafb_handle_irq(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t pxafb_handle_irq(int irq, void *dev_id)
 {
        struct pxafb_info *fbi = dev_id;
        unsigned int lcsr = LCSR;
index ad3bdd6f1ac1fa39ca03896b9873cc1b56dd6639..59407343cc731d25322d025e9b7485fb814551d5 100644 (file)
@@ -614,7 +614,7 @@ static void s3c2410fb_write_palette(struct s3c2410fb_info *fbi)
        }
 }
 
-static irqreturn_t s3c2410fb_irq(int irq, void *dev_id, struct pt_regs *r)
+static irqreturn_t s3c2410fb_irq(int irq, void *dev_id)
 {
        struct s3c2410fb_info *fbi = dev_id;
        unsigned long lcdirq = readl(S3C2410_LCDINTPND);
index a2e6e7205d7e082b79a2428a35b406059fa59c3e..cd10b18150b879f15ddc919e611d4e789fd8771c 100644 (file)
@@ -1085,7 +1085,7 @@ static void sa1100fb_disable_controller(struct sa1100fb_info *fbi)
 /*
  *  sa1100fb_handle_irq: Handle 'LCD DONE' interrupts.
  */
-static irqreturn_t sa1100fb_handle_irq(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t sa1100fb_handle_irq(int irq, void *dev_id)
 {
        struct sa1100fb_info *fbi = dev_id;
        unsigned int lcsr = LCSR;
index 47f27924a7d75728424281b8f9255323b0c16832..06fc19a6119249a8a6128799c1d9fd226f36494b 100644 (file)
@@ -284,7 +284,7 @@ static void __init valkyrie_choose_mode(struct fb_info_valkyrie *p)
        printk(KERN_INFO "Monitor sense value = 0x%x\n", p->sense);
 
        /* Try to pick a video mode out of NVRAM if we have one. */
-#ifndef CONFIG_MAC
+#if !defined(CONFIG_MAC) && defined(CONFIG_NVRAM)
        if (default_vmode == VMODE_NVRAM) {
                default_vmode = nvram_read_byte(NV_VMODE);
                if (default_vmode <= 0
@@ -297,7 +297,7 @@ static void __init valkyrie_choose_mode(struct fb_info_valkyrie *p)
                default_vmode = mac_map_monitor_sense(p->sense);
        if (!valkyrie_reg_init[default_vmode - 1])
                default_vmode = VMODE_640_480_67;
-#ifndef CONFIG_MAC
+#if !defined(CONFIG_MAC) && defined(CONFIG_NVRAM)
        if (default_cmode == CMODE_NVRAM)
                default_cmode = nvram_read_byte(NV_CMODE);
 #endif
index 27c9d05d03ef23f1280754fab152393d6995bb14..c287a9ae4fdd56690444c44a2f6e57269e50cb5a 100644 (file)
@@ -2,7 +2,6 @@ menu "Dallas's 1-wire bus"
 
 config W1
        tristate "Dallas's 1-wire support"
-       depends on CONNECTOR
        ---help---
          Dallas' 1-wire bus is useful to connect slow 1-pin devices
          such as iButtons and thermal sensors.
index 599de54451af61c3297e4d18b068e5799b36e4b2..fee318e6f4bb30e8b40c932c103caf857bbc77b1 100644 (file)
@@ -140,6 +140,73 @@ config EXT3_FS_SECURITY
          If you are not using a security module that requires using
          extended attributes for file security labels, say N.
 
+config EXT4DEV_FS
+       tristate "Ext4dev/ext4 extended fs support development (EXPERIMENTAL)"
+       depends on EXPERIMENTAL
+       select JBD2
+       help
+         Ext4dev is a predecessor filesystem of the next generation
+         extended fs ext4, based on ext3 filesystem code. It will be
+         renamed ext4 fs later, once ext4dev is mature and stabilized.
+
+         Unlike the change from ext2 filesystem to ext3 filesystem,
+         the on-disk format of ext4dev is not the same as ext3 any more:
+         it is based on extent maps and it supports 48-bit physical block
+         numbers. These combined on-disk format changes will allow
+         ext4dev/ext4 to handle more than 16 TB filesystem volumes --
+         a hard limit that ext3 cannot overcome without changing the
+         on-disk format.
+
+         Other than extent maps and 48-bit block numbers, ext4dev also is
+         likely to have other new features such as persistent preallocation,
+         high resolution time stamps, and larger file support etc.  These
+         features will be added to ext4dev gradually.
+
+         To compile this file system support as a module, choose M here. The
+         module will be called ext4dev.  Be aware, however, that the filesystem
+         of your root partition (the one containing the directory /) cannot
+         be compiled as a module, and so this could be dangerous.
+
+         If unsure, say N.
+
+config EXT4DEV_FS_XATTR
+       bool "Ext4dev extended attributes"
+       depends on EXT4DEV_FS
+       default y
+       help
+         Extended attributes are name:value pairs associated with inodes by
+         the kernel or by users (see the attr(5) manual page, or visit
+         <http://acl.bestbits.at/> for details).
+
+         If unsure, say N.
+
+         You need this for POSIX ACL support on ext4dev/ext4.
+
+config EXT4DEV_FS_POSIX_ACL
+       bool "Ext4dev POSIX Access Control Lists"
+       depends on EXT4DEV_FS_XATTR
+       select FS_POSIX_ACL
+       help
+         POSIX Access Control Lists (ACLs) support permissions for users and
+         groups beyond the owner/group/world scheme.
+
+         To learn more about Access Control Lists, visit the POSIX ACLs for
+         Linux website <http://acl.bestbits.at/>.
+
+         If you don't know what Access Control Lists are, say N
+
+config EXT4DEV_FS_SECURITY
+       bool "Ext4dev Security Labels"
+       depends on EXT4DEV_FS_XATTR
+       help
+         Security labels support alternative access control models
+         implemented by security modules like SELinux.  This option
+         enables an extended attribute handler for file security
+         labels in the ext4dev/ext4 filesystem.
+
+         If you are not using a security module that requires using
+         extended attributes for file security labels, say N.
+
 config JBD
        tristate
        help
@@ -172,12 +239,44 @@ config JBD_DEBUG
          generated.  To turn debugging off again, do
          "echo 0 > /proc/sys/fs/jbd-debug".
 
+config JBD2
+       tristate
+       help
+         This is a generic journaling layer for block devices that support
+         both 32-bit and 64-bit block numbers.  It is currently used by
+         the ext4dev/ext4 filesystem, but it could also be used to add
+         journal support to other file systems or block devices such
+         as RAID or LVM.
+
+         If you are using ext4dev/ext4, you need to say Y here. If you are not
+         using ext4dev/ext4 then you will probably want to say N.
+
+         To compile this device as a module, choose M here. The module will be
+         called jbd2.  If you are compiling ext4dev/ext4 into the kernel,
+         you cannot compile this code as a module.
+
+config JBD2_DEBUG
+       bool "JBD2 (ext4dev/ext4) debugging support"
+       depends on JBD2
+       help
+         If you are using the ext4dev/ext4 journaled file system (or
+         potentially any other filesystem/device using JBD2), this option
+         allows you to enable debugging output while the system is running,
+         in order to help track down any problems you are having.
+         By default, the debugging output will be turned off.
+
+         If you select Y here, then you will be able to turn on debugging
+         with "echo N > /proc/sys/fs/jbd2-debug", where N is a number between
+         1 and 5. The higher the number, the more debugging output is
+         generated.  To turn debugging off again, do
+         "echo 0 > /proc/sys/fs/jbd2-debug".
+
 config FS_MBCACHE
-# Meta block cache for Extended Attributes (ext2/ext3)
+# Meta block cache for Extended Attributes (ext2/ext3/ext4)
        tristate
-       depends on EXT2_FS_XATTR || EXT3_FS_XATTR
-       default y if EXT2_FS=y || EXT3_FS=y
-       default m if EXT2_FS=m || EXT3_FS=m
+       depends on EXT2_FS_XATTR || EXT3_FS_XATTR || EXT4DEV_FS_XATTR
+       default y if EXT2_FS=y || EXT3_FS=y || EXT4DEV_FS=y
+       default m if EXT2_FS=m || EXT3_FS=m || EXT4DEV_FS=m
 
 config REISERFS_FS
        tristate "Reiserfs support"
@@ -535,6 +634,10 @@ config FUSE_FS
          If you want to develop a userspace FS, or if you want to use
          a filesystem based on FUSE, answer Y or M.
 
+config GENERIC_ACL
+       bool
+       select FS_POSIX_ACL
+
 if BLOCK
 menu "CD-ROM/DVD Filesystems"
 
@@ -1887,7 +1990,7 @@ config CIFS_EXPERIMENTAL
 config CIFS_UPCALL
          bool "Kerberos/SPNEGO advanced session setup (EXPERIMENTAL)"
          depends on CIFS_EXPERIMENTAL
-         select CONNECTOR
+         depends on CONNECTOR
          help
            Enables an upcall mechanism for CIFS which will be used to contact
            userspace helper utilities to provide SPNEGO packaged Kerberos
@@ -1981,10 +2084,6 @@ config 9P_FS
 
          If unsure, say N.
 
-config GENERIC_ACL
-       bool
-       select FS_POSIX_ACL
-
 endmenu
 
 if BLOCK
index df614eacee8620c07b15bb3080f65405e4674392..9a5ce9323bfd0c65ffed56f597294b29db75efa9 100644 (file)
@@ -62,7 +62,9 @@ obj-$(CONFIG_DLM)             += dlm/
 # Do not add any filesystems before this line
 obj-$(CONFIG_REISERFS_FS)      += reiserfs/
 obj-$(CONFIG_EXT3_FS)          += ext3/ # Before ext2 so root fs can be ext3
+obj-$(CONFIG_EXT4DEV_FS)       += ext4/ # Before ext2 so root fs can be ext4dev
 obj-$(CONFIG_JBD)              += jbd/
+obj-$(CONFIG_JBD2)             += jbd2/
 obj-$(CONFIG_EXT2_FS)          += ext2/
 obj-$(CONFIG_CRAMFS)           += cramfs/
 obj-$(CONFIG_RAMFS)            += ramfs/
index cf8a2cb2850563d9c9d19741dd2c3b12d367b01a..a6ec75c56fcf76cf44b12f28969180e588eee966 100644 (file)
@@ -211,8 +211,8 @@ static int afs_dir_open(struct inode *inode, struct file *file)
 {
        _enter("{%lu}", inode->i_ino);
 
-       BUG_ON(sizeof(union afs_dir_block) != 2048);
-       BUG_ON(sizeof(union afs_dirent) != 32);
+       BUILD_BUG_ON(sizeof(union afs_dir_block) != 2048);
+       BUILD_BUG_ON(sizeof(union afs_dirent) != 32);
 
        if (AFS_FS_I(inode)->flags & AFS_VNODE_DELETED)
                return -ENOENT;
@@ -446,8 +446,8 @@ static struct dentry *afs_dir_lookup(struct inode *dir, struct dentry *dentry,
        _enter("{%lu},%p{%s}", dir->i_ino, dentry, dentry->d_name.name);
 
        /* insanity checks first */
-       BUG_ON(sizeof(union afs_dir_block) != 2048);
-       BUG_ON(sizeof(union afs_dirent) != 32);
+       BUILD_BUG_ON(sizeof(union afs_dir_block) != 2048);
+       BUILD_BUG_ON(sizeof(union afs_dirent) != 32);
 
        if (dentry->d_name.len > 255) {
                _leave(" = -ENAMETOOLONG");
index c7700d9b3f96792b74651d8d3890b396976204a2..906ba5ce22617b12d7d3000eaab056f495b4159d 100644 (file)
@@ -149,6 +149,7 @@ extern const struct file_operations autofs_root_operations;
 /* Initializing function */
 
 int autofs_fill_super(struct super_block *, void *, int);
+void autofs_kill_sb(struct super_block *sb);
 
 /* Queue management functions */
 
index 3fded389d06b9fe1e1d8df20f08ac541b87f9bb1..bf8c8af980044462ece05e7fc9772d0efb9d6c13 100644 (file)
@@ -246,5 +246,4 @@ void autofs_hash_nuke(struct autofs_sb_info *sbi)
                        kfree(ent);
                }
        }
-       shrink_dcache_sb(sbi->sb);
 }
index aca12375240694975523badc164647cb10ca01c1..cea5219b4f377ba00b3deb95f58455986764d676 100644 (file)
@@ -24,7 +24,7 @@ static struct file_system_type autofs_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "autofs",
        .get_sb         = autofs_get_sb,
-       .kill_sb        = kill_anon_super,
+       .kill_sb        = autofs_kill_sb,
 };
 
 static int __init init_autofs_fs(void)
index 2c9759baad61bf0f875c4adbb4abba6e8fdebb04..54c518c89e4cf86a8fec90124f21d7ca2e776169 100644 (file)
@@ -20,7 +20,7 @@
 #include "autofs_i.h"
 #include <linux/module.h>
 
-static void autofs_put_super(struct super_block *sb)
+void autofs_kill_sb(struct super_block *sb)
 {
        struct autofs_sb_info *sbi = autofs_sbi(sb);
        unsigned int n;
@@ -37,13 +37,13 @@ static void autofs_put_super(struct super_block *sb)
        kfree(sb->s_fs_info);
 
        DPRINTK(("autofs: shutting down\n"));
+       kill_anon_super(sb);
 }
 
 static void autofs_read_inode(struct inode *inode);
 
 static struct super_operations autofs_sops = {
        .read_inode     = autofs_read_inode,
-       .put_super      = autofs_put_super,
        .statfs         = simple_statfs,
 };
 
index 480ab178cba50eca22e35bb3af4d0709c0d37258..b13f32c8aeeea26914163e35e7b45a9782e779eb 100644 (file)
@@ -94,7 +94,6 @@ struct autofs_wait_queue {
 
 struct autofs_sb_info {
        u32 magic;
-       struct dentry *root;
        int pipefd;
        struct file *pipe;
        pid_t oz_pgrp;
@@ -229,4 +228,4 @@ out:
 }
 
 void autofs4_dentry_release(struct dentry *);
-
+extern void autofs4_kill_sb(struct super_block *);
index 5d9193332bef1b9eac190d80fb0fa5f97ff28f8a..723a1c5e361b2786c8f8ec97e9332b77b1484e15 100644 (file)
@@ -24,7 +24,7 @@ static struct file_system_type autofs_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "autofs",
        .get_sb         = autofs_get_sb,
-       .kill_sb        = kill_anon_super,
+       .kill_sb        = autofs4_kill_sb,
 };
 
 static int __init init_autofs4_fs(void)
index 800ce876caeca6e33fc427e40d34d89a69923ed3..51fd8595bf85197d252ce3414b73539dd0b9eae8 100644 (file)
@@ -96,7 +96,7 @@ void autofs4_free_ino(struct autofs_info *ino)
  */
 static void autofs4_force_release(struct autofs_sb_info *sbi)
 {
-       struct dentry *this_parent = sbi->root;
+       struct dentry *this_parent = sbi->sb->s_root;
        struct list_head *next;
 
        spin_lock(&dcache_lock);
@@ -127,7 +127,7 @@ resume:
                spin_lock(&dcache_lock);
        }
 
-       if (this_parent != sbi->root) {
+       if (this_parent != sbi->sb->s_root) {
                struct dentry *dentry = this_parent;
 
                next = this_parent->d_u.d_child.next;
@@ -140,15 +140,9 @@ resume:
                goto resume;
        }
        spin_unlock(&dcache_lock);
-
-       dput(sbi->root);
-       sbi->root = NULL;
-       shrink_dcache_sb(sbi->sb);
-
-       return;
 }
 
-static void autofs4_put_super(struct super_block *sb)
+void autofs4_kill_sb(struct super_block *sb)
 {
        struct autofs_sb_info *sbi = autofs4_sbi(sb);
 
@@ -163,6 +157,7 @@ static void autofs4_put_super(struct super_block *sb)
        kfree(sbi);
 
        DPRINTK("shutting down");
+       kill_anon_super(sb);
 }
 
 static int autofs4_show_options(struct seq_file *m, struct vfsmount *mnt)
@@ -189,7 +184,6 @@ static int autofs4_show_options(struct seq_file *m, struct vfsmount *mnt)
 }
 
 static struct super_operations autofs4_sops = {
-       .put_super      = autofs4_put_super,
        .statfs         = simple_statfs,
        .show_options   = autofs4_show_options,
 };
@@ -315,7 +309,6 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent)
 
        s->s_fs_info = sbi;
        sbi->magic = AUTOFS_SBI_MAGIC;
-       sbi->root = NULL;
        sbi->pipefd = -1;
        sbi->catatonic = 0;
        sbi->exp_timeout = 0;
@@ -396,13 +389,6 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent)
        sbi->pipe = pipe;
        sbi->pipefd = pipefd;
 
-       /*
-        * Take a reference to the root dentry so we get a chance to
-        * clean up the dentry tree on umount.
-        * See autofs4_force_release.
-        */
-       sbi->root = dget(root);
-
        /*
         * Success! Install the root dentry now to indicate completion.
         */
index ce103e7b0bc360f684a2556c55ea9ed8be0e38f2..c0a6c8d445c7b7cffc8a7c5163bd32d7ba6bdbd7 100644 (file)
@@ -45,7 +45,6 @@ void autofs4_catatonic_mode(struct autofs_sb_info *sbi)
                fput(sbi->pipe);        /* Close the pipe */
                sbi->pipe = NULL;
        }
-       shrink_dcache_sb(sbi->sb);
 }
 
 static int autofs4_write(struct file *file, const void *addr, int bytes)
index 057a2c3d73b77dc4afb1e1522363337fa673b995..d9a40abda6b700e6fd0c6fcf5cd65b0f97cfb193 100644 (file)
@@ -94,7 +94,7 @@ void befs_debug(const struct super_block *sb, const char *fmt, ...);
 
 void befs_dump_super_block(const struct super_block *sb, befs_super_block *);
 void befs_dump_inode(const struct super_block *sb, befs_inode *);
-void befs_dump_index_entry(const struct super_block *sb, befs_btree_super *);
+void befs_dump_index_entry(const struct super_block *sb, befs_disk_btree_super *);
 void befs_dump_index_node(const struct super_block *sb, befs_btree_nodehead *);
 /****************************/
 
@@ -136,7 +136,7 @@ blockno2iaddr(struct super_block *sb, befs_blocknr_t blockno)
 static inline unsigned int
 befs_iaddrs_per_block(struct super_block *sb)
 {
-       return BEFS_SB(sb)->block_size / sizeof (befs_inode_addr);
+       return BEFS_SB(sb)->block_size / sizeof (befs_disk_inode_addr);
 }
 
 static inline int
@@ -151,4 +151,6 @@ befs_brun_size(struct super_block *sb, befs_block_run run)
        return BEFS_SB(sb)->block_size * run.len;
 }
 
+#include "endian.h"
+
 #endif                         /* _LINUX_BEFS_H */
index 63ef1e18fb84d2f2052dc8861f5df267f23b0727..e2595c2c403a9bfd01dffc1ac54594356e09e811 100644 (file)
@@ -79,17 +79,27 @@ enum inode_flags {
  * On-Disk datastructures of BeFS
  */
 
+typedef u64 __bitwise fs64;
+typedef u32 __bitwise fs32;
+typedef u16 __bitwise fs16;
+
 typedef u64 befs_off_t;
-typedef u64 befs_time_t;
-typedef void befs_binode_etc;
+typedef fs64 befs_time_t;
 
 /* Block runs */
+typedef struct {
+       fs32 allocation_group;
+       fs16 start;
+       fs16 len;
+} PACKED befs_disk_block_run;
+
 typedef struct {
        u32 allocation_group;
        u16 start;
        u16 len;
 } PACKED befs_block_run;
 
+typedef befs_disk_block_run befs_disk_inode_addr;
 typedef befs_block_run befs_inode_addr;
 
 /*
@@ -97,31 +107,31 @@ typedef befs_block_run befs_inode_addr;
  */
 typedef struct {
        char name[B_OS_NAME_LENGTH];
-       u32 magic1;
-       u32 fs_byte_order;
+       fs32 magic1;
+       fs32 fs_byte_order;
 
-       u32 block_size;
-       u32 block_shift;
+       fs32 block_size;
+       fs32 block_shift;
 
-       befs_off_t num_blocks;
-       befs_off_t used_blocks;
+       fs64 num_blocks;
+       fs64 used_blocks;
 
-       u32 inode_size;
+       fs32 inode_size;
 
-       u32 magic2;
-       u32 blocks_per_ag;
-       u32 ag_shift;
-       u32 num_ags;
+       fs32 magic2;
+       fs32 blocks_per_ag;
+       fs32 ag_shift;
+       fs32 num_ags;
 
-       u32 flags;
+       fs32 flags;
 
-       befs_block_run log_blocks;
-       befs_off_t log_start;
-       befs_off_t log_end;
+       befs_disk_block_run log_blocks;
+       fs64 log_start;
+       fs64 log_end;
 
-       u32 magic3;
-       befs_inode_addr root_dir;
-       befs_inode_addr indices;
+       fs32 magic3;
+       befs_disk_inode_addr root_dir;
+       befs_disk_inode_addr indices;
 
 } PACKED befs_super_block;
 
@@ -129,6 +139,16 @@ typedef struct {
  * Note: the indirect and dbl_indir block_runs may
  * be longer than one block!
  */
+typedef struct {
+       befs_disk_block_run direct[BEFS_NUM_DIRECT_BLOCKS];
+       fs64 max_direct_range;
+       befs_disk_block_run indirect;
+       fs64 max_indirect_range;
+       befs_disk_block_run double_indirect;
+       fs64 max_double_indirect_range;
+       fs64 size;
+} PACKED befs_disk_data_stream;
+
 typedef struct {
        befs_block_run direct[BEFS_NUM_DIRECT_BLOCKS];
        befs_off_t max_direct_range;
@@ -141,35 +161,35 @@ typedef struct {
 
 /* Attribute */
 typedef struct {
-       u32 type;
-       u16 name_size;
-       u16 data_size;
+       fs32 type;
+       fs16 name_size;
+       fs16 data_size;
        char name[1];
 } PACKED befs_small_data;
 
 /* Inode structure */
 typedef struct {
-       u32 magic1;
-       befs_inode_addr inode_num;
-       u32 uid;
-       u32 gid;
-       u32 mode;
-       u32 flags;
+       fs32 magic1;
+       befs_disk_inode_addr inode_num;
+       fs32 uid;
+       fs32 gid;
+       fs32 mode;
+       fs32 flags;
        befs_time_t create_time;
        befs_time_t last_modified_time;
-       befs_inode_addr parent;
-       befs_inode_addr attributes;
-       u32 type;
+       befs_disk_inode_addr parent;
+       befs_disk_inode_addr attributes;
+       fs32 type;
 
-       u32 inode_size;
-       u32 etc;                /* not use */
+       fs32 inode_size;
+       fs32 etc;               /* not use */
 
        union {
-               befs_data_stream datastream;
+               befs_disk_data_stream datastream;
                char symlink[BEFS_SYMLINK_LEN];
        } data;
 
-       u32 pad[4];             /* not use */
+       fs32 pad[4];            /* not use */
        befs_small_data small_data[1];
 } PACKED befs_inode;
 
@@ -189,6 +209,16 @@ enum btree_types {
        BTREE_DOUBLE_TYPE = 6
 };
 
+typedef struct {
+       fs32 magic;
+       fs32 node_size;
+       fs32 max_depth;
+       fs32 data_type;
+       fs64 root_node_ptr;
+       fs64 free_node_ptr;
+       fs64 max_size;
+} PACKED befs_disk_btree_super;
+
 typedef struct {
        u32 magic;
        u32 node_size;
@@ -202,12 +232,20 @@ typedef struct {
 /*
  * Header stucture of each btree node
  */
+typedef struct {
+       fs64 left;
+       fs64 right;
+       fs64 overflow;
+       fs16 all_key_count;
+       fs16 all_key_length;
+} PACKED befs_btree_nodehead;
+
 typedef struct {
        befs_off_t left;
        befs_off_t right;
        befs_off_t overflow;
        u16 all_key_count;
        u16 all_key_length;
-} PACKED befs_btree_nodehead;
+} PACKED befs_host_btree_nodehead;
 
 #endif                         /* _LINUX_BEFS_FS_TYPES */
index 76e2197994095ca57c6f3c712e7b15e9b47e700e..81b042ee24e650339445504e5e83a9ecda9ca384 100644 (file)
@@ -30,7 +30,6 @@
 #include "befs.h"
 #include "btree.h"
 #include "datastream.h"
-#include "endian.h"
 
 /*
  * The btree functions in this file are built on top of the
@@ -80,7 +79,7 @@
  * In memory structure of each btree node
  */
 typedef struct {
-       befs_btree_nodehead head;       /* head of node converted to cpu byteorder */
+       befs_host_btree_nodehead head;  /* head of node converted to cpu byteorder */
        struct buffer_head *bh;
        befs_btree_nodehead *od_node;   /* on disk node */
 } befs_btree_node;
@@ -102,9 +101,9 @@ static int befs_bt_read_node(struct super_block *sb, befs_data_stream * ds,
 
 static int befs_leafnode(befs_btree_node * node);
 
-static u16 *befs_bt_keylen_index(befs_btree_node * node);
+static fs16 *befs_bt_keylen_index(befs_btree_node * node);
 
-static befs_off_t *befs_bt_valarray(befs_btree_node * node);
+static fs64 *befs_bt_valarray(befs_btree_node * node);
 
 static char *befs_bt_keydata(befs_btree_node * node);
 
@@ -136,7 +135,7 @@ befs_bt_read_super(struct super_block *sb, befs_data_stream * ds,
                   befs_btree_super * sup)
 {
        struct buffer_head *bh = NULL;
-       befs_btree_super *od_sup = NULL;
+       befs_disk_btree_super *od_sup = NULL;
 
        befs_debug(sb, "---> befs_btree_read_super()");
 
@@ -146,7 +145,7 @@ befs_bt_read_super(struct super_block *sb, befs_data_stream * ds,
                befs_error(sb, "Couldn't read index header.");
                goto error;
        }
-       od_sup = (befs_btree_super *) bh->b_data;
+       od_sup = (befs_disk_btree_super *) bh->b_data;
        befs_dump_index_entry(sb, od_sup);
 
        sup->magic = fs32_to_cpu(sb, od_sup->magic);
@@ -342,7 +341,7 @@ befs_find_key(struct super_block *sb, befs_btree_node * node,
        u16 keylen;
        int findkey_len;
        char *thiskey;
-       befs_off_t *valarray;
+       fs64 *valarray;
 
        befs_debug(sb, "---> befs_find_key() %s", findkey);
 
@@ -422,7 +421,7 @@ befs_btree_read(struct super_block *sb, befs_data_stream * ds,
        befs_btree_super bt_super;
        befs_off_t node_off = 0;
        int cur_key;
-       befs_off_t *valarray;
+       fs64 *valarray;
        char *keystart;
        u16 keylen;
        int res;
@@ -572,7 +571,7 @@ befs_btree_seekleaf(struct super_block *sb, befs_data_stream * ds,
                                   this_node->head.overflow);
                        *node_off = this_node->head.overflow;
                } else {
-                       befs_off_t *valarray = befs_bt_valarray(this_node);
+                       fs64 *valarray = befs_bt_valarray(this_node);
                        *node_off = fs64_to_cpu(sb, valarray[0]);
                }
                if (befs_bt_read_node(sb, ds, this_node, *node_off) != BEFS_OK) {
@@ -622,7 +621,7 @@ befs_leafnode(befs_btree_node * node)
  *
  * Except that rounding up to 8 works, and rounding up to 4 doesn't.
  */
-static u16 *
+static fs16 *
 befs_bt_keylen_index(befs_btree_node * node)
 {
        const int keylen_align = 8;
@@ -633,7 +632,7 @@ befs_bt_keylen_index(befs_btree_node * node)
        if (tmp)
                off += keylen_align - tmp;
 
-       return (u16 *) ((void *) node->od_node + off);
+       return (fs16 *) ((void *) node->od_node + off);
 }
 
 /**
@@ -643,13 +642,13 @@ befs_bt_keylen_index(befs_btree_node * node)
  * Returns a pointer to the start of the value array
  * of the node pointed to by the node header
  */
-static befs_off_t *
+static fs64 *
 befs_bt_valarray(befs_btree_node * node)
 {
        void *keylen_index_start = (void *) befs_bt_keylen_index(node);
-       size_t keylen_index_size = node->head.all_key_count * sizeof (u16);
+       size_t keylen_index_size = node->head.all_key_count * sizeof (fs16);
 
-       return (befs_off_t *) (keylen_index_start + keylen_index_size);
+       return (fs64 *) (keylen_index_start + keylen_index_size);
 }
 
 /**
@@ -681,7 +680,7 @@ befs_bt_get_key(struct super_block *sb, befs_btree_node * node,
 {
        int prev_key_end;
        char *keystart;
-       u16 *keylen_index;
+       fs16 *keylen_index;
 
        if (index < 0 || index > node->head.all_key_count) {
                *keylen = 0;
index b7d6b920f65f129a1c2e656cf61d11329d33dcea..aacb4da6298aefe41200fb587784e09ce7d842ae 100644 (file)
@@ -18,7 +18,6 @@
 #include "befs.h"
 #include "datastream.h"
 #include "io.h"
-#include "endian.h"
 
 const befs_inode_addr BAD_IADDR = { 0, 0, 0 };
 
@@ -312,7 +311,7 @@ befs_find_brun_indirect(struct super_block *sb,
        befs_blocknr_t indir_start_blk;
        befs_blocknr_t search_blk;
        struct buffer_head *indirblock;
-       befs_block_run *array;
+       befs_disk_block_run *array;
 
        befs_block_run indirect = data->indirect;
        befs_blocknr_t indirblockno = iaddr2blockno(sb, &indirect);
@@ -334,7 +333,7 @@ befs_find_brun_indirect(struct super_block *sb,
                        return BEFS_ERR;
                }
 
-               array = (befs_block_run *) indirblock->b_data;
+               array = (befs_disk_block_run *) indirblock->b_data;
 
                for (j = 0; j < arraylen; ++j) {
                        int len = fs16_to_cpu(sb, array[j].len);
@@ -427,7 +426,7 @@ befs_find_brun_dblindirect(struct super_block *sb,
        struct buffer_head *dbl_indir_block;
        struct buffer_head *indir_block;
        befs_block_run indir_run;
-       befs_inode_addr *iaddr_array = NULL;
+       befs_disk_inode_addr *iaddr_array = NULL;
        befs_sb_info *befs_sb = BEFS_SB(sb);
 
        befs_blocknr_t indir_start_blk =
@@ -482,7 +481,7 @@ befs_find_brun_dblindirect(struct super_block *sb,
 
        dbl_block_indx =
            dblindir_indx - (dbl_which_block * befs_iaddrs_per_block(sb));
-       iaddr_array = (befs_inode_addr *) dbl_indir_block->b_data;
+       iaddr_array = (befs_disk_inode_addr *) dbl_indir_block->b_data;
        indir_run = fsrun_to_cpu(sb, iaddr_array[dbl_block_indx]);
        brelse(dbl_indir_block);
        iaddr_array = NULL;
@@ -507,7 +506,7 @@ befs_find_brun_dblindirect(struct super_block *sb,
        }
 
        block_indx = indir_indx - (which_block * befs_iaddrs_per_block(sb));
-       iaddr_array = (befs_inode_addr *) indir_block->b_data;
+       iaddr_array = (befs_disk_inode_addr *) indir_block->b_data;
        *run = fsrun_to_cpu(sb, iaddr_array[block_indx]);
        brelse(indir_block);
        iaddr_array = NULL;
index 875cc0aa318c9c803ee70bd0fe64532fb80dedfa..e831a8f30849a98a088d46394742cc3b4c476182 100644 (file)
@@ -21,7 +21,6 @@
 #endif                         /* __KERNEL__ */
 
 #include "befs.h"
-#include "endian.h"
 
 #define ERRBUFSIZE 1024
 
@@ -125,7 +124,7 @@ befs_dump_inode(const struct super_block *sb, befs_inode * inode)
        befs_debug(sb, "  type %08x", fs32_to_cpu(sb, inode->type));
        befs_debug(sb, "  inode_size %u", fs32_to_cpu(sb, inode->inode_size));
 
-       if (S_ISLNK(inode->mode)) {
+       if (S_ISLNK(fs32_to_cpu(sb, inode->mode))) {
                befs_debug(sb, "  Symbolic link [%s]", inode->data.symlink);
        } else {
                int i;
@@ -231,21 +230,20 @@ befs_dump_small_data(const struct super_block *sb, befs_small_data * sd)
 
 /* unused */
 void
-befs_dump_run(const struct super_block *sb, befs_block_run run)
+befs_dump_run(const struct super_block *sb, befs_disk_block_run run)
 {
 #ifdef CONFIG_BEFS_DEBUG
 
-       run = fsrun_to_cpu(sb, run);
+       befs_block_run n = fsrun_to_cpu(sb, run);
 
-       befs_debug(sb, "[%u, %hu, %hu]",
-                  run.allocation_group, run.start, run.len);
+       befs_debug(sb, "[%u, %hu, %hu]", n.allocation_group, n.start, n.len);
 
 #endif                         //CONFIG_BEFS_DEBUG
 }
 #endif  /*  0  */
 
 void
-befs_dump_index_entry(const struct super_block *sb, befs_btree_super * super)
+befs_dump_index_entry(const struct super_block *sb, befs_disk_btree_super * super)
 {
 #ifdef CONFIG_BEFS_DEBUG
 
index 9ecaea4e3325f661fda861ebb78ade6b5c1385fb..e254a20869f4084bca2fd850af876919fd935ccb 100644 (file)
 #define LINUX_BEFS_ENDIAN
 
 #include <linux/byteorder/generic.h>
-#include "befs.h"
 
 static inline u64
-fs64_to_cpu(const struct super_block *sb, u64 n)
+fs64_to_cpu(const struct super_block *sb, fs64 n)
 {
        if (BEFS_SB(sb)->byte_order == BEFS_BYTESEX_LE)
-               return le64_to_cpu(n);
+               return le64_to_cpu((__force __le64)n);
        else
-               return be64_to_cpu(n);
+               return be64_to_cpu((__force __be64)n);
 }
 
-static inline u64
+static inline fs64
 cpu_to_fs64(const struct super_block *sb, u64 n)
 {
        if (BEFS_SB(sb)->byte_order == BEFS_BYTESEX_LE)
-               return cpu_to_le64(n);
+               return (__force fs64)cpu_to_le64(n);
        else
-               return cpu_to_be64(n);
+               return (__force fs64)cpu_to_be64(n);
 }
 
 static inline u32
-fs32_to_cpu(const struct super_block *sb, u32 n)
+fs32_to_cpu(const struct super_block *sb, fs32 n)
 {
        if (BEFS_SB(sb)->byte_order == BEFS_BYTESEX_LE)
-               return le32_to_cpu(n);
+               return le32_to_cpu((__force __le32)n);
        else
-               return be32_to_cpu(n);
+               return be32_to_cpu((__force __be32)n);
 }
 
-static inline u32
+static inline fs32
 cpu_to_fs32(const struct super_block *sb, u32 n)
 {
        if (BEFS_SB(sb)->byte_order == BEFS_BYTESEX_LE)
-               return cpu_to_le32(n);
+               return (__force fs32)cpu_to_le32(n);
        else
-               return cpu_to_be32(n);
+               return (__force fs32)cpu_to_be32(n);
 }
 
 static inline u16
-fs16_to_cpu(const struct super_block *sb, u16 n)
+fs16_to_cpu(const struct super_block *sb, fs16 n)
 {
        if (BEFS_SB(sb)->byte_order == BEFS_BYTESEX_LE)
-               return le16_to_cpu(n);
+               return le16_to_cpu((__force __le16)n);
        else
-               return be16_to_cpu(n);
+               return be16_to_cpu((__force __be16)n);
 }
 
-static inline u16
+static inline fs16
 cpu_to_fs16(const struct super_block *sb, u16 n)
 {
        if (BEFS_SB(sb)->byte_order == BEFS_BYTESEX_LE)
-               return cpu_to_le16(n);
+               return (__force fs16)cpu_to_le16(n);
        else
-               return cpu_to_be16(n);
+               return (__force fs16)cpu_to_be16(n);
 }
 
 /* Composite types below here */
 
 static inline befs_block_run
-fsrun_to_cpu(const struct super_block *sb, befs_block_run n)
+fsrun_to_cpu(const struct super_block *sb, befs_disk_block_run n)
 {
        befs_block_run run;
 
        if (BEFS_SB(sb)->byte_order == BEFS_BYTESEX_LE) {
-               run.allocation_group = le32_to_cpu(n.allocation_group);
-               run.start = le16_to_cpu(n.start);
-               run.len = le16_to_cpu(n.len);
+               run.allocation_group = le32_to_cpu((__force __le32)n.allocation_group);
+               run.start = le16_to_cpu((__force __le16)n.start);
+               run.len = le16_to_cpu((__force __le16)n.len);
        } else {
-               run.allocation_group = be32_to_cpu(n.allocation_group);
-               run.start = be16_to_cpu(n.start);
-               run.len = be16_to_cpu(n.len);
+               run.allocation_group = be32_to_cpu((__force __be32)n.allocation_group);
+               run.start = be16_to_cpu((__force __be16)n.start);
+               run.len = be16_to_cpu((__force __be16)n.len);
        }
        return run;
 }
 
-static inline befs_block_run
+static inline befs_disk_block_run
 cpu_to_fsrun(const struct super_block *sb, befs_block_run n)
 {
-       befs_block_run run;
+       befs_disk_block_run run;
 
        if (BEFS_SB(sb)->byte_order == BEFS_BYTESEX_LE) {
                run.allocation_group = cpu_to_le32(n.allocation_group);
@@ -103,7 +102,7 @@ cpu_to_fsrun(const struct super_block *sb, befs_block_run n)
 }
 
 static inline befs_data_stream
-fsds_to_cpu(const struct super_block *sb, befs_data_stream n)
+fsds_to_cpu(const struct super_block *sb, befs_disk_data_stream n)
 {
        befs_data_stream data;
        int i;
index d41c9247ae8af62764f7fa05226a68437bff7508..94c17f9a95767ca7a4d775bb5b662c9cd279f9ff 100644 (file)
@@ -8,7 +8,6 @@
 
 #include "befs.h"
 #include "inode.h"
-#include "endian.h"
 
 /*
        Validates the correctness of the befs inode
index 57020c7a7e6589fc84717d6015743bcbd9004627..07f7144f0e2e942feb736e33b315c8baae03cb20 100644 (file)
@@ -22,7 +22,6 @@
 #include "datastream.h"
 #include "super.h"
 #include "io.h"
-#include "endian.h"
 
 MODULE_DESCRIPTION("BeOS File System (BeFS) driver");
 MODULE_AUTHOR("Will Dyson");
index 4557acbac5283d2d5c26e818088b20d2863f6316..8c3401ff6d6a2a50013423feedff544b2f946f14 100644 (file)
@@ -11,7 +11,6 @@
 
 #include "befs.h"
 #include "super.h"
-#include "endian.h"
 
 /**
  * load_befs_sb -- Read from disk and properly byteswap all the fields
index 06435f3665f472f7a1e7ff4879627bff3064c740..79b05a1a436582ebfd2415a682cce4a322be00d5 100644 (file)
@@ -1152,7 +1152,7 @@ static int dump_write(struct file *file, const void *addr, int nr)
 static int dump_seek(struct file *file, loff_t off)
 {
        if (file->f_op->llseek && file->f_op->llseek != no_llseek) {
-               if (file->f_op->llseek(file, off, 1) != off)
+               if (file->f_op->llseek(file, off, SEEK_CUR) < 0)
                        return 0;
        } else {
                char *buf = (char *)get_zeroed_page(GFP_KERNEL);
@@ -1220,7 +1220,7 @@ static int notesize(struct memelfnote *en)
 
 static int alignfile(struct file *file, loff_t *foffset)
 {
-       char buf[4] = { 0, };
+       static const char buf[4] = { 0, };
        DUMP_WRITE(buf, roundup(*foffset, 4) - *foffset, foffset);
        return 1;
 }
@@ -1569,7 +1569,8 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file)
 
        DUMP_WRITE(elf, sizeof(*elf));
        offset += sizeof(*elf);                         /* Elf header */
-       offset += (segs+1) * sizeof(struct elf_phdr);   /* Program headers */
+       offset += (segs + 1) * sizeof(struct elf_phdr); /* Program headers */
+       foffset = offset;
 
        /* Write notes phdr entry */
        {
@@ -1586,8 +1587,6 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file)
                DUMP_WRITE(&phdr, sizeof(phdr));
        }
 
-       foffset = offset;
-
        dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE);
 
        /* Write program headers for segments dump */
@@ -1612,7 +1611,6 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file)
                phdr.p_align = ELF_EXEC_PAGESIZE;
 
                DUMP_WRITE(&phdr, sizeof(phdr));
-               foffset += sizeof(phdr);
        }
 
 #ifdef ELF_CORE_WRITE_EXTRA_PHDRS
index 8f93e939f21375abe2c205fd2783c319098cc87f..f95c8749499f9db7fe799594161a183ed9896910 100644 (file)
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -79,7 +79,6 @@ static struct bio_set *fs_bio_set;
 static inline struct bio_vec *bvec_alloc_bs(gfp_t gfp_mask, int nr, unsigned long *idx, struct bio_set *bs)
 {
        struct bio_vec *bvl;
-       struct biovec_slab *bp;
 
        /*
         * see comment near bvec_array define!
@@ -98,10 +97,12 @@ static inline struct bio_vec *bvec_alloc_bs(gfp_t gfp_mask, int nr, unsigned lon
         * idx now points to the pool we want to allocate from
         */
 
-       bp = bvec_slabs + *idx;
        bvl = mempool_alloc(bs->bvec_pools[*idx], gfp_mask);
-       if (bvl)
+       if (bvl) {
+               struct biovec_slab *bp = bvec_slabs + *idx;
+
                memset(bvl, 0, bp->nr_vecs * sizeof(struct bio_vec));
+       }
 
        return bvl;
 }
@@ -166,7 +167,7 @@ struct bio *bio_alloc_bioset(gfp_t gfp_mask, int nr_iovecs, struct bio_set *bs)
 
                bio_init(bio);
                if (likely(nr_iovecs)) {
-                       unsigned long idx;
+                       unsigned long idx = 0; /* shut up gcc */
 
                        bvl = bvec_alloc_bs(gfp_mask, nr_iovecs, &idx, bs);
                        if (unlikely(!bvl)) {
index 16cfbcd254f15fa05eb452eb512297c439605035..35527dca1dbcc415d95d76780537c577808df9ff 100644 (file)
@@ -452,6 +452,7 @@ static void end_buffer_async_write(struct buffer_head *bh, int uptodate)
                               bdevname(bh->b_bdev, b));
                }
                set_bit(AS_EIO, &page->mapping->flags);
+               set_buffer_write_io_error(bh);
                clear_buffer_uptodate(bh);
                SetPageError(page);
        }
@@ -571,6 +572,10 @@ EXPORT_SYMBOL(mark_buffer_async_write);
 static inline void __remove_assoc_queue(struct buffer_head *bh)
 {
        list_del_init(&bh->b_assoc_buffers);
+       WARN_ON(!bh->b_assoc_map);
+       if (buffer_write_io_error(bh))
+               set_bit(AS_EIO, &bh->b_assoc_map->flags);
+       bh->b_assoc_map = NULL;
 }
 
 int inode_has_buffers(struct inode *inode)
@@ -669,6 +674,7 @@ void mark_buffer_dirty_inode(struct buffer_head *bh, struct inode *inode)
                spin_lock(&buffer_mapping->private_lock);
                list_move_tail(&bh->b_assoc_buffers,
                                &mapping->private_list);
+               bh->b_assoc_map = mapping;
                spin_unlock(&buffer_mapping->private_lock);
        }
 }
@@ -701,7 +707,10 @@ EXPORT_SYMBOL(mark_buffer_dirty_inode);
  */
 int __set_page_dirty_buffers(struct page *page)
 {
-       struct address_space * const mapping = page->mapping;
+       struct address_space * const mapping = page_mapping(page);
+
+       if (unlikely(!mapping))
+               return !TestSetPageDirty(page);
 
        spin_lock(&mapping->private_lock);
        if (page_has_buffers(page)) {
@@ -762,7 +771,7 @@ static int fsync_buffers_list(spinlock_t *lock, struct list_head *list)
        spin_lock(lock);
        while (!list_empty(list)) {
                bh = BH_ENTRY(list->next);
-               list_del_init(&bh->b_assoc_buffers);
+               __remove_assoc_queue(bh);
                if (buffer_dirty(bh) || buffer_locked(bh)) {
                        list_add(&bh->b_assoc_buffers, &tmp);
                        if (buffer_dirty(bh)) {
@@ -783,7 +792,7 @@ static int fsync_buffers_list(spinlock_t *lock, struct list_head *list)
 
        while (!list_empty(&tmp)) {
                bh = BH_ENTRY(tmp.prev);
-               __remove_assoc_queue(bh);
+               list_del_init(&bh->b_assoc_buffers);
                get_bh(bh);
                spin_unlock(lock);
                wait_on_buffer(bh);
@@ -1039,8 +1048,21 @@ grow_buffers(struct block_device *bdev, sector_t block, int size)
        } while ((size << sizebits) < PAGE_SIZE);
 
        index = block >> sizebits;
-       block = index << sizebits;
 
+       /*
+        * Check for a block which wants to lie outside our maximum possible
+        * pagecache index.  (this comparison is done using sector_t types).
+        */
+       if (unlikely(index != block >> sizebits)) {
+               char b[BDEVNAME_SIZE];
+
+               printk(KERN_ERR "%s: requested out-of-range block %llu for "
+                       "device %s\n",
+                       __FUNCTION__, (unsigned long long)block,
+                       bdevname(bdev, b));
+               return -EIO;
+       }
+       block = index << sizebits;
        /* Create a page with the proper size buffers.. */
        page = grow_dev_page(bdev, block, index, size);
        if (!page)
@@ -1067,12 +1089,16 @@ __getblk_slow(struct block_device *bdev, sector_t block, int size)
 
        for (;;) {
                struct buffer_head * bh;
+               int ret;
 
                bh = __find_get_block(bdev, block, size);
                if (bh)
                        return bh;
 
-               if (!grow_buffers(bdev, block, size))
+               ret = grow_buffers(bdev, block, size);
+               if (ret < 0)
+                       return NULL;
+               if (ret == 0)
                        free_more_memory();
        }
 }
@@ -1147,6 +1173,7 @@ void __bforget(struct buffer_head *bh)
 
                spin_lock(&buffer_mapping->private_lock);
                list_del_init(&bh->b_assoc_buffers);
+               bh->b_assoc_map = NULL;
                spin_unlock(&buffer_mapping->private_lock);
        }
        __brelse(bh);
@@ -1834,6 +1861,7 @@ static int __block_prepare_write(struct inode *inode, struct page *page,
                        clear_buffer_new(bh);
                        kaddr = kmap_atomic(page, KM_USER0);
                        memset(kaddr+block_start, 0, bh->b_size);
+                       flush_dcache_page(page);
                        kunmap_atomic(kaddr, KM_USER0);
                        set_buffer_uptodate(bh);
                        mark_buffer_dirty(bh);
@@ -2340,6 +2368,7 @@ failed:
         */
        kaddr = kmap_atomic(page, KM_USER0);
        memset(kaddr, 0, PAGE_CACHE_SIZE);
+       flush_dcache_page(page);
        kunmap_atomic(kaddr, KM_USER0);
        SetPageUptodate(page);
        set_page_dirty(page);
index d0776ac2b8048938bcc58b0615b52b53e29a3c02..5eff35d6e564ac95550697f7b884a9612ac667ca 100644 (file)
@@ -31,8 +31,8 @@ struct cifs_sid {
 } __attribute__((packed));
 
 /* everyone */
-extern const struct cifs_sid sid_everyone;
+/* extern const struct cifs_sid sid_everyone;*/
 /* group users */
-extern const struct cifs_sid sid_user;
+/* extern const struct cifs_sid sid_user;*/
 
 #endif /* _CIFSACL_H */
index 03e359b3286117922f0a47aad41a9f1be1e6c823..152fa2dcfc6c70e80741f92be2e56ab7e5799226 100644 (file)
@@ -27,8 +27,6 @@ extern void mdfour(unsigned char *out, unsigned char *in, int n);
 /* smbdes.c */
 extern void E_P16(unsigned char *p14, unsigned char *p16);
 extern void E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24);
-extern void D_P16(unsigned char *p14, unsigned char *in, unsigned char *out);
-extern void E_old_pw_hash(unsigned char *, unsigned char *, unsigned char *);
 
 
 
index c00c654f2e11c0ce9cdbb3d597bb1afe9e673ddb..84976cdbe7136c4b76ad0777c924d44fd4b613cd 100644 (file)
@@ -63,6 +63,7 @@ extern struct task_struct * oplockThread; /* remove sparse warning */
 struct task_struct * oplockThread = NULL;
 extern struct task_struct * dnotifyThread; /* remove sparse warning */
 struct task_struct * dnotifyThread = NULL;
+static struct super_operations cifs_super_ops; 
 unsigned int CIFSMaxBufSize = CIFS_MAX_MSGSIZE;
 module_param(CIFSMaxBufSize, int, 0);
 MODULE_PARM_DESC(CIFSMaxBufSize,"Network buffer size (not including header). Default: 16384 Range: 8192 to 130048");
@@ -198,10 +199,12 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf)
     /* Only need to call the old QFSInfo if failed
     on newer one */
     if(rc)
-       rc = CIFSSMBQFSInfo(xid, pTcon, buf);
+       if(pTcon->ses->capabilities & CAP_NT_SMBS)
+               rc = CIFSSMBQFSInfo(xid, pTcon, buf); /* not supported by OS2 */
 
-       /* Old Windows servers do not support level 103, retry with level 
-          one if old server failed the previous call */ 
+       /* Some old Windows servers also do not support level 103, retry with
+          older level one if old server failed the previous call or we
+          bypassed it because we detected that this was an older LANMAN sess */
        if(rc)
                rc = SMBOldQFSInfo(xid, pTcon, buf);
        /*     
@@ -435,13 +438,21 @@ static void cifs_umount_begin(struct vfsmount * vfsmnt, int flags)
        return;
 }
 
+#ifdef CONFIG_CIFS_STATS2
+static int cifs_show_stats(struct seq_file *s, struct vfsmount *mnt)
+{
+       /* BB FIXME */
+       return 0;
+}
+#endif
+
 static int cifs_remount(struct super_block *sb, int *flags, char *data)
 {
        *flags |= MS_NODIRATIME;
        return 0;
 }
 
-struct super_operations cifs_super_ops = {
+static struct super_operations cifs_super_ops = {
        .read_inode = cifs_read_inode,
        .put_super = cifs_put_super,
        .statfs = cifs_statfs,
@@ -454,6 +465,9 @@ struct super_operations cifs_super_ops = {
        .show_options = cifs_show_options,
        .umount_begin   = cifs_umount_begin,
        .remount_fs = cifs_remount,
+#ifdef CONFIG_CIFS_STATS2
+       .show_stats = cifs_show_stats,
+#endif
 };
 
 static int
@@ -495,7 +509,7 @@ static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
 static loff_t cifs_llseek(struct file *file, loff_t offset, int origin)
 {
        /* origin == SEEK_END => we must revalidate the cached file length */
-       if (origin == 2) {
+       if (origin == SEEK_END) {
                int retval = cifs_revalidate(file->f_dentry);
                if (retval < 0)
                        return (loff_t)retval;
@@ -903,7 +917,7 @@ init_cifs(void)
 #ifdef CONFIG_PROC_FS
        cifs_proc_init();
 #endif
-       INIT_LIST_HEAD(&GlobalServerList);      /* BB not implemented yet */
+/*     INIT_LIST_HEAD(&GlobalServerList);*/    /* BB not implemented yet */
        INIT_LIST_HEAD(&GlobalSMBSessionList);
        INIT_LIST_HEAD(&GlobalTreeConnectionList);
        INIT_LIST_HEAD(&GlobalOplock_Q);
@@ -931,6 +945,7 @@ init_cifs(void)
        GlobalCurrentXid = 0;
        GlobalTotalActiveXid = 0;
        GlobalMaxActiveXid = 0;
+       memset(Local_System_Name, 0, 15);
        rwlock_init(&GlobalSMBSeslock);
        spin_lock_init(&GlobalMid_Lock);
 
index bea875d9a46acda0578f7c92f7c84232824a0ff0..a243f779b363a9a9cff261f65f23027dc9e30c15 100644 (file)
@@ -36,7 +36,7 @@ extern const struct address_space_operations cifs_addr_ops;
 extern const struct address_space_operations cifs_addr_ops_smallbuf;
 
 /* Functions related to super block operations */
-extern struct super_operations cifs_super_ops;
+/* extern struct super_operations cifs_super_ops;*/
 extern void cifs_read_inode(struct inode *);
 extern void cifs_delete_inode(struct inode *);
 /* extern void cifs_write_inode(struct inode *); *//* BB not needed yet */
index b24006c47df10b720cf2d05e98bda80c124c19c2..74d3ccbb103bfdbaf82b56cb03272ceebf9c022e 100644 (file)
@@ -153,7 +153,7 @@ struct TCP_Server_Info {
        char sessid[4];         /* unique token id for this session */
        /* (returned on Negotiate */
        int capabilities; /* allow selective disabling of caps by smb sess */
-       __u16 timeZone;
+       int timeAdj;  /* Adjust for difference in server time zone in sec */
        __u16 CurrentMid;         /* multiplex id - rotating counter */
        char cryptKey[CIFS_CRYPTO_KEY_SIZE];
        /* 16th byte of RFC1001 workstation name is always null */
@@ -203,9 +203,14 @@ struct cifsSesInfo {
        char * domainName;
        char * password;
 };
-/* session flags */
+/* no more than one of the following three session flags may be set */
 #define CIFS_SES_NT4 1
-
+#define CIFS_SES_OS2 2
+#define CIFS_SES_W9X 4
+/* following flag is set for old servers such as OS2 (and Win95?)
+   which do not negotiate NTLM or POSIX dialects, but instead
+   negotiate one of the older LANMAN dialects */
+#define CIFS_SES_LANMAN 8
 /*
  * there is one of these for each connection to a resource on a particular
  * session 
@@ -512,7 +517,8 @@ require use of the stronger protocol */
  * This list helps improve performance and eliminate the messages indicating
  * that we had a communications error talking to the server in this list. 
  */
-GLOBAL_EXTERN struct servers_not_supported *NotSuppList;       /*@z4a */
+/* Feature not supported */
+/* GLOBAL_EXTERN struct servers_not_supported *NotSuppList; */
 
 /*
  * The following is a hash table of all the users we know about.
@@ -568,7 +574,6 @@ GLOBAL_EXTERN unsigned int lookupCacheEnabled;
 GLOBAL_EXTERN unsigned int extended_security;  /* if on, session setup sent 
                                with more secure ntlmssp2 challenge/resp */
 GLOBAL_EXTERN unsigned int sign_CIFS_PDUs;  /* enable smb packet signing */
-GLOBAL_EXTERN unsigned int secFlags;
 GLOBAL_EXTERN unsigned int linuxExtEnabled;/*enable Linux/Unix CIFS extensions*/
 GLOBAL_EXTERN unsigned int CIFSMaxBufSize;  /* max size not including hdr */
 GLOBAL_EXTERN unsigned int cifs_min_rcv;    /* min size of big ntwrk buf pool */
index 81df2bf8e75a70d222f85757c5afdd1df9f20246..6df9dadba647035ad58f719a5e322bca1b9ac8de 100644 (file)
@@ -26,7 +26,8 @@
 
 #ifdef CONFIG_CIFS_WEAK_PW_HASH
 #define LANMAN_PROT 0
-#define CIFS_PROT   1
+#define LANMAN2_PROT 1
+#define CIFS_PROT   2
 #else
 #define CIFS_PROT   0
 #endif
@@ -408,6 +409,8 @@ typedef struct negotiate_req {
 
 /* Dialect index is 13 for LANMAN */
 
+#define MIN_TZ_ADJ (15 * 60) /* minimum grid for timezones in seconds */
+
 typedef struct lanman_neg_rsp {
        struct smb_hdr hdr;     /* wct = 13 */
        __le16 DialectIndex;
@@ -417,7 +420,10 @@ typedef struct lanman_neg_rsp {
        __le16 MaxNumberVcs;
        __le16 RawMode;
        __le32 SessionKey;
-       __le32 ServerTime;
+       struct {
+               __le16 Time;
+               __le16 Date;
+       } __attribute__((packed)) SrvTime;
        __le16 ServerTimeZone;
        __le16 EncryptionKeyLength;
        __le16 Reserved;
@@ -674,7 +680,7 @@ typedef union smb_com_tree_disconnect {     /* as an altetnative can use flag on
 typedef struct smb_com_close_req {
        struct smb_hdr hdr;     /* wct = 3 */
        __u16 FileID;
-       __u32 LastWriteTime;    /* should be zero */
+       __u32 LastWriteTime;    /* should be zero or -1 */
        __u16 ByteCount;        /* 0 */
 } __attribute__((packed)) CLOSE_REQ;
 
index b35c55c3c8bb9d76b1afc8ae9e13189d2f3f6071..f1f8225102f0a6dead4670ef95c6fa42fe0917e3 100644 (file)
@@ -50,12 +50,12 @@ extern int SendReceive(const unsigned int /* xid */ , struct cifsSesInfo *,
 extern int SendReceive2(const unsigned int /* xid */ , struct cifsSesInfo *,
                        struct kvec *, int /* nvec to send */, 
                        int * /* type of buf returned */ , const int long_op);
-extern int SendReceiveBlockingLock(const unsigned int /* xid */ , struct cifsTconInfo *,
+extern int SendReceiveBlockingLock(const unsigned int /* xid */ , 
+                                       struct cifsTconInfo *,
                                struct smb_hdr * /* input */ ,
                                struct smb_hdr * /* out */ ,
                                int * /* bytes returned */);
-extern int checkSMBhdr(struct smb_hdr *smb, __u16 mid);
-extern int checkSMB(struct smb_hdr *smb, __u16 mid, int length);
+extern int checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length);
 extern int is_valid_oplock_break(struct smb_hdr *smb, struct TCP_Server_Info *);
 extern int is_size_safe_to_change(struct cifsInodeInfo *);
 extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *);
@@ -80,6 +80,9 @@ extern struct oplock_q_entry * AllocOplockQEntry(struct inode *, u16,
 extern void DeleteOplockQEntry(struct oplock_q_entry *);
 extern struct timespec cifs_NTtimeToUnix(u64 /* utc nanoseconds since 1601 */ );
 extern u64 cifs_UnixTimeToNT(struct timespec);
+extern __le64 cnvrtDosCifsTm(__u16 date, __u16 time);
+extern struct timespec cnvrtDosUnixTm(__u16 date, __u16 time);
+
 extern int cifs_get_inode_info(struct inode **pinode,
                        const unsigned char *search_path, 
                        FILE_ALL_INFO * pfile_info,
@@ -116,6 +119,7 @@ extern int CIFSFindClose(const int, struct cifsTconInfo *tcon,
 extern int CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
                        const unsigned char *searchName,
                        FILE_ALL_INFO * findData,
+                       int legacy /* whether to use old info level */,
                        const struct nls_table *nls_codepage, int remap);
 extern int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon,
                         const unsigned char *searchName,
@@ -279,8 +283,6 @@ extern void sesInfoFree(struct cifsSesInfo *);
 extern struct cifsTconInfo *tconInfoAlloc(void);
 extern void tconInfoFree(struct cifsTconInfo *);
 
-extern int cifs_reconnect(struct TCP_Server_Info *server);
-
 extern int cifs_sign_smb(struct smb_hdr *, struct TCP_Server_Info *,__u32 *);
 extern int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *,
                          __u32 *);
index 075d8fb3d37608a96d0610c519794388351d1173..098790eb2aa161967538c91b734c3fe45fa5d8b7 100644 (file)
@@ -46,6 +46,7 @@ static struct {
 } protocols[] = {
 #ifdef CONFIG_CIFS_WEAK_PW_HASH
        {LANMAN_PROT, "\2LM1.2X002"},
+       {LANMAN2_PROT, "\2LANMAN2.1"},
 #endif /* weak password hashing for legacy clients */
        {CIFS_PROT, "\2NT LM 0.12"}, 
        {POSIX_PROT, "\2POSIX 2"},
@@ -58,6 +59,7 @@ static struct {
 } protocols[] = {
 #ifdef CONFIG_CIFS_WEAK_PW_HASH
        {LANMAN_PROT, "\2LM1.2X002"},
+       {LANMAN2_PROT, "\2LANMAN2.1"},
 #endif /* weak password hashing for legacy clients */
        {CIFS_PROT, "\2NT LM 0.12"}, 
        {BAD_PROT, "\2"}
@@ -67,13 +69,13 @@ static struct {
 /* define the number of elements in the cifs dialect array */
 #ifdef CONFIG_CIFS_POSIX
 #ifdef CONFIG_CIFS_WEAK_PW_HASH
-#define CIFS_NUM_PROT 3
+#define CIFS_NUM_PROT 4
 #else
 #define CIFS_NUM_PROT 2
 #endif /* CIFS_WEAK_PW_HASH */
 #else /* not posix */
 #ifdef CONFIG_CIFS_WEAK_PW_HASH
-#define CIFS_NUM_PROT 2
+#define CIFS_NUM_PROT 3
 #else
 #define CIFS_NUM_PROT 1
 #endif /* CONFIG_CIFS_WEAK_PW_HASH */
@@ -397,6 +399,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
        struct TCP_Server_Info * server;
        u16 count;
        unsigned int secFlags;
+       u16 dialect;
 
        if(ses->server)
                server = ses->server;
@@ -436,9 +439,10 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
        if (rc != 0) 
                goto neg_err_exit;
 
-       cFYI(1,("Dialect: %d", pSMBr->DialectIndex));
+       dialect = le16_to_cpu(pSMBr->DialectIndex);
+       cFYI(1,("Dialect: %d", dialect));
        /* Check wct = 1 error case */
-       if((pSMBr->hdr.WordCount < 13) || (pSMBr->DialectIndex == BAD_PROT)) {
+       if((pSMBr->hdr.WordCount < 13) || (dialect == BAD_PROT)) {
                /* core returns wct = 1, but we do not ask for core - otherwise
                small wct just comes when dialect index is -1 indicating we 
                could not negotiate a common dialect */
@@ -446,7 +450,9 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
                goto neg_err_exit;
 #ifdef CONFIG_CIFS_WEAK_PW_HASH 
        } else if((pSMBr->hdr.WordCount == 13)
-                       && (pSMBr->DialectIndex == LANMAN_PROT)) {
+                       && ((dialect == LANMAN_PROT)
+                               || (dialect == LANMAN2_PROT))) {
+               __s16 tmp;
                struct lanman_neg_rsp * rsp = (struct lanman_neg_rsp *)pSMBr;
 
                if((secFlags & CIFSSEC_MAY_LANMAN) || 
@@ -472,12 +478,44 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
                        server->maxRw = 0;/* we do not need to use raw anyway */
                        server->capabilities = CAP_MPX_MODE;
                }
-               server->timeZone = le16_to_cpu(rsp->ServerTimeZone);
+               tmp = (__s16)le16_to_cpu(rsp->ServerTimeZone);
+               if (tmp == -1) {
+                       /* OS/2 often does not set timezone therefore
+                        * we must use server time to calc time zone.
+                        * Could deviate slightly from the right zone.
+                        * Smallest defined timezone difference is 15 minutes
+                        * (i.e. Nepal).  Rounding up/down is done to match
+                        * this requirement.
+                        */
+                       int val, seconds, remain, result;
+                       struct timespec ts, utc;
+                       utc = CURRENT_TIME;
+                       ts = cnvrtDosUnixTm(le16_to_cpu(rsp->SrvTime.Date),
+                                               le16_to_cpu(rsp->SrvTime.Time));
+                       cFYI(1,("SrvTime: %d sec since 1970 (utc: %d) diff: %d",
+                               (int)ts.tv_sec, (int)utc.tv_sec, 
+                               (int)(utc.tv_sec - ts.tv_sec)));
+                       val = (int)(utc.tv_sec - ts.tv_sec);
+                       seconds = val < 0 ? -val : val;
+                       result = (seconds / MIN_TZ_ADJ) * MIN_TZ_ADJ;
+                       remain = seconds % MIN_TZ_ADJ;
+                       if(remain >= (MIN_TZ_ADJ / 2))
+                               result += MIN_TZ_ADJ;
+                       if(val < 0)
+                               result = - result;
+                       server->timeAdj = result;
+               } else {
+                       server->timeAdj = (int)tmp;
+                       server->timeAdj *= 60; /* also in seconds */
+               }
+               cFYI(1,("server->timeAdj: %d seconds", server->timeAdj));
+
 
                /* BB get server time for time conversions and add
                code to use it and timezone since this is not UTC */    
 
-               if (rsp->EncryptionKeyLength == cpu_to_le16(CIFS_CRYPTO_KEY_SIZE)) {
+               if (rsp->EncryptionKeyLength == 
+                               cpu_to_le16(CIFS_CRYPTO_KEY_SIZE)) {
                        memcpy(server->cryptKey, rsp->EncryptionKey,
                                CIFS_CRYPTO_KEY_SIZE);
                } else if (server->secMode & SECMODE_PW_ENCRYPT) {
@@ -531,7 +569,8 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
        cFYI(0, ("Max buf = %d", ses->server->maxBuf));
        GETU32(ses->server->sessid) = le32_to_cpu(pSMBr->SessionKey);
        server->capabilities = le32_to_cpu(pSMBr->Capabilities);
-       server->timeZone = le16_to_cpu(pSMBr->ServerTimeZone);  
+       server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone);
+       server->timeAdj *= 60;
        if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) {
                memcpy(server->cryptKey, pSMBr->u.EncryptionKey,
                       CIFS_CRYPTO_KEY_SIZE);
@@ -1617,7 +1656,7 @@ CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
        pSMBr = (CLOSE_RSP *)pSMB; /* BB removeme BB */
 
        pSMB->FileID = (__u16) smb_file_id;
-       pSMB->LastWriteTime = 0;
+       pSMB->LastWriteTime = 0xFFFFFFFF;
        pSMB->ByteCount = 0;
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
@@ -2773,9 +2812,11 @@ GetExtAttrOut:
 
 
 /* security id for everyone */
-const struct cifs_sid sid_everyone = {1, 1, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0}};
+const static struct cifs_sid sid_everyone = 
+               {1, 1, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0}};
 /* group users */
-const struct cifs_sid sid_user = {1, 2 , {0, 0, 0, 0, 0, 5}, {32, 545, 0, 0}};
+const static struct cifs_sid sid_user = 
+               {1, 2 , {0, 0, 0, 0, 0, 5}, {32, 545, 0, 0}};
 
 /* Convert CIFS ACL to POSIX form */
 static int parse_sec_desc(struct cifs_sid * psec_desc, int acl_len)
@@ -2856,7 +2897,6 @@ qsec_out:
        return rc;
 }
 
-
 /* Legacy Query Path Information call for lookup to old servers such
    as Win9x/WinME */
 int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon,
@@ -2898,7 +2938,16 @@ QInfRetry:
        if (rc) {
                cFYI(1, ("Send error in QueryInfo = %d", rc));
        } else if (pFinfo) {            /* decode response */
+               struct timespec ts;
+               __u32 time = le32_to_cpu(pSMBr->last_write_time);
+               /* BB FIXME - add time zone adjustment BB */
                memset(pFinfo, 0, sizeof(FILE_ALL_INFO));
+               ts.tv_nsec = 0;
+               ts.tv_sec = time;
+               /* decode time fields */
+               pFinfo->ChangeTime = cpu_to_le64(cifs_UnixTimeToNT(ts));
+               pFinfo->LastWriteTime = pFinfo->ChangeTime;
+               pFinfo->LastAccessTime = 0;
                pFinfo->AllocationSize =
                        cpu_to_le64(le32_to_cpu(pSMBr->size));
                pFinfo->EndOfFile = pFinfo->AllocationSize;
@@ -2922,6 +2971,7 @@ int
 CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
                 const unsigned char *searchName,
                 FILE_ALL_INFO * pFindData,
+                int legacy /* old style infolevel */,
                 const struct nls_table *nls_codepage, int remap)
 {
 /* level 263 SMB_QUERY_FILE_ALL_INFO */
@@ -2970,7 +3020,10 @@ QPathInfoRetry:
        byte_count = params + 1 /* pad */ ;
        pSMB->TotalParameterCount = cpu_to_le16(params);
        pSMB->ParameterCount = pSMB->TotalParameterCount;
-       pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
+       if(legacy)
+               pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD);
+       else
+               pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
        pSMB->Reserved4 = 0;
        pSMB->hdr.smb_buf_length += byte_count;
        pSMB->ByteCount = cpu_to_le16(byte_count);
@@ -2982,13 +3035,24 @@ QPathInfoRetry:
        } else {                /* decode response */
                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
 
-               if (rc || (pSMBr->ByteCount < 40)) 
+               if (rc) /* BB add auto retry on EOPNOTSUPP? */
+                       rc = -EIO;
+               else if (!legacy && (pSMBr->ByteCount < 40)) 
                        rc = -EIO;      /* bad smb */
+               else if(legacy && (pSMBr->ByteCount < 24))
+                       rc = -EIO;  /* 24 or 26 expected but we do not read last field */
                else if (pFindData){
+                       int size;
                        __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
+                       if(legacy) /* we do not read the last field, EAsize, fortunately
+                                          since it varies by subdialect and on Set vs. Get, is  
+                                          two bytes or 4 bytes depending but we don't care here */
+                               size = sizeof(FILE_INFO_STANDARD);
+                       else
+                               size = sizeof(FILE_ALL_INFO);
                        memcpy((char *) pFindData,
                               (char *) &pSMBr->hdr.Protocol +
-                              data_offset, sizeof (FILE_ALL_INFO));
+                              data_offset, size);
                } else
                    rc = -ENOMEM;
        }
@@ -3613,6 +3677,14 @@ getDFSRetry:
                strncpy(pSMB->RequestFileName, searchName, name_len);
        }
 
+       if(ses->server) {
+               if(ses->server->secMode &
+                  (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
+                       pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
+       }
+
+        pSMB->hdr.Uid = ses->Suid;
+
        params = 2 /* level */  + name_len /*includes null */ ;
        pSMB->TotalDataCount = 0;
        pSMB->DataCount = 0;
index c78762051da4e5b15da45fa06b46b66d85e55d82..4093d53329306bfc74c0487e06c09d434d7043a6 100644 (file)
@@ -109,7 +109,7 @@ static int ipv6_connect(struct sockaddr_in6 *psin_server,
         * wake up waiters on reconnection? - (not needed currently)
         */
 
-int
+static int
 cifs_reconnect(struct TCP_Server_Info *server)
 {
        int rc = 0;
@@ -771,13 +771,18 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
        separator[0] = ',';
        separator[1] = 0; 
 
-       memset(vol->source_rfc1001_name,0x20,15);
-       for(i=0;i < strnlen(utsname()->nodename,15);i++) {
-               /* does not have to be a perfect mapping since the field is
-               informational, only used for servers that do not support
-               port 445 and it can be overridden at mount time */
-               vol->source_rfc1001_name[i] = 
-                       toupper(utsname()->nodename[i]);
+       if (Local_System_Name[0] != 0)
+               memcpy(vol->source_rfc1001_name, Local_System_Name,15);
+       else {
+               char *nodename = utsname()->nodename;
+               int n = strnlen(nodename,15);
+               memset(vol->source_rfc1001_name,0x20,15);
+               for(i=0 ; i < n ; i++) {
+                       /* does not have to be perfect mapping since field is
+                       informational, only used for servers that do not support
+                       port 445 and it can be overridden at mount time */
+                       vol->source_rfc1001_name[i] = toupper(nodename[i]);
+               }
        }
        vol->source_rfc1001_name[15] = 0;
        /* null target name indicates to use *SMBSERVR default called name
@@ -3215,7 +3220,9 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
                        }
                        /* else do not bother copying these informational fields */
                }
-               if(smb_buffer_response->WordCount == 3)
+               if((smb_buffer_response->WordCount == 3) ||
+                        (smb_buffer_response->WordCount == 7))
+                       /* field is in same location */
                        tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport);
                else
                        tcon->Flags = 0;
@@ -3312,19 +3319,21 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
                first_time = 1;
        }
        if (!rc) {
+               pSesInfo->flags = 0;
                pSesInfo->capabilities = pSesInfo->server->capabilities;
                if(linuxExtEnabled == 0)
                        pSesInfo->capabilities &= (~CAP_UNIX);
        /*      pSesInfo->sequence_number = 0;*/
-               cFYI(1,("Security Mode: 0x%x Capabilities: 0x%x Time Zone: %d",
+               cFYI(1,("Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d",
                        pSesInfo->server->secMode,
                        pSesInfo->server->capabilities,
-                       pSesInfo->server->timeZone));
+                       pSesInfo->server->timeAdj));
                if(experimEnabled < 2)
                        rc = CIFS_SessSetup(xid, pSesInfo,
                                            first_time, nls_info);
                else if (extended_security
-                               && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY)
+                               && (pSesInfo->capabilities 
+                                       & CAP_EXTENDED_SECURITY)
                                && (pSesInfo->server->secType == NTLMSSP)) {
                        rc = -EOPNOTSUPP;
                } else if (extended_security
@@ -3338,7 +3347,7 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
                        if (!rc) {
                                if(ntlmv2_flag) {
                                        char * v2_response;
-                                       cFYI(1,("Can use more secure NTLM version 2 password hash"));
+                                       cFYI(1,("more secure NTLM ver2 hash"));
                                        if(CalcNTLMv2_partial_mac_key(pSesInfo, 
                                                nls_info)) {
                                                rc = -ENOMEM;
index 6b90ef98e4cfe9cdfcd224bdb0a2df202b66612f..35d54bb0869ab67510449f4a412aa0018c9fcfc8 100644 (file)
@@ -337,6 +337,7 @@ int cifs_get_inode_info(struct inode **pinode,
                pfindData = (FILE_ALL_INFO *)buf;
                /* could do find first instead but this returns more info */
                rc = CIFSSMBQPathInfo(xid, pTcon, search_path, pfindData,
+                             0 /* not legacy */,
                              cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
                                CIFS_MOUNT_MAP_SPECIAL_CHR);
                /* BB optimize code so we do not make the above call
@@ -384,8 +385,10 @@ int cifs_get_inode_info(struct inode **pinode,
                /* get new inode */
                if (*pinode == NULL) {
                        *pinode = new_inode(sb);
-                       if (*pinode == NULL)
+                       if (*pinode == NULL) {
+                               kfree(buf);
                                return -ENOMEM;
+                       }
                        /* Is an i_ino of zero legal? Can we use that to check
                           if the server supports returning inode numbers?  Are
                           there other sanity checks we can use to ensure that
@@ -431,8 +434,11 @@ int cifs_get_inode_info(struct inode **pinode,
                (pTcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFE00;*/
 
                /* Linux can not store file creation time so ignore it */
-               inode->i_atime =
-                   cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastAccessTime));
+               if(pfindData->LastAccessTime)
+                       inode->i_atime = cifs_NTtimeToUnix
+                               (le64_to_cpu(pfindData->LastAccessTime));
+               else /* do not need to use current_fs_time - time not stored */
+                       inode->i_atime = CURRENT_TIME;
                inode->i_mtime =
                    cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastWriteTime));
                inode->i_ctime =
index a57f5d6e6213d6f23e693c88a98c3d539eb4ae6a..0bee8b7e521a2a153fa50e03bde68ec69865a364 100644 (file)
@@ -254,7 +254,11 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen)
                                tmpbuffer,
                                len - 1,
                                cifs_sb->local_nls);
-       else {
+       else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
+               cERROR(1,("SFU style symlinks not implemented yet"));
+               /* add open and read as in fs/cifs/inode.c */
+       
+       } else {
                rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, GENERIC_READ,
                                OPEN_REPARSE_POINT,&fid, &oplock, NULL, 
                                cifs_sb->local_nls, 
index 7aa23490541f9d68edee8c465e489ec79ab4b95f..ccebf9b7eb86e2293d0cd52ee15137b6dbdd4ad4 100644 (file)
@@ -252,10 +252,11 @@ MD5Transform(__u32 buf[4], __u32 const in[16])
        buf[3] += d;
 }
 
+#if 0   /* currently unused */
 /***********************************************************************
  the rfc 2104 version of hmac_md5 initialisation.
 ***********************************************************************/
-void
+static void
 hmac_md5_init_rfc2104(unsigned char *key, int key_len,
                      struct HMACMD5Context *ctx)
 {
@@ -289,6 +290,7 @@ hmac_md5_init_rfc2104(unsigned char *key, int key_len,
        MD5Init(&ctx->ctx);
        MD5Update(&ctx->ctx, ctx->k_ipad, 64);
 }
+#endif
 
 /***********************************************************************
  the microsoft version of hmac_md5 initialisation.
@@ -350,7 +352,8 @@ hmac_md5_final(unsigned char *digest, struct HMACMD5Context *ctx)
  single function to calculate an HMAC MD5 digest from data.
  use the microsoft hmacmd5 init method because the key is 16 bytes.
 ************************************************************/
-void
+#if 0 /* currently unused */
+static void
 hmac_md5(unsigned char key[16], unsigned char *data, int data_len,
         unsigned char *digest)
 {
@@ -361,3 +364,4 @@ hmac_md5(unsigned char key[16], unsigned char *data, int data_len,
        }
        hmac_md5_final(digest, &ctx);
 }
+#endif
index 00e1c5394fe1e8977d031f08a3e74f92b9ae10cc..f7d4f4197bac3cc6973e8c1c5de2ddc9c8721493 100644 (file)
@@ -27,12 +27,12 @@ void MD5Final(unsigned char digest[16], struct MD5Context *context);
 
 /* The following definitions come from lib/hmacmd5.c  */
 
-void hmac_md5_init_rfc2104(unsigned char *key, int key_len,
-                       struct HMACMD5Context *ctx);
+/* void hmac_md5_init_rfc2104(unsigned char *key, int key_len,
+                       struct HMACMD5Context *ctx);*/
 void hmac_md5_init_limK_to_64(const unsigned char *key, int key_len,
                        struct HMACMD5Context *ctx);
 void hmac_md5_update(const unsigned char *text, int text_len,
                        struct HMACMD5Context *ctx);
 void hmac_md5_final(unsigned char *digest, struct HMACMD5Context *ctx);
-void hmac_md5(unsigned char key[16], unsigned char *data, int data_len,
-                       unsigned char *digest);
+/* void hmac_md5(unsigned char key[16], unsigned char *data, int data_len,
+                       unsigned char *digest);*/
index 22c937e5884f36baf85e49cb9f3c3fc014de4522..bbc9cd34b6ea42f02d85e9e31c140824b4ab5dd8 100644 (file)
@@ -389,7 +389,7 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
        return;
 }
 
-int
+static int
 checkSMBhdr(struct smb_hdr *smb, __u16 mid)
 {
        /* Make sure that this really is an SMB, that it is a response, 
@@ -418,26 +418,42 @@ checkSMBhdr(struct smb_hdr *smb, __u16 mid)
 }
 
 int
-checkSMB(struct smb_hdr *smb, __u16 mid, int length)
+checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length)
 {
        __u32 len = smb->smb_buf_length;
        __u32 clc_len;  /* calculated length */
        cFYI(0, ("checkSMB Length: 0x%x, smb_buf_length: 0x%x", length, len));
-       if (((unsigned int)length < 2 + sizeof (struct smb_hdr)) ||
-           (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4)) {
-               if ((unsigned int)length < 2 + sizeof (struct smb_hdr)) {
-                       if (((unsigned int)length >= 
-                               sizeof (struct smb_hdr) - 1)
+
+       if (length < 2 + sizeof (struct smb_hdr)) {
+               if ((length >= sizeof (struct smb_hdr) - 1)
                            && (smb->Status.CifsError != 0)) {
-                               smb->WordCount = 0;
-                               /* some error cases do not return wct and bcc */
+                       smb->WordCount = 0;
+                       /* some error cases do not return wct and bcc */
+                       return 0;
+               } else if ((length == sizeof(struct smb_hdr) + 1) && 
+                               (smb->WordCount == 0)) {
+                       char * tmp = (char *)smb;
+                       /* Need to work around a bug in two servers here */
+                       /* First, check if the part of bcc they sent was zero */
+                       if (tmp[sizeof(struct smb_hdr)] == 0) {
+                               /* some servers return only half of bcc
+                                * on simple responses (wct, bcc both zero)
+                                * in particular have seen this on
+                                * ulogoffX and FindClose. This leaves
+                                * one byte of bcc potentially unitialized
+                                */
+                               /* zero rest of bcc */
+                               tmp[sizeof(struct smb_hdr)+1] = 0;
                                return 0;
-                       } else {
-                               cERROR(1, ("Length less than smb header size"));
                        }
+                       cERROR(1,("rcvd invalid byte count (bcc)"));
+               } else {
+                       cERROR(1, ("Length less than smb header size"));
                }
-               if (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4)
-                       cERROR(1, ("smb length greater than MaxBufSize, mid=%d",
+               return 1;
+       }
+       if (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) {
+               cERROR(1, ("smb length greater than MaxBufSize, mid=%d",
                                   smb->Mid));
                return 1;
        }
@@ -446,7 +462,7 @@ checkSMB(struct smb_hdr *smb, __u16 mid, int length)
                return 1;
        clc_len = smbCalcSize_LE(smb);
 
-       if(4 + len != (unsigned int)length) {
+       if(4 + len != length) {
                cERROR(1, ("Length read does not match RFC1001 length %d",len));
                return 1;
        }
index ce87550e918f8d33d87573677287e24d2da234e9..992e80edc720bb782cc13d5dcb1843691a240adf 100644 (file)
@@ -909,3 +909,61 @@ cifs_UnixTimeToNT(struct timespec t)
        /* Convert to 100ns intervals and then add the NTFS time offset. */
        return (u64) t.tv_sec * 10000000 + t.tv_nsec/100 + NTFS_TIME_OFFSET;
 }
+
+static int total_days_of_prev_months[] =
+{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
+
+
+__le64 cnvrtDosCifsTm(__u16 date, __u16 time)
+{
+       return cpu_to_le64(cifs_UnixTimeToNT(cnvrtDosUnixTm(date, time)));
+}
+
+struct timespec cnvrtDosUnixTm(__u16 date, __u16 time)
+{
+       struct timespec ts;
+       int sec, min, days, month, year;
+       SMB_TIME * st = (SMB_TIME *)&time;
+       SMB_DATE * sd = (SMB_DATE *)&date;
+
+       cFYI(1,("date %d time %d",date, time));
+
+       sec = 2 * st->TwoSeconds;
+       min = st->Minutes;
+       if((sec > 59) || (min > 59))
+               cERROR(1,("illegal time min %d sec %d", min, sec));
+       sec += (min * 60);
+       sec += 60 * 60 * st->Hours;
+       if(st->Hours > 24)
+               cERROR(1,("illegal hours %d",st->Hours));
+       days = sd->Day;
+       month = sd->Month;
+       if((days > 31) || (month > 12))
+               cERROR(1,("illegal date, month %d day: %d", month, days));
+       month -= 1;
+       days += total_days_of_prev_months[month];
+       days += 3652; /* account for difference in days between 1980 and 1970 */
+       year = sd->Year;
+       days += year * 365;
+       days += (year/4); /* leap year */
+       /* generalized leap year calculation is more complex, ie no leap year
+       for years/100 except for years/400, but since the maximum number for DOS
+        year is 2**7, the last year is 1980+127, which means we need only
+        consider 2 special case years, ie the years 2000 and 2100, and only
+        adjust for the lack of leap year for the year 2100, as 2000 was a 
+        leap year (divisable by 400) */
+       if(year >= 120)  /* the year 2100 */
+               days = days - 1;  /* do not count leap year for the year 2100 */
+
+       /* adjust for leap year where we are still before leap day */
+       if(year != 120)
+               days -= ((year & 0x03) == 0) && (month < 2 ? 1 : 0);
+       sec += 24 * 60 * 60 * days; 
+
+       ts.tv_sec = sec;
+
+       /* cFYI(1,("sec after cnvrt dos to unix time %d",sec)); */
+
+       ts.tv_nsec = 0;
+       return ts;
+} 
index b27b34537bf23c2bf3bbc566c1155c3d331df7a1..b5b0a2a41befe85734ffc30dc47f68f76bf05790 100644 (file)
@@ -106,6 +106,17 @@ static int construct_dentry(struct qstr *qstring, struct file *file,
        return rc;
 }
 
+static void AdjustForTZ(struct cifsTconInfo * tcon, struct inode * inode)
+{
+       if((tcon) && (tcon->ses) && (tcon->ses->server)) {
+               inode->i_ctime.tv_sec += tcon->ses->server->timeAdj;
+               inode->i_mtime.tv_sec += tcon->ses->server->timeAdj;
+               inode->i_atime.tv_sec += tcon->ses->server->timeAdj;
+       }
+       return;
+}
+
+
 static void fill_in_inode(struct inode *tmp_inode, int new_buf_type,
                char * buf, int *pobject_type, int isNewInode)
 {
@@ -135,16 +146,23 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type,
                tmp_inode->i_ctime =
                      cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime));
        } else { /* legacy, OS2 and DOS style */
+/*             struct timespec ts;*/
                FIND_FILE_STANDARD_INFO * pfindData = 
                        (FIND_FILE_STANDARD_INFO *)buf;
 
+               tmp_inode->i_mtime = cnvrtDosUnixTm(
+                               le16_to_cpu(pfindData->LastWriteDate),
+                               le16_to_cpu(pfindData->LastWriteTime));
+               tmp_inode->i_atime = cnvrtDosUnixTm(
+                               le16_to_cpu(pfindData->LastAccessDate),
+                               le16_to_cpu(pfindData->LastAccessTime));
+                tmp_inode->i_ctime = cnvrtDosUnixTm(
+                                le16_to_cpu(pfindData->LastWriteDate),
+                                le16_to_cpu(pfindData->LastWriteTime));
+               AdjustForTZ(cifs_sb->tcon, tmp_inode);
                attr = le16_to_cpu(pfindData->Attributes);
                allocation_size = le32_to_cpu(pfindData->AllocationSize);
                end_of_file = le32_to_cpu(pfindData->DataSize);
-               tmp_inode->i_atime = CURRENT_TIME;
-               /* tmp_inode->i_mtime =  BB FIXME - add dos time handling
-               tmp_inode->i_ctime = 0;   BB FIXME */
-
        }
 
        /* Linux can not store file creation time unfortunately so ignore it */
@@ -938,6 +956,7 @@ static int cifs_save_resume_key(const char *current_entry,
                filename = &pFindData->FileName[0];
                /* one byte length, no name conversion */
                len = (unsigned int)pFindData->FileNameLength;
+               cifsFile->srch_inf.resume_key = pFindData->ResumeKey;
        } else {
                cFYI(1,("Unknown findfirst level %d",level));
                return -EINVAL;
index 22b4c35dcfe3e4bfbc067b56880f5fb958df50ae..a8a083543ba050fa65cceee9a302c9b733f68311 100644 (file)
@@ -268,6 +268,10 @@ static int decode_ascii_ssetup(char ** pbcc_area, int bleft, struct cifsSesInfo
        ses->serverOS = kzalloc(len + 1, GFP_KERNEL);
        if(ses->serverOS)
                strncpy(ses->serverOS, bcc_ptr, len);
+       if(strncmp(ses->serverOS, "OS/2",4) == 0) {
+                       cFYI(1,("OS/2 server"));
+                       ses->flags |= CIFS_SES_OS2;
+       }
 
        bcc_ptr += len + 1;
        bleft -= len + 1;
@@ -290,16 +294,11 @@ static int decode_ascii_ssetup(char ** pbcc_area, int bleft, struct cifsSesInfo
         if(len > bleft)
                 return rc;
 
-        if(ses->serverDomain)
-                kfree(ses->serverDomain);
-
-        ses->serverDomain = kzalloc(len + 1, GFP_KERNEL);
-        if(ses->serverOS)
-                strncpy(ses->serverOS, bcc_ptr, len);
-
-        bcc_ptr += len + 1;
-       bleft -= len + 1;
-
+       /* No domain field in LANMAN case. Domain is
+          returned by old servers in the SMB negprot response */
+       /* BB For newer servers which do not support Unicode,
+          but thus do return domain here we could add parsing
+          for it later, but it is not very important */
        cFYI(1,("ascii: bytes left %d",bleft));
 
        return rc;
@@ -366,6 +365,8 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
        str_area = kmalloc(2000, GFP_KERNEL);
        bcc_ptr = str_area;
 
+       ses->flags &= ~CIFS_SES_LANMAN;
+
        if(type == LANMAN) {
 #ifdef CONFIG_CIFS_WEAK_PW_HASH
                char lnm_session_key[CIFS_SESS_KEY_SIZE];
@@ -377,7 +378,7 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
                /* and copy into bcc */
 
                calc_lanman_hash(ses, lnm_session_key);
-
+               ses->flags |= CIFS_SES_LANMAN; 
 /* #ifdef CONFIG_CIFS_DEBUG2
                cifs_dump_mem("cryptkey: ",ses->server->cryptKey,
                        CIFS_SESS_KEY_SIZE);
index efaa044523a7094ecbbddd1ead52f89fc424cc7e..7a1b2b961ec875b7f1a964d8f20f27b8fec58239 100644 (file)
@@ -364,20 +364,20 @@ E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24)
        smbhash(p24 + 16, c8, p21 + 14, 1);
 }
 
-void
+#if 0 /* currently unsued */
+static void
 D_P16(unsigned char *p14, unsigned char *in, unsigned char *out)
 {
        smbhash(out, in, p14, 0);
        smbhash(out + 8, in + 8, p14 + 7, 0);
 }
 
-void
+static void
 E_old_pw_hash(unsigned char *p14, unsigned char *in, unsigned char *out)
 {
        smbhash(out, in, p14, 1);
        smbhash(out + 8, in + 8, p14 + 7, 1);
 }
-#if 0
 /* these routines are currently unneeded, but may be
        needed later */
 void
index f518c5e45035c50955b51c55d08ab86b66127842..4b25ba92180d649497b74f77a594b7ba7327ed5f 100644 (file)
 
 void SMBencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24);
 void E_md4hash(const unsigned char *passwd, unsigned char *p16);
-void nt_lm_owf_gen(char *pwd, unsigned char nt_p16[16], unsigned char p16[16]);
 static void SMBOWFencrypt(unsigned char passwd[16], unsigned char *c8,
                   unsigned char p24[24]);
-void NTLMSSPOWFencrypt(unsigned char passwd[8],
-                      unsigned char *ntlmchalresp, unsigned char p24[24]);
 void SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24);
 
 /*
@@ -144,8 +141,9 @@ E_md4hash(const unsigned char *passwd, unsigned char *p16)
        memset(wpwd,0,129 * 2);
 }
 
+#if 0 /* currently unused */
 /* Does both the NT and LM owfs of a user's password */
-void
+static void
 nt_lm_owf_gen(char *pwd, unsigned char nt_p16[16], unsigned char p16[16])
 {
        char passwd[514];
@@ -171,6 +169,7 @@ nt_lm_owf_gen(char *pwd, unsigned char nt_p16[16], unsigned char p16[16])
        /* clear out local copy of user's password (just being paranoid). */
        memset(passwd, '\0', sizeof (passwd));
 }
+#endif
 
 /* Does the NTLMv2 owfs of a user's password */
 #if 0  /* function not needed yet - but will be soon */
@@ -223,7 +222,8 @@ SMBOWFencrypt(unsigned char passwd[16], unsigned char *c8,
 }
 
 /* Does the des encryption from the FIRST 8 BYTES of the NT or LM MD4 hash. */
-void
+#if 0 /* currently unused */
+static void
 NTLMSSPOWFencrypt(unsigned char passwd[8],
                  unsigned char *ntlmchalresp, unsigned char p24[24])
 {
@@ -235,6 +235,7 @@ NTLMSSPOWFencrypt(unsigned char passwd[8],
 
        E_P24(p21, ntlmchalresp, p24);
 }
+#endif
 
 /* Does the NT MD4 hash then des encryption. */
 
index 4d3fbcb2ddb1a32353dcf6001c9a4f53e42e94d4..50624d4a70c6c771b14c6ff12de3fbde65175aa7 100644 (file)
@@ -1316,7 +1316,7 @@ compat_sys_vmsplice(int fd, const struct compat_iovec __user *iov32,
                    unsigned int nr_segs, unsigned int flags)
 {
        unsigned i;
-       struct iovec *iov;
+       struct iovec __user *iov;
        if (nr_segs > UIO_MAXIOV)
                return -EINVAL;
        iov = compat_alloc_user_space(nr_segs * sizeof(struct iovec));
index 27ca1aa305625fbc19b0122b7875d75f06125c53..a91f2628c981328e41a1b93a5b9c22cc7b0f913a 100644 (file)
@@ -2438,13 +2438,17 @@ HANDLE_IOCTL(0x1260, broken_blkgetsize)
 HANDLE_IOCTL(BLKFRAGET, w_long)
 HANDLE_IOCTL(BLKSECTGET, w_long)
 HANDLE_IOCTL(BLKPG, blkpg_ioctl_trans)
-HANDLE_IOCTL(HDIO_GET_KEEPSETTINGS, hdio_ioctl_trans)
 HANDLE_IOCTL(HDIO_GET_UNMASKINTR, hdio_ioctl_trans)
-HANDLE_IOCTL(HDIO_GET_DMA, hdio_ioctl_trans)
-HANDLE_IOCTL(HDIO_GET_32BIT, hdio_ioctl_trans)
 HANDLE_IOCTL(HDIO_GET_MULTCOUNT, hdio_ioctl_trans)
+HANDLE_IOCTL(HDIO_GET_KEEPSETTINGS, hdio_ioctl_trans)
+HANDLE_IOCTL(HDIO_GET_32BIT, hdio_ioctl_trans)
 HANDLE_IOCTL(HDIO_GET_NOWERR, hdio_ioctl_trans)
+HANDLE_IOCTL(HDIO_GET_DMA, hdio_ioctl_trans)
 HANDLE_IOCTL(HDIO_GET_NICE, hdio_ioctl_trans)
+HANDLE_IOCTL(HDIO_GET_WCACHE, hdio_ioctl_trans)
+HANDLE_IOCTL(HDIO_GET_ACOUSTIC, hdio_ioctl_trans)
+HANDLE_IOCTL(HDIO_GET_ADDRESS, hdio_ioctl_trans)
+HANDLE_IOCTL(HDIO_GET_BUSSTATE, hdio_ioctl_trans)
 HANDLE_IOCTL(FDSETPRM32, fd_ioctl_trans)
 HANDLE_IOCTL(FDDEFPRM32, fd_ioctl_trans)
 HANDLE_IOCTL(FDGETPRM32, fd_ioctl_trans)
index e6d5754a715ecde980dd50225495d3628c49e2d8..cf33fac68c840cccc21ac91c617064ac36f90097 100644 (file)
@@ -275,13 +275,14 @@ static int check_perm(struct inode * inode, struct file * file)
         * it in file->private_data for easy access.
         */
        buffer = kzalloc(sizeof(struct configfs_buffer),GFP_KERNEL);
-       if (buffer) {
-               init_MUTEX(&buffer->sem);
-               buffer->needs_read_fill = 1;
-               buffer->ops = ops;
-               file->private_data = buffer;
-       } else
+       if (!buffer) {
                error = -ENOMEM;
+               goto Enomem;
+       }
+       init_MUTEX(&buffer->sem);
+       buffer->needs_read_fill = 1;
+       buffer->ops = ops;
+       file->private_data = buffer;
        goto Done;
 
  Einval:
@@ -289,6 +290,7 @@ static int check_perm(struct inode * inode, struct file * file)
        goto Done;
  Eaccess:
        error = -EACCES;
+ Enomem:
        module_put(attr->ca_owner);
  Done:
        if (error && item)
index 2355bddad8de12609bcc0b517a151883638c79eb..a1ff91eef10810c50583962ae671f07e14737bf6 100644 (file)
@@ -548,6 +548,136 @@ repeat:
        spin_unlock(&dcache_lock);
 }
 
+/*
+ * destroy a single subtree of dentries for unmount
+ * - see the comments on shrink_dcache_for_umount() for a description of the
+ *   locking
+ */
+static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
+{
+       struct dentry *parent;
+
+       BUG_ON(!IS_ROOT(dentry));
+
+       /* detach this root from the system */
+       spin_lock(&dcache_lock);
+       if (!list_empty(&dentry->d_lru)) {
+               dentry_stat.nr_unused--;
+               list_del_init(&dentry->d_lru);
+       }
+       __d_drop(dentry);
+       spin_unlock(&dcache_lock);
+
+       for (;;) {
+               /* descend to the first leaf in the current subtree */
+               while (!list_empty(&dentry->d_subdirs)) {
+                       struct dentry *loop;
+
+                       /* this is a branch with children - detach all of them
+                        * from the system in one go */
+                       spin_lock(&dcache_lock);
+                       list_for_each_entry(loop, &dentry->d_subdirs,
+                                           d_u.d_child) {
+                               if (!list_empty(&loop->d_lru)) {
+                                       dentry_stat.nr_unused--;
+                                       list_del_init(&loop->d_lru);
+                               }
+
+                               __d_drop(loop);
+                               cond_resched_lock(&dcache_lock);
+                       }
+                       spin_unlock(&dcache_lock);
+
+                       /* move to the first child */
+                       dentry = list_entry(dentry->d_subdirs.next,
+                                           struct dentry, d_u.d_child);
+               }
+
+               /* consume the dentries from this leaf up through its parents
+                * until we find one with children or run out altogether */
+               do {
+                       struct inode *inode;
+
+                       if (atomic_read(&dentry->d_count) != 0) {
+                               printk(KERN_ERR
+                                      "BUG: Dentry %p{i=%lx,n=%s}"
+                                      " still in use (%d)"
+                                      " [unmount of %s %s]\n",
+                                      dentry,
+                                      dentry->d_inode ?
+                                      dentry->d_inode->i_ino : 0UL,
+                                      dentry->d_name.name,
+                                      atomic_read(&dentry->d_count),
+                                      dentry->d_sb->s_type->name,
+                                      dentry->d_sb->s_id);
+                               BUG();
+                       }
+
+                       parent = dentry->d_parent;
+                       if (parent == dentry)
+                               parent = NULL;
+                       else
+                               atomic_dec(&parent->d_count);
+
+                       list_del(&dentry->d_u.d_child);
+                       dentry_stat.nr_dentry--;        /* For d_free, below */
+
+                       inode = dentry->d_inode;
+                       if (inode) {
+                               dentry->d_inode = NULL;
+                               list_del_init(&dentry->d_alias);
+                               if (dentry->d_op && dentry->d_op->d_iput)
+                                       dentry->d_op->d_iput(dentry, inode);
+                               else
+                                       iput(inode);
+                       }
+
+                       d_free(dentry);
+
+                       /* finished when we fall off the top of the tree,
+                        * otherwise we ascend to the parent and move to the
+                        * next sibling if there is one */
+                       if (!parent)
+                               return;
+
+                       dentry = parent;
+
+               } while (list_empty(&dentry->d_subdirs));
+
+               dentry = list_entry(dentry->d_subdirs.next,
+                                   struct dentry, d_u.d_child);
+       }
+}
+
+/*
+ * destroy the dentries attached to a superblock on unmounting
+ * - we don't need to use dentry->d_lock, and only need dcache_lock when
+ *   removing the dentry from the system lists and hashes because:
+ *   - the superblock is detached from all mountings and open files, so the
+ *     dentry trees will not be rearranged by the VFS
+ *   - s_umount is write-locked, so the memory pressure shrinker will ignore
+ *     any dentries belonging to this superblock that it comes across
+ *   - the filesystem itself is no longer permitted to rearrange the dentries
+ *     in this superblock
+ */
+void shrink_dcache_for_umount(struct super_block *sb)
+{
+       struct dentry *dentry;
+
+       if (down_read_trylock(&sb->s_umount))
+               BUG();
+
+       dentry = sb->s_root;
+       sb->s_root = NULL;
+       atomic_dec(&dentry->d_count);
+       shrink_dcache_for_umount_subtree(dentry);
+
+       while (!hlist_empty(&sb->s_anon)) {
+               dentry = hlist_entry(sb->s_anon.first, struct dentry, d_hash);
+               shrink_dcache_for_umount_subtree(dentry);
+       }
+}
+
 /*
  * Search for at least 1 mount point in the dentry's subdirs.
  * We descend to the next level whenever the d_subdirs
@@ -1339,23 +1469,21 @@ static void switch_names(struct dentry *dentry, struct dentry *target)
  * deleted it.
  */
  
-/**
- * d_move - move a dentry
+/*
+ * d_move_locked - move a dentry
  * @dentry: entry to move
  * @target: new dentry
  *
  * Update the dcache to reflect the move of a file name. Negative
  * dcache entries should not be moved in this way.
  */
-
-void d_move(struct dentry * dentry, struct dentry * target)
+static void d_move_locked(struct dentry * dentry, struct dentry * target)
 {
        struct hlist_head *list;
 
        if (!dentry->d_inode)
                printk(KERN_WARNING "VFS: moving negative dcache entry\n");
 
-       spin_lock(&dcache_lock);
        write_seqlock(&rename_lock);
        /*
         * XXXX: do we really need to take target->d_lock?
@@ -1406,9 +1534,83 @@ already_unhashed:
        fsnotify_d_move(dentry);
        spin_unlock(&dentry->d_lock);
        write_sequnlock(&rename_lock);
+}
+
+/**
+ * d_move - move a dentry
+ * @dentry: entry to move
+ * @target: new dentry
+ *
+ * Update the dcache to reflect the move of a file name. Negative
+ * dcache entries should not be moved in this way.
+ */
+
+void d_move(struct dentry * dentry, struct dentry * target)
+{
+       spin_lock(&dcache_lock);
+       d_move_locked(dentry, target);
        spin_unlock(&dcache_lock);
 }
 
+/*
+ * Helper that returns 1 if p1 is a parent of p2, else 0
+ */
+static int d_isparent(struct dentry *p1, struct dentry *p2)
+{
+       struct dentry *p;
+
+       for (p = p2; p->d_parent != p; p = p->d_parent) {
+               if (p->d_parent == p1)
+                       return 1;
+       }
+       return 0;
+}
+
+/*
+ * This helper attempts to cope with remotely renamed directories
+ *
+ * It assumes that the caller is already holding
+ * dentry->d_parent->d_inode->i_mutex and the dcache_lock
+ *
+ * Note: If ever the locking in lock_rename() changes, then please
+ * remember to update this too...
+ *
+ * On return, dcache_lock will have been unlocked.
+ */
+static struct dentry *__d_unalias(struct dentry *dentry, struct dentry *alias)
+{
+       struct mutex *m1 = NULL, *m2 = NULL;
+       struct dentry *ret;
+
+       /* If alias and dentry share a parent, then no extra locks required */
+       if (alias->d_parent == dentry->d_parent)
+               goto out_unalias;
+
+       /* Check for loops */
+       ret = ERR_PTR(-ELOOP);
+       if (d_isparent(alias, dentry))
+               goto out_err;
+
+       /* See lock_rename() */
+       ret = ERR_PTR(-EBUSY);
+       if (!mutex_trylock(&dentry->d_sb->s_vfs_rename_mutex))
+               goto out_err;
+       m1 = &dentry->d_sb->s_vfs_rename_mutex;
+       if (!mutex_trylock(&alias->d_parent->d_inode->i_mutex))
+               goto out_err;
+       m2 = &alias->d_parent->d_inode->i_mutex;
+out_unalias:
+       d_move_locked(alias, dentry);
+       ret = alias;
+out_err:
+       spin_unlock(&dcache_lock);
+       if (m2)
+               mutex_unlock(m2);
+       if (m1)
+               mutex_unlock(m1);
+       return ret;
+}
+
 /*
  * Prepare an anonymous dentry for life in the superblock's dentry tree as a
  * named dentry in place of the dentry to be replaced.
@@ -1451,7 +1653,7 @@ static void __d_materialise_dentry(struct dentry *dentry, struct dentry *anon)
  */
 struct dentry *d_materialise_unique(struct dentry *dentry, struct inode *inode)
 {
-       struct dentry *alias, *actual;
+       struct dentry *actual;
 
        BUG_ON(!d_unhashed(dentry));
 
@@ -1463,26 +1665,27 @@ struct dentry *d_materialise_unique(struct dentry *dentry, struct inode *inode)
                goto found_lock;
        }
 
-       /* See if a disconnected directory already exists as an anonymous root
-        * that we should splice into the tree instead */
-       if (S_ISDIR(inode->i_mode) && (alias = __d_find_alias(inode, 1))) {
-               spin_lock(&alias->d_lock);
-
-               /* Is this a mountpoint that we could splice into our tree? */
-               if (IS_ROOT(alias))
-                       goto connect_mountpoint;
-
-               if (alias->d_name.len == dentry->d_name.len &&
-                   alias->d_parent == dentry->d_parent &&
-                   memcmp(alias->d_name.name,
-                          dentry->d_name.name,
-                          dentry->d_name.len) == 0)
-                       goto replace_with_alias;
-
-               spin_unlock(&alias->d_lock);
-
-               /* Doh! Seem to be aliasing directories for some reason... */
-               dput(alias);
+       if (S_ISDIR(inode->i_mode)) {
+               struct dentry *alias;
+
+               /* Does an aliased dentry already exist? */
+               alias = __d_find_alias(inode, 0);
+               if (alias) {
+                       actual = alias;
+                       /* Is this an anonymous mountpoint that we could splice
+                        * into our tree? */
+                       if (IS_ROOT(alias)) {
+                               spin_lock(&alias->d_lock);
+                               __d_materialise_dentry(dentry, alias);
+                               __d_drop(alias);
+                               goto found;
+                       }
+                       /* Nope, but we must(!) avoid directory aliasing */
+                       actual = __d_unalias(dentry, alias);
+                       if (IS_ERR(actual))
+                               dput(alias);
+                       goto out_nolock;
+               }
        }
 
        /* Add a unique reference */
@@ -1498,7 +1701,7 @@ found:
        _d_rehash(actual);
        spin_unlock(&actual->d_lock);
        spin_unlock(&dcache_lock);
-
+out_nolock:
        if (actual == dentry) {
                security_d_instantiate(dentry, inode);
                return NULL;
@@ -1507,16 +1710,6 @@ found:
        iput(inode);
        return actual;
 
-       /* Convert the anonymous/root alias into an ordinary dentry */
-connect_mountpoint:
-       __d_materialise_dentry(dentry, alias);
-
-       /* Replace the candidate dentry with the alias in the tree */
-replace_with_alias:
-       __d_drop(alias);
-       actual = alias;
-       goto found;
-
 shouldnt_be_hashed:
        spin_unlock(&dcache_lock);
        BUG();
index 490f85b3fa590efd76ae504b51790a58900625d0..81b2c6465eeb26dd21f23746209162eee8169b22 100644 (file)
@@ -1,10 +1,9 @@
 menu "Distributed Lock Manager"
-       depends on INET && EXPERIMENTAL
+       depends on INET && IP_SCTP && EXPERIMENTAL
 
 config DLM
        tristate "Distributed Lock Manager (DLM)"
        depends on IPV6 || IPV6=n
-       depends on IP_SCTP
        select CONFIGFS_FS
        help
        A general purpose distributed lock manager for kernel or userspace
index 23f5ce12080b0e2f0d48b03ff844c78c5932113a..6da6b14d5a61b40a83e904e6f56cc19d12865ad2 100644 (file)
@@ -174,7 +174,7 @@ static int nodeid_to_addr(int nodeid, struct sockaddr *retaddr)
        return 0;
 }
 
-static struct nodeinfo *nodeid2nodeinfo(int nodeid, int alloc)
+static struct nodeinfo *nodeid2nodeinfo(int nodeid, gfp_t alloc)
 {
        struct nodeinfo *ni;
        int r;
@@ -519,6 +519,7 @@ static int receive_from_sock(void)
        msg.msg_flags = 0;
        msg.msg_control = incmsg;
        msg.msg_controllen = sizeof(incmsg);
+       msg.msg_iovlen = 1;
 
        /* I don't see why this circular buffer stuff is necessary for SCTP
         * which is a packet-based protocol, but the whole thing breaks under
@@ -548,7 +549,7 @@ static int receive_from_sock(void)
        }
        len = iov[0].iov_len + iov[1].iov_len;
 
-       r = ret = kernel_recvmsg(sctp_con.sock, &msg, iov, 1, len,
+       r = ret = kernel_recvmsg(sctp_con.sock, &msg, iov, msg.msg_iovlen, len,
                                 MSG_NOSIGNAL | MSG_DONTWAIT);
        if (ret <= 0)
                goto out_close;
@@ -726,7 +727,7 @@ static int init_sock(void)
 }
 
 
-static struct writequeue_entry *new_writequeue_entry(int allocation)
+static struct writequeue_entry *new_writequeue_entry(gfp_t allocation)
 {
        struct writequeue_entry *entry;
 
@@ -748,7 +749,7 @@ static struct writequeue_entry *new_writequeue_entry(int allocation)
        return entry;
 }
 
-void *dlm_lowcomms_get_buffer(int nodeid, int len, int allocation, char **ppc)
+void *dlm_lowcomms_get_buffer(int nodeid, int len, gfp_t allocation, char **ppc)
 {
        struct writequeue_entry *e;
        int offset = 0;
index 6c04bb09cfa8dc73b081b39fe3625f5904ff7686..2d045e0daae1f6a0d2c07e8e82b74b2004ed5602 100644 (file)
@@ -19,7 +19,7 @@ void dlm_lowcomms_exit(void);
 int dlm_lowcomms_start(void);
 void dlm_lowcomms_stop(void);
 int dlm_lowcomms_close(int nodeid);
-void *dlm_lowcomms_get_buffer(int nodeid, int len, int allocation, char **ppc);
+void *dlm_lowcomms_get_buffer(int nodeid, int len, gfp_t allocation, char **ppc);
 void dlm_lowcomms_commit_buffer(void *mh);
 
 #endif                         /* __LOWCOMMS_DOT_H__ */
index 7a11b8ae66443ce6b094bc25ef381258a6af63f9..5938a232d11bd3e3feed0ed01ae3ba5a04918c7f 100644 (file)
@@ -104,10 +104,7 @@ int ecryptfs_interpose(struct dentry *lower_dentry, struct dentry *dentry,
                inode->i_op = &ecryptfs_dir_iops;
        if (S_ISDIR(lower_inode->i_mode))
                inode->i_fop = &ecryptfs_dir_fops;
-       /* TODO: Is there a better way to identify if the inode is
-        * special? */
-       if (S_ISBLK(lower_inode->i_mode) || S_ISCHR(lower_inode->i_mode) ||
-           S_ISFIFO(lower_inode->i_mode) || S_ISSOCK(lower_inode->i_mode))
+       if (special_file(lower_inode->i_mode))
                init_special_inode(inode, lower_inode->i_mode,
                                   lower_inode->i_rdev);
        dentry->d_op = &ecryptfs_dops;
index 557d5b614fae6ba694703b86d950471cc2eeedc5..ae228ec54e948a63b25bb39f34577baa22fd06ed 100644 (file)
 /* Maximum msec timeout value storeable in a long int */
 #define EP_MAX_MSTIMEO min(1000ULL * MAX_SCHEDULE_TIMEOUT / HZ, (LONG_MAX - 999ULL) / HZ)
 
+#define EP_MAX_EVENTS (INT_MAX / sizeof(struct epoll_event))
+
 
 struct epoll_filefd {
        struct file *file;
@@ -497,7 +499,7 @@ void eventpoll_release_file(struct file *file)
  */
 asmlinkage long sys_epoll_create(int size)
 {
-       int error, fd;
+       int error, fd = -1;
        struct eventpoll *ep;
        struct inode *inode;
        struct file *file;
@@ -640,7 +642,6 @@ eexit_1:
        return error;
 }
 
-#define MAX_EVENTS (INT_MAX / sizeof(struct epoll_event))
 
 /*
  * Implement the event wait interface for the eventpoll file. It is the kernel
@@ -657,7 +658,7 @@ asmlinkage long sys_epoll_wait(int epfd, struct epoll_event __user *events,
                     current, epfd, events, maxevents, timeout));
 
        /* The maximum number of event must be greater than zero */
-       if (maxevents <= 0 || maxevents > MAX_EVENTS)
+       if (maxevents <= 0 || maxevents > EP_MAX_EVENTS)
                return -EINVAL;
 
        /* Verify that the area passed by the user is writeable */
@@ -699,6 +700,55 @@ eexit_1:
 }
 
 
+#ifdef TIF_RESTORE_SIGMASK
+
+/*
+ * Implement the event wait interface for the eventpoll file. It is the kernel
+ * part of the user space epoll_pwait(2).
+ */
+asmlinkage long sys_epoll_pwait(int epfd, struct epoll_event __user *events,
+               int maxevents, int timeout, const sigset_t __user *sigmask,
+               size_t sigsetsize)
+{
+       int error;
+       sigset_t ksigmask, sigsaved;
+
+       /*
+        * If the caller wants a certain signal mask to be set during the wait,
+        * we apply it here.
+        */
+       if (sigmask) {
+               if (sigsetsize != sizeof(sigset_t))
+                       return -EINVAL;
+               if (copy_from_user(&ksigmask, sigmask, sizeof(ksigmask)))
+                       return -EFAULT;
+               sigdelsetmask(&ksigmask, sigmask(SIGKILL) | sigmask(SIGSTOP));
+               sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved);
+       }
+
+       error = sys_epoll_wait(epfd, events, maxevents, timeout);
+
+       /*
+        * If we changed the signal mask, we need to restore the original one.
+        * In case we've got a signal while waiting, we do not restore the
+        * signal mask yet, and we allow do_signal() to deliver the signal on
+        * the way back to userspace, before the signal mask is restored.
+        */
+       if (sigmask) {
+               if (error == -EINTR) {
+                       memcpy(&current->saved_sigmask, &sigsaved,
+                               sizeof(sigsaved));
+                       set_thread_flag(TIF_RESTORE_SIGMASK);
+               } else
+                       sigprocmask(SIG_SETMASK, &sigsaved, NULL);
+       }
+
+       return error;
+}
+
+#endif /* #ifdef TIF_RESTORE_SIGMASK */
+
+
 /*
  * Creates the file descriptor to be used by the epoll interface.
  */
index 513cd421ac0b6627da069f16a1274154500a8374..d8b9abd95d07e4bf2fa81020856cd4026b766790 100644 (file)
@@ -364,7 +364,6 @@ static int parse_options (char * options,
 {
        char * p;
        substring_t args[MAX_OPT_ARGS];
-       unsigned long kind = EXT2_MOUNT_ERRORS_CONT;
        int option;
 
        if (!options)
@@ -404,13 +403,19 @@ static int parse_options (char * options,
                        /* *sb_block = match_int(&args[0]); */
                        break;
                case Opt_err_panic:
-                       kind = EXT2_MOUNT_ERRORS_PANIC;
+                       clear_opt (sbi->s_mount_opt, ERRORS_CONT);
+                       clear_opt (sbi->s_mount_opt, ERRORS_RO);
+                       set_opt (sbi->s_mount_opt, ERRORS_PANIC);
                        break;
                case Opt_err_ro:
-                       kind = EXT2_MOUNT_ERRORS_RO;
+                       clear_opt (sbi->s_mount_opt, ERRORS_CONT);
+                       clear_opt (sbi->s_mount_opt, ERRORS_PANIC);
+                       set_opt (sbi->s_mount_opt, ERRORS_RO);
                        break;
                case Opt_err_cont:
-                       kind = EXT2_MOUNT_ERRORS_CONT;
+                       clear_opt (sbi->s_mount_opt, ERRORS_RO);
+                       clear_opt (sbi->s_mount_opt, ERRORS_PANIC);
+                       set_opt (sbi->s_mount_opt, ERRORS_CONT);
                        break;
                case Opt_nouid32:
                        set_opt (sbi->s_mount_opt, NO_UID32);
@@ -489,7 +494,6 @@ static int parse_options (char * options,
                        return 0;
                }
        }
-       sbi->s_mount_opt |= kind;
        return 1;
 }
 
@@ -715,6 +719,8 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
                set_opt(sbi->s_mount_opt, ERRORS_PANIC);
        else if (le16_to_cpu(sbi->s_es->s_errors) == EXT2_ERRORS_RO)
                set_opt(sbi->s_mount_opt, ERRORS_RO);
+       else
+               set_opt(sbi->s_mount_opt, ERRORS_CONT);
 
        sbi->s_resuid = le16_to_cpu(es->s_def_resuid);
        sbi->s_resgid = le16_to_cpu(es->s_def_resgid);
index 8bfd56ef18ca56d9c584b250b77ab3aa1220a337..afc2d4f42d7782800f6d65dfc49c6aebc1925169 100644 (file)
@@ -1470,6 +1470,8 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
                set_opt(sbi->s_mount_opt, ERRORS_PANIC);
        else if (le16_to_cpu(sbi->s_es->s_errors) == EXT3_ERRORS_RO)
                set_opt(sbi->s_mount_opt, ERRORS_RO);
+       else
+               set_opt(sbi->s_mount_opt, ERRORS_CONT);
 
        sbi->s_resuid = le16_to_cpu(es->s_def_resuid);
        sbi->s_resgid = le16_to_cpu(es->s_def_resgid);
diff --git a/fs/ext4/Makefile b/fs/ext4/Makefile
new file mode 100644 (file)
index 0000000..a6acb96
--- /dev/null
@@ -0,0 +1,12 @@
+#
+# Makefile for the linux ext4-filesystem routines.
+#
+
+obj-$(CONFIG_EXT4DEV_FS) += ext4dev.o
+
+ext4dev-y      := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
+          ioctl.o namei.o super.o symlink.o hash.o resize.o extents.o
+
+ext4dev-$(CONFIG_EXT4DEV_FS_XATTR)     += xattr.o xattr_user.o xattr_trusted.o
+ext4dev-$(CONFIG_EXT4DEV_FS_POSIX_ACL) += acl.o
+ext4dev-$(CONFIG_EXT4DEV_FS_SECURITY)  += xattr_security.o
diff --git a/fs/ext4/acl.c b/fs/ext4/acl.c
new file mode 100644 (file)
index 0000000..9e88254
--- /dev/null
@@ -0,0 +1,551 @@
+/*
+ * linux/fs/ext4/acl.c
+ *
+ * Copyright (C) 2001-2003 Andreas Gruenbacher, <agruen@suse.de>
+ */
+
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/capability.h>
+#include <linux/fs.h>
+#include <linux/ext4_jbd2.h>
+#include <linux/ext4_fs.h>
+#include "xattr.h"
+#include "acl.h"
+
+/*
+ * Convert from filesystem to in-memory representation.
+ */
+static struct posix_acl *
+ext4_acl_from_disk(const void *value, size_t size)
+{
+       const char *end = (char *)value + size;
+       int n, count;
+       struct posix_acl *acl;
+
+       if (!value)
+               return NULL;
+       if (size < sizeof(ext4_acl_header))
+                return ERR_PTR(-EINVAL);
+       if (((ext4_acl_header *)value)->a_version !=
+           cpu_to_le32(EXT4_ACL_VERSION))
+               return ERR_PTR(-EINVAL);
+       value = (char *)value + sizeof(ext4_acl_header);
+       count = ext4_acl_count(size);
+       if (count < 0)
+               return ERR_PTR(-EINVAL);
+       if (count == 0)
+               return NULL;
+       acl = posix_acl_alloc(count, GFP_KERNEL);
+       if (!acl)
+               return ERR_PTR(-ENOMEM);
+       for (n=0; n < count; n++) {
+               ext4_acl_entry *entry =
+                       (ext4_acl_entry *)value;
+               if ((char *)value + sizeof(ext4_acl_entry_short) > end)
+                       goto fail;
+               acl->a_entries[n].e_tag  = le16_to_cpu(entry->e_tag);
+               acl->a_entries[n].e_perm = le16_to_cpu(entry->e_perm);
+               switch(acl->a_entries[n].e_tag) {
+                       case ACL_USER_OBJ:
+                       case ACL_GROUP_OBJ:
+                       case ACL_MASK:
+                       case ACL_OTHER:
+                               value = (char *)value +
+                                       sizeof(ext4_acl_entry_short);
+                               acl->a_entries[n].e_id = ACL_UNDEFINED_ID;
+                               break;
+
+                       case ACL_USER:
+                       case ACL_GROUP:
+                               value = (char *)value + sizeof(ext4_acl_entry);
+                               if ((char *)value > end)
+                                       goto fail;
+                               acl->a_entries[n].e_id =
+                                       le32_to_cpu(entry->e_id);
+                               break;
+
+                       default:
+                               goto fail;
+               }
+       }
+       if (value != end)
+               goto fail;
+       return acl;
+
+fail:
+       posix_acl_release(acl);
+       return ERR_PTR(-EINVAL);
+}
+
+/*
+ * Convert from in-memory to filesystem representation.
+ */
+static void *
+ext4_acl_to_disk(const struct posix_acl *acl, size_t *size)
+{
+       ext4_acl_header *ext_acl;
+       char *e;
+       size_t n;
+
+       *size = ext4_acl_size(acl->a_count);
+       ext_acl = kmalloc(sizeof(ext4_acl_header) + acl->a_count *
+                       sizeof(ext4_acl_entry), GFP_KERNEL);
+       if (!ext_acl)
+               return ERR_PTR(-ENOMEM);
+       ext_acl->a_version = cpu_to_le32(EXT4_ACL_VERSION);
+       e = (char *)ext_acl + sizeof(ext4_acl_header);
+       for (n=0; n < acl->a_count; n++) {
+               ext4_acl_entry *entry = (ext4_acl_entry *)e;
+               entry->e_tag  = cpu_to_le16(acl->a_entries[n].e_tag);
+               entry->e_perm = cpu_to_le16(acl->a_entries[n].e_perm);
+               switch(acl->a_entries[n].e_tag) {
+                       case ACL_USER:
+                       case ACL_GROUP:
+                               entry->e_id =
+                                       cpu_to_le32(acl->a_entries[n].e_id);
+                               e += sizeof(ext4_acl_entry);
+                               break;
+
+                       case ACL_USER_OBJ:
+                       case ACL_GROUP_OBJ:
+                       case ACL_MASK:
+                       case ACL_OTHER:
+                               e += sizeof(ext4_acl_entry_short);
+                               break;
+
+                       default:
+                               goto fail;
+               }
+       }
+       return (char *)ext_acl;
+
+fail:
+       kfree(ext_acl);
+       return ERR_PTR(-EINVAL);
+}
+
+static inline struct posix_acl *
+ext4_iget_acl(struct inode *inode, struct posix_acl **i_acl)
+{
+       struct posix_acl *acl = EXT4_ACL_NOT_CACHED;
+
+       spin_lock(&inode->i_lock);
+       if (*i_acl != EXT4_ACL_NOT_CACHED)
+               acl = posix_acl_dup(*i_acl);
+       spin_unlock(&inode->i_lock);
+
+       return acl;
+}
+
+static inline void
+ext4_iset_acl(struct inode *inode, struct posix_acl **i_acl,
+               struct posix_acl *acl)
+{
+       spin_lock(&inode->i_lock);
+       if (*i_acl != EXT4_ACL_NOT_CACHED)
+               posix_acl_release(*i_acl);
+       *i_acl = posix_acl_dup(acl);
+       spin_unlock(&inode->i_lock);
+}
+
+/*
+ * Inode operation get_posix_acl().
+ *
+ * inode->i_mutex: don't care
+ */
+static struct posix_acl *
+ext4_get_acl(struct inode *inode, int type)
+{
+       struct ext4_inode_info *ei = EXT4_I(inode);
+       int name_index;
+       char *value = NULL;
+       struct posix_acl *acl;
+       int retval;
+
+       if (!test_opt(inode->i_sb, POSIX_ACL))
+               return NULL;
+
+       switch(type) {
+               case ACL_TYPE_ACCESS:
+                       acl = ext4_iget_acl(inode, &ei->i_acl);
+                       if (acl != EXT4_ACL_NOT_CACHED)
+                               return acl;
+                       name_index = EXT4_XATTR_INDEX_POSIX_ACL_ACCESS;
+                       break;
+
+               case ACL_TYPE_DEFAULT:
+                       acl = ext4_iget_acl(inode, &ei->i_default_acl);
+                       if (acl != EXT4_ACL_NOT_CACHED)
+                               return acl;
+                       name_index = EXT4_XATTR_INDEX_POSIX_ACL_DEFAULT;
+                       break;
+
+               default:
+                       return ERR_PTR(-EINVAL);
+       }
+       retval = ext4_xattr_get(inode, name_index, "", NULL, 0);
+       if (retval > 0) {
+               value = kmalloc(retval, GFP_KERNEL);
+               if (!value)
+                       return ERR_PTR(-ENOMEM);
+               retval = ext4_xattr_get(inode, name_index, "", value, retval);
+       }
+       if (retval > 0)
+               acl = ext4_acl_from_disk(value, retval);
+       else if (retval == -ENODATA || retval == -ENOSYS)
+               acl = NULL;
+       else
+               acl = ERR_PTR(retval);
+       kfree(value);
+
+       if (!IS_ERR(acl)) {
+               switch(type) {
+                       case ACL_TYPE_ACCESS:
+                               ext4_iset_acl(inode, &ei->i_acl, acl);
+                               break;
+
+                       case ACL_TYPE_DEFAULT:
+                               ext4_iset_acl(inode, &ei->i_default_acl, acl);
+                               break;
+               }
+       }
+       return acl;
+}
+
+/*
+ * Set the access or default ACL of an inode.
+ *
+ * inode->i_mutex: down unless called from ext4_new_inode
+ */
+static int
+ext4_set_acl(handle_t *handle, struct inode *inode, int type,
+            struct posix_acl *acl)
+{
+       struct ext4_inode_info *ei = EXT4_I(inode);
+       int name_index;
+       void *value = NULL;
+       size_t size = 0;
+       int error;
+
+       if (S_ISLNK(inode->i_mode))
+               return -EOPNOTSUPP;
+
+       switch(type) {
+               case ACL_TYPE_ACCESS:
+                       name_index = EXT4_XATTR_INDEX_POSIX_ACL_ACCESS;
+                       if (acl) {
+                               mode_t mode = inode->i_mode;
+                               error = posix_acl_equiv_mode(acl, &mode);
+                               if (error < 0)
+                                       return error;
+                               else {
+                                       inode->i_mode = mode;
+                                       ext4_mark_inode_dirty(handle, inode);
+                                       if (error == 0)
+                                               acl = NULL;
+                               }
+                       }
+                       break;
+
+               case ACL_TYPE_DEFAULT:
+                       name_index = EXT4_XATTR_INDEX_POSIX_ACL_DEFAULT;
+                       if (!S_ISDIR(inode->i_mode))
+                               return acl ? -EACCES : 0;
+                       break;
+
+               default:
+                       return -EINVAL;
+       }
+       if (acl) {
+               value = ext4_acl_to_disk(acl, &size);
+               if (IS_ERR(value))
+                       return (int)PTR_ERR(value);
+       }
+
+       error = ext4_xattr_set_handle(handle, inode, name_index, "",
+                                     value, size, 0);
+
+       kfree(value);
+       if (!error) {
+               switch(type) {
+                       case ACL_TYPE_ACCESS:
+                               ext4_iset_acl(inode, &ei->i_acl, acl);
+                               break;
+
+                       case ACL_TYPE_DEFAULT:
+                               ext4_iset_acl(inode, &ei->i_default_acl, acl);
+                               break;
+               }
+       }
+       return error;
+}
+
+static int
+ext4_check_acl(struct inode *inode, int mask)
+{
+       struct posix_acl *acl = ext4_get_acl(inode, ACL_TYPE_ACCESS);
+
+       if (IS_ERR(acl))
+               return PTR_ERR(acl);
+       if (acl) {
+               int error = posix_acl_permission(inode, acl, mask);
+               posix_acl_release(acl);
+               return error;
+       }
+
+       return -EAGAIN;
+}
+
+int
+ext4_permission(struct inode *inode, int mask, struct nameidata *nd)
+{
+       return generic_permission(inode, mask, ext4_check_acl);
+}
+
+/*
+ * Initialize the ACLs of a new inode. Called from ext4_new_inode.
+ *
+ * dir->i_mutex: down
+ * inode->i_mutex: up (access to inode is still exclusive)
+ */
+int
+ext4_init_acl(handle_t *handle, struct inode *inode, struct inode *dir)
+{
+       struct posix_acl *acl = NULL;
+       int error = 0;
+
+       if (!S_ISLNK(inode->i_mode)) {
+               if (test_opt(dir->i_sb, POSIX_ACL)) {
+                       acl = ext4_get_acl(dir, ACL_TYPE_DEFAULT);
+                       if (IS_ERR(acl))
+                               return PTR_ERR(acl);
+               }
+               if (!acl)
+                       inode->i_mode &= ~current->fs->umask;
+       }
+       if (test_opt(inode->i_sb, POSIX_ACL) && acl) {
+               struct posix_acl *clone;
+               mode_t mode;
+
+               if (S_ISDIR(inode->i_mode)) {
+                       error = ext4_set_acl(handle, inode,
+                                            ACL_TYPE_DEFAULT, acl);
+                       if (error)
+                               goto cleanup;
+               }
+               clone = posix_acl_clone(acl, GFP_KERNEL);
+               error = -ENOMEM;
+               if (!clone)
+                       goto cleanup;
+
+               mode = inode->i_mode;
+               error = posix_acl_create_masq(clone, &mode);
+               if (error >= 0) {
+                       inode->i_mode = mode;
+                       if (error > 0) {
+                               /* This is an extended ACL */
+                               error = ext4_set_acl(handle, inode,
+                                                    ACL_TYPE_ACCESS, clone);
+                       }
+               }
+               posix_acl_release(clone);
+       }
+cleanup:
+       posix_acl_release(acl);
+       return error;
+}
+
+/*
+ * Does chmod for an inode that may have an Access Control List. The
+ * inode->i_mode field must be updated to the desired value by the caller
+ * before calling this function.
+ * Returns 0 on success, or a negative error number.
+ *
+ * We change the ACL rather than storing some ACL entries in the file
+ * mode permission bits (which would be more efficient), because that
+ * would break once additional permissions (like  ACL_APPEND, ACL_DELETE
+ * for directories) are added. There are no more bits available in the
+ * file mode.
+ *
+ * inode->i_mutex: down
+ */
+int
+ext4_acl_chmod(struct inode *inode)
+{
+       struct posix_acl *acl, *clone;
+       int error;
+
+       if (S_ISLNK(inode->i_mode))
+               return -EOPNOTSUPP;
+       if (!test_opt(inode->i_sb, POSIX_ACL))
+               return 0;
+       acl = ext4_get_acl(inode, ACL_TYPE_ACCESS);
+       if (IS_ERR(acl) || !acl)
+               return PTR_ERR(acl);
+       clone = posix_acl_clone(acl, GFP_KERNEL);
+       posix_acl_release(acl);
+       if (!clone)
+               return -ENOMEM;
+       error = posix_acl_chmod_masq(clone, inode->i_mode);
+       if (!error) {
+               handle_t *handle;
+               int retries = 0;
+
+       retry:
+               handle = ext4_journal_start(inode,
+                               EXT4_DATA_TRANS_BLOCKS(inode->i_sb));
+               if (IS_ERR(handle)) {
+                       error = PTR_ERR(handle);
+                       ext4_std_error(inode->i_sb, error);
+                       goto out;
+               }
+               error = ext4_set_acl(handle, inode, ACL_TYPE_ACCESS, clone);
+               ext4_journal_stop(handle);
+               if (error == -ENOSPC &&
+                   ext4_should_retry_alloc(inode->i_sb, &retries))
+                       goto retry;
+       }
+out:
+       posix_acl_release(clone);
+       return error;
+}
+
+/*
+ * Extended attribute handlers
+ */
+static size_t
+ext4_xattr_list_acl_access(struct inode *inode, char *list, size_t list_len,
+                          const char *name, size_t name_len)
+{
+       const size_t size = sizeof(POSIX_ACL_XATTR_ACCESS);
+
+       if (!test_opt(inode->i_sb, POSIX_ACL))
+               return 0;
+       if (list && size <= list_len)
+               memcpy(list, POSIX_ACL_XATTR_ACCESS, size);
+       return size;
+}
+
+static size_t
+ext4_xattr_list_acl_default(struct inode *inode, char *list, size_t list_len,
+                           const char *name, size_t name_len)
+{
+       const size_t size = sizeof(POSIX_ACL_XATTR_DEFAULT);
+
+       if (!test_opt(inode->i_sb, POSIX_ACL))
+               return 0;
+       if (list && size <= list_len)
+               memcpy(list, POSIX_ACL_XATTR_DEFAULT, size);
+       return size;
+}
+
+static int
+ext4_xattr_get_acl(struct inode *inode, int type, void *buffer, size_t size)
+{
+       struct posix_acl *acl;
+       int error;
+
+       if (!test_opt(inode->i_sb, POSIX_ACL))
+               return -EOPNOTSUPP;
+
+       acl = ext4_get_acl(inode, type);
+       if (IS_ERR(acl))
+               return PTR_ERR(acl);
+       if (acl == NULL)
+               return -ENODATA;
+       error = posix_acl_to_xattr(acl, buffer, size);
+       posix_acl_release(acl);
+
+       return error;
+}
+
+static int
+ext4_xattr_get_acl_access(struct inode *inode, const char *name,
+                         void *buffer, size_t size)
+{
+       if (strcmp(name, "") != 0)
+               return -EINVAL;
+       return ext4_xattr_get_acl(inode, ACL_TYPE_ACCESS, buffer, size);
+}
+
+static int
+ext4_xattr_get_acl_default(struct inode *inode, const char *name,
+                          void *buffer, size_t size)
+{
+       if (strcmp(name, "") != 0)
+               return -EINVAL;
+       return ext4_xattr_get_acl(inode, ACL_TYPE_DEFAULT, buffer, size);
+}
+
+static int
+ext4_xattr_set_acl(struct inode *inode, int type, const void *value,
+                  size_t size)
+{
+       handle_t *handle;
+       struct posix_acl *acl;
+       int error, retries = 0;
+
+       if (!test_opt(inode->i_sb, POSIX_ACL))
+               return -EOPNOTSUPP;
+       if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
+               return -EPERM;
+
+       if (value) {
+               acl = posix_acl_from_xattr(value, size);
+               if (IS_ERR(acl))
+                       return PTR_ERR(acl);
+               else if (acl) {
+                       error = posix_acl_valid(acl);
+                       if (error)
+                               goto release_and_out;
+               }
+       } else
+               acl = NULL;
+
+retry:
+       handle = ext4_journal_start(inode, EXT4_DATA_TRANS_BLOCKS(inode->i_sb));
+       if (IS_ERR(handle))
+               return PTR_ERR(handle);
+       error = ext4_set_acl(handle, inode, type, acl);
+       ext4_journal_stop(handle);
+       if (error == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries))
+               goto retry;
+
+release_and_out:
+       posix_acl_release(acl);
+       return error;
+}
+
+static int
+ext4_xattr_set_acl_access(struct inode *inode, const char *name,
+                         const void *value, size_t size, int flags)
+{
+       if (strcmp(name, "") != 0)
+               return -EINVAL;
+       return ext4_xattr_set_acl(inode, ACL_TYPE_ACCESS, value, size);
+}
+
+static int
+ext4_xattr_set_acl_default(struct inode *inode, const char *name,
+                          const void *value, size_t size, int flags)
+{
+       if (strcmp(name, "") != 0)
+               return -EINVAL;
+       return ext4_xattr_set_acl(inode, ACL_TYPE_DEFAULT, value, size);
+}
+
+struct xattr_handler ext4_xattr_acl_access_handler = {
+       .prefix = POSIX_ACL_XATTR_ACCESS,
+       .list   = ext4_xattr_list_acl_access,
+       .get    = ext4_xattr_get_acl_access,
+       .set    = ext4_xattr_set_acl_access,
+};
+
+struct xattr_handler ext4_xattr_acl_default_handler = {
+       .prefix = POSIX_ACL_XATTR_DEFAULT,
+       .list   = ext4_xattr_list_acl_default,
+       .get    = ext4_xattr_get_acl_default,
+       .set    = ext4_xattr_set_acl_default,
+};
diff --git a/fs/ext4/acl.h b/fs/ext4/acl.h
new file mode 100644 (file)
index 0000000..26a5c1a
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+  File: fs/ext4/acl.h
+
+  (C) 2001 Andreas Gruenbacher, <a.gruenbacher@computer.org>
+*/
+
+#include <linux/posix_acl_xattr.h>
+
+#define EXT4_ACL_VERSION       0x0001
+
+typedef struct {
+       __le16          e_tag;
+       __le16          e_perm;
+       __le32          e_id;
+} ext4_acl_entry;
+
+typedef struct {
+       __le16          e_tag;
+       __le16          e_perm;
+} ext4_acl_entry_short;
+
+typedef struct {
+       __le32          a_version;
+} ext4_acl_header;
+
+static inline size_t ext4_acl_size(int count)
+{
+       if (count <= 4) {
+               return sizeof(ext4_acl_header) +
+                      count * sizeof(ext4_acl_entry_short);
+       } else {
+               return sizeof(ext4_acl_header) +
+                      4 * sizeof(ext4_acl_entry_short) +
+                      (count - 4) * sizeof(ext4_acl_entry);
+       }
+}
+
+static inline int ext4_acl_count(size_t size)
+{
+       ssize_t s;
+       size -= sizeof(ext4_acl_header);
+       s = size - 4 * sizeof(ext4_acl_entry_short);
+       if (s < 0) {
+               if (size % sizeof(ext4_acl_entry_short))
+                       return -1;
+               return size / sizeof(ext4_acl_entry_short);
+       } else {
+               if (s % sizeof(ext4_acl_entry))
+                       return -1;
+               return s / sizeof(ext4_acl_entry) + 4;
+       }
+}
+
+#ifdef CONFIG_EXT4DEV_FS_POSIX_ACL
+
+/* Value for inode->u.ext4_i.i_acl and inode->u.ext4_i.i_default_acl
+   if the ACL has not been cached */
+#define EXT4_ACL_NOT_CACHED ((void *)-1)
+
+/* acl.c */
+extern int ext4_permission (struct inode *, int, struct nameidata *);
+extern int ext4_acl_chmod (struct inode *);
+extern int ext4_init_acl (handle_t *, struct inode *, struct inode *);
+
+#else  /* CONFIG_EXT4DEV_FS_POSIX_ACL */
+#include <linux/sched.h>
+#define ext4_permission NULL
+
+static inline int
+ext4_acl_chmod(struct inode *inode)
+{
+       return 0;
+}
+
+static inline int
+ext4_init_acl(handle_t *handle, struct inode *inode, struct inode *dir)
+{
+       return 0;
+}
+#endif  /* CONFIG_EXT4DEV_FS_POSIX_ACL */
+
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
new file mode 100644 (file)
index 0000000..5d45582
--- /dev/null
@@ -0,0 +1,1833 @@
+/*
+ *  linux/fs/ext4/balloc.c
+ *
+ * Copyright (C) 1992, 1993, 1994, 1995
+ * Remy Card (card@masi.ibp.fr)
+ * Laboratoire MASI - Institut Blaise Pascal
+ * Universite Pierre et Marie Curie (Paris VI)
+ *
+ *  Enhanced block allocation by Stephen Tweedie (sct@redhat.com), 1993
+ *  Big-endian to little-endian byte-swapping/bitmaps by
+ *        David S. Miller (davem@caip.rutgers.edu), 1995
+ */
+
+#include <linux/time.h>
+#include <linux/capability.h>
+#include <linux/fs.h>
+#include <linux/jbd2.h>
+#include <linux/ext4_fs.h>
+#include <linux/ext4_jbd2.h>
+#include <linux/quotaops.h>
+#include <linux/buffer_head.h>
+
+/*
+ * balloc.c contains the blocks allocation and deallocation routines
+ */
+
+/*
+ * Calculate the block group number and offset, given a block number
+ */
+void ext4_get_group_no_and_offset(struct super_block *sb, ext4_fsblk_t blocknr,
+               unsigned long *blockgrpp, ext4_grpblk_t *offsetp)
+{
+        struct ext4_super_block *es = EXT4_SB(sb)->s_es;
+       ext4_grpblk_t offset;
+
+        blocknr = blocknr - le32_to_cpu(es->s_first_data_block);
+       offset = do_div(blocknr, EXT4_BLOCKS_PER_GROUP(sb));
+       if (offsetp)
+               *offsetp = offset;
+       if (blockgrpp)
+               *blockgrpp = blocknr;
+
+}
+
+/*
+ * The free blocks are managed by bitmaps.  A file system contains several
+ * blocks groups.  Each group contains 1 bitmap block for blocks, 1 bitmap
+ * block for inodes, N blocks for the inode table and data blocks.
+ *
+ * The file system contains group descriptors which are located after the
+ * super block.  Each descriptor contains the number of the bitmap block and
+ * the free blocks count in the block.  The descriptors are loaded in memory
+ * when a file system is mounted (see ext4_read_super).
+ */
+
+
+#define in_range(b, first, len)        ((b) >= (first) && (b) <= (first) + (len) - 1)
+
+/**
+ * ext4_get_group_desc() -- load group descriptor from disk
+ * @sb:                        super block
+ * @block_group:       given block group
+ * @bh:                        pointer to the buffer head to store the block
+ *                     group descriptor
+ */
+struct ext4_group_desc * ext4_get_group_desc(struct super_block * sb,
+                                            unsigned int block_group,
+                                            struct buffer_head ** bh)
+{
+       unsigned long group_desc;
+       unsigned long offset;
+       struct ext4_group_desc * desc;
+       struct ext4_sb_info *sbi = EXT4_SB(sb);
+
+       if (block_group >= sbi->s_groups_count) {
+               ext4_error (sb, "ext4_get_group_desc",
+                           "block_group >= groups_count - "
+                           "block_group = %d, groups_count = %lu",
+                           block_group, sbi->s_groups_count);
+
+               return NULL;
+       }
+       smp_rmb();
+
+       group_desc = block_group >> EXT4_DESC_PER_BLOCK_BITS(sb);
+       offset = block_group & (EXT4_DESC_PER_BLOCK(sb) - 1);
+       if (!sbi->s_group_desc[group_desc]) {
+               ext4_error (sb, "ext4_get_group_desc",
+                           "Group descriptor not loaded - "
+                           "block_group = %d, group_desc = %lu, desc = %lu",
+                            block_group, group_desc, offset);
+               return NULL;
+       }
+
+       desc = (struct ext4_group_desc *)(
+               (__u8 *)sbi->s_group_desc[group_desc]->b_data +
+               offset * EXT4_DESC_SIZE(sb));
+       if (bh)
+               *bh = sbi->s_group_desc[group_desc];
+       return desc;
+}
+
+/**
+ * read_block_bitmap()
+ * @sb:                        super block
+ * @block_group:       given block group
+ *
+ * Read the bitmap for a given block_group, reading into the specified
+ * slot in the superblock's bitmap cache.
+ *
+ * Return buffer_head on success or NULL in case of failure.
+ */
+static struct buffer_head *
+read_block_bitmap(struct super_block *sb, unsigned int block_group)
+{
+       struct ext4_group_desc * desc;
+       struct buffer_head * bh = NULL;
+
+       desc = ext4_get_group_desc (sb, block_group, NULL);
+       if (!desc)
+               goto error_out;
+       bh = sb_bread(sb, ext4_block_bitmap(sb, desc));
+       if (!bh)
+               ext4_error (sb, "read_block_bitmap",
+                           "Cannot read block bitmap - "
+                           "block_group = %d, block_bitmap = %llu",
+                           block_group,
+                           ext4_block_bitmap(sb, desc));
+error_out:
+       return bh;
+}
+/*
+ * The reservation window structure operations
+ * --------------------------------------------
+ * Operations include:
+ * dump, find, add, remove, is_empty, find_next_reservable_window, etc.
+ *
+ * We use a red-black tree to represent per-filesystem reservation
+ * windows.
+ *
+ */
+
+/**
+ * __rsv_window_dump() -- Dump the filesystem block allocation reservation map
+ * @rb_root:           root of per-filesystem reservation rb tree
+ * @verbose:           verbose mode
+ * @fn:                        function which wishes to dump the reservation map
+ *
+ * If verbose is turned on, it will print the whole block reservation
+ * windows(start, end).        Otherwise, it will only print out the "bad" windows,
+ * those windows that overlap with their immediate neighbors.
+ */
+#if 1
+static void __rsv_window_dump(struct rb_root *root, int verbose,
+                             const char *fn)
+{
+       struct rb_node *n;
+       struct ext4_reserve_window_node *rsv, *prev;
+       int bad;
+
+restart:
+       n = rb_first(root);
+       bad = 0;
+       prev = NULL;
+
+       printk("Block Allocation Reservation Windows Map (%s):\n", fn);
+       while (n) {
+               rsv = list_entry(n, struct ext4_reserve_window_node, rsv_node);
+               if (verbose)
+                       printk("reservation window 0x%p "
+                              "start:  %llu, end:  %llu\n",
+                              rsv, rsv->rsv_start, rsv->rsv_end);
+               if (rsv->rsv_start && rsv->rsv_start >= rsv->rsv_end) {
+                       printk("Bad reservation %p (start >= end)\n",
+                              rsv);
+                       bad = 1;
+               }
+               if (prev && prev->rsv_end >= rsv->rsv_start) {
+                       printk("Bad reservation %p (prev->end >= start)\n",
+                              rsv);
+                       bad = 1;
+               }
+               if (bad) {
+                       if (!verbose) {
+                               printk("Restarting reservation walk in verbose mode\n");
+                               verbose = 1;
+                               goto restart;
+                       }
+               }
+               n = rb_next(n);
+               prev = rsv;
+       }
+       printk("Window map complete.\n");
+       if (bad)
+               BUG();
+}
+#define rsv_window_dump(root, verbose) \
+       __rsv_window_dump((root), (verbose), __FUNCTION__)
+#else
+#define rsv_window_dump(root, verbose) do {} while (0)
+#endif
+
+/**
+ * goal_in_my_reservation()
+ * @rsv:               inode's reservation window
+ * @grp_goal:          given goal block relative to the allocation block group
+ * @group:             the current allocation block group
+ * @sb:                        filesystem super block
+ *
+ * Test if the given goal block (group relative) is within the file's
+ * own block reservation window range.
+ *
+ * If the reservation window is outside the goal allocation group, return 0;
+ * grp_goal (given goal block) could be -1, which means no specific
+ * goal block. In this case, always return 1.
+ * If the goal block is within the reservation window, return 1;
+ * otherwise, return 0;
+ */
+static int
+goal_in_my_reservation(struct ext4_reserve_window *rsv, ext4_grpblk_t grp_goal,
+                       unsigned int group, struct super_block * sb)
+{
+       ext4_fsblk_t group_first_block, group_last_block;
+
+       group_first_block = ext4_group_first_block_no(sb, group);
+       group_last_block = group_first_block + (EXT4_BLOCKS_PER_GROUP(sb) - 1);
+
+       if ((rsv->_rsv_start > group_last_block) ||
+           (rsv->_rsv_end < group_first_block))
+               return 0;
+       if ((grp_goal >= 0) && ((grp_goal + group_first_block < rsv->_rsv_start)
+               || (grp_goal + group_first_block > rsv->_rsv_end)))
+               return 0;
+       return 1;
+}
+
+/**
+ * search_reserve_window()
+ * @rb_root:           root of reservation tree
+ * @goal:              target allocation block
+ *
+ * Find the reserved window which includes the goal, or the previous one
+ * if the goal is not in any window.
+ * Returns NULL if there are no windows or if all windows start after the goal.
+ */
+static struct ext4_reserve_window_node *
+search_reserve_window(struct rb_root *root, ext4_fsblk_t goal)
+{
+       struct rb_node *n = root->rb_node;
+       struct ext4_reserve_window_node *rsv;
+
+       if (!n)
+               return NULL;
+
+       do {
+               rsv = rb_entry(n, struct ext4_reserve_window_node, rsv_node);
+
+               if (goal < rsv->rsv_start)
+                       n = n->rb_left;
+               else if (goal > rsv->rsv_end)
+                       n = n->rb_right;
+               else
+                       return rsv;
+       } while (n);
+       /*
+        * We've fallen off the end of the tree: the goal wasn't inside
+        * any particular node.  OK, the previous node must be to one
+        * side of the interval containing the goal.  If it's the RHS,
+        * we need to back up one.
+        */
+       if (rsv->rsv_start > goal) {
+               n = rb_prev(&rsv->rsv_node);
+               rsv = rb_entry(n, struct ext4_reserve_window_node, rsv_node);
+       }
+       return rsv;
+}
+
+/**
+ * ext4_rsv_window_add() -- Insert a window to the block reservation rb tree.
+ * @sb:                        super block
+ * @rsv:               reservation window to add
+ *
+ * Must be called with rsv_lock hold.
+ */
+void ext4_rsv_window_add(struct super_block *sb,
+                   struct ext4_reserve_window_node *rsv)
+{
+       struct rb_root *root = &EXT4_SB(sb)->s_rsv_window_root;
+       struct rb_node *node = &rsv->rsv_node;
+       ext4_fsblk_t start = rsv->rsv_start;
+
+       struct rb_node ** p = &root->rb_node;
+       struct rb_node * parent = NULL;
+       struct ext4_reserve_window_node *this;
+
+       while (*p)
+       {
+               parent = *p;
+               this = rb_entry(parent, struct ext4_reserve_window_node, rsv_node);
+
+               if (start < this->rsv_start)
+                       p = &(*p)->rb_left;
+               else if (start > this->rsv_end)
+                       p = &(*p)->rb_right;
+               else {
+                       rsv_window_dump(root, 1);
+                       BUG();
+               }
+       }
+
+       rb_link_node(node, parent, p);
+       rb_insert_color(node, root);
+}
+
+/**
+ * ext4_rsv_window_remove() -- unlink a window from the reservation rb tree
+ * @sb:                        super block
+ * @rsv:               reservation window to remove
+ *
+ * Mark the block reservation window as not allocated, and unlink it
+ * from the filesystem reservation window rb tree. Must be called with
+ * rsv_lock hold.
+ */
+static void rsv_window_remove(struct super_block *sb,
+                             struct ext4_reserve_window_node *rsv)
+{
+       rsv->rsv_start = EXT4_RESERVE_WINDOW_NOT_ALLOCATED;
+       rsv->rsv_end = EXT4_RESERVE_WINDOW_NOT_ALLOCATED;
+       rsv->rsv_alloc_hit = 0;
+       rb_erase(&rsv->rsv_node, &EXT4_SB(sb)->s_rsv_window_root);
+}
+
+/*
+ * rsv_is_empty() -- Check if the reservation window is allocated.
+ * @rsv:               given reservation window to check
+ *
+ * returns 1 if the end block is EXT4_RESERVE_WINDOW_NOT_ALLOCATED.
+ */
+static inline int rsv_is_empty(struct ext4_reserve_window *rsv)
+{
+       /* a valid reservation end block could not be 0 */
+       return rsv->_rsv_end == EXT4_RESERVE_WINDOW_NOT_ALLOCATED;
+}
+
+/**
+ * ext4_init_block_alloc_info()
+ * @inode:             file inode structure
+ *
+ * Allocate and initialize the reservation window structure, and
+ * link the window to the ext4 inode structure at last
+ *
+ * The reservation window structure is only dynamically allocated
+ * and linked to ext4 inode the first time the open file
+ * needs a new block. So, before every ext4_new_block(s) call, for
+ * regular files, we should check whether the reservation window
+ * structure exists or not. In the latter case, this function is called.
+ * Fail to do so will result in block reservation being turned off for that
+ * open file.
+ *
+ * This function is called from ext4_get_blocks_handle(), also called
+ * when setting the reservation window size through ioctl before the file
+ * is open for write (needs block allocation).
+ *
+ * Needs truncate_mutex protection prior to call this function.
+ */
+void ext4_init_block_alloc_info(struct inode *inode)
+{
+       struct ext4_inode_info *ei = EXT4_I(inode);
+       struct ext4_block_alloc_info *block_i = ei->i_block_alloc_info;
+       struct super_block *sb = inode->i_sb;
+
+       block_i = kmalloc(sizeof(*block_i), GFP_NOFS);
+       if (block_i) {
+               struct ext4_reserve_window_node *rsv = &block_i->rsv_window_node;
+
+               rsv->rsv_start = EXT4_RESERVE_WINDOW_NOT_ALLOCATED;
+               rsv->rsv_end = EXT4_RESERVE_WINDOW_NOT_ALLOCATED;
+
+               /*
+                * if filesystem is mounted with NORESERVATION, the goal
+                * reservation window size is set to zero to indicate
+                * block reservation is off
+                */
+               if (!test_opt(sb, RESERVATION))
+                       rsv->rsv_goal_size = 0;
+               else
+                       rsv->rsv_goal_size = EXT4_DEFAULT_RESERVE_BLOCKS;
+               rsv->rsv_alloc_hit = 0;
+               block_i->last_alloc_logical_block = 0;
+               block_i->last_alloc_physical_block = 0;
+       }
+       ei->i_block_alloc_info = block_i;
+}
+
+/**
+ * ext4_discard_reservation()
+ * @inode:             inode
+ *
+ * Discard(free) block reservation window on last file close, or truncate
+ * or at last iput().
+ *
+ * It is being called in three cases:
+ *     ext4_release_file(): last writer close the file
+ *     ext4_clear_inode(): last iput(), when nobody link to this file.
+ *     ext4_truncate(): when the block indirect map is about to change.
+ *
+ */
+void ext4_discard_reservation(struct inode *inode)
+{
+       struct ext4_inode_info *ei = EXT4_I(inode);
+       struct ext4_block_alloc_info *block_i = ei->i_block_alloc_info;
+       struct ext4_reserve_window_node *rsv;
+       spinlock_t *rsv_lock = &EXT4_SB(inode->i_sb)->s_rsv_window_lock;
+
+       if (!block_i)
+               return;
+
+       rsv = &block_i->rsv_window_node;
+       if (!rsv_is_empty(&rsv->rsv_window)) {
+               spin_lock(rsv_lock);
+               if (!rsv_is_empty(&rsv->rsv_window))
+                       rsv_window_remove(inode->i_sb, rsv);
+               spin_unlock(rsv_lock);
+       }
+}
+
+/**
+ * ext4_free_blocks_sb() -- Free given blocks and update quota
+ * @handle:                    handle to this transaction
+ * @sb:                                super block
+ * @block:                     start physcial block to free
+ * @count:                     number of blocks to free
+ * @pdquot_freed_blocks:       pointer to quota
+ */
+void ext4_free_blocks_sb(handle_t *handle, struct super_block *sb,
+                        ext4_fsblk_t block, unsigned long count,
+                        unsigned long *pdquot_freed_blocks)
+{
+       struct buffer_head *bitmap_bh = NULL;
+       struct buffer_head *gd_bh;
+       unsigned long block_group;
+       ext4_grpblk_t bit;
+       unsigned long i;
+       unsigned long overflow;
+       struct ext4_group_desc * desc;
+       struct ext4_super_block * es;
+       struct ext4_sb_info *sbi;
+       int err = 0, ret;
+       ext4_grpblk_t group_freed;
+
+       *pdquot_freed_blocks = 0;
+       sbi = EXT4_SB(sb);
+       es = sbi->s_es;
+       if (block < le32_to_cpu(es->s_first_data_block) ||
+           block + count < block ||
+           block + count > ext4_blocks_count(es)) {
+               ext4_error (sb, "ext4_free_blocks",
+                           "Freeing blocks not in datazone - "
+                           "block = %llu, count = %lu", block, count);
+               goto error_return;
+       }
+
+       ext4_debug ("freeing block(s) %llu-%llu\n", block, block + count - 1);
+
+do_more:
+       overflow = 0;
+       ext4_get_group_no_and_offset(sb, block, &block_group, &bit);
+       /*
+        * Check to see if we are freeing blocks across a group
+        * boundary.
+        */
+       if (bit + count > EXT4_BLOCKS_PER_GROUP(sb)) {
+               overflow = bit + count - EXT4_BLOCKS_PER_GROUP(sb);
+               count -= overflow;
+       }
+       brelse(bitmap_bh);
+       bitmap_bh = read_block_bitmap(sb, block_group);
+       if (!bitmap_bh)
+               goto error_return;
+       desc = ext4_get_group_desc (sb, block_group, &gd_bh);
+       if (!desc)
+               goto error_return;
+
+       if (in_range(ext4_block_bitmap(sb, desc), block, count) ||
+           in_range(ext4_inode_bitmap(sb, desc), block, count) ||
+           in_range(block, ext4_inode_table(sb, desc), sbi->s_itb_per_group) ||
+           in_range(block + count - 1, ext4_inode_table(sb, desc),
+                    sbi->s_itb_per_group))
+               ext4_error (sb, "ext4_free_blocks",
+                           "Freeing blocks in system zones - "
+                           "Block = %llu, count = %lu",
+                           block, count);
+
+       /*
+        * We are about to start releasing blocks in the bitmap,
+        * so we need undo access.
+        */
+       /* @@@ check errors */
+       BUFFER_TRACE(bitmap_bh, "getting undo access");
+       err = ext4_journal_get_undo_access(handle, bitmap_bh);
+       if (err)
+               goto error_return;
+
+       /*
+        * We are about to modify some metadata.  Call the journal APIs
+        * to unshare ->b_data if a currently-committing transaction is
+        * using it
+        */
+       BUFFER_TRACE(gd_bh, "get_write_access");
+       err = ext4_journal_get_write_access(handle, gd_bh);
+       if (err)
+               goto error_return;
+
+       jbd_lock_bh_state(bitmap_bh);
+
+       for (i = 0, group_freed = 0; i < count; i++) {
+               /*
+                * An HJ special.  This is expensive...
+                */
+#ifdef CONFIG_JBD_DEBUG
+               jbd_unlock_bh_state(bitmap_bh);
+               {
+                       struct buffer_head *debug_bh;
+                       debug_bh = sb_find_get_block(sb, block + i);
+                       if (debug_bh) {
+                               BUFFER_TRACE(debug_bh, "Deleted!");
+                               if (!bh2jh(bitmap_bh)->b_committed_data)
+                                       BUFFER_TRACE(debug_bh,
+                                               "No commited data in bitmap");
+                               BUFFER_TRACE2(debug_bh, bitmap_bh, "bitmap");
+                               __brelse(debug_bh);
+                       }
+               }
+               jbd_lock_bh_state(bitmap_bh);
+#endif
+               if (need_resched()) {
+                       jbd_unlock_bh_state(bitmap_bh);
+                       cond_resched();
+                       jbd_lock_bh_state(bitmap_bh);
+               }
+               /* @@@ This prevents newly-allocated data from being
+                * freed and then reallocated within the same
+                * transaction.
+                *
+                * Ideally we would want to allow that to happen, but to
+                * do so requires making jbd2_journal_forget() capable of
+                * revoking the queued write of a data block, which
+                * implies blocking on the journal lock.  *forget()
+                * cannot block due to truncate races.
+                *
+                * Eventually we can fix this by making jbd2_journal_forget()
+                * return a status indicating whether or not it was able
+                * to revoke the buffer.  On successful revoke, it is
+                * safe not to set the allocation bit in the committed
+                * bitmap, because we know that there is no outstanding
+                * activity on the buffer any more and so it is safe to
+                * reallocate it.
+                */
+               BUFFER_TRACE(bitmap_bh, "set in b_committed_data");
+               J_ASSERT_BH(bitmap_bh,
+                               bh2jh(bitmap_bh)->b_committed_data != NULL);
+               ext4_set_bit_atomic(sb_bgl_lock(sbi, block_group), bit + i,
+                               bh2jh(bitmap_bh)->b_committed_data);
+
+               /*
+                * We clear the bit in the bitmap after setting the committed
+                * data bit, because this is the reverse order to that which
+                * the allocator uses.
+                */
+               BUFFER_TRACE(bitmap_bh, "clear bit");
+               if (!ext4_clear_bit_atomic(sb_bgl_lock(sbi, block_group),
+                                               bit + i, bitmap_bh->b_data)) {
+                       jbd_unlock_bh_state(bitmap_bh);
+                       ext4_error(sb, __FUNCTION__,
+                                  "bit already cleared for block %llu",
+                                  (ext4_fsblk_t)(block + i));
+                       jbd_lock_bh_state(bitmap_bh);
+                       BUFFER_TRACE(bitmap_bh, "bit already cleared");
+               } else {
+                       group_freed++;
+               }
+       }
+       jbd_unlock_bh_state(bitmap_bh);
+
+       spin_lock(sb_bgl_lock(sbi, block_group));
+       desc->bg_free_blocks_count =
+               cpu_to_le16(le16_to_cpu(desc->bg_free_blocks_count) +
+                       group_freed);
+       spin_unlock(sb_bgl_lock(sbi, block_group));
+       percpu_counter_mod(&sbi->s_freeblocks_counter, count);
+
+       /* We dirtied the bitmap block */
+       BUFFER_TRACE(bitmap_bh, "dirtied bitmap block");
+       err = ext4_journal_dirty_metadata(handle, bitmap_bh);
+
+       /* And the group descriptor block */
+       BUFFER_TRACE(gd_bh, "dirtied group descriptor block");
+       ret = ext4_journal_dirty_metadata(handle, gd_bh);
+       if (!err) err = ret;
+       *pdquot_freed_blocks += group_freed;
+
+       if (overflow && !err) {
+               block += count;
+               count = overflow;
+               goto do_more;
+       }
+       sb->s_dirt = 1;
+error_return:
+       brelse(bitmap_bh);
+       ext4_std_error(sb, err);
+       return;
+}
+
+/**
+ * ext4_free_blocks() -- Free given blocks and update quota
+ * @handle:            handle for this transaction
+ * @inode:             inode
+ * @block:             start physical block to free
+ * @count:             number of blocks to count
+ */
+void ext4_free_blocks(handle_t *handle, struct inode *inode,
+                       ext4_fsblk_t block, unsigned long count)
+{
+       struct super_block * sb;
+       unsigned long dquot_freed_blocks;
+
+       sb = inode->i_sb;
+       if (!sb) {
+               printk ("ext4_free_blocks: nonexistent device");
+               return;
+       }
+       ext4_free_blocks_sb(handle, sb, block, count, &dquot_freed_blocks);
+       if (dquot_freed_blocks)
+               DQUOT_FREE_BLOCK(inode, dquot_freed_blocks);
+       return;
+}
+
+/**
+ * ext4_test_allocatable()
+ * @nr:                        given allocation block group
+ * @bh:                        bufferhead contains the bitmap of the given block group
+ *
+ * For ext4 allocations, we must not reuse any blocks which are
+ * allocated in the bitmap buffer's "last committed data" copy.  This
+ * prevents deletes from freeing up the page for reuse until we have
+ * committed the delete transaction.
+ *
+ * If we didn't do this, then deleting something and reallocating it as
+ * data would allow the old block to be overwritten before the
+ * transaction committed (because we force data to disk before commit).
+ * This would lead to corruption if we crashed between overwriting the
+ * data and committing the delete.
+ *
+ * @@@ We may want to make this allocation behaviour conditional on
+ * data-writes at some point, and disable it for metadata allocations or
+ * sync-data inodes.
+ */
+static int ext4_test_allocatable(ext4_grpblk_t nr, struct buffer_head *bh)
+{
+       int ret;
+       struct journal_head *jh = bh2jh(bh);
+
+       if (ext4_test_bit(nr, bh->b_data))
+               return 0;
+
+       jbd_lock_bh_state(bh);
+       if (!jh->b_committed_data)
+               ret = 1;
+       else
+               ret = !ext4_test_bit(nr, jh->b_committed_data);
+       jbd_unlock_bh_state(bh);
+       return ret;
+}
+
+/**
+ * bitmap_search_next_usable_block()
+ * @start:             the starting block (group relative) of the search
+ * @bh:                        bufferhead contains the block group bitmap
+ * @maxblocks:         the ending block (group relative) of the reservation
+ *
+ * The bitmap search --- search forward alternately through the actual
+ * bitmap on disk and the last-committed copy in journal, until we find a
+ * bit free in both bitmaps.
+ */
+static ext4_grpblk_t
+bitmap_search_next_usable_block(ext4_grpblk_t start, struct buffer_head *bh,
+                                       ext4_grpblk_t maxblocks)
+{
+       ext4_grpblk_t next;
+       struct journal_head *jh = bh2jh(bh);
+
+       while (start < maxblocks) {
+               next = ext4_find_next_zero_bit(bh->b_data, maxblocks, start);
+               if (next >= maxblocks)
+                       return -1;
+               if (ext4_test_allocatable(next, bh))
+                       return next;
+               jbd_lock_bh_state(bh);
+               if (jh->b_committed_data)
+                       start = ext4_find_next_zero_bit(jh->b_committed_data,
+                                                       maxblocks, next);
+               jbd_unlock_bh_state(bh);
+       }
+       return -1;
+}
+
+/**
+ * find_next_usable_block()
+ * @start:             the starting block (group relative) to find next
+ *                     allocatable block in bitmap.
+ * @bh:                        bufferhead contains the block group bitmap
+ * @maxblocks:         the ending block (group relative) for the search
+ *
+ * Find an allocatable block in a bitmap.  We honor both the bitmap and
+ * its last-committed copy (if that exists), and perform the "most
+ * appropriate allocation" algorithm of looking for a free block near
+ * the initial goal; then for a free byte somewhere in the bitmap; then
+ * for any free bit in the bitmap.
+ */
+static ext4_grpblk_t
+find_next_usable_block(ext4_grpblk_t start, struct buffer_head *bh,
+                       ext4_grpblk_t maxblocks)
+{
+       ext4_grpblk_t here, next;
+       char *p, *r;
+
+       if (start > 0) {
+               /*
+                * The goal was occupied; search forward for a free
+                * block within the next XX blocks.
+                *
+                * end_goal is more or less random, but it has to be
+                * less than EXT4_BLOCKS_PER_GROUP. Aligning up to the
+                * next 64-bit boundary is simple..
+                */
+               ext4_grpblk_t end_goal = (start + 63) & ~63;
+               if (end_goal > maxblocks)
+                       end_goal = maxblocks;
+               here = ext4_find_next_zero_bit(bh->b_data, end_goal, start);
+               if (here < end_goal && ext4_test_allocatable(here, bh))
+                       return here;
+               ext4_debug("Bit not found near goal\n");
+       }
+
+       here = start;
+       if (here < 0)
+               here = 0;
+
+       p = ((char *)bh->b_data) + (here >> 3);
+       r = memscan(p, 0, (maxblocks - here + 7) >> 3);
+       next = (r - ((char *)bh->b_data)) << 3;
+
+       if (next < maxblocks && next >= start && ext4_test_allocatable(next, bh))
+               return next;
+
+       /*
+        * The bitmap search --- search forward alternately through the actual
+        * bitmap and the last-committed copy until we find a bit free in
+        * both
+        */
+       here = bitmap_search_next_usable_block(here, bh, maxblocks);
+       return here;
+}
+
+/**
+ * claim_block()
+ * @block:             the free block (group relative) to allocate
+ * @bh:                        the bufferhead containts the block group bitmap
+ *
+ * We think we can allocate this block in this bitmap.  Try to set the bit.
+ * If that succeeds then check that nobody has allocated and then freed the
+ * block since we saw that is was not marked in b_committed_data.  If it _was_
+ * allocated and freed then clear the bit in the bitmap again and return
+ * zero (failure).
+ */
+static inline int
+claim_block(spinlock_t *lock, ext4_grpblk_t block, struct buffer_head *bh)
+{
+       struct journal_head *jh = bh2jh(bh);
+       int ret;
+
+       if (ext4_set_bit_atomic(lock, block, bh->b_data))
+               return 0;
+       jbd_lock_bh_state(bh);
+       if (jh->b_committed_data && ext4_test_bit(block,jh->b_committed_data)) {
+               ext4_clear_bit_atomic(lock, block, bh->b_data);
+               ret = 0;
+       } else {
+               ret = 1;
+       }
+       jbd_unlock_bh_state(bh);
+       return ret;
+}
+
+/**
+ * ext4_try_to_allocate()
+ * @sb:                        superblock
+ * @handle:            handle to this transaction
+ * @group:             given allocation block group
+ * @bitmap_bh:         bufferhead holds the block bitmap
+ * @grp_goal:          given target block within the group
+ * @count:             target number of blocks to allocate
+ * @my_rsv:            reservation window
+ *
+ * Attempt to allocate blocks within a give range. Set the range of allocation
+ * first, then find the first free bit(s) from the bitmap (within the range),
+ * and at last, allocate the blocks by claiming the found free bit as allocated.
+ *
+ * To set the range of this allocation:
+ *     if there is a reservation window, only try to allocate block(s) from the
+ *     file's own reservation window;
+ *     Otherwise, the allocation range starts from the give goal block, ends at
+ *     the block group's last block.
+ *
+ * If we failed to allocate the desired block then we may end up crossing to a
+ * new bitmap.  In that case we must release write access to the old one via
+ * ext4_journal_release_buffer(), else we'll run out of credits.
+ */
+static ext4_grpblk_t
+ext4_try_to_allocate(struct super_block *sb, handle_t *handle, int group,
+                       struct buffer_head *bitmap_bh, ext4_grpblk_t grp_goal,
+                       unsigned long *count, struct ext4_reserve_window *my_rsv)
+{
+       ext4_fsblk_t group_first_block;
+       ext4_grpblk_t start, end;
+       unsigned long num = 0;
+
+       /* we do allocation within the reservation window if we have a window */
+       if (my_rsv) {
+               group_first_block = ext4_group_first_block_no(sb, group);
+               if (my_rsv->_rsv_start >= group_first_block)
+                       start = my_rsv->_rsv_start - group_first_block;
+               else
+                       /* reservation window cross group boundary */
+                       start = 0;
+               end = my_rsv->_rsv_end - group_first_block + 1;
+               if (end > EXT4_BLOCKS_PER_GROUP(sb))
+                       /* reservation window crosses group boundary */
+                       end = EXT4_BLOCKS_PER_GROUP(sb);
+               if ((start <= grp_goal) && (grp_goal < end))
+                       start = grp_goal;
+               else
+                       grp_goal = -1;
+       } else {
+               if (grp_goal > 0)
+                       start = grp_goal;
+               else
+                       start = 0;
+               end = EXT4_BLOCKS_PER_GROUP(sb);
+       }
+
+       BUG_ON(start > EXT4_BLOCKS_PER_GROUP(sb));
+
+repeat:
+       if (grp_goal < 0 || !ext4_test_allocatable(grp_goal, bitmap_bh)) {
+               grp_goal = find_next_usable_block(start, bitmap_bh, end);
+               if (grp_goal < 0)
+                       goto fail_access;
+               if (!my_rsv) {
+                       int i;
+
+                       for (i = 0; i < 7 && grp_goal > start &&
+                                       ext4_test_allocatable(grp_goal - 1,
+                                                               bitmap_bh);
+                                       i++, grp_goal--)
+                               ;
+               }
+       }
+       start = grp_goal;
+
+       if (!claim_block(sb_bgl_lock(EXT4_SB(sb), group),
+               grp_goal, bitmap_bh)) {
+               /*
+                * The block was allocated by another thread, or it was
+                * allocated and then freed by another thread
+                */
+               start++;
+               grp_goal++;
+               if (start >= end)
+                       goto fail_access;
+               goto repeat;
+       }
+       num++;
+       grp_goal++;
+       while (num < *count && grp_goal < end
+               && ext4_test_allocatable(grp_goal, bitmap_bh)
+               && claim_block(sb_bgl_lock(EXT4_SB(sb), group),
+                               grp_goal, bitmap_bh)) {
+               num++;
+               grp_goal++;
+       }
+       *count = num;
+       return grp_goal - num;
+fail_access:
+       *count = num;
+       return -1;
+}
+
+/**
+ *     find_next_reservable_window():
+ *             find a reservable space within the given range.
+ *             It does not allocate the reservation window for now:
+ *             alloc_new_reservation() will do the work later.
+ *
+ *     @search_head: the head of the searching list;
+ *             This is not necessarily the list head of the whole filesystem
+ *
+ *             We have both head and start_block to assist the search
+ *             for the reservable space. The list starts from head,
+ *             but we will shift to the place where start_block is,
+ *             then start from there, when looking for a reservable space.
+ *
+ *     @size: the target new reservation window size
+ *
+ *     @group_first_block: the first block we consider to start
+ *                     the real search from
+ *
+ *     @last_block:
+ *             the maximum block number that our goal reservable space
+ *             could start from. This is normally the last block in this
+ *             group. The search will end when we found the start of next
+ *             possible reservable space is out of this boundary.
+ *             This could handle the cross boundary reservation window
+ *             request.
+ *
+ *     basically we search from the given range, rather than the whole
+ *     reservation double linked list, (start_block, last_block)
+ *     to find a free region that is of my size and has not
+ *     been reserved.
+ *
+ */
+static int find_next_reservable_window(
+                               struct ext4_reserve_window_node *search_head,
+                               struct ext4_reserve_window_node *my_rsv,
+                               struct super_block * sb,
+                               ext4_fsblk_t start_block,
+                               ext4_fsblk_t last_block)
+{
+       struct rb_node *next;
+       struct ext4_reserve_window_node *rsv, *prev;
+       ext4_fsblk_t cur;
+       int size = my_rsv->rsv_goal_size;
+
+       /* TODO: make the start of the reservation window byte-aligned */
+       /* cur = *start_block & ~7;*/
+       cur = start_block;
+       rsv = search_head;
+       if (!rsv)
+               return -1;
+
+       while (1) {
+               if (cur <= rsv->rsv_end)
+                       cur = rsv->rsv_end + 1;
+
+               /* TODO?
+                * in the case we could not find a reservable space
+                * that is what is expected, during the re-search, we could
+                * remember what's the largest reservable space we could have
+                * and return that one.
+                *
+                * For now it will fail if we could not find the reservable
+                * space with expected-size (or more)...
+                */
+               if (cur > last_block)
+                       return -1;              /* fail */
+
+               prev = rsv;
+               next = rb_next(&rsv->rsv_node);
+               rsv = list_entry(next,struct ext4_reserve_window_node,rsv_node);
+
+               /*
+                * Reached the last reservation, we can just append to the
+                * previous one.
+                */
+               if (!next)
+                       break;
+
+               if (cur + size <= rsv->rsv_start) {
+                       /*
+                        * Found a reserveable space big enough.  We could
+                        * have a reservation across the group boundary here
+                        */
+                       break;
+               }
+       }
+       /*
+        * we come here either :
+        * when we reach the end of the whole list,
+        * and there is empty reservable space after last entry in the list.
+        * append it to the end of the list.
+        *
+        * or we found one reservable space in the middle of the list,
+        * return the reservation window that we could append to.
+        * succeed.
+        */
+
+       if ((prev != my_rsv) && (!rsv_is_empty(&my_rsv->rsv_window)))
+               rsv_window_remove(sb, my_rsv);
+
+       /*
+        * Let's book the whole avaliable window for now.  We will check the
+        * disk bitmap later and then, if there are free blocks then we adjust
+        * the window size if it's larger than requested.
+        * Otherwise, we will remove this node from the tree next time
+        * call find_next_reservable_window.
+        */
+       my_rsv->rsv_start = cur;
+       my_rsv->rsv_end = cur + size - 1;
+       my_rsv->rsv_alloc_hit = 0;
+
+       if (prev != my_rsv)
+               ext4_rsv_window_add(sb, my_rsv);
+
+       return 0;
+}
+
+/**
+ *     alloc_new_reservation()--allocate a new reservation window
+ *
+ *             To make a new reservation, we search part of the filesystem
+ *             reservation list (the list that inside the group). We try to
+ *             allocate a new reservation window near the allocation goal,
+ *             or the beginning of the group, if there is no goal.
+ *
+ *             We first find a reservable space after the goal, then from
+ *             there, we check the bitmap for the first free block after
+ *             it. If there is no free block until the end of group, then the
+ *             whole group is full, we failed. Otherwise, check if the free
+ *             block is inside the expected reservable space, if so, we
+ *             succeed.
+ *             If the first free block is outside the reservable space, then
+ *             start from the first free block, we search for next available
+ *             space, and go on.
+ *
+ *     on succeed, a new reservation will be found and inserted into the list
+ *     It contains at least one free block, and it does not overlap with other
+ *     reservation windows.
+ *
+ *     failed: we failed to find a reservation window in this group
+ *
+ *     @rsv: the reservation
+ *
+ *     @grp_goal: The goal (group-relative).  It is where the search for a
+ *             free reservable space should start from.
+ *             if we have a grp_goal(grp_goal >0 ), then start from there,
+ *             no grp_goal(grp_goal = -1), we start from the first block
+ *             of the group.
+ *
+ *     @sb: the super block
+ *     @group: the group we are trying to allocate in
+ *     @bitmap_bh: the block group block bitmap
+ *
+ */
+static int alloc_new_reservation(struct ext4_reserve_window_node *my_rsv,
+               ext4_grpblk_t grp_goal, struct super_block *sb,
+               unsigned int group, struct buffer_head *bitmap_bh)
+{
+       struct ext4_reserve_window_node *search_head;
+       ext4_fsblk_t group_first_block, group_end_block, start_block;
+       ext4_grpblk_t first_free_block;
+       struct rb_root *fs_rsv_root = &EXT4_SB(sb)->s_rsv_window_root;
+       unsigned long size;
+       int ret;
+       spinlock_t *rsv_lock = &EXT4_SB(sb)->s_rsv_window_lock;
+
+       group_first_block = ext4_group_first_block_no(sb, group);
+       group_end_block = group_first_block + (EXT4_BLOCKS_PER_GROUP(sb) - 1);
+
+       if (grp_goal < 0)
+               start_block = group_first_block;
+       else
+               start_block = grp_goal + group_first_block;
+
+       size = my_rsv->rsv_goal_size;
+
+       if (!rsv_is_empty(&my_rsv->rsv_window)) {
+               /*
+                * if the old reservation is cross group boundary
+                * and if the goal is inside the old reservation window,
+                * we will come here when we just failed to allocate from
+                * the first part of the window. We still have another part
+                * that belongs to the next group. In this case, there is no
+                * point to discard our window and try to allocate a new one
+                * in this group(which will fail). we should
+                * keep the reservation window, just simply move on.
+                *
+                * Maybe we could shift the start block of the reservation
+                * window to the first block of next group.
+                */
+
+               if ((my_rsv->rsv_start <= group_end_block) &&
+                               (my_rsv->rsv_end > group_end_block) &&
+                               (start_block >= my_rsv->rsv_start))
+                       return -1;
+
+               if ((my_rsv->rsv_alloc_hit >
+                    (my_rsv->rsv_end - my_rsv->rsv_start + 1) / 2)) {
+                       /*
+                        * if the previously allocation hit ratio is
+                        * greater than 1/2, then we double the size of
+                        * the reservation window the next time,
+                        * otherwise we keep the same size window
+                        */
+                       size = size * 2;
+                       if (size > EXT4_MAX_RESERVE_BLOCKS)
+                               size = EXT4_MAX_RESERVE_BLOCKS;
+                       my_rsv->rsv_goal_size= size;
+               }
+       }
+
+       spin_lock(rsv_lock);
+       /*
+        * shift the search start to the window near the goal block
+        */
+       search_head = search_reserve_window(fs_rsv_root, start_block);
+
+       /*
+        * find_next_reservable_window() simply finds a reservable window
+        * inside the given range(start_block, group_end_block).
+        *
+        * To make sure the reservation window has a free bit inside it, we
+        * need to check the bitmap after we found a reservable window.
+        */
+retry:
+       ret = find_next_reservable_window(search_head, my_rsv, sb,
+                                               start_block, group_end_block);
+
+       if (ret == -1) {
+               if (!rsv_is_empty(&my_rsv->rsv_window))
+                       rsv_window_remove(sb, my_rsv);
+               spin_unlock(rsv_lock);
+               return -1;
+       }
+
+       /*
+        * On success, find_next_reservable_window() returns the
+        * reservation window where there is a reservable space after it.
+        * Before we reserve this reservable space, we need
+        * to make sure there is at least a free block inside this region.
+        *
+        * searching the first free bit on the block bitmap and copy of
+        * last committed bitmap alternatively, until we found a allocatable
+        * block. Search start from the start block of the reservable space
+        * we just found.
+        */
+       spin_unlock(rsv_lock);
+       first_free_block = bitmap_search_next_usable_block(
+                       my_rsv->rsv_start - group_first_block,
+                       bitmap_bh, group_end_block - group_first_block + 1);
+
+       if (first_free_block < 0) {
+               /*
+                * no free block left on the bitmap, no point
+                * to reserve the space. return failed.
+                */
+               spin_lock(rsv_lock);
+               if (!rsv_is_empty(&my_rsv->rsv_window))
+                       rsv_window_remove(sb, my_rsv);
+               spin_unlock(rsv_lock);
+               return -1;              /* failed */
+       }
+
+       start_block = first_free_block + group_first_block;
+       /*
+        * check if the first free block is within the
+        * free space we just reserved
+        */
+       if (start_block >= my_rsv->rsv_start && start_block < my_rsv->rsv_end)
+               return 0;               /* success */
+       /*
+        * if the first free bit we found is out of the reservable space
+        * continue search for next reservable space,
+        * start from where the free block is,
+        * we also shift the list head to where we stopped last time
+        */
+       search_head = my_rsv;
+       spin_lock(rsv_lock);
+       goto retry;
+}
+
+/**
+ * try_to_extend_reservation()
+ * @my_rsv:            given reservation window
+ * @sb:                        super block
+ * @size:              the delta to extend
+ *
+ * Attempt to expand the reservation window large enough to have
+ * required number of free blocks
+ *
+ * Since ext4_try_to_allocate() will always allocate blocks within
+ * the reservation window range, if the window size is too small,
+ * multiple blocks allocation has to stop at the end of the reservation
+ * window. To make this more efficient, given the total number of
+ * blocks needed and the current size of the window, we try to
+ * expand the reservation window size if necessary on a best-effort
+ * basis before ext4_new_blocks() tries to allocate blocks,
+ */
+static void try_to_extend_reservation(struct ext4_reserve_window_node *my_rsv,
+                       struct super_block *sb, int size)
+{
+       struct ext4_reserve_window_node *next_rsv;
+       struct rb_node *next;
+       spinlock_t *rsv_lock = &EXT4_SB(sb)->s_rsv_window_lock;
+
+       if (!spin_trylock(rsv_lock))
+               return;
+
+       next = rb_next(&my_rsv->rsv_node);
+
+       if (!next)
+               my_rsv->rsv_end += size;
+       else {
+               next_rsv = list_entry(next, struct ext4_reserve_window_node, rsv_node);
+
+               if ((next_rsv->rsv_start - my_rsv->rsv_end - 1) >= size)
+                       my_rsv->rsv_end += size;
+               else
+                       my_rsv->rsv_end = next_rsv->rsv_start - 1;
+       }
+       spin_unlock(rsv_lock);
+}
+
+/**
+ * ext4_try_to_allocate_with_rsv()
+ * @sb:                        superblock
+ * @handle:            handle to this transaction
+ * @group:             given allocation block group
+ * @bitmap_bh:         bufferhead holds the block bitmap
+ * @grp_goal:          given target block within the group
+ * @count:             target number of blocks to allocate
+ * @my_rsv:            reservation window
+ * @errp:              pointer to store the error code
+ *
+ * This is the main function used to allocate a new block and its reservation
+ * window.
+ *
+ * Each time when a new block allocation is need, first try to allocate from
+ * its own reservation.  If it does not have a reservation window, instead of
+ * looking for a free bit on bitmap first, then look up the reservation list to
+ * see if it is inside somebody else's reservation window, we try to allocate a
+ * reservation window for it starting from the goal first. Then do the block
+ * allocation within the reservation window.
+ *
+ * This will avoid keeping on searching the reservation list again and
+ * again when somebody is looking for a free block (without
+ * reservation), and there are lots of free blocks, but they are all
+ * being reserved.
+ *
+ * We use a red-black tree for the per-filesystem reservation list.
+ *
+ */
+static ext4_grpblk_t
+ext4_try_to_allocate_with_rsv(struct super_block *sb, handle_t *handle,
+                       unsigned int group, struct buffer_head *bitmap_bh,
+                       ext4_grpblk_t grp_goal,
+                       struct ext4_reserve_window_node * my_rsv,
+                       unsigned long *count, int *errp)
+{
+       ext4_fsblk_t group_first_block, group_last_block;
+       ext4_grpblk_t ret = 0;
+       int fatal;
+       unsigned long num = *count;
+
+       *errp = 0;
+
+       /*
+        * Make sure we use undo access for the bitmap, because it is critical
+        * that we do the frozen_data COW on bitmap buffers in all cases even
+        * if the buffer is in BJ_Forget state in the committing transaction.
+        */
+       BUFFER_TRACE(bitmap_bh, "get undo access for new block");
+       fatal = ext4_journal_get_undo_access(handle, bitmap_bh);
+       if (fatal) {
+               *errp = fatal;
+               return -1;
+       }
+
+       /*
+        * we don't deal with reservation when
+        * filesystem is mounted without reservation
+        * or the file is not a regular file
+        * or last attempt to allocate a block with reservation turned on failed
+        */
+       if (my_rsv == NULL ) {
+               ret = ext4_try_to_allocate(sb, handle, group, bitmap_bh,
+                                               grp_goal, count, NULL);
+               goto out;
+       }
+       /*
+        * grp_goal is a group relative block number (if there is a goal)
+        * 0 < grp_goal < EXT4_BLOCKS_PER_GROUP(sb)
+        * first block is a filesystem wide block number
+        * first block is the block number of the first block in this group
+        */
+       group_first_block = ext4_group_first_block_no(sb, group);
+       group_last_block = group_first_block + (EXT4_BLOCKS_PER_GROUP(sb) - 1);
+
+       /*
+        * Basically we will allocate a new block from inode's reservation
+        * window.
+        *
+        * We need to allocate a new reservation window, if:
+        * a) inode does not have a reservation window; or
+        * b) last attempt to allocate a block from existing reservation
+        *    failed; or
+        * c) we come here with a goal and with a reservation window
+        *
+        * We do not need to allocate a new reservation window if we come here
+        * at the beginning with a goal and the goal is inside the window, or
+        * we don't have a goal but already have a reservation window.
+        * then we could go to allocate from the reservation window directly.
+        */
+       while (1) {
+               if (rsv_is_empty(&my_rsv->rsv_window) || (ret < 0) ||
+                       !goal_in_my_reservation(&my_rsv->rsv_window,
+                                               grp_goal, group, sb)) {
+                       if (my_rsv->rsv_goal_size < *count)
+                               my_rsv->rsv_goal_size = *count;
+                       ret = alloc_new_reservation(my_rsv, grp_goal, sb,
+                                                       group, bitmap_bh);
+                       if (ret < 0)
+                               break;                  /* failed */
+
+                       if (!goal_in_my_reservation(&my_rsv->rsv_window,
+                                                       grp_goal, group, sb))
+                               grp_goal = -1;
+               } else if (grp_goal > 0 &&
+                         (my_rsv->rsv_end-grp_goal+1) < *count)
+                       try_to_extend_reservation(my_rsv, sb,
+                                       *count-my_rsv->rsv_end + grp_goal - 1);
+
+               if ((my_rsv->rsv_start > group_last_block) ||
+                               (my_rsv->rsv_end < group_first_block)) {
+                       rsv_window_dump(&EXT4_SB(sb)->s_rsv_window_root, 1);
+                       BUG();
+               }
+               ret = ext4_try_to_allocate(sb, handle, group, bitmap_bh,
+                                          grp_goal, &num, &my_rsv->rsv_window);
+               if (ret >= 0) {
+                       my_rsv->rsv_alloc_hit += num;
+                       *count = num;
+                       break;                          /* succeed */
+               }
+               num = *count;
+       }
+out:
+       if (ret >= 0) {
+               BUFFER_TRACE(bitmap_bh, "journal_dirty_metadata for "
+                                       "bitmap block");
+               fatal = ext4_journal_dirty_metadata(handle, bitmap_bh);
+               if (fatal) {
+                       *errp = fatal;
+                       return -1;
+               }
+               return ret;
+       }
+
+       BUFFER_TRACE(bitmap_bh, "journal_release_buffer");
+       ext4_journal_release_buffer(handle, bitmap_bh);
+       return ret;
+}
+
+/**
+ * ext4_has_free_blocks()
+ * @sbi:               in-core super block structure.
+ *
+ * Check if filesystem has at least 1 free block available for allocation.
+ */
+static int ext4_has_free_blocks(struct ext4_sb_info *sbi)
+{
+       ext4_fsblk_t free_blocks, root_blocks;
+
+       free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
+       root_blocks = ext4_r_blocks_count(sbi->s_es);
+       if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) &&
+               sbi->s_resuid != current->fsuid &&
+               (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
+               return 0;
+       }
+       return 1;
+}
+
+/**
+ * ext4_should_retry_alloc()
+ * @sb:                        super block
+ * @retries            number of attemps has been made
+ *
+ * ext4_should_retry_alloc() is called when ENOSPC is returned, and if
+ * it is profitable to retry the operation, this function will wait
+ * for the current or commiting transaction to complete, and then
+ * return TRUE.
+ *
+ * if the total number of retries exceed three times, return FALSE.
+ */
+int ext4_should_retry_alloc(struct super_block *sb, int *retries)
+{
+       if (!ext4_has_free_blocks(EXT4_SB(sb)) || (*retries)++ > 3)
+               return 0;
+
+       jbd_debug(1, "%s: retrying operation after ENOSPC\n", sb->s_id);
+
+       return jbd2_journal_force_commit_nested(EXT4_SB(sb)->s_journal);
+}
+
+/**
+ * ext4_new_blocks() -- core block(s) allocation function
+ * @handle:            handle to this transaction
+ * @inode:             file inode
+ * @goal:              given target block(filesystem wide)
+ * @count:             target number of blocks to allocate
+ * @errp:              error code
+ *
+ * ext4_new_blocks uses a goal block to assist allocation.  It tries to
+ * allocate block(s) from the block group contains the goal block first. If that
+ * fails, it will try to allocate block(s) from other block groups without
+ * any specific goal block.
+ *
+ */
+ext4_fsblk_t ext4_new_blocks(handle_t *handle, struct inode *inode,
+                       ext4_fsblk_t goal, unsigned long *count, int *errp)
+{
+       struct buffer_head *bitmap_bh = NULL;
+       struct buffer_head *gdp_bh;
+       unsigned long group_no;
+       int goal_group;
+       ext4_grpblk_t grp_target_blk;   /* blockgroup relative goal block */
+       ext4_grpblk_t grp_alloc_blk;    /* blockgroup-relative allocated block*/
+       ext4_fsblk_t ret_block;         /* filesyetem-wide allocated block */
+       int bgi;                        /* blockgroup iteration index */
+       int fatal = 0, err;
+       int performed_allocation = 0;
+       ext4_grpblk_t free_blocks;      /* number of free blocks in a group */
+       struct super_block *sb;
+       struct ext4_group_desc *gdp;
+       struct ext4_super_block *es;
+       struct ext4_sb_info *sbi;
+       struct ext4_reserve_window_node *my_rsv = NULL;
+       struct ext4_block_alloc_info *block_i;
+       unsigned short windowsz = 0;
+#ifdef EXT4FS_DEBUG
+       static int goal_hits, goal_attempts;
+#endif
+       unsigned long ngroups;
+       unsigned long num = *count;
+
+       *errp = -ENOSPC;
+       sb = inode->i_sb;
+       if (!sb) {
+               printk("ext4_new_block: nonexistent device");
+               return 0;
+       }
+
+       /*
+        * Check quota for allocation of this block.
+        */
+       if (DQUOT_ALLOC_BLOCK(inode, num)) {
+               *errp = -EDQUOT;
+               return 0;
+       }
+
+       sbi = EXT4_SB(sb);
+       es = EXT4_SB(sb)->s_es;
+       ext4_debug("goal=%lu.\n", goal);
+       /*
+        * Allocate a block from reservation only when
+        * filesystem is mounted with reservation(default,-o reservation), and
+        * it's a regular file, and
+        * the desired window size is greater than 0 (One could use ioctl
+        * command EXT4_IOC_SETRSVSZ to set the window size to 0 to turn off
+        * reservation on that particular file)
+        */
+       block_i = EXT4_I(inode)->i_block_alloc_info;
+       if (block_i && ((windowsz = block_i->rsv_window_node.rsv_goal_size) > 0))
+               my_rsv = &block_i->rsv_window_node;
+
+       if (!ext4_has_free_blocks(sbi)) {
+               *errp = -ENOSPC;
+               goto out;
+       }
+
+       /*
+        * First, test whether the goal block is free.
+        */
+       if (goal < le32_to_cpu(es->s_first_data_block) ||
+           goal >= ext4_blocks_count(es))
+               goal = le32_to_cpu(es->s_first_data_block);
+       ext4_get_group_no_and_offset(sb, goal, &group_no, &grp_target_blk);
+       goal_group = group_no;
+retry_alloc:
+       gdp = ext4_get_group_desc(sb, group_no, &gdp_bh);
+       if (!gdp)
+               goto io_error;
+
+       free_blocks = le16_to_cpu(gdp->bg_free_blocks_count);
+       /*
+        * if there is not enough free blocks to make a new resevation
+        * turn off reservation for this allocation
+        */
+       if (my_rsv && (free_blocks < windowsz)
+               && (rsv_is_empty(&my_rsv->rsv_window)))
+               my_rsv = NULL;
+
+       if (free_blocks > 0) {
+               bitmap_bh = read_block_bitmap(sb, group_no);
+               if (!bitmap_bh)
+                       goto io_error;
+               grp_alloc_blk = ext4_try_to_allocate_with_rsv(sb, handle,
+                                       group_no, bitmap_bh, grp_target_blk,
+                                       my_rsv, &num, &fatal);
+               if (fatal)
+                       goto out;
+               if (grp_alloc_blk >= 0)
+                       goto allocated;
+       }
+
+       ngroups = EXT4_SB(sb)->s_groups_count;
+       smp_rmb();
+
+       /*
+        * Now search the rest of the groups.  We assume that
+        * i and gdp correctly point to the last group visited.
+        */
+       for (bgi = 0; bgi < ngroups; bgi++) {
+               group_no++;
+               if (group_no >= ngroups)
+                       group_no = 0;
+               gdp = ext4_get_group_desc(sb, group_no, &gdp_bh);
+               if (!gdp) {
+                       *errp = -EIO;
+                       goto out;
+               }
+               free_blocks = le16_to_cpu(gdp->bg_free_blocks_count);
+               /*
+                * skip this group if the number of
+                * free blocks is less than half of the reservation
+                * window size.
+                */
+               if (free_blocks <= (windowsz/2))
+                       continue;
+
+               brelse(bitmap_bh);
+               bitmap_bh = read_block_bitmap(sb, group_no);
+               if (!bitmap_bh)
+                       goto io_error;
+               /*
+                * try to allocate block(s) from this group, without a goal(-1).
+                */
+               grp_alloc_blk = ext4_try_to_allocate_with_rsv(sb, handle,
+                                       group_no, bitmap_bh, -1, my_rsv,
+                                       &num, &fatal);
+               if (fatal)
+                       goto out;
+               if (grp_alloc_blk >= 0)
+                       goto allocated;
+       }
+       /*
+        * We may end up a bogus ealier ENOSPC error due to
+        * filesystem is "full" of reservations, but
+        * there maybe indeed free blocks avaliable on disk
+        * In this case, we just forget about the reservations
+        * just do block allocation as without reservations.
+        */
+       if (my_rsv) {
+               my_rsv = NULL;
+               group_no = goal_group;
+               goto retry_alloc;
+       }
+       /* No space left on the device */
+       *errp = -ENOSPC;
+       goto out;
+
+allocated:
+
+       ext4_debug("using block group %d(%d)\n",
+                       group_no, gdp->bg_free_blocks_count);
+
+       BUFFER_TRACE(gdp_bh, "get_write_access");
+       fatal = ext4_journal_get_write_access(handle, gdp_bh);
+       if (fatal)
+               goto out;
+
+       ret_block = grp_alloc_blk + ext4_group_first_block_no(sb, group_no);
+
+       if (in_range(ext4_block_bitmap(sb, gdp), ret_block, num) ||
+           in_range(ext4_block_bitmap(sb, gdp), ret_block, num) ||
+           in_range(ret_block, ext4_inode_table(sb, gdp),
+                    EXT4_SB(sb)->s_itb_per_group) ||
+           in_range(ret_block + num - 1, ext4_inode_table(sb, gdp),
+                    EXT4_SB(sb)->s_itb_per_group))
+               ext4_error(sb, "ext4_new_block",
+                           "Allocating block in system zone - "
+                           "blocks from %llu, length %lu",
+                            ret_block, num);
+
+       performed_allocation = 1;
+
+#ifdef CONFIG_JBD_DEBUG
+       {
+               struct buffer_head *debug_bh;
+
+               /* Record bitmap buffer state in the newly allocated block */
+               debug_bh = sb_find_get_block(sb, ret_block);
+               if (debug_bh) {
+                       BUFFER_TRACE(debug_bh, "state when allocated");
+                       BUFFER_TRACE2(debug_bh, bitmap_bh, "bitmap state");
+                       brelse(debug_bh);
+               }
+       }
+       jbd_lock_bh_state(bitmap_bh);
+       spin_lock(sb_bgl_lock(sbi, group_no));
+       if (buffer_jbd(bitmap_bh) && bh2jh(bitmap_bh)->b_committed_data) {
+               int i;
+
+               for (i = 0; i < num; i++) {
+                       if (ext4_test_bit(grp_alloc_blk+i,
+                                       bh2jh(bitmap_bh)->b_committed_data)) {
+                               printk("%s: block was unexpectedly set in "
+                                       "b_committed_data\n", __FUNCTION__);
+                       }
+               }
+       }
+       ext4_debug("found bit %d\n", grp_alloc_blk);
+       spin_unlock(sb_bgl_lock(sbi, group_no));
+       jbd_unlock_bh_state(bitmap_bh);
+#endif
+
+       if (ret_block + num - 1 >= ext4_blocks_count(es)) {
+               ext4_error(sb, "ext4_new_block",
+                           "block(%llu) >= blocks count(%llu) - "
+                           "block_group = %lu, es == %p ", ret_block,
+                       ext4_blocks_count(es), group_no, es);
+               goto out;
+       }
+
+       /*
+        * It is up to the caller to add the new buffer to a journal
+        * list of some description.  We don't know in advance whether
+        * the caller wants to use it as metadata or data.
+        */
+       ext4_debug("allocating block %lu. Goal hits %d of %d.\n",
+                       ret_block, goal_hits, goal_attempts);
+
+       spin_lock(sb_bgl_lock(sbi, group_no));
+       gdp->bg_free_blocks_count =
+                       cpu_to_le16(le16_to_cpu(gdp->bg_free_blocks_count)-num);
+       spin_unlock(sb_bgl_lock(sbi, group_no));
+       percpu_counter_mod(&sbi->s_freeblocks_counter, -num);
+
+       BUFFER_TRACE(gdp_bh, "journal_dirty_metadata for group descriptor");
+       err = ext4_journal_dirty_metadata(handle, gdp_bh);
+       if (!fatal)
+               fatal = err;
+
+       sb->s_dirt = 1;
+       if (fatal)
+               goto out;
+
+       *errp = 0;
+       brelse(bitmap_bh);
+       DQUOT_FREE_BLOCK(inode, *count-num);
+       *count = num;
+       return ret_block;
+
+io_error:
+       *errp = -EIO;
+out:
+       if (fatal) {
+               *errp = fatal;
+               ext4_std_error(sb, fatal);
+       }
+       /*
+        * Undo the block allocation
+        */
+       if (!performed_allocation)
+               DQUOT_FREE_BLOCK(inode, *count);
+       brelse(bitmap_bh);
+       return 0;
+}
+
+ext4_fsblk_t ext4_new_block(handle_t *handle, struct inode *inode,
+                       ext4_fsblk_t goal, int *errp)
+{
+       unsigned long count = 1;
+
+       return ext4_new_blocks(handle, inode, goal, &count, errp);
+}
+
+/**
+ * ext4_count_free_blocks() -- count filesystem free blocks
+ * @sb:                superblock
+ *
+ * Adds up the number of free blocks from each block group.
+ */
+ext4_fsblk_t ext4_count_free_blocks(struct super_block *sb)
+{
+       ext4_fsblk_t desc_count;
+       struct ext4_group_desc *gdp;
+       int i;
+       unsigned long ngroups = EXT4_SB(sb)->s_groups_count;
+#ifdef EXT4FS_DEBUG
+       struct ext4_super_block *es;
+       ext4_fsblk_t bitmap_count;
+       unsigned long x;
+       struct buffer_head *bitmap_bh = NULL;
+
+       es = EXT4_SB(sb)->s_es;
+       desc_count = 0;
+       bitmap_count = 0;
+       gdp = NULL;
+
+       smp_rmb();
+       for (i = 0; i < ngroups; i++) {
+               gdp = ext4_get_group_desc(sb, i, NULL);
+               if (!gdp)
+                       continue;
+               desc_count += le16_to_cpu(gdp->bg_free_blocks_count);
+               brelse(bitmap_bh);
+               bitmap_bh = read_block_bitmap(sb, i);
+               if (bitmap_bh == NULL)
+                       continue;
+
+               x = ext4_count_free(bitmap_bh, sb->s_blocksize);
+               printk("group %d: stored = %d, counted = %lu\n",
+                       i, le16_to_cpu(gdp->bg_free_blocks_count), x);
+               bitmap_count += x;
+       }
+       brelse(bitmap_bh);
+       printk("ext4_count_free_blocks: stored = %llu"
+               ", computed = %llu, %llu\n",
+              EXT4_FREE_BLOCKS_COUNT(es),
+               desc_count, bitmap_count);
+       return bitmap_count;
+#else
+       desc_count = 0;
+       smp_rmb();
+       for (i = 0; i < ngroups; i++) {
+               gdp = ext4_get_group_desc(sb, i, NULL);
+               if (!gdp)
+                       continue;
+               desc_count += le16_to_cpu(gdp->bg_free_blocks_count);
+       }
+
+       return desc_count;
+#endif
+}
+
+static inline int
+block_in_use(ext4_fsblk_t block, struct super_block *sb, unsigned char *map)
+{
+       ext4_grpblk_t offset;
+
+       ext4_get_group_no_and_offset(sb, block, NULL, &offset);
+       return ext4_test_bit (offset, map);
+}
+
+static inline int test_root(int a, int b)
+{
+       int num = b;
+
+       while (a > num)
+               num *= b;
+       return num == a;
+}
+
+static int ext4_group_sparse(int group)
+{
+       if (group <= 1)
+               return 1;
+       if (!(group & 1))
+               return 0;
+       return (test_root(group, 7) || test_root(group, 5) ||
+               test_root(group, 3));
+}
+
+/**
+ *     ext4_bg_has_super - number of blocks used by the superblock in group
+ *     @sb: superblock for filesystem
+ *     @group: group number to check
+ *
+ *     Return the number of blocks used by the superblock (primary or backup)
+ *     in this group.  Currently this will be only 0 or 1.
+ */
+int ext4_bg_has_super(struct super_block *sb, int group)
+{
+       if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
+                               EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER) &&
+                       !ext4_group_sparse(group))
+               return 0;
+       return 1;
+}
+
+static unsigned long ext4_bg_num_gdb_meta(struct super_block *sb, int group)
+{
+       unsigned long metagroup = group / EXT4_DESC_PER_BLOCK(sb);
+       unsigned long first = metagroup * EXT4_DESC_PER_BLOCK(sb);
+       unsigned long last = first + EXT4_DESC_PER_BLOCK(sb) - 1;
+
+       if (group == first || group == first + 1 || group == last)
+               return 1;
+       return 0;
+}
+
+static unsigned long ext4_bg_num_gdb_nometa(struct super_block *sb, int group)
+{
+       if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
+                               EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER) &&
+                       !ext4_group_sparse(group))
+               return 0;
+       return EXT4_SB(sb)->s_gdb_count;
+}
+
+/**
+ *     ext4_bg_num_gdb - number of blocks used by the group table in group
+ *     @sb: superblock for filesystem
+ *     @group: group number to check
+ *
+ *     Return the number of blocks used by the group descriptor table
+ *     (primary or backup) in this group.  In the future there may be a
+ *     different number of descriptor blocks in each group.
+ */
+unsigned long ext4_bg_num_gdb(struct super_block *sb, int group)
+{
+       unsigned long first_meta_bg =
+                       le32_to_cpu(EXT4_SB(sb)->s_es->s_first_meta_bg);
+       unsigned long metagroup = group / EXT4_DESC_PER_BLOCK(sb);
+
+       if (!EXT4_HAS_INCOMPAT_FEATURE(sb,EXT4_FEATURE_INCOMPAT_META_BG) ||
+                       metagroup < first_meta_bg)
+               return ext4_bg_num_gdb_nometa(sb,group);
+
+       return ext4_bg_num_gdb_meta(sb,group);
+
+}
diff --git a/fs/ext4/bitmap.c b/fs/ext4/bitmap.c
new file mode 100644 (file)
index 0000000..11e93c1
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ *  linux/fs/ext4/bitmap.c
+ *
+ * Copyright (C) 1992, 1993, 1994, 1995
+ * Remy Card (card@masi.ibp.fr)
+ * Laboratoire MASI - Institut Blaise Pascal
+ * Universite Pierre et Marie Curie (Paris VI)
+ */
+
+#include <linux/buffer_head.h>
+#include <linux/jbd2.h>
+#include <linux/ext4_fs.h>
+
+#ifdef EXT4FS_DEBUG
+
+static int nibblemap[] = {4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0};
+
+unsigned long ext4_count_free (struct buffer_head * map, unsigned int numchars)
+{
+       unsigned int i;
+       unsigned long sum = 0;
+
+       if (!map)
+               return (0);
+       for (i = 0; i < numchars; i++)
+               sum += nibblemap[map->b_data[i] & 0xf] +
+                       nibblemap[(map->b_data[i] >> 4) & 0xf];
+       return (sum);
+}
+
+#endif  /*  EXT4FS_DEBUG  */
+
diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c
new file mode 100644 (file)
index 0000000..f859578
--- /dev/null
@@ -0,0 +1,518 @@
+/*
+ *  linux/fs/ext4/dir.c
+ *
+ * Copyright (C) 1992, 1993, 1994, 1995
+ * Remy Card (card@masi.ibp.fr)
+ * Laboratoire MASI - Institut Blaise Pascal
+ * Universite Pierre et Marie Curie (Paris VI)
+ *
+ *  from
+ *
+ *  linux/fs/minix/dir.c
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ *
+ *  ext4 directory handling functions
+ *
+ *  Big-endian to little-endian byte-swapping/bitmaps by
+ *        David S. Miller (davem@caip.rutgers.edu), 1995
+ *
+ * Hash Tree Directory indexing (c) 2001  Daniel Phillips
+ *
+ */
+
+#include <linux/fs.h>
+#include <linux/jbd2.h>
+#include <linux/ext4_fs.h>
+#include <linux/buffer_head.h>
+#include <linux/smp_lock.h>
+#include <linux/slab.h>
+#include <linux/rbtree.h>
+
+static unsigned char ext4_filetype_table[] = {
+       DT_UNKNOWN, DT_REG, DT_DIR, DT_CHR, DT_BLK, DT_FIFO, DT_SOCK, DT_LNK
+};
+
+static int ext4_readdir(struct file *, void *, filldir_t);
+static int ext4_dx_readdir(struct file * filp,
+                          void * dirent, filldir_t filldir);
+static int ext4_release_dir (struct inode * inode,
+                               struct file * filp);
+
+const struct file_operations ext4_dir_operations = {
+       .llseek         = generic_file_llseek,
+       .read           = generic_read_dir,
+       .readdir        = ext4_readdir,         /* we take BKL. needed?*/
+       .ioctl          = ext4_ioctl,           /* BKL held */
+#ifdef CONFIG_COMPAT
+       .compat_ioctl   = ext4_compat_ioctl,
+#endif
+       .fsync          = ext4_sync_file,       /* BKL held */
+#ifdef CONFIG_EXT4_INDEX
+       .release        = ext4_release_dir,
+#endif
+};
+
+
+static unsigned char get_dtype(struct super_block *sb, int filetype)
+{
+       if (!EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FILETYPE) ||
+           (filetype >= EXT4_FT_MAX))
+               return DT_UNKNOWN;
+
+       return (ext4_filetype_table[filetype]);
+}
+
+
+int ext4_check_dir_entry (const char * function, struct inode * dir,
+                         struct ext4_dir_entry_2 * de,
+                         struct buffer_head * bh,
+                         unsigned long offset)
+{
+       const char * error_msg = NULL;
+       const int rlen = le16_to_cpu(de->rec_len);
+
+       if (rlen < EXT4_DIR_REC_LEN(1))
+               error_msg = "rec_len is smaller than minimal";
+       else if (rlen % 4 != 0)
+               error_msg = "rec_len % 4 != 0";
+       else if (rlen < EXT4_DIR_REC_LEN(de->name_len))
+               error_msg = "rec_len is too small for name_len";
+       else if (((char *) de - bh->b_data) + rlen > dir->i_sb->s_blocksize)
+               error_msg = "directory entry across blocks";
+       else if (le32_to_cpu(de->inode) >
+                       le32_to_cpu(EXT4_SB(dir->i_sb)->s_es->s_inodes_count))
+               error_msg = "inode out of bounds";
+
+       if (error_msg != NULL)
+               ext4_error (dir->i_sb, function,
+                       "bad entry in directory #%lu: %s - "
+                       "offset=%lu, inode=%lu, rec_len=%d, name_len=%d",
+                       dir->i_ino, error_msg, offset,
+                       (unsigned long) le32_to_cpu(de->inode),
+                       rlen, de->name_len);
+       return error_msg == NULL ? 1 : 0;
+}
+
+static int ext4_readdir(struct file * filp,
+                        void * dirent, filldir_t filldir)
+{
+       int error = 0;
+       unsigned long offset;
+       int i, stored;
+       struct ext4_dir_entry_2 *de;
+       struct super_block *sb;
+       int err;
+       struct inode *inode = filp->f_dentry->d_inode;
+       int ret = 0;
+
+       sb = inode->i_sb;
+
+#ifdef CONFIG_EXT4_INDEX
+       if (EXT4_HAS_COMPAT_FEATURE(inode->i_sb,
+                                   EXT4_FEATURE_COMPAT_DIR_INDEX) &&
+           ((EXT4_I(inode)->i_flags & EXT4_INDEX_FL) ||
+            ((inode->i_size >> sb->s_blocksize_bits) == 1))) {
+               err = ext4_dx_readdir(filp, dirent, filldir);
+               if (err != ERR_BAD_DX_DIR) {
+                       ret = err;
+                       goto out;
+               }
+               /*
+                * We don't set the inode dirty flag since it's not
+                * critical that it get flushed back to the disk.
+                */
+               EXT4_I(filp->f_dentry->d_inode)->i_flags &= ~EXT4_INDEX_FL;
+       }
+#endif
+       stored = 0;
+       offset = filp->f_pos & (sb->s_blocksize - 1);
+
+       while (!error && !stored && filp->f_pos < inode->i_size) {
+               unsigned long blk = filp->f_pos >> EXT4_BLOCK_SIZE_BITS(sb);
+               struct buffer_head map_bh;
+               struct buffer_head *bh = NULL;
+
+               map_bh.b_state = 0;
+               err = ext4_get_blocks_wrap(NULL, inode, blk, 1, &map_bh, 0, 0);
+               if (err > 0) {
+                       page_cache_readahead(sb->s_bdev->bd_inode->i_mapping,
+                               &filp->f_ra,
+                               filp,
+                               map_bh.b_blocknr >>
+                                       (PAGE_CACHE_SHIFT - inode->i_blkbits),
+                               1);
+                       bh = ext4_bread(NULL, inode, blk, 0, &err);
+               }
+
+               /*
+                * We ignore I/O errors on directories so users have a chance
+                * of recovering data when there's a bad sector
+                */
+               if (!bh) {
+                       ext4_error (sb, "ext4_readdir",
+                               "directory #%lu contains a hole at offset %lu",
+                               inode->i_ino, (unsigned long)filp->f_pos);
+                       filp->f_pos += sb->s_blocksize - offset;
+                       continue;
+               }
+
+revalidate:
+               /* If the dir block has changed since the last call to
+                * readdir(2), then we might be pointing to an invalid
+                * dirent right now.  Scan from the start of the block
+                * to make sure. */
+               if (filp->f_version != inode->i_version) {
+                       for (i = 0; i < sb->s_blocksize && i < offset; ) {
+                               de = (struct ext4_dir_entry_2 *)
+                                       (bh->b_data + i);
+                               /* It's too expensive to do a full
+                                * dirent test each time round this
+                                * loop, but we do have to test at
+                                * least that it is non-zero.  A
+                                * failure will be detected in the
+                                * dirent test below. */
+                               if (le16_to_cpu(de->rec_len) <
+                                               EXT4_DIR_REC_LEN(1))
+                                       break;
+                               i += le16_to_cpu(de->rec_len);
+                       }
+                       offset = i;
+                       filp->f_pos = (filp->f_pos & ~(sb->s_blocksize - 1))
+                               | offset;
+                       filp->f_version = inode->i_version;
+               }
+
+               while (!error && filp->f_pos < inode->i_size
+                      && offset < sb->s_blocksize) {
+                       de = (struct ext4_dir_entry_2 *) (bh->b_data + offset);
+                       if (!ext4_check_dir_entry ("ext4_readdir", inode, de,
+                                                  bh, offset)) {
+                               /*
+                                * On error, skip the f_pos to the next block
+                                */
+                               filp->f_pos = (filp->f_pos |
+                                               (sb->s_blocksize - 1)) + 1;
+                               brelse (bh);
+                               ret = stored;
+                               goto out;
+                       }
+                       offset += le16_to_cpu(de->rec_len);
+                       if (le32_to_cpu(de->inode)) {
+                               /* We might block in the next section
+                                * if the data destination is
+                                * currently swapped out.  So, use a
+                                * version stamp to detect whether or
+                                * not the directory has been modified
+                                * during the copy operation.
+                                */
+                               unsigned long version = filp->f_version;
+
+                               error = filldir(dirent, de->name,
+                                               de->name_len,
+                                               filp->f_pos,
+                                               le32_to_cpu(de->inode),
+                                               get_dtype(sb, de->file_type));
+                               if (error)
+                                       break;
+                               if (version != filp->f_version)
+                                       goto revalidate;
+                               stored ++;
+                       }
+                       filp->f_pos += le16_to_cpu(de->rec_len);
+               }
+               offset = 0;
+               brelse (bh);
+       }
+out:
+       return ret;
+}
+
+#ifdef CONFIG_EXT4_INDEX
+/*
+ * These functions convert from the major/minor hash to an f_pos
+ * value.
+ *
+ * Currently we only use major hash numer.  This is unfortunate, but
+ * on 32-bit machines, the same VFS interface is used for lseek and
+ * llseek, so if we use the 64 bit offset, then the 32-bit versions of
+ * lseek/telldir/seekdir will blow out spectacularly, and from within
+ * the ext2 low-level routine, we don't know if we're being called by
+ * a 64-bit version of the system call or the 32-bit version of the
+ * system call.  Worse yet, NFSv2 only allows for a 32-bit readdir
+ * cookie.  Sigh.
+ */
+#define hash2pos(major, minor) (major >> 1)
+#define pos2maj_hash(pos)      ((pos << 1) & 0xffffffff)
+#define pos2min_hash(pos)      (0)
+
+/*
+ * This structure holds the nodes of the red-black tree used to store
+ * the directory entry in hash order.
+ */
+struct fname {
+       __u32           hash;
+       __u32           minor_hash;
+       struct rb_node  rb_hash;
+       struct fname    *next;
+       __u32           inode;
+       __u8            name_len;
+       __u8            file_type;
+       char            name[0];
+};
+
+/*
+ * This functoin implements a non-recursive way of freeing all of the
+ * nodes in the red-black tree.
+ */
+static void free_rb_tree_fname(struct rb_root *root)
+{
+       struct rb_node  *n = root->rb_node;
+       struct rb_node  *parent;
+       struct fname    *fname;
+
+       while (n) {
+               /* Do the node's children first */
+               if ((n)->rb_left) {
+                       n = n->rb_left;
+                       continue;
+               }
+               if (n->rb_right) {
+                       n = n->rb_right;
+                       continue;
+               }
+               /*
+                * The node has no children; free it, and then zero
+                * out parent's link to it.  Finally go to the
+                * beginning of the loop and try to free the parent
+                * node.
+                */
+               parent = rb_parent(n);
+               fname = rb_entry(n, struct fname, rb_hash);
+               while (fname) {
+                       struct fname * old = fname;
+                       fname = fname->next;
+                       kfree (old);
+               }
+               if (!parent)
+                       root->rb_node = NULL;
+               else if (parent->rb_left == n)
+                       parent->rb_left = NULL;
+               else if (parent->rb_right == n)
+                       parent->rb_right = NULL;
+               n = parent;
+       }
+       root->rb_node = NULL;
+}
+
+
+static struct dir_private_info *create_dir_info(loff_t pos)
+{
+       struct dir_private_info *p;
+
+       p = kmalloc(sizeof(struct dir_private_info), GFP_KERNEL);
+       if (!p)
+               return NULL;
+       p->root.rb_node = NULL;
+       p->curr_node = NULL;
+       p->extra_fname = NULL;
+       p->last_pos = 0;
+       p->curr_hash = pos2maj_hash(pos);
+       p->curr_minor_hash = pos2min_hash(pos);
+       p->next_hash = 0;
+       return p;
+}
+
+void ext4_htree_free_dir_info(struct dir_private_info *p)
+{
+       free_rb_tree_fname(&p->root);
+       kfree(p);
+}
+
+/*
+ * Given a directory entry, enter it into the fname rb tree.
+ */
+int ext4_htree_store_dirent(struct file *dir_file, __u32 hash,
+                            __u32 minor_hash,
+                            struct ext4_dir_entry_2 *dirent)
+{
+       struct rb_node **p, *parent = NULL;
+       struct fname * fname, *new_fn;
+       struct dir_private_info *info;
+       int len;
+
+       info = (struct dir_private_info *) dir_file->private_data;
+       p = &info->root.rb_node;
+
+       /* Create and allocate the fname structure */
+       len = sizeof(struct fname) + dirent->name_len + 1;
+       new_fn = kzalloc(len, GFP_KERNEL);
+       if (!new_fn)
+               return -ENOMEM;
+       new_fn->hash = hash;
+       new_fn->minor_hash = minor_hash;
+       new_fn->inode = le32_to_cpu(dirent->inode);
+       new_fn->name_len = dirent->name_len;
+       new_fn->file_type = dirent->file_type;
+       memcpy(new_fn->name, dirent->name, dirent->name_len);
+       new_fn->name[dirent->name_len] = 0;
+
+       while (*p) {
+               parent = *p;
+               fname = rb_entry(parent, struct fname, rb_hash);
+
+               /*
+                * If the hash and minor hash match up, then we put
+                * them on a linked list.  This rarely happens...
+                */
+               if ((new_fn->hash == fname->hash) &&
+                   (new_fn->minor_hash == fname->minor_hash)) {
+                       new_fn->next = fname->next;
+                       fname->next = new_fn;
+                       return 0;
+               }
+
+               if (new_fn->hash < fname->hash)
+                       p = &(*p)->rb_left;
+               else if (new_fn->hash > fname->hash)
+                       p = &(*p)->rb_right;
+               else if (new_fn->minor_hash < fname->minor_hash)
+                       p = &(*p)->rb_left;
+               else /* if (new_fn->minor_hash > fname->minor_hash) */
+                       p = &(*p)->rb_right;
+       }
+
+       rb_link_node(&new_fn->rb_hash, parent, p);
+       rb_insert_color(&new_fn->rb_hash, &info->root);
+       return 0;
+}
+
+
+
+/*
+ * This is a helper function for ext4_dx_readdir.  It calls filldir
+ * for all entres on the fname linked list.  (Normally there is only
+ * one entry on the linked list, unless there are 62 bit hash collisions.)
+ */
+static int call_filldir(struct file * filp, void * dirent,
+                       filldir_t filldir, struct fname *fname)
+{
+       struct dir_private_info *info = filp->private_data;
+       loff_t  curr_pos;
+       struct inode *inode = filp->f_dentry->d_inode;
+       struct super_block * sb;
+       int error;
+
+       sb = inode->i_sb;
+
+       if (!fname) {
+               printk("call_filldir: called with null fname?!?\n");
+               return 0;
+       }
+       curr_pos = hash2pos(fname->hash, fname->minor_hash);
+       while (fname) {
+               error = filldir(dirent, fname->name,
+                               fname->name_len, curr_pos,
+                               fname->inode,
+                               get_dtype(sb, fname->file_type));
+               if (error) {
+                       filp->f_pos = curr_pos;
+                       info->extra_fname = fname->next;
+                       return error;
+               }
+               fname = fname->next;
+       }
+       return 0;
+}
+
+static int ext4_dx_readdir(struct file * filp,
+                        void * dirent, filldir_t filldir)
+{
+       struct dir_private_info *info = filp->private_data;
+       struct inode *inode = filp->f_dentry->d_inode;
+       struct fname *fname;
+       int     ret;
+
+       if (!info) {
+               info = create_dir_info(filp->f_pos);
+               if (!info)
+                       return -ENOMEM;
+               filp->private_data = info;
+       }
+
+       if (filp->f_pos == EXT4_HTREE_EOF)
+               return 0;       /* EOF */
+
+       /* Some one has messed with f_pos; reset the world */
+       if (info->last_pos != filp->f_pos) {
+               free_rb_tree_fname(&info->root);
+               info->curr_node = NULL;
+               info->extra_fname = NULL;
+               info->curr_hash = pos2maj_hash(filp->f_pos);
+               info->curr_minor_hash = pos2min_hash(filp->f_pos);
+       }
+
+       /*
+        * If there are any leftover names on the hash collision
+        * chain, return them first.
+        */
+       if (info->extra_fname &&
+           call_filldir(filp, dirent, filldir, info->extra_fname))
+               goto finished;
+
+       if (!info->curr_node)
+               info->curr_node = rb_first(&info->root);
+
+       while (1) {
+               /*
+                * Fill the rbtree if we have no more entries,
+                * or the inode has changed since we last read in the
+                * cached entries.
+                */
+               if ((!info->curr_node) ||
+                   (filp->f_version != inode->i_version)) {
+                       info->curr_node = NULL;
+                       free_rb_tree_fname(&info->root);
+                       filp->f_version = inode->i_version;
+                       ret = ext4_htree_fill_tree(filp, info->curr_hash,
+                                                  info->curr_minor_hash,
+                                                  &info->next_hash);
+                       if (ret < 0)
+                               return ret;
+                       if (ret == 0) {
+                               filp->f_pos = EXT4_HTREE_EOF;
+                               break;
+                       }
+                       info->curr_node = rb_first(&info->root);
+               }
+
+               fname = rb_entry(info->curr_node, struct fname, rb_hash);
+               info->curr_hash = fname->hash;
+               info->curr_minor_hash = fname->minor_hash;
+               if (call_filldir(filp, dirent, filldir, fname))
+                       break;
+
+               info->curr_node = rb_next(info->curr_node);
+               if (!info->curr_node) {
+                       if (info->next_hash == ~0) {
+                               filp->f_pos = EXT4_HTREE_EOF;
+                               break;
+                       }
+                       info->curr_hash = info->next_hash;
+                       info->curr_minor_hash = 0;
+               }
+       }
+finished:
+       info->last_pos = filp->f_pos;
+       return 0;
+}
+
+static int ext4_release_dir (struct inode * inode, struct file * filp)
+{
+       if (filp->private_data)
+               ext4_htree_free_dir_info(filp->private_data);
+
+       return 0;
+}
+
+#endif
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
new file mode 100644 (file)
index 0000000..2608dce
--- /dev/null
@@ -0,0 +1,2152 @@
+/*
+ * Copyright (c) 2003-2006, Cluster File Systems, Inc, info@clusterfs.com
+ * Written by Alex Tomas <alex@clusterfs.com>
+ *
+ * Architecture independence:
+ *   Copyright (c) 2005, Bull S.A.
+ *   Written by Pierre Peiffer <pierre.peiffer@bull.net>
+ *
+ * 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 Licens
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-
+ */
+
+/*
+ * Extents support for EXT4
+ *
+ * TODO:
+ *   - ext4*_error() should be used in some situations
+ *   - analyze all BUG()/BUG_ON(), use -EIO where appropriate
+ *   - smart tree reduction
+ */
+
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/time.h>
+#include <linux/ext4_jbd2.h>
+#include <linux/jbd.h>
+#include <linux/smp_lock.h>
+#include <linux/highuid.h>
+#include <linux/pagemap.h>
+#include <linux/quotaops.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/ext4_fs_extents.h>
+#include <asm/uaccess.h>
+
+
+/*
+ * ext_pblock:
+ * combine low and high parts of physical block number into ext4_fsblk_t
+ */
+static inline ext4_fsblk_t ext_pblock(struct ext4_extent *ex)
+{
+       ext4_fsblk_t block;
+
+       block = le32_to_cpu(ex->ee_start);
+       block |= ((ext4_fsblk_t) le16_to_cpu(ex->ee_start_hi) << 31) << 1;
+       return block;
+}
+
+/*
+ * idx_pblock:
+ * combine low and high parts of a leaf physical block number into ext4_fsblk_t
+ */
+static inline ext4_fsblk_t idx_pblock(struct ext4_extent_idx *ix)
+{
+       ext4_fsblk_t block;
+
+       block = le32_to_cpu(ix->ei_leaf);
+       block |= ((ext4_fsblk_t) le16_to_cpu(ix->ei_leaf_hi) << 31) << 1;
+       return block;
+}
+
+/*
+ * ext4_ext_store_pblock:
+ * stores a large physical block number into an extent struct,
+ * breaking it into parts
+ */
+static inline void ext4_ext_store_pblock(struct ext4_extent *ex, ext4_fsblk_t pb)
+{
+       ex->ee_start = cpu_to_le32((unsigned long) (pb & 0xffffffff));
+       ex->ee_start_hi = cpu_to_le16((unsigned long) ((pb >> 31) >> 1) & 0xffff);
+}
+
+/*
+ * ext4_idx_store_pblock:
+ * stores a large physical block number into an index struct,
+ * breaking it into parts
+ */
+static inline void ext4_idx_store_pblock(struct ext4_extent_idx *ix, ext4_fsblk_t pb)
+{
+       ix->ei_leaf = cpu_to_le32((unsigned long) (pb & 0xffffffff));
+       ix->ei_leaf_hi = cpu_to_le16((unsigned long) ((pb >> 31) >> 1) & 0xffff);
+}
+
+static int ext4_ext_check_header(const char *function, struct inode *inode,
+                               struct ext4_extent_header *eh)
+{
+       const char *error_msg = NULL;
+
+       if (unlikely(eh->eh_magic != EXT4_EXT_MAGIC)) {
+               error_msg = "invalid magic";
+               goto corrupted;
+       }
+       if (unlikely(eh->eh_max == 0)) {
+               error_msg = "invalid eh_max";
+               goto corrupted;
+       }
+       if (unlikely(le16_to_cpu(eh->eh_entries) > le16_to_cpu(eh->eh_max))) {
+               error_msg = "invalid eh_entries";
+               goto corrupted;
+       }
+       return 0;
+
+corrupted:
+       ext4_error(inode->i_sb, function,
+                       "bad header in inode #%lu: %s - magic %x, "
+                       "entries %u, max %u, depth %u",
+                       inode->i_ino, error_msg, le16_to_cpu(eh->eh_magic),
+                       le16_to_cpu(eh->eh_entries), le16_to_cpu(eh->eh_max),
+                       le16_to_cpu(eh->eh_depth));
+
+       return -EIO;
+}
+
+static handle_t *ext4_ext_journal_restart(handle_t *handle, int needed)
+{
+       int err;
+
+       if (handle->h_buffer_credits > needed)
+               return handle;
+       if (!ext4_journal_extend(handle, needed))
+               return handle;
+       err = ext4_journal_restart(handle, needed);
+
+       return handle;
+}
+
+/*
+ * could return:
+ *  - EROFS
+ *  - ENOMEM
+ */
+static int ext4_ext_get_access(handle_t *handle, struct inode *inode,
+                               struct ext4_ext_path *path)
+{
+       if (path->p_bh) {
+               /* path points to block */
+               return ext4_journal_get_write_access(handle, path->p_bh);
+       }
+       /* path points to leaf/index in inode body */
+       /* we use in-core data, no need to protect them */
+       return 0;
+}
+
+/*
+ * could return:
+ *  - EROFS
+ *  - ENOMEM
+ *  - EIO
+ */
+static int ext4_ext_dirty(handle_t *handle, struct inode *inode,
+                               struct ext4_ext_path *path)
+{
+       int err;
+       if (path->p_bh) {
+               /* path points to block */
+               err = ext4_journal_dirty_metadata(handle, path->p_bh);
+       } else {
+               /* path points to leaf/index in inode body */
+               err = ext4_mark_inode_dirty(handle, inode);
+       }
+       return err;
+}
+
+static ext4_fsblk_t ext4_ext_find_goal(struct inode *inode,
+                             struct ext4_ext_path *path,
+                             ext4_fsblk_t block)
+{
+       struct ext4_inode_info *ei = EXT4_I(inode);
+       ext4_fsblk_t bg_start;
+       ext4_grpblk_t colour;
+       int depth;
+
+       if (path) {
+               struct ext4_extent *ex;
+               depth = path->p_depth;
+
+               /* try to predict block placement */
+               if ((ex = path[depth].p_ext))
+                       return ext_pblock(ex)+(block-le32_to_cpu(ex->ee_block));
+
+               /* it looks like index is empty;
+                * try to find starting block from index itself */
+               if (path[depth].p_bh)
+                       return path[depth].p_bh->b_blocknr;
+       }
+
+       /* OK. use inode's group */
+       bg_start = (ei->i_block_group * EXT4_BLOCKS_PER_GROUP(inode->i_sb)) +
+               le32_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_first_data_block);
+       colour = (current->pid % 16) *
+                       (EXT4_BLOCKS_PER_GROUP(inode->i_sb) / 16);
+       return bg_start + colour + block;
+}
+
+static ext4_fsblk_t
+ext4_ext_new_block(handle_t *handle, struct inode *inode,
+                       struct ext4_ext_path *path,
+                       struct ext4_extent *ex, int *err)
+{
+       ext4_fsblk_t goal, newblock;
+
+       goal = ext4_ext_find_goal(inode, path, le32_to_cpu(ex->ee_block));
+       newblock = ext4_new_block(handle, inode, goal, err);
+       return newblock;
+}
+
+static inline int ext4_ext_space_block(struct inode *inode)
+{
+       int size;
+
+       size = (inode->i_sb->s_blocksize - sizeof(struct ext4_extent_header))
+                       / sizeof(struct ext4_extent);
+#ifdef AGRESSIVE_TEST
+       if (size > 6)
+               size = 6;
+#endif
+       return size;
+}
+
+static inline int ext4_ext_space_block_idx(struct inode *inode)
+{
+       int size;
+
+       size = (inode->i_sb->s_blocksize - sizeof(struct ext4_extent_header))
+                       / sizeof(struct ext4_extent_idx);
+#ifdef AGRESSIVE_TEST
+       if (size > 5)
+               size = 5;
+#endif
+       return size;
+}
+
+static inline int ext4_ext_space_root(struct inode *inode)
+{
+       int size;
+
+       size = sizeof(EXT4_I(inode)->i_data);
+       size -= sizeof(struct ext4_extent_header);
+       size /= sizeof(struct ext4_extent);
+#ifdef AGRESSIVE_TEST
+       if (size > 3)
+               size = 3;
+#endif
+       return size;
+}
+
+static inline int ext4_ext_space_root_idx(struct inode *inode)
+{
+       int size;
+
+       size = sizeof(EXT4_I(inode)->i_data);
+       size -= sizeof(struct ext4_extent_header);
+       size /= sizeof(struct ext4_extent_idx);
+#ifdef AGRESSIVE_TEST
+       if (size > 4)
+               size = 4;
+#endif
+       return size;
+}
+
+#ifdef EXT_DEBUG
+static void ext4_ext_show_path(struct inode *inode, struct ext4_ext_path *path)
+{
+       int k, l = path->p_depth;
+
+       ext_debug("path:");
+       for (k = 0; k <= l; k++, path++) {
+               if (path->p_idx) {
+                 ext_debug("  %d->%llu", le32_to_cpu(path->p_idx->ei_block),
+                           idx_pblock(path->p_idx));
+               } else if (path->p_ext) {
+                       ext_debug("  %d:%d:%llu ",
+                                 le32_to_cpu(path->p_ext->ee_block),
+                                 le16_to_cpu(path->p_ext->ee_len),
+                                 ext_pblock(path->p_ext));
+               } else
+                       ext_debug("  []");
+       }
+       ext_debug("\n");
+}
+
+static void ext4_ext_show_leaf(struct inode *inode, struct ext4_ext_path *path)
+{
+       int depth = ext_depth(inode);
+       struct ext4_extent_header *eh;
+       struct ext4_extent *ex;
+       int i;
+
+       if (!path)
+               return;
+
+       eh = path[depth].p_hdr;
+       ex = EXT_FIRST_EXTENT(eh);
+
+       for (i = 0; i < le16_to_cpu(eh->eh_entries); i++, ex++) {
+               ext_debug("%d:%d:%llu ", le32_to_cpu(ex->ee_block),
+                         le16_to_cpu(ex->ee_len), ext_pblock(ex));
+       }
+       ext_debug("\n");
+}
+#else
+#define ext4_ext_show_path(inode,path)
+#define ext4_ext_show_leaf(inode,path)
+#endif
+
+static void ext4_ext_drop_refs(struct ext4_ext_path *path)
+{
+       int depth = path->p_depth;
+       int i;
+
+       for (i = 0; i <= depth; i++, path++)
+               if (path->p_bh) {
+                       brelse(path->p_bh);
+                       path->p_bh = NULL;
+               }
+}
+
+/*
+ * ext4_ext_binsearch_idx:
+ * binary search for the closest index of the given block
+ */
+static void
+ext4_ext_binsearch_idx(struct inode *inode, struct ext4_ext_path *path, int block)
+{
+       struct ext4_extent_header *eh = path->p_hdr;
+       struct ext4_extent_idx *r, *l, *m;
+
+       BUG_ON(eh->eh_magic != EXT4_EXT_MAGIC);
+       BUG_ON(le16_to_cpu(eh->eh_entries) > le16_to_cpu(eh->eh_max));
+       BUG_ON(le16_to_cpu(eh->eh_entries) <= 0);
+
+       ext_debug("binsearch for %d(idx):  ", block);
+
+       l = EXT_FIRST_INDEX(eh) + 1;
+       r = EXT_FIRST_INDEX(eh) + le16_to_cpu(eh->eh_entries) - 1;
+       while (l <= r) {
+               m = l + (r - l) / 2;
+               if (block < le32_to_cpu(m->ei_block))
+                       r = m - 1;
+               else
+                       l = m + 1;
+               ext_debug("%p(%u):%p(%u):%p(%u) ", l, l->ei_block,
+                               m, m->ei_block, r, r->ei_block);
+       }
+
+       path->p_idx = l - 1;
+       ext_debug("  -> %d->%lld ", le32_to_cpu(path->p_idx->ei_block),
+                 idx_block(path->p_idx));
+
+#ifdef CHECK_BINSEARCH
+       {
+               struct ext4_extent_idx *chix, *ix;
+               int k;
+
+               chix = ix = EXT_FIRST_INDEX(eh);
+               for (k = 0; k < le16_to_cpu(eh->eh_entries); k++, ix++) {
+                 if (k != 0 &&
+                     le32_to_cpu(ix->ei_block) <= le32_to_cpu(ix[-1].ei_block)) {
+                               printk("k=%d, ix=0x%p, first=0x%p\n", k,
+                                       ix, EXT_FIRST_INDEX(eh));
+                               printk("%u <= %u\n",
+                                      le32_to_cpu(ix->ei_block),
+                                      le32_to_cpu(ix[-1].ei_block));
+                       }
+                       BUG_ON(k && le32_to_cpu(ix->ei_block)
+                                          <= le32_to_cpu(ix[-1].ei_block));
+                       if (block < le32_to_cpu(ix->ei_block))
+                               break;
+                       chix = ix;
+               }
+               BUG_ON(chix != path->p_idx);
+       }
+#endif
+
+}
+
+/*
+ * ext4_ext_binsearch:
+ * binary search for closest extent of the given block
+ */
+static void
+ext4_ext_binsearch(struct inode *inode, struct ext4_ext_path *path, int block)
+{
+       struct ext4_extent_header *eh = path->p_hdr;
+       struct ext4_extent *r, *l, *m;
+
+       BUG_ON(eh->eh_magic != EXT4_EXT_MAGIC);
+       BUG_ON(le16_to_cpu(eh->eh_entries) > le16_to_cpu(eh->eh_max));
+
+       if (eh->eh_entries == 0) {
+               /*
+                * this leaf is empty:
+                * we get such a leaf in split/add case
+                */
+               return;
+       }
+
+       ext_debug("binsearch for %d:  ", block);
+
+       l = EXT_FIRST_EXTENT(eh) + 1;
+       r = EXT_FIRST_EXTENT(eh) + le16_to_cpu(eh->eh_entries) - 1;
+
+       while (l <= r) {
+               m = l + (r - l) / 2;
+               if (block < le32_to_cpu(m->ee_block))
+                       r = m - 1;
+               else
+                       l = m + 1;
+               ext_debug("%p(%u):%p(%u):%p(%u) ", l, l->ee_block,
+                               m, m->ee_block, r, r->ee_block);
+       }
+
+       path->p_ext = l - 1;
+       ext_debug("  -> %d:%llu:%d ",
+                       le32_to_cpu(path->p_ext->ee_block),
+                       ext_pblock(path->p_ext),
+                       le16_to_cpu(path->p_ext->ee_len));
+
+#ifdef CHECK_BINSEARCH
+       {
+               struct ext4_extent *chex, *ex;
+               int k;
+
+               chex = ex = EXT_FIRST_EXTENT(eh);
+               for (k = 0; k < le16_to_cpu(eh->eh_entries); k++, ex++) {
+                       BUG_ON(k && le32_to_cpu(ex->ee_block)
+                                         <= le32_to_cpu(ex[-1].ee_block));
+                       if (block < le32_to_cpu(ex->ee_block))
+                               break;
+                       chex = ex;
+               }
+               BUG_ON(chex != path->p_ext);
+       }
+#endif
+
+}
+
+int ext4_ext_tree_init(handle_t *handle, struct inode *inode)
+{
+       struct ext4_extent_header *eh;
+
+       eh = ext_inode_hdr(inode);
+       eh->eh_depth = 0;
+       eh->eh_entries = 0;
+       eh->eh_magic = EXT4_EXT_MAGIC;
+       eh->eh_max = cpu_to_le16(ext4_ext_space_root(inode));
+       ext4_mark_inode_dirty(handle, inode);
+       ext4_ext_invalidate_cache(inode);
+       return 0;
+}
+
+struct ext4_ext_path *
+ext4_ext_find_extent(struct inode *inode, int block, struct ext4_ext_path *path)
+{
+       struct ext4_extent_header *eh;
+       struct buffer_head *bh;
+       short int depth, i, ppos = 0, alloc = 0;
+
+       eh = ext_inode_hdr(inode);
+       BUG_ON(eh == NULL);
+       if (ext4_ext_check_header(__FUNCTION__, inode, eh))
+               return ERR_PTR(-EIO);
+
+       i = depth = ext_depth(inode);
+
+       /* account possible depth increase */
+       if (!path) {
+               path = kmalloc(sizeof(struct ext4_ext_path) * (depth + 2),
+                               GFP_NOFS);
+               if (!path)
+                       return ERR_PTR(-ENOMEM);
+               alloc = 1;
+       }
+       memset(path, 0, sizeof(struct ext4_ext_path) * (depth + 1));
+       path[0].p_hdr = eh;
+
+       /* walk through the tree */
+       while (i) {
+               ext_debug("depth %d: num %d, max %d\n",
+                         ppos, le16_to_cpu(eh->eh_entries), le16_to_cpu(eh->eh_max));
+               ext4_ext_binsearch_idx(inode, path + ppos, block);
+               path[ppos].p_block = idx_pblock(path[ppos].p_idx);
+               path[ppos].p_depth = i;
+               path[ppos].p_ext = NULL;
+
+               bh = sb_bread(inode->i_sb, path[ppos].p_block);
+               if (!bh)
+                       goto err;
+
+               eh = ext_block_hdr(bh);
+               ppos++;
+               BUG_ON(ppos > depth);
+               path[ppos].p_bh = bh;
+               path[ppos].p_hdr = eh;
+               i--;
+
+               if (ext4_ext_check_header(__FUNCTION__, inode, eh))
+                       goto err;
+       }
+
+       path[ppos].p_depth = i;
+       path[ppos].p_hdr = eh;
+       path[ppos].p_ext = NULL;
+       path[ppos].p_idx = NULL;
+
+       if (ext4_ext_check_header(__FUNCTION__, inode, eh))
+               goto err;
+
+       /* find extent */
+       ext4_ext_binsearch(inode, path + ppos, block);
+
+       ext4_ext_show_path(inode, path);
+
+       return path;
+
+err:
+       ext4_ext_drop_refs(path);
+       if (alloc)
+               kfree(path);
+       return ERR_PTR(-EIO);
+}
+
+/*
+ * ext4_ext_insert_index:
+ * insert new index [@logical;@ptr] into the block at @curp;
+ * check where to insert: before @curp or after @curp
+ */
+static int ext4_ext_insert_index(handle_t *handle, struct inode *inode,
+                               struct ext4_ext_path *curp,
+                               int logical, ext4_fsblk_t ptr)
+{
+       struct ext4_extent_idx *ix;
+       int len, err;
+
+       if ((err = ext4_ext_get_access(handle, inode, curp)))
+               return err;
+
+       BUG_ON(logical == le32_to_cpu(curp->p_idx->ei_block));
+       len = EXT_MAX_INDEX(curp->p_hdr) - curp->p_idx;
+       if (logical > le32_to_cpu(curp->p_idx->ei_block)) {
+               /* insert after */
+               if (curp->p_idx != EXT_LAST_INDEX(curp->p_hdr)) {
+                       len = (len - 1) * sizeof(struct ext4_extent_idx);
+                       len = len < 0 ? 0 : len;
+                       ext_debug("insert new index %d after: %d. "
+                                       "move %d from 0x%p to 0x%p\n",
+                                       logical, ptr, len,
+                                       (curp->p_idx + 1), (curp->p_idx + 2));
+                       memmove(curp->p_idx + 2, curp->p_idx + 1, len);
+               }
+               ix = curp->p_idx + 1;
+       } else {
+               /* insert before */
+               len = len * sizeof(struct ext4_extent_idx);
+               len = len < 0 ? 0 : len;
+               ext_debug("insert new index %d before: %d. "
+                               "move %d from 0x%p to 0x%p\n",
+                               logical, ptr, len,
+                               curp->p_idx, (curp->p_idx + 1));
+               memmove(curp->p_idx + 1, curp->p_idx, len);
+               ix = curp->p_idx;
+       }
+
+       ix->ei_block = cpu_to_le32(logical);
+       ext4_idx_store_pblock(ix, ptr);
+       curp->p_hdr->eh_entries = cpu_to_le16(le16_to_cpu(curp->p_hdr->eh_entries)+1);
+
+       BUG_ON(le16_to_cpu(curp->p_hdr->eh_entries)
+                            > le16_to_cpu(curp->p_hdr->eh_max));
+       BUG_ON(ix > EXT_LAST_INDEX(curp->p_hdr));
+
+       err = ext4_ext_dirty(handle, inode, curp);
+       ext4_std_error(inode->i_sb, err);
+
+       return err;
+}
+
+/*
+ * ext4_ext_split:
+ * inserts new subtree into the path, using free index entry
+ * at depth @at:
+ * - allocates all needed blocks (new leaf and all intermediate index blocks)
+ * - makes decision where to split
+ * - moves remaining extents and index entries (right to the split point)
+ *   into the newly allocated blocks
+ * - initializes subtree
+ */
+static int ext4_ext_split(handle_t *handle, struct inode *inode,
+                               struct ext4_ext_path *path,
+                               struct ext4_extent *newext, int at)
+{
+       struct buffer_head *bh = NULL;
+       int depth = ext_depth(inode);
+       struct ext4_extent_header *neh;
+       struct ext4_extent_idx *fidx;
+       struct ext4_extent *ex;
+       int i = at, k, m, a;
+       ext4_fsblk_t newblock, oldblock;
+       __le32 border;
+       ext4_fsblk_t *ablocks = NULL; /* array of allocated blocks */
+       int err = 0;
+
+       /* make decision: where to split? */
+       /* FIXME: now decision is simplest: at current extent */
+
+       /* if current leaf will be split, then we should use
+        * border from split point */
+       BUG_ON(path[depth].p_ext > EXT_MAX_EXTENT(path[depth].p_hdr));
+       if (path[depth].p_ext != EXT_MAX_EXTENT(path[depth].p_hdr)) {
+               border = path[depth].p_ext[1].ee_block;
+               ext_debug("leaf will be split."
+                               " next leaf starts at %d\n",
+                                 le32_to_cpu(border));
+       } else {
+               border = newext->ee_block;
+               ext_debug("leaf will be added."
+                               " next leaf starts at %d\n",
+                               le32_to_cpu(border));
+       }
+
+       /*
+        * If error occurs, then we break processing
+        * and mark filesystem read-only. index won't
+        * be inserted and tree will be in consistent
+        * state. Next mount will repair buffers too.
+        */
+
+       /*
+        * Get array to track all allocated blocks.
+        * We need this to handle errors and free blocks
+        * upon them.
+        */
+       ablocks = kmalloc(sizeof(ext4_fsblk_t) * depth, GFP_NOFS);
+       if (!ablocks)
+               return -ENOMEM;
+       memset(ablocks, 0, sizeof(ext4_fsblk_t) * depth);
+
+       /* allocate all needed blocks */
+       ext_debug("allocate %d blocks for indexes/leaf\n", depth - at);
+       for (a = 0; a < depth - at; a++) {
+               newblock = ext4_ext_new_block(handle, inode, path, newext, &err);
+               if (newblock == 0)
+                       goto cleanup;
+               ablocks[a] = newblock;
+       }
+
+       /* initialize new leaf */
+       newblock = ablocks[--a];
+       BUG_ON(newblock == 0);
+       bh = sb_getblk(inode->i_sb, newblock);
+       if (!bh) {
+               err = -EIO;
+               goto cleanup;
+       }
+       lock_buffer(bh);
+
+       if ((err = ext4_journal_get_create_access(handle, bh)))
+               goto cleanup;
+
+       neh = ext_block_hdr(bh);
+       neh->eh_entries = 0;
+       neh->eh_max = cpu_to_le16(ext4_ext_space_block(inode));
+       neh->eh_magic = EXT4_EXT_MAGIC;
+       neh->eh_depth = 0;
+       ex = EXT_FIRST_EXTENT(neh);
+
+       /* move remainder of path[depth] to the new leaf */
+       BUG_ON(path[depth].p_hdr->eh_entries != path[depth].p_hdr->eh_max);
+       /* start copy from next extent */
+       /* TODO: we could do it by single memmove */
+       m = 0;
+       path[depth].p_ext++;
+       while (path[depth].p_ext <=
+                       EXT_MAX_EXTENT(path[depth].p_hdr)) {
+               ext_debug("move %d:%llu:%d in new leaf %llu\n",
+                               le32_to_cpu(path[depth].p_ext->ee_block),
+                               ext_pblock(path[depth].p_ext),
+                               le16_to_cpu(path[depth].p_ext->ee_len),
+                               newblock);
+               /*memmove(ex++, path[depth].p_ext++,
+                               sizeof(struct ext4_extent));
+               neh->eh_entries++;*/
+               path[depth].p_ext++;
+               m++;
+       }
+       if (m) {
+               memmove(ex, path[depth].p_ext-m, sizeof(struct ext4_extent)*m);
+               neh->eh_entries = cpu_to_le16(le16_to_cpu(neh->eh_entries)+m);
+       }
+
+       set_buffer_uptodate(bh);
+       unlock_buffer(bh);
+
+       if ((err = ext4_journal_dirty_metadata(handle, bh)))
+               goto cleanup;
+       brelse(bh);
+       bh = NULL;
+
+       /* correct old leaf */
+       if (m) {
+               if ((err = ext4_ext_get_access(handle, inode, path + depth)))
+                       goto cleanup;
+               path[depth].p_hdr->eh_entries =
+                    cpu_to_le16(le16_to_cpu(path[depth].p_hdr->eh_entries)-m);
+               if ((err = ext4_ext_dirty(handle, inode, path + depth)))
+                       goto cleanup;
+
+       }
+
+       /* create intermediate indexes */
+       k = depth - at - 1;
+       BUG_ON(k < 0);
+       if (k)
+               ext_debug("create %d intermediate indices\n", k);
+       /* insert new index into current index block */
+       /* current depth stored in i var */
+       i = depth - 1;
+       while (k--) {
+               oldblock = newblock;
+               newblock = ablocks[--a];
+               bh = sb_getblk(inode->i_sb, (ext4_fsblk_t)newblock);
+               if (!bh) {
+                       err = -EIO;
+                       goto cleanup;
+               }
+               lock_buffer(bh);
+
+               if ((err = ext4_journal_get_create_access(handle, bh)))
+                       goto cleanup;
+
+               neh = ext_block_hdr(bh);
+               neh->eh_entries = cpu_to_le16(1);
+               neh->eh_magic = EXT4_EXT_MAGIC;
+               neh->eh_max = cpu_to_le16(ext4_ext_space_block_idx(inode));
+               neh->eh_depth = cpu_to_le16(depth - i);
+               fidx = EXT_FIRST_INDEX(neh);
+               fidx->ei_block = border;
+               ext4_idx_store_pblock(fidx, oldblock);
+
+               ext_debug("int.index at %d (block %llu): %lu -> %llu\n", i,
+                               newblock, (unsigned long) le32_to_cpu(border),
+                               oldblock);
+               /* copy indexes */
+               m = 0;
+               path[i].p_idx++;
+
+               ext_debug("cur 0x%p, last 0x%p\n", path[i].p_idx,
+                               EXT_MAX_INDEX(path[i].p_hdr));
+               BUG_ON(EXT_MAX_INDEX(path[i].p_hdr) !=
+                               EXT_LAST_INDEX(path[i].p_hdr));
+               while (path[i].p_idx <= EXT_MAX_INDEX(path[i].p_hdr)) {
+                       ext_debug("%d: move %d:%d in new index %llu\n", i,
+                                       le32_to_cpu(path[i].p_idx->ei_block),
+                                       idx_pblock(path[i].p_idx),
+                                       newblock);
+                       /*memmove(++fidx, path[i].p_idx++,
+                                       sizeof(struct ext4_extent_idx));
+                       neh->eh_entries++;
+                       BUG_ON(neh->eh_entries > neh->eh_max);*/
+                       path[i].p_idx++;
+                       m++;
+               }
+               if (m) {
+                       memmove(++fidx, path[i].p_idx - m,
+                               sizeof(struct ext4_extent_idx) * m);
+                       neh->eh_entries =
+                               cpu_to_le16(le16_to_cpu(neh->eh_entries) + m);
+               }
+               set_buffer_uptodate(bh);
+               unlock_buffer(bh);
+
+               if ((err = ext4_journal_dirty_metadata(handle, bh)))
+                       goto cleanup;
+               brelse(bh);
+               bh = NULL;
+
+               /* correct old index */
+               if (m) {
+                       err = ext4_ext_get_access(handle, inode, path + i);
+                       if (err)
+                               goto cleanup;
+                       path[i].p_hdr->eh_entries = cpu_to_le16(le16_to_cpu(path[i].p_hdr->eh_entries)-m);
+                       err = ext4_ext_dirty(handle, inode, path + i);
+                       if (err)
+                               goto cleanup;
+               }
+
+               i--;
+       }
+
+       /* insert new index */
+       if (err)
+               goto cleanup;
+
+       err = ext4_ext_insert_index(handle, inode, path + at,
+                                   le32_to_cpu(border), newblock);
+
+cleanup:
+       if (bh) {
+               if (buffer_locked(bh))
+                       unlock_buffer(bh);
+               brelse(bh);
+       }
+
+       if (err) {
+               /* free all allocated blocks in error case */
+               for (i = 0; i < depth; i++) {
+                       if (!ablocks[i])
+                               continue;
+                       ext4_free_blocks(handle, inode, ablocks[i], 1);
+               }
+       }
+       kfree(ablocks);
+
+       return err;
+}
+
+/*
+ * ext4_ext_grow_indepth:
+ * implements tree growing procedure:
+ * - allocates new block
+ * - moves top-level data (index block or leaf) into the new block
+ * - initializes new top-level, creating index that points to the
+ *   just created block
+ */
+static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode,
+                                       struct ext4_ext_path *path,
+                                       struct ext4_extent *newext)
+{
+       struct ext4_ext_path *curp = path;
+       struct ext4_extent_header *neh;
+       struct ext4_extent_idx *fidx;
+       struct buffer_head *bh;
+       ext4_fsblk_t newblock;
+       int err = 0;
+
+       newblock = ext4_ext_new_block(handle, inode, path, newext, &err);
+       if (newblock == 0)
+               return err;
+
+       bh = sb_getblk(inode->i_sb, newblock);
+       if (!bh) {
+               err = -EIO;
+               ext4_std_error(inode->i_sb, err);
+               return err;
+       }
+       lock_buffer(bh);
+
+       if ((err = ext4_journal_get_create_access(handle, bh))) {
+               unlock_buffer(bh);
+               goto out;
+       }
+
+       /* move top-level index/leaf into new block */
+       memmove(bh->b_data, curp->p_hdr, sizeof(EXT4_I(inode)->i_data));
+
+       /* set size of new block */
+       neh = ext_block_hdr(bh);
+       /* old root could have indexes or leaves
+        * so calculate e_max right way */
+       if (ext_depth(inode))
+         neh->eh_max = cpu_to_le16(ext4_ext_space_block_idx(inode));
+       else
+         neh->eh_max = cpu_to_le16(ext4_ext_space_block(inode));
+       neh->eh_magic = EXT4_EXT_MAGIC;
+       set_buffer_uptodate(bh);
+       unlock_buffer(bh);
+
+       if ((err = ext4_journal_dirty_metadata(handle, bh)))
+               goto out;
+
+       /* create index in new top-level index: num,max,pointer */
+       if ((err = ext4_ext_get_access(handle, inode, curp)))
+               goto out;
+
+       curp->p_hdr->eh_magic = EXT4_EXT_MAGIC;
+       curp->p_hdr->eh_max = cpu_to_le16(ext4_ext_space_root_idx(inode));
+       curp->p_hdr->eh_entries = cpu_to_le16(1);
+       curp->p_idx = EXT_FIRST_INDEX(curp->p_hdr);
+       /* FIXME: it works, but actually path[0] can be index */
+       curp->p_idx->ei_block = EXT_FIRST_EXTENT(path[0].p_hdr)->ee_block;
+       ext4_idx_store_pblock(curp->p_idx, newblock);
+
+       neh = ext_inode_hdr(inode);
+       fidx = EXT_FIRST_INDEX(neh);
+       ext_debug("new root: num %d(%d), lblock %d, ptr %llu\n",
+                 le16_to_cpu(neh->eh_entries), le16_to_cpu(neh->eh_max),
+                 le32_to_cpu(fidx->ei_block), idx_pblock(fidx));
+
+       neh->eh_depth = cpu_to_le16(path->p_depth + 1);
+       err = ext4_ext_dirty(handle, inode, curp);
+out:
+       brelse(bh);
+
+       return err;
+}
+
+/*
+ * ext4_ext_create_new_leaf:
+ * finds empty index and adds new leaf.
+ * if no free index is found, then it requests in-depth growing.
+ */
+static int ext4_ext_create_new_leaf(handle_t *handle, struct inode *inode,
+                                       struct ext4_ext_path *path,
+                                       struct ext4_extent *newext)
+{
+       struct ext4_ext_path *curp;
+       int depth, i, err = 0;
+
+repeat:
+       i = depth = ext_depth(inode);
+
+       /* walk up to the tree and look for free index entry */
+       curp = path + depth;
+       while (i > 0 && !EXT_HAS_FREE_INDEX(curp)) {
+               i--;
+               curp--;
+       }
+
+       /* we use already allocated block for index block,
+        * so subsequent data blocks should be contiguous */
+       if (EXT_HAS_FREE_INDEX(curp)) {
+               /* if we found index with free entry, then use that
+                * entry: create all needed subtree and add new leaf */
+               err = ext4_ext_split(handle, inode, path, newext, i);
+
+               /* refill path */
+               ext4_ext_drop_refs(path);
+               path = ext4_ext_find_extent(inode,
+                                           le32_to_cpu(newext->ee_block),
+                                           path);
+               if (IS_ERR(path))
+                       err = PTR_ERR(path);
+       } else {
+               /* tree is full, time to grow in depth */
+               err = ext4_ext_grow_indepth(handle, inode, path, newext);
+               if (err)
+                       goto out;
+
+               /* refill path */
+               ext4_ext_drop_refs(path);
+               path = ext4_ext_find_extent(inode,
+                                           le32_to_cpu(newext->ee_block),
+                                           path);
+               if (IS_ERR(path)) {
+                       err = PTR_ERR(path);
+                       goto out;
+               }
+
+               /*
+                * only first (depth 0 -> 1) produces free space;
+                * in all other cases we have to split the grown tree
+                */
+               depth = ext_depth(inode);
+               if (path[depth].p_hdr->eh_entries == path[depth].p_hdr->eh_max) {
+                       /* now we need to split */
+                       goto repeat;
+               }
+       }
+
+out:
+       return err;
+}
+
+/*
+ * ext4_ext_next_allocated_block:
+ * returns allocated block in subsequent extent or EXT_MAX_BLOCK.
+ * NOTE: it considers block number from index entry as
+ * allocated block. Thus, index entries have to be consistent
+ * with leaves.
+ */
+static unsigned long
+ext4_ext_next_allocated_block(struct ext4_ext_path *path)
+{
+       int depth;
+
+       BUG_ON(path == NULL);
+       depth = path->p_depth;
+
+       if (depth == 0 && path->p_ext == NULL)
+               return EXT_MAX_BLOCK;
+
+       while (depth >= 0) {
+               if (depth == path->p_depth) {
+                       /* leaf */
+                       if (path[depth].p_ext !=
+                                       EXT_LAST_EXTENT(path[depth].p_hdr))
+                         return le32_to_cpu(path[depth].p_ext[1].ee_block);
+               } else {
+                       /* index */
+                       if (path[depth].p_idx !=
+                                       EXT_LAST_INDEX(path[depth].p_hdr))
+                         return le32_to_cpu(path[depth].p_idx[1].ei_block);
+               }
+               depth--;
+       }
+
+       return EXT_MAX_BLOCK;
+}
+
+/*
+ * ext4_ext_next_leaf_block:
+ * returns first allocated block from next leaf or EXT_MAX_BLOCK
+ */
+static unsigned ext4_ext_next_leaf_block(struct inode *inode,
+                                       struct ext4_ext_path *path)
+{
+       int depth;
+
+       BUG_ON(path == NULL);
+       depth = path->p_depth;
+
+       /* zero-tree has no leaf blocks at all */
+       if (depth == 0)
+               return EXT_MAX_BLOCK;
+
+       /* go to index block */
+       depth--;
+
+       while (depth >= 0) {
+               if (path[depth].p_idx !=
+                               EXT_LAST_INDEX(path[depth].p_hdr))
+                 return le32_to_cpu(path[depth].p_idx[1].ei_block);
+               depth--;
+       }
+
+       return EXT_MAX_BLOCK;
+}
+
+/*
+ * ext4_ext_correct_indexes:
+ * if leaf gets modified and modified extent is first in the leaf,
+ * then we have to correct all indexes above.
+ * TODO: do we need to correct tree in all cases?
+ */
+int ext4_ext_correct_indexes(handle_t *handle, struct inode *inode,
+                               struct ext4_ext_path *path)
+{
+       struct ext4_extent_header *eh;
+       int depth = ext_depth(inode);
+       struct ext4_extent *ex;
+       __le32 border;
+       int k, err = 0;
+
+       eh = path[depth].p_hdr;
+       ex = path[depth].p_ext;
+       BUG_ON(ex == NULL);
+       BUG_ON(eh == NULL);
+
+       if (depth == 0) {
+               /* there is no tree at all */
+               return 0;
+       }
+
+       if (ex != EXT_FIRST_EXTENT(eh)) {
+               /* we correct tree if first leaf got modified only */
+               return 0;
+       }
+
+       /*
+        * TODO: we need correction if border is smaller than current one
+        */
+       k = depth - 1;
+       border = path[depth].p_ext->ee_block;
+       if ((err = ext4_ext_get_access(handle, inode, path + k)))
+               return err;
+       path[k].p_idx->ei_block = border;
+       if ((err = ext4_ext_dirty(handle, inode, path + k)))
+               return err;
+
+       while (k--) {
+               /* change all left-side indexes */
+               if (path[k+1].p_idx != EXT_FIRST_INDEX(path[k+1].p_hdr))
+                       break;
+               if ((err = ext4_ext_get_access(handle, inode, path + k)))
+                       break;
+               path[k].p_idx->ei_block = border;
+               if ((err = ext4_ext_dirty(handle, inode, path + k)))
+                       break;
+       }
+
+       return err;
+}
+
+static int inline
+ext4_can_extents_be_merged(struct inode *inode, struct ext4_extent *ex1,
+                               struct ext4_extent *ex2)
+{
+       if (le32_to_cpu(ex1->ee_block) + le16_to_cpu(ex1->ee_len) !=
+                       le32_to_cpu(ex2->ee_block))
+               return 0;
+
+       /*
+        * To allow future support for preallocated extents to be added
+        * as an RO_COMPAT feature, refuse to merge to extents if
+        * this can result in the top bit of ee_len being set.
+        */
+       if (le16_to_cpu(ex1->ee_len) + le16_to_cpu(ex2->ee_len) > EXT_MAX_LEN)
+               return 0;
+#ifdef AGRESSIVE_TEST
+       if (le16_to_cpu(ex1->ee_len) >= 4)
+               return 0;
+#endif
+
+       if (ext_pblock(ex1) + le16_to_cpu(ex1->ee_len) == ext_pblock(ex2))
+               return 1;
+       return 0;
+}
+
+/*
+ * ext4_ext_insert_extent:
+ * tries to merge requsted extent into the existing extent or
+ * inserts requested extent as new one into the tree,
+ * creating new leaf in the no-space case.
+ */
+int ext4_ext_insert_extent(handle_t *handle, struct inode *inode,
+                               struct ext4_ext_path *path,
+                               struct ext4_extent *newext)
+{
+       struct ext4_extent_header * eh;
+       struct ext4_extent *ex, *fex;
+       struct ext4_extent *nearex; /* nearest extent */
+       struct ext4_ext_path *npath = NULL;
+       int depth, len, err, next;
+
+       BUG_ON(newext->ee_len == 0);
+       depth = ext_depth(inode);
+       ex = path[depth].p_ext;
+       BUG_ON(path[depth].p_hdr == NULL);
+
+       /* try to insert block into found extent and return */
+       if (ex && ext4_can_extents_be_merged(inode, ex, newext)) {
+               ext_debug("append %d block to %d:%d (from %llu)\n",
+                               le16_to_cpu(newext->ee_len),
+                               le32_to_cpu(ex->ee_block),
+                               le16_to_cpu(ex->ee_len), ext_pblock(ex));
+               if ((err = ext4_ext_get_access(handle, inode, path + depth)))
+                       return err;
+               ex->ee_len = cpu_to_le16(le16_to_cpu(ex->ee_len)
+                                        + le16_to_cpu(newext->ee_len));
+               eh = path[depth].p_hdr;
+               nearex = ex;
+               goto merge;
+       }
+
+repeat:
+       depth = ext_depth(inode);
+       eh = path[depth].p_hdr;
+       if (le16_to_cpu(eh->eh_entries) < le16_to_cpu(eh->eh_max))
+               goto has_space;
+
+       /* probably next leaf has space for us? */
+       fex = EXT_LAST_EXTENT(eh);
+       next = ext4_ext_next_leaf_block(inode, path);
+       if (le32_to_cpu(newext->ee_block) > le32_to_cpu(fex->ee_block)
+           && next != EXT_MAX_BLOCK) {
+               ext_debug("next leaf block - %d\n", next);
+               BUG_ON(npath != NULL);
+               npath = ext4_ext_find_extent(inode, next, NULL);
+               if (IS_ERR(npath))
+                       return PTR_ERR(npath);
+               BUG_ON(npath->p_depth != path->p_depth);
+               eh = npath[depth].p_hdr;
+               if (le16_to_cpu(eh->eh_entries) < le16_to_cpu(eh->eh_max)) {
+                       ext_debug("next leaf isnt full(%d)\n",
+                                 le16_to_cpu(eh->eh_entries));
+                       path = npath;
+                       goto repeat;
+               }
+               ext_debug("next leaf has no free space(%d,%d)\n",
+                         le16_to_cpu(eh->eh_entries), le16_to_cpu(eh->eh_max));
+       }
+
+       /*
+        * There is no free space in the found leaf.
+        * We're gonna add a new leaf in the tree.
+        */
+       err = ext4_ext_create_new_leaf(handle, inode, path, newext);
+       if (err)
+               goto cleanup;
+       depth = ext_depth(inode);
+       eh = path[depth].p_hdr;
+
+has_space:
+       nearex = path[depth].p_ext;
+
+       if ((err = ext4_ext_get_access(handle, inode, path + depth)))
+               goto cleanup;
+
+       if (!nearex) {
+               /* there is no extent in this leaf, create first one */
+               ext_debug("first extent in the leaf: %d:%llu:%d\n",
+                               le32_to_cpu(newext->ee_block),
+                               ext_pblock(newext),
+                               le16_to_cpu(newext->ee_len));
+               path[depth].p_ext = EXT_FIRST_EXTENT(eh);
+       } else if (le32_to_cpu(newext->ee_block)
+                          > le32_to_cpu(nearex->ee_block)) {
+/*             BUG_ON(newext->ee_block == nearex->ee_block); */
+               if (nearex != EXT_LAST_EXTENT(eh)) {
+                       len = EXT_MAX_EXTENT(eh) - nearex;
+                       len = (len - 1) * sizeof(struct ext4_extent);
+                       len = len < 0 ? 0 : len;
+                       ext_debug("insert %d:%llu:%d after: nearest 0x%p, "
+                                       "move %d from 0x%p to 0x%p\n",
+                                       le32_to_cpu(newext->ee_block),
+                                       ext_pblock(newext),
+                                       le16_to_cpu(newext->ee_len),
+                                       nearex, len, nearex + 1, nearex + 2);
+                       memmove(nearex + 2, nearex + 1, len);
+               }
+               path[depth].p_ext = nearex + 1;
+       } else {
+               BUG_ON(newext->ee_block == nearex->ee_block);
+               len = (EXT_MAX_EXTENT(eh) - nearex) * sizeof(struct ext4_extent);
+               len = len < 0 ? 0 : len;
+               ext_debug("insert %d:%llu:%d before: nearest 0x%p, "
+                               "move %d from 0x%p to 0x%p\n",
+                               le32_to_cpu(newext->ee_block),
+                               ext_pblock(newext),
+                               le16_to_cpu(newext->ee_len),
+                               nearex, len, nearex + 1, nearex + 2);
+               memmove(nearex + 1, nearex, len);
+               path[depth].p_ext = nearex;
+       }
+
+       eh->eh_entries = cpu_to_le16(le16_to_cpu(eh->eh_entries)+1);
+       nearex = path[depth].p_ext;
+       nearex->ee_block = newext->ee_block;
+       nearex->ee_start = newext->ee_start;
+       nearex->ee_start_hi = newext->ee_start_hi;
+       nearex->ee_len = newext->ee_len;
+
+merge:
+       /* try to merge extents to the right */
+       while (nearex < EXT_LAST_EXTENT(eh)) {
+               if (!ext4_can_extents_be_merged(inode, nearex, nearex + 1))
+                       break;
+               /* merge with next extent! */
+               nearex->ee_len = cpu_to_le16(le16_to_cpu(nearex->ee_len)
+                                            + le16_to_cpu(nearex[1].ee_len));
+               if (nearex + 1 < EXT_LAST_EXTENT(eh)) {
+                       len = (EXT_LAST_EXTENT(eh) - nearex - 1)
+                                       * sizeof(struct ext4_extent);
+                       memmove(nearex + 1, nearex + 2, len);
+               }
+               eh->eh_entries = cpu_to_le16(le16_to_cpu(eh->eh_entries)-1);
+               BUG_ON(eh->eh_entries == 0);
+       }
+
+       /* try to merge extents to the left */
+
+       /* time to correct all indexes above */
+       err = ext4_ext_correct_indexes(handle, inode, path);
+       if (err)
+               goto cleanup;
+
+       err = ext4_ext_dirty(handle, inode, path + depth);
+
+cleanup:
+       if (npath) {
+               ext4_ext_drop_refs(npath);
+               kfree(npath);
+       }
+       ext4_ext_tree_changed(inode);
+       ext4_ext_invalidate_cache(inode);
+       return err;
+}
+
+int ext4_ext_walk_space(struct inode *inode, unsigned long block,
+                       unsigned long num, ext_prepare_callback func,
+                       void *cbdata)
+{
+       struct ext4_ext_path *path = NULL;
+       struct ext4_ext_cache cbex;
+       struct ext4_extent *ex;
+       unsigned long next, start = 0, end = 0;
+       unsigned long last = block + num;
+       int depth, exists, err = 0;
+
+       BUG_ON(func == NULL);
+       BUG_ON(inode == NULL);
+
+       while (block < last && block != EXT_MAX_BLOCK) {
+               num = last - block;
+               /* find extent for this block */
+               path = ext4_ext_find_extent(inode, block, path);
+               if (IS_ERR(path)) {
+                       err = PTR_ERR(path);
+                       path = NULL;
+                       break;
+               }
+
+               depth = ext_depth(inode);
+               BUG_ON(path[depth].p_hdr == NULL);
+               ex = path[depth].p_ext;
+               next = ext4_ext_next_allocated_block(path);
+
+               exists = 0;
+               if (!ex) {
+                       /* there is no extent yet, so try to allocate
+                        * all requested space */
+                       start = block;
+                       end = block + num;
+               } else if (le32_to_cpu(ex->ee_block) > block) {
+                       /* need to allocate space before found extent */
+                       start = block;
+                       end = le32_to_cpu(ex->ee_block);
+                       if (block + num < end)
+                               end = block + num;
+               } else if (block >=
+                            le32_to_cpu(ex->ee_block) + le16_to_cpu(ex->ee_len)) {
+                       /* need to allocate space after found extent */
+                       start = block;
+                       end = block + num;
+                       if (end >= next)
+                               end = next;
+               } else if (block >= le32_to_cpu(ex->ee_block)) {
+                       /*
+                        * some part of requested space is covered
+                        * by found extent
+                        */
+                       start = block;
+                       end = le32_to_cpu(ex->ee_block) + le16_to_cpu(ex->ee_len);
+                       if (block + num < end)
+                               end = block + num;
+                       exists = 1;
+               } else {
+                       BUG();
+               }
+               BUG_ON(end <= start);
+
+               if (!exists) {
+                       cbex.ec_block = start;
+                       cbex.ec_len = end - start;
+                       cbex.ec_start = 0;
+                       cbex.ec_type = EXT4_EXT_CACHE_GAP;
+               } else {
+                       cbex.ec_block = le32_to_cpu(ex->ee_block);
+                       cbex.ec_len = le16_to_cpu(ex->ee_len);
+                       cbex.ec_start = ext_pblock(ex);
+                       cbex.ec_type = EXT4_EXT_CACHE_EXTENT;
+               }
+
+               BUG_ON(cbex.ec_len == 0);
+               err = func(inode, path, &cbex, cbdata);
+               ext4_ext_drop_refs(path);
+
+               if (err < 0)
+                       break;
+               if (err == EXT_REPEAT)
+                       continue;
+               else if (err == EXT_BREAK) {
+                       err = 0;
+                       break;
+               }
+
+               if (ext_depth(inode) != depth) {
+                       /* depth was changed. we have to realloc path */
+                       kfree(path);
+                       path = NULL;
+               }
+
+               block = cbex.ec_block + cbex.ec_len;
+       }
+
+       if (path) {
+               ext4_ext_drop_refs(path);
+               kfree(path);
+       }
+
+       return err;
+}
+
+static inline void
+ext4_ext_put_in_cache(struct inode *inode, __u32 block,
+                       __u32 len, __u32 start, int type)
+{
+       struct ext4_ext_cache *cex;
+       BUG_ON(len == 0);
+       cex = &EXT4_I(inode)->i_cached_extent;
+       cex->ec_type = type;
+       cex->ec_block = block;
+       cex->ec_len = len;
+       cex->ec_start = start;
+}
+
+/*
+ * ext4_ext_put_gap_in_cache:
+ * calculate boundaries of the gap that the requested block fits into
+ * and cache this gap
+ */
+static inline void
+ext4_ext_put_gap_in_cache(struct inode *inode, struct ext4_ext_path *path,
+                               unsigned long block)
+{
+       int depth = ext_depth(inode);
+       unsigned long lblock, len;
+       struct ext4_extent *ex;
+
+       ex = path[depth].p_ext;
+       if (ex == NULL) {
+               /* there is no extent yet, so gap is [0;-] */
+               lblock = 0;
+               len = EXT_MAX_BLOCK;
+               ext_debug("cache gap(whole file):");
+       } else if (block < le32_to_cpu(ex->ee_block)) {
+               lblock = block;
+               len = le32_to_cpu(ex->ee_block) - block;
+               ext_debug("cache gap(before): %lu [%lu:%lu]",
+                               (unsigned long) block,
+                               (unsigned long) le32_to_cpu(ex->ee_block),
+                               (unsigned long) le16_to_cpu(ex->ee_len));
+       } else if (block >= le32_to_cpu(ex->ee_block)
+                           + le16_to_cpu(ex->ee_len)) {
+               lblock = le32_to_cpu(ex->ee_block)
+                        + le16_to_cpu(ex->ee_len);
+               len = ext4_ext_next_allocated_block(path);
+               ext_debug("cache gap(after): [%lu:%lu] %lu",
+                               (unsigned long) le32_to_cpu(ex->ee_block),
+                               (unsigned long) le16_to_cpu(ex->ee_len),
+                               (unsigned long) block);
+               BUG_ON(len == lblock);
+               len = len - lblock;
+       } else {
+               lblock = len = 0;
+               BUG();
+       }
+
+       ext_debug(" -> %lu:%lu\n", (unsigned long) lblock, len);
+       ext4_ext_put_in_cache(inode, lblock, len, 0, EXT4_EXT_CACHE_GAP);
+}
+
+static inline int
+ext4_ext_in_cache(struct inode *inode, unsigned long block,
+                       struct ext4_extent *ex)
+{
+       struct ext4_ext_cache *cex;
+
+       cex = &EXT4_I(inode)->i_cached_extent;
+
+       /* has cache valid data? */
+       if (cex->ec_type == EXT4_EXT_CACHE_NO)
+               return EXT4_EXT_CACHE_NO;
+
+       BUG_ON(cex->ec_type != EXT4_EXT_CACHE_GAP &&
+                       cex->ec_type != EXT4_EXT_CACHE_EXTENT);
+       if (block >= cex->ec_block && block < cex->ec_block + cex->ec_len) {
+               ex->ee_block = cpu_to_le32(cex->ec_block);
+               ext4_ext_store_pblock(ex, cex->ec_start);
+               ex->ee_len = cpu_to_le16(cex->ec_len);
+               ext_debug("%lu cached by %lu:%lu:%llu\n",
+                               (unsigned long) block,
+                               (unsigned long) cex->ec_block,
+                               (unsigned long) cex->ec_len,
+                               cex->ec_start);
+               return cex->ec_type;
+       }
+
+       /* not in cache */
+       return EXT4_EXT_CACHE_NO;
+}
+
+/*
+ * ext4_ext_rm_idx:
+ * removes index from the index block.
+ * It's used in truncate case only, thus all requests are for
+ * last index in the block only.
+ */
+int ext4_ext_rm_idx(handle_t *handle, struct inode *inode,
+                       struct ext4_ext_path *path)
+{
+       struct buffer_head *bh;
+       int err;
+       ext4_fsblk_t leaf;
+
+       /* free index block */
+       path--;
+       leaf = idx_pblock(path->p_idx);
+       BUG_ON(path->p_hdr->eh_entries == 0);
+       if ((err = ext4_ext_get_access(handle, inode, path)))
+               return err;
+       path->p_hdr->eh_entries = cpu_to_le16(le16_to_cpu(path->p_hdr->eh_entries)-1);
+       if ((err = ext4_ext_dirty(handle, inode, path)))
+               return err;
+       ext_debug("index is empty, remove it, free block %llu\n", leaf);
+       bh = sb_find_get_block(inode->i_sb, leaf);
+       ext4_forget(handle, 1, inode, bh, leaf);
+       ext4_free_blocks(handle, inode, leaf, 1);
+       return err;
+}
+
+/*
+ * ext4_ext_calc_credits_for_insert:
+ * This routine returns max. credits that the extent tree can consume.
+ * It should be OK for low-performance paths like ->writepage()
+ * To allow many writing processes to fit into a single transaction,
+ * the caller should calculate credits under truncate_mutex and
+ * pass the actual path.
+ */
+int inline ext4_ext_calc_credits_for_insert(struct inode *inode,
+                                               struct ext4_ext_path *path)
+{
+       int depth, needed;
+
+       if (path) {
+               /* probably there is space in leaf? */
+               depth = ext_depth(inode);
+               if (le16_to_cpu(path[depth].p_hdr->eh_entries)
+                               < le16_to_cpu(path[depth].p_hdr->eh_max))
+                       return 1;
+       }
+
+       /*
+        * given 32-bit logical block (4294967296 blocks), max. tree
+        * can be 4 levels in depth -- 4 * 340^4 == 53453440000.
+        * Let's also add one more level for imbalance.
+        */
+       depth = 5;
+
+       /* allocation of new data block(s) */
+       needed = 2;
+
+       /*
+        * tree can be full, so it would need to grow in depth:
+        * allocation + old root + new root
+        */
+       needed += 2 + 1 + 1;
+
+       /*
+        * Index split can happen, we would need:
+        *    allocate intermediate indexes (bitmap + group)
+        *  + change two blocks at each level, but root (already included)
+        */
+       needed = (depth * 2) + (depth * 2);
+
+       /* any allocation modifies superblock */
+       needed += 1;
+
+       return needed;
+}
+
+static int ext4_remove_blocks(handle_t *handle, struct inode *inode,
+                               struct ext4_extent *ex,
+                               unsigned long from, unsigned long to)
+{
+       struct buffer_head *bh;
+       int i;
+
+#ifdef EXTENTS_STATS
+       {
+               struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
+               unsigned short ee_len =  le16_to_cpu(ex->ee_len);
+               spin_lock(&sbi->s_ext_stats_lock);
+               sbi->s_ext_blocks += ee_len;
+               sbi->s_ext_extents++;
+               if (ee_len < sbi->s_ext_min)
+                       sbi->s_ext_min = ee_len;
+               if (ee_len > sbi->s_ext_max)
+                       sbi->s_ext_max = ee_len;
+               if (ext_depth(inode) > sbi->s_depth_max)
+                       sbi->s_depth_max = ext_depth(inode);
+               spin_unlock(&sbi->s_ext_stats_lock);
+       }
+#endif
+       if (from >= le32_to_cpu(ex->ee_block)
+           && to == le32_to_cpu(ex->ee_block) + le16_to_cpu(ex->ee_len) - 1) {
+               /* tail removal */
+               unsigned long num;
+               ext4_fsblk_t start;
+               num = le32_to_cpu(ex->ee_block) + le16_to_cpu(ex->ee_len) - from;
+               start = ext_pblock(ex) + le16_to_cpu(ex->ee_len) - num;
+               ext_debug("free last %lu blocks starting %llu\n", num, start);
+               for (i = 0; i < num; i++) {
+                       bh = sb_find_get_block(inode->i_sb, start + i);
+                       ext4_forget(handle, 0, inode, bh, start + i);
+               }
+               ext4_free_blocks(handle, inode, start, num);
+       } else if (from == le32_to_cpu(ex->ee_block)
+                  && to <= le32_to_cpu(ex->ee_block) + le16_to_cpu(ex->ee_len) - 1) {
+               printk("strange request: removal %lu-%lu from %u:%u\n",
+                      from, to, le32_to_cpu(ex->ee_block), le16_to_cpu(ex->ee_len));
+       } else {
+               printk("strange request: removal(2) %lu-%lu from %u:%u\n",
+                      from, to, le32_to_cpu(ex->ee_block), le16_to_cpu(ex->ee_len));
+       }
+       return 0;
+}
+
+static int
+ext4_ext_rm_leaf(handle_t *handle, struct inode *inode,
+               struct ext4_ext_path *path, unsigned long start)
+{
+       int err = 0, correct_index = 0;
+       int depth = ext_depth(inode), credits;
+       struct ext4_extent_header *eh;
+       unsigned a, b, block, num;
+       unsigned long ex_ee_block;
+       unsigned short ex_ee_len;
+       struct ext4_extent *ex;
+
+       ext_debug("truncate since %lu in leaf\n", start);
+       if (!path[depth].p_hdr)
+               path[depth].p_hdr = ext_block_hdr(path[depth].p_bh);
+       eh = path[depth].p_hdr;
+       BUG_ON(eh == NULL);
+       BUG_ON(le16_to_cpu(eh->eh_entries) > le16_to_cpu(eh->eh_max));
+       BUG_ON(eh->eh_magic != EXT4_EXT_MAGIC);
+
+       /* find where to start removing */
+       ex = EXT_LAST_EXTENT(eh);
+
+       ex_ee_block = le32_to_cpu(ex->ee_block);
+       ex_ee_len = le16_to_cpu(ex->ee_len);
+
+       while (ex >= EXT_FIRST_EXTENT(eh) &&
+                       ex_ee_block + ex_ee_len > start) {
+               ext_debug("remove ext %lu:%u\n", ex_ee_block, ex_ee_len);
+               path[depth].p_ext = ex;
+
+               a = ex_ee_block > start ? ex_ee_block : start;
+               b = ex_ee_block + ex_ee_len - 1 < EXT_MAX_BLOCK ?
+                       ex_ee_block + ex_ee_len - 1 : EXT_MAX_BLOCK;
+
+               ext_debug("  border %u:%u\n", a, b);
+
+               if (a != ex_ee_block && b != ex_ee_block + ex_ee_len - 1) {
+                       block = 0;
+                       num = 0;
+                       BUG();
+               } else if (a != ex_ee_block) {
+                       /* remove tail of the extent */
+                       block = ex_ee_block;
+                       num = a - block;
+               } else if (b != ex_ee_block + ex_ee_len - 1) {
+                       /* remove head of the extent */
+                       block = a;
+                       num = b - a;
+                       /* there is no "make a hole" API yet */
+                       BUG();
+               } else {
+                       /* remove whole extent: excellent! */
+                       block = ex_ee_block;
+                       num = 0;
+                       BUG_ON(a != ex_ee_block);
+                       BUG_ON(b != ex_ee_block + ex_ee_len - 1);
+               }
+
+               /* at present, extent can't cross block group: */
+               /* leaf + bitmap + group desc + sb + inode */
+               credits = 5;
+               if (ex == EXT_FIRST_EXTENT(eh)) {
+                       correct_index = 1;
+                       credits += (ext_depth(inode)) + 1;
+               }
+#ifdef CONFIG_QUOTA
+               credits += 2 * EXT4_QUOTA_TRANS_BLOCKS(inode->i_sb);
+#endif
+
+               handle = ext4_ext_journal_restart(handle, credits);
+               if (IS_ERR(handle)) {
+                       err = PTR_ERR(handle);
+                       goto out;
+               }
+
+               err = ext4_ext_get_access(handle, inode, path + depth);
+               if (err)
+                       goto out;
+
+               err = ext4_remove_blocks(handle, inode, ex, a, b);
+               if (err)
+                       goto out;
+
+               if (num == 0) {
+                       /* this extent is removed; mark slot entirely unused */
+                       ext4_ext_store_pblock(ex, 0);
+                       eh->eh_entries = cpu_to_le16(le16_to_cpu(eh->eh_entries)-1);
+               }
+
+               ex->ee_block = cpu_to_le32(block);
+               ex->ee_len = cpu_to_le16(num);
+
+               err = ext4_ext_dirty(handle, inode, path + depth);
+               if (err)
+                       goto out;
+
+               ext_debug("new extent: %u:%u:%llu\n", block, num,
+                               ext_pblock(ex));
+               ex--;
+               ex_ee_block = le32_to_cpu(ex->ee_block);
+               ex_ee_len = le16_to_cpu(ex->ee_len);
+       }
+
+       if (correct_index && eh->eh_entries)
+               err = ext4_ext_correct_indexes(handle, inode, path);
+
+       /* if this leaf is free, then we should
+        * remove it from index block above */
+       if (err == 0 && eh->eh_entries == 0 && path[depth].p_bh != NULL)
+               err = ext4_ext_rm_idx(handle, inode, path + depth);
+
+out:
+       return err;
+}
+
+/*
+ * ext4_ext_more_to_rm:
+ * returns 1 if current index has to be freed (even partial)
+ */
+static int inline
+ext4_ext_more_to_rm(struct ext4_ext_path *path)
+{
+       BUG_ON(path->p_idx == NULL);
+
+       if (path->p_idx < EXT_FIRST_INDEX(path->p_hdr))
+               return 0;
+
+       /*
+        * if truncate on deeper level happened, it wasn't partial,
+        * so we have to consider current index for truncation
+        */
+       if (le16_to_cpu(path->p_hdr->eh_entries) == path->p_block)
+               return 0;
+       return 1;
+}
+
+int ext4_ext_remove_space(struct inode *inode, unsigned long start)
+{
+       struct super_block *sb = inode->i_sb;
+       int depth = ext_depth(inode);
+       struct ext4_ext_path *path;
+       handle_t *handle;
+       int i = 0, err = 0;
+
+       ext_debug("truncate since %lu\n", start);
+
+       /* probably first extent we're gonna free will be last in block */
+       handle = ext4_journal_start(inode, depth + 1);
+       if (IS_ERR(handle))
+               return PTR_ERR(handle);
+
+       ext4_ext_invalidate_cache(inode);
+
+       /*
+        * We start scanning from right side, freeing all the blocks
+        * after i_size and walking into the tree depth-wise.
+        */
+       path = kmalloc(sizeof(struct ext4_ext_path) * (depth + 1), GFP_KERNEL);
+       if (path == NULL) {
+               ext4_journal_stop(handle);
+               return -ENOMEM;
+       }
+       memset(path, 0, sizeof(struct ext4_ext_path) * (depth + 1));
+       path[0].p_hdr = ext_inode_hdr(inode);
+       if (ext4_ext_check_header(__FUNCTION__, inode, path[0].p_hdr)) {
+               err = -EIO;
+               goto out;
+       }
+       path[0].p_depth = depth;
+
+       while (i >= 0 && err == 0) {
+               if (i == depth) {
+                       /* this is leaf block */
+                       err = ext4_ext_rm_leaf(handle, inode, path, start);
+                       /* root level has p_bh == NULL, brelse() eats this */
+                       brelse(path[i].p_bh);
+                       path[i].p_bh = NULL;
+                       i--;
+                       continue;
+               }
+
+               /* this is index block */
+               if (!path[i].p_hdr) {
+                       ext_debug("initialize header\n");
+                       path[i].p_hdr = ext_block_hdr(path[i].p_bh);
+                       if (ext4_ext_check_header(__FUNCTION__, inode,
+                                                       path[i].p_hdr)) {
+                               err = -EIO;
+                               goto out;
+                       }
+               }
+
+               BUG_ON(le16_to_cpu(path[i].p_hdr->eh_entries)
+                          > le16_to_cpu(path[i].p_hdr->eh_max));
+               BUG_ON(path[i].p_hdr->eh_magic != EXT4_EXT_MAGIC);
+
+               if (!path[i].p_idx) {
+                       /* this level hasn't been touched yet */
+                       path[i].p_idx = EXT_LAST_INDEX(path[i].p_hdr);
+                       path[i].p_block = le16_to_cpu(path[i].p_hdr->eh_entries)+1;
+                       ext_debug("init index ptr: hdr 0x%p, num %d\n",
+                                 path[i].p_hdr,
+                                 le16_to_cpu(path[i].p_hdr->eh_entries));
+               } else {
+                       /* we were already here, see at next index */
+                       path[i].p_idx--;
+               }
+
+               ext_debug("level %d - index, first 0x%p, cur 0x%p\n",
+                               i, EXT_FIRST_INDEX(path[i].p_hdr),
+                               path[i].p_idx);
+               if (ext4_ext_more_to_rm(path + i)) {
+                       /* go to the next level */
+                       ext_debug("move to level %d (block %llu)\n",
+                                 i + 1, idx_pblock(path[i].p_idx));
+                       memset(path + i + 1, 0, sizeof(*path));
+                       path[i+1].p_bh =
+                               sb_bread(sb, idx_pblock(path[i].p_idx));
+                       if (!path[i+1].p_bh) {
+                               /* should we reset i_size? */
+                               err = -EIO;
+                               break;
+                       }
+
+                       /* save actual number of indexes since this
+                        * number is changed at the next iteration */
+                       path[i].p_block = le16_to_cpu(path[i].p_hdr->eh_entries);
+                       i++;
+               } else {
+                       /* we finished processing this index, go up */
+                       if (path[i].p_hdr->eh_entries == 0 && i > 0) {
+                               /* index is empty, remove it;
+                                * handle must be already prepared by the
+                                * truncatei_leaf() */
+                               err = ext4_ext_rm_idx(handle, inode, path + i);
+                       }
+                       /* root level has p_bh == NULL, brelse() eats this */
+                       brelse(path[i].p_bh);
+                       path[i].p_bh = NULL;
+                       i--;
+                       ext_debug("return to level %d\n", i);
+               }
+       }
+
+       /* TODO: flexible tree reduction should be here */
+       if (path->p_hdr->eh_entries == 0) {
+               /*
+                * truncate to zero freed all the tree,
+                * so we need to correct eh_depth
+                */
+               err = ext4_ext_get_access(handle, inode, path);
+               if (err == 0) {
+                       ext_inode_hdr(inode)->eh_depth = 0;
+                       ext_inode_hdr(inode)->eh_max =
+                               cpu_to_le16(ext4_ext_space_root(inode));
+                       err = ext4_ext_dirty(handle, inode, path);
+               }
+       }
+out:
+       ext4_ext_tree_changed(inode);
+       ext4_ext_drop_refs(path);
+       kfree(path);
+       ext4_journal_stop(handle);
+
+       return err;
+}
+
+/*
+ * called at mount time
+ */
+void ext4_ext_init(struct super_block *sb)
+{
+       /*
+        * possible initialization would be here
+        */
+
+       if (test_opt(sb, EXTENTS)) {
+               printk("EXT4-fs: file extents enabled");
+#ifdef AGRESSIVE_TEST
+               printk(", agressive tests");
+#endif
+#ifdef CHECK_BINSEARCH
+               printk(", check binsearch");
+#endif
+#ifdef EXTENTS_STATS
+               printk(", stats");
+#endif
+               printk("\n");
+#ifdef EXTENTS_STATS
+               spin_lock_init(&EXT4_SB(sb)->s_ext_stats_lock);
+               EXT4_SB(sb)->s_ext_min = 1 << 30;
+               EXT4_SB(sb)->s_ext_max = 0;
+#endif
+       }
+}
+
+/*
+ * called at umount time
+ */
+void ext4_ext_release(struct super_block *sb)
+{
+       if (!test_opt(sb, EXTENTS))
+               return;
+
+#ifdef EXTENTS_STATS
+       if (EXT4_SB(sb)->s_ext_blocks && EXT4_SB(sb)->s_ext_extents) {
+               struct ext4_sb_info *sbi = EXT4_SB(sb);
+               printk(KERN_ERR "EXT4-fs: %lu blocks in %lu extents (%lu ave)\n",
+                       sbi->s_ext_blocks, sbi->s_ext_extents,
+                       sbi->s_ext_blocks / sbi->s_ext_extents);
+               printk(KERN_ERR "EXT4-fs: extents: %lu min, %lu max, max depth %lu\n",
+                       sbi->s_ext_min, sbi->s_ext_max, sbi->s_depth_max);
+       }
+#endif
+}
+
+int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
+                       ext4_fsblk_t iblock,
+                       unsigned long max_blocks, struct buffer_head *bh_result,
+                       int create, int extend_disksize)
+{
+       struct ext4_ext_path *path = NULL;
+       struct ext4_extent newex, *ex;
+       ext4_fsblk_t goal, newblock;
+       int err = 0, depth;
+       unsigned long allocated = 0;
+
+       __clear_bit(BH_New, &bh_result->b_state);
+       ext_debug("blocks %d/%lu requested for inode %u\n", (int) iblock,
+                       max_blocks, (unsigned) inode->i_ino);
+       mutex_lock(&EXT4_I(inode)->truncate_mutex);
+
+       /* check in cache */
+       if ((goal = ext4_ext_in_cache(inode, iblock, &newex))) {
+               if (goal == EXT4_EXT_CACHE_GAP) {
+                       if (!create) {
+                               /* block isn't allocated yet and
+                                * user doesn't want to allocate it */
+                               goto out2;
+                       }
+                       /* we should allocate requested block */
+               } else if (goal == EXT4_EXT_CACHE_EXTENT) {
+                       /* block is already allocated */
+                       newblock = iblock
+                                  - le32_to_cpu(newex.ee_block)
+                                  + ext_pblock(&newex);
+                       /* number of remaining blocks in the extent */
+                       allocated = le16_to_cpu(newex.ee_len) -
+                                       (iblock - le32_to_cpu(newex.ee_block));
+                       goto out;
+               } else {
+                       BUG();
+               }
+       }
+
+       /* find extent for this block */
+       path = ext4_ext_find_extent(inode, iblock, NULL);
+       if (IS_ERR(path)) {
+               err = PTR_ERR(path);
+               path = NULL;
+               goto out2;
+       }
+
+       depth = ext_depth(inode);
+
+       /*
+        * consistent leaf must not be empty;
+        * this situation is possible, though, _during_ tree modification;
+        * this is why assert can't be put in ext4_ext_find_extent()
+        */
+       BUG_ON(path[depth].p_ext == NULL && depth != 0);
+
+       if ((ex = path[depth].p_ext)) {
+               unsigned long ee_block = le32_to_cpu(ex->ee_block);
+               ext4_fsblk_t ee_start = ext_pblock(ex);
+               unsigned short ee_len  = le16_to_cpu(ex->ee_len);
+
+               /*
+                * Allow future support for preallocated extents to be added
+                * as an RO_COMPAT feature:
+                * Uninitialized extents are treated as holes, except that
+                * we avoid (fail) allocating new blocks during a write.
+                */
+               if (ee_len > EXT_MAX_LEN)
+                       goto out2;
+               /* if found extent covers block, simply return it */
+               if (iblock >= ee_block && iblock < ee_block + ee_len) {
+                       newblock = iblock - ee_block + ee_start;
+                       /* number of remaining blocks in the extent */
+                       allocated = ee_len - (iblock - ee_block);
+                       ext_debug("%d fit into %lu:%d -> %llu\n", (int) iblock,
+                                       ee_block, ee_len, newblock);
+                       ext4_ext_put_in_cache(inode, ee_block, ee_len,
+                                               ee_start, EXT4_EXT_CACHE_EXTENT);
+                       goto out;
+               }
+       }
+
+       /*
+        * requested block isn't allocated yet;
+        * we couldn't try to create block if create flag is zero
+        */
+       if (!create) {
+               /* put just found gap into cache to speed up
+                * subsequent requests */
+               ext4_ext_put_gap_in_cache(inode, path, iblock);
+               goto out2;
+       }
+       /*
+        * Okay, we need to do block allocation.  Lazily initialize the block
+        * allocation info here if necessary.
+        */
+       if (S_ISREG(inode->i_mode) && (!EXT4_I(inode)->i_block_alloc_info))
+               ext4_init_block_alloc_info(inode);
+
+       /* allocate new block */
+       goal = ext4_ext_find_goal(inode, path, iblock);
+       allocated = max_blocks;
+       newblock = ext4_new_blocks(handle, inode, goal, &allocated, &err);
+       if (!newblock)
+               goto out2;
+       ext_debug("allocate new block: goal %llu, found %llu/%lu\n",
+                       goal, newblock, allocated);
+
+       /* try to insert new extent into found leaf and return */
+       newex.ee_block = cpu_to_le32(iblock);
+       ext4_ext_store_pblock(&newex, newblock);
+       newex.ee_len = cpu_to_le16(allocated);
+       err = ext4_ext_insert_extent(handle, inode, path, &newex);
+       if (err)
+               goto out2;
+
+       if (extend_disksize && inode->i_size > EXT4_I(inode)->i_disksize)
+               EXT4_I(inode)->i_disksize = inode->i_size;
+
+       /* previous routine could use block we allocated */
+       newblock = ext_pblock(&newex);
+       __set_bit(BH_New, &bh_result->b_state);
+
+       ext4_ext_put_in_cache(inode, iblock, allocated, newblock,
+                               EXT4_EXT_CACHE_EXTENT);
+out:
+       if (allocated > max_blocks)
+               allocated = max_blocks;
+       ext4_ext_show_leaf(inode, path);
+       __set_bit(BH_Mapped, &bh_result->b_state);
+       bh_result->b_bdev = inode->i_sb->s_bdev;
+       bh_result->b_blocknr = newblock;
+out2:
+       if (path) {
+               ext4_ext_drop_refs(path);
+               kfree(path);
+       }
+       mutex_unlock(&EXT4_I(inode)->truncate_mutex);
+
+       return err ? err : allocated;
+}
+
+void ext4_ext_truncate(struct inode * inode, struct page *page)
+{
+       struct address_space *mapping = inode->i_mapping;
+       struct super_block *sb = inode->i_sb;
+       unsigned long last_block;
+       handle_t *handle;
+       int err = 0;
+
+       /*
+        * probably first extent we're gonna free will be last in block
+        */
+       err = ext4_writepage_trans_blocks(inode) + 3;
+       handle = ext4_journal_start(inode, err);
+       if (IS_ERR(handle)) {
+               if (page) {
+                       clear_highpage(page);
+                       flush_dcache_page(page);
+                       unlock_page(page);
+                       page_cache_release(page);
+               }
+               return;
+       }
+
+       if (page)
+               ext4_block_truncate_page(handle, page, mapping, inode->i_size);
+
+       mutex_lock(&EXT4_I(inode)->truncate_mutex);
+       ext4_ext_invalidate_cache(inode);
+
+       /*
+        * TODO: optimization is possible here.
+        * Probably we need not scan at all,
+        * because page truncation is enough.
+        */
+       if (ext4_orphan_add(handle, inode))
+               goto out_stop;
+
+       /* we have to know where to truncate from in crash case */
+       EXT4_I(inode)->i_disksize = inode->i_size;
+       ext4_mark_inode_dirty(handle, inode);
+
+       last_block = (inode->i_size + sb->s_blocksize - 1)
+                       >> EXT4_BLOCK_SIZE_BITS(sb);
+       err = ext4_ext_remove_space(inode, last_block);
+
+       /* In a multi-transaction truncate, we only make the final
+        * transaction synchronous. */
+       if (IS_SYNC(inode))
+               handle->h_sync = 1;
+
+out_stop:
+       /*
+        * If this was a simple ftruncate() and the file will remain alive,
+        * then we need to clear up the orphan record which we created above.
+        * However, if this was a real unlink then we were called by
+        * ext4_delete_inode(), and we allow that function to clean up the
+        * orphan info for us.
+        */
+       if (inode->i_nlink)
+               ext4_orphan_del(handle, inode);
+
+       mutex_unlock(&EXT4_I(inode)->truncate_mutex);
+       ext4_journal_stop(handle);
+}
+
+/*
+ * ext4_ext_writepage_trans_blocks:
+ * calculate max number of blocks we could modify
+ * in order to allocate new block for an inode
+ */
+int ext4_ext_writepage_trans_blocks(struct inode *inode, int num)
+{
+       int needed;
+
+       needed = ext4_ext_calc_credits_for_insert(inode, NULL);
+
+       /* caller wants to allocate num blocks, but note it includes sb */
+       needed = needed * num - (num - 1);
+
+#ifdef CONFIG_QUOTA
+       needed += 2 * EXT4_QUOTA_TRANS_BLOCKS(inode->i_sb);
+#endif
+
+       return needed;
+}
+
+EXPORT_SYMBOL(ext4_mark_inode_dirty);
+EXPORT_SYMBOL(ext4_ext_invalidate_cache);
+EXPORT_SYMBOL(ext4_ext_insert_extent);
+EXPORT_SYMBOL(ext4_ext_walk_space);
+EXPORT_SYMBOL(ext4_ext_find_goal);
+EXPORT_SYMBOL(ext4_ext_calc_credits_for_insert);
+
diff --git a/fs/ext4/file.c b/fs/ext4/file.c
new file mode 100644 (file)
index 0000000..0b622c0
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ *  linux/fs/ext4/file.c
+ *
+ * Copyright (C) 1992, 1993, 1994, 1995
+ * Remy Card (card@masi.ibp.fr)
+ * Laboratoire MASI - Institut Blaise Pascal
+ * Universite Pierre et Marie Curie (Paris VI)
+ *
+ *  from
+ *
+ *  linux/fs/minix/file.c
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ *
+ *  ext4 fs regular file handling primitives
+ *
+ *  64-bit file support on 64-bit platforms by Jakub Jelinek
+ *     (jj@sunsite.ms.mff.cuni.cz)
+ */
+
+#include <linux/time.h>
+#include <linux/fs.h>
+#include <linux/jbd2.h>
+#include <linux/ext4_fs.h>
+#include <linux/ext4_jbd2.h>
+#include "xattr.h"
+#include "acl.h"
+
+/*
+ * Called when an inode is released. Note that this is different
+ * from ext4_file_open: open gets called at every open, but release
+ * gets called only when /all/ the files are closed.
+ */
+static int ext4_release_file (struct inode * inode, struct file * filp)
+{
+       /* if we are the last writer on the inode, drop the block reservation */
+       if ((filp->f_mode & FMODE_WRITE) &&
+                       (atomic_read(&inode->i_writecount) == 1))
+       {
+               mutex_lock(&EXT4_I(inode)->truncate_mutex);
+               ext4_discard_reservation(inode);
+               mutex_unlock(&EXT4_I(inode)->truncate_mutex);
+       }
+       if (is_dx(inode) && filp->private_data)
+               ext4_htree_free_dir_info(filp->private_data);
+
+       return 0;
+}
+
+static ssize_t
+ext4_file_write(struct kiocb *iocb, const struct iovec *iov,
+               unsigned long nr_segs, loff_t pos)
+{
+       struct file *file = iocb->ki_filp;
+       struct inode *inode = file->f_dentry->d_inode;
+       ssize_t ret;
+       int err;
+
+       ret = generic_file_aio_write(iocb, iov, nr_segs, pos);
+
+       /*
+        * Skip flushing if there was an error, or if nothing was written.
+        */
+       if (ret <= 0)
+               return ret;
+
+       /*
+        * If the inode is IS_SYNC, or is O_SYNC and we are doing data
+        * journalling then we need to make sure that we force the transaction
+        * to disk to keep all metadata uptodate synchronously.
+        */
+       if (file->f_flags & O_SYNC) {
+               /*
+                * If we are non-data-journaled, then the dirty data has
+                * already been flushed to backing store by generic_osync_inode,
+                * and the inode has been flushed too if there have been any
+                * modifications other than mere timestamp updates.
+                *
+                * Open question --- do we care about flushing timestamps too
+                * if the inode is IS_SYNC?
+                */
+               if (!ext4_should_journal_data(inode))
+                       return ret;
+
+               goto force_commit;
+       }
+
+       /*
+        * So we know that there has been no forced data flush.  If the inode
+        * is marked IS_SYNC, we need to force one ourselves.
+        */
+       if (!IS_SYNC(inode))
+               return ret;
+
+       /*
+        * Open question #2 --- should we force data to disk here too?  If we
+        * don't, the only impact is that data=writeback filesystems won't
+        * flush data to disk automatically on IS_SYNC, only metadata (but
+        * historically, that is what ext2 has done.)
+        */
+
+force_commit:
+       err = ext4_force_commit(inode->i_sb);
+       if (err)
+               return err;
+       return ret;
+}
+
+const struct file_operations ext4_file_operations = {
+       .llseek         = generic_file_llseek,
+       .read           = do_sync_read,
+       .write          = do_sync_write,
+       .aio_read       = generic_file_aio_read,
+       .aio_write      = ext4_file_write,
+       .ioctl          = ext4_ioctl,
+#ifdef CONFIG_COMPAT
+       .compat_ioctl   = ext4_compat_ioctl,
+#endif
+       .mmap           = generic_file_mmap,
+       .open           = generic_file_open,
+       .release        = ext4_release_file,
+       .fsync          = ext4_sync_file,
+       .sendfile       = generic_file_sendfile,
+       .splice_read    = generic_file_splice_read,
+       .splice_write   = generic_file_splice_write,
+};
+
+struct inode_operations ext4_file_inode_operations = {
+       .truncate       = ext4_truncate,
+       .setattr        = ext4_setattr,
+#ifdef CONFIG_EXT4DEV_FS_XATTR
+       .setxattr       = generic_setxattr,
+       .getxattr       = generic_getxattr,
+       .listxattr      = ext4_listxattr,
+       .removexattr    = generic_removexattr,
+#endif
+       .permission     = ext4_permission,
+};
+
diff --git a/fs/ext4/fsync.c b/fs/ext4/fsync.c
new file mode 100644 (file)
index 0000000..2a167d7
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ *  linux/fs/ext4/fsync.c
+ *
+ *  Copyright (C) 1993  Stephen Tweedie (sct@redhat.com)
+ *  from
+ *  Copyright (C) 1992  Remy Card (card@masi.ibp.fr)
+ *                      Laboratoire MASI - Institut Blaise Pascal
+ *                      Universite Pierre et Marie Curie (Paris VI)
+ *  from
+ *  linux/fs/minix/truncate.c   Copyright (C) 1991, 1992  Linus Torvalds
+ *
+ *  ext4fs fsync primitive
+ *
+ *  Big-endian to little-endian byte-swapping/bitmaps by
+ *        David S. Miller (davem@caip.rutgers.edu), 1995
+ *
+ *  Removed unnecessary code duplication for little endian machines
+ *  and excessive __inline__s.
+ *        Andi Kleen, 1997
+ *
+ * Major simplications and cleanup - we only need to do the metadata, because
+ * we can depend on generic_block_fdatasync() to sync the data blocks.
+ */
+
+#include <linux/time.h>
+#include <linux/fs.h>
+#include <linux/sched.h>
+#include <linux/writeback.h>
+#include <linux/jbd2.h>
+#include <linux/ext4_fs.h>
+#include <linux/ext4_jbd2.h>
+
+/*
+ * akpm: A new design for ext4_sync_file().
+ *
+ * This is only called from sys_fsync(), sys_fdatasync() and sys_msync().
+ * There cannot be a transaction open by this task.
+ * Another task could have dirtied this inode.  Its data can be in any
+ * state in the journalling system.
+ *
+ * What we do is just kick off a commit and wait on it.  This will snapshot the
+ * inode to disk.
+ */
+
+int ext4_sync_file(struct file * file, struct dentry *dentry, int datasync)
+{
+       struct inode *inode = dentry->d_inode;
+       int ret = 0;
+
+       J_ASSERT(ext4_journal_current_handle() == 0);
+
+       /*
+        * data=writeback:
+        *  The caller's filemap_fdatawrite()/wait will sync the data.
+        *  sync_inode() will sync the metadata
+        *
+        * data=ordered:
+        *  The caller's filemap_fdatawrite() will write the data and
+        *  sync_inode() will write the inode if it is dirty.  Then the caller's
+        *  filemap_fdatawait() will wait on the pages.
+        *
+        * data=journal:
+        *  filemap_fdatawrite won't do anything (the buffers are clean).
+        *  ext4_force_commit will write the file data into the journal and
+        *  will wait on that.
+        *  filemap_fdatawait() will encounter a ton of newly-dirtied pages
+        *  (they were dirtied by commit).  But that's OK - the blocks are
+        *  safe in-journal, which is all fsync() needs to ensure.
+        */
+       if (ext4_should_journal_data(inode)) {
+               ret = ext4_force_commit(inode->i_sb);
+               goto out;
+       }
+
+       /*
+        * The VFS has written the file data.  If the inode is unaltered
+        * then we need not start a commit.
+        */
+       if (inode->i_state & (I_DIRTY_SYNC|I_DIRTY_DATASYNC)) {
+               struct writeback_control wbc = {
+                       .sync_mode = WB_SYNC_ALL,
+                       .nr_to_write = 0, /* sys_fsync did this */
+               };
+               ret = sync_inode(inode, &wbc);
+       }
+out:
+       return ret;
+}
diff --git a/fs/ext4/hash.c b/fs/ext4/hash.c
new file mode 100644 (file)
index 0000000..a679663
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+ *  linux/fs/ext4/hash.c
+ *
+ * Copyright (C) 2002 by Theodore Ts'o
+ *
+ * This file is released under the GPL v2.
+ *
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ */
+
+#include <linux/fs.h>
+#include <linux/jbd2.h>
+#include <linux/sched.h>
+#include <linux/ext4_fs.h>
+#include <linux/cryptohash.h>
+
+#define DELTA 0x9E3779B9
+
+static void TEA_transform(__u32 buf[4], __u32 const in[])
+{
+       __u32   sum = 0;
+       __u32   b0 = buf[0], b1 = buf[1];
+       __u32   a = in[0], b = in[1], c = in[2], d = in[3];
+       int     n = 16;
+
+       do {
+               sum += DELTA;
+               b0 += ((b1 << 4)+a) ^ (b1+sum) ^ ((b1 >> 5)+b);
+               b1 += ((b0 << 4)+c) ^ (b0+sum) ^ ((b0 >> 5)+d);
+       } while(--n);
+
+       buf[0] += b0;
+       buf[1] += b1;
+}
+
+
+/* The old legacy hash */
+static __u32 dx_hack_hash (const char *name, int len)
+{
+       __u32 hash0 = 0x12a3fe2d, hash1 = 0x37abe8f9;
+       while (len--) {
+               __u32 hash = hash1 + (hash0 ^ (*name++ * 7152373));
+
+               if (hash & 0x80000000) hash -= 0x7fffffff;
+               hash1 = hash0;
+               hash0 = hash;
+       }
+       return (hash0 << 1);
+}
+
+static void str2hashbuf(const char *msg, int len, __u32 *buf, int num)
+{
+       __u32   pad, val;
+       int     i;
+
+       pad = (__u32)len | ((__u32)len << 8);
+       pad |= pad << 16;
+
+       val = pad;
+       if (len > num*4)
+               len = num * 4;
+       for (i=0; i < len; i++) {
+               if ((i % 4) == 0)
+                       val = pad;
+               val = msg[i] + (val << 8);
+               if ((i % 4) == 3) {
+                       *buf++ = val;
+                       val = pad;
+                       num--;
+               }
+       }
+       if (--num >= 0)
+               *buf++ = val;
+       while (--num >= 0)
+               *buf++ = pad;
+}
+
+/*
+ * Returns the hash of a filename.  If len is 0 and name is NULL, then
+ * this function can be used to test whether or not a hash version is
+ * supported.
+ *
+ * The seed is an 4 longword (32 bits) "secret" which can be used to
+ * uniquify a hash.  If the seed is all zero's, then some default seed
+ * may be used.
+ *
+ * A particular hash version specifies whether or not the seed is
+ * represented, and whether or not the returned hash is 32 bits or 64
+ * bits.  32 bit hashes will return 0 for the minor hash.
+ */
+int ext4fs_dirhash(const char *name, int len, struct dx_hash_info *hinfo)
+{
+       __u32   hash;
+       __u32   minor_hash = 0;
+       const char      *p;
+       int             i;
+       __u32           in[8], buf[4];
+
+       /* Initialize the default seed for the hash checksum functions */
+       buf[0] = 0x67452301;
+       buf[1] = 0xefcdab89;
+       buf[2] = 0x98badcfe;
+       buf[3] = 0x10325476;
+
+       /* Check to see if the seed is all zero's */
+       if (hinfo->seed) {
+               for (i=0; i < 4; i++) {
+                       if (hinfo->seed[i])
+                               break;
+               }
+               if (i < 4)
+                       memcpy(buf, hinfo->seed, sizeof(buf));
+       }
+
+       switch (hinfo->hash_version) {
+       case DX_HASH_LEGACY:
+               hash = dx_hack_hash(name, len);
+               break;
+       case DX_HASH_HALF_MD4:
+               p = name;
+               while (len > 0) {
+                       str2hashbuf(p, len, in, 8);
+                       half_md4_transform(buf, in);
+                       len -= 32;
+                       p += 32;
+               }
+               minor_hash = buf[2];
+               hash = buf[1];
+               break;
+       case DX_HASH_TEA:
+               p = name;
+               while (len > 0) {
+                       str2hashbuf(p, len, in, 4);
+                       TEA_transform(buf, in);
+                       len -= 16;
+                       p += 16;
+               }
+               hash = buf[0];
+               minor_hash = buf[1];
+               break;
+       default:
+               hinfo->hash = 0;
+               return -1;
+       }
+       hash = hash & ~1;
+       if (hash == (EXT4_HTREE_EOF << 1))
+               hash = (EXT4_HTREE_EOF-1) << 1;
+       hinfo->hash = hash;
+       hinfo->minor_hash = minor_hash;
+       return 0;
+}
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
new file mode 100644 (file)
index 0000000..c88b439
--- /dev/null
@@ -0,0 +1,772 @@
+/*
+ *  linux/fs/ext4/ialloc.c
+ *
+ * Copyright (C) 1992, 1993, 1994, 1995
+ * Remy Card (card@masi.ibp.fr)
+ * Laboratoire MASI - Institut Blaise Pascal
+ * Universite Pierre et Marie Curie (Paris VI)
+ *
+ *  BSD ufs-inspired inode and directory allocation by
+ *  Stephen Tweedie (sct@redhat.com), 1993
+ *  Big-endian to little-endian byte-swapping/bitmaps by
+ *        David S. Miller (davem@caip.rutgers.edu), 1995
+ */
+
+#include <linux/time.h>
+#include <linux/fs.h>
+#include <linux/jbd2.h>
+#include <linux/ext4_fs.h>
+#include <linux/ext4_jbd2.h>
+#include <linux/stat.h>
+#include <linux/string.h>
+#include <linux/quotaops.h>
+#include <linux/buffer_head.h>
+#include <linux/random.h>
+#include <linux/bitops.h>
+#include <linux/blkdev.h>
+#include <asm/byteorder.h>
+
+#include "xattr.h"
+#include "acl.h"
+
+/*
+ * ialloc.c contains the inodes allocation and deallocation routines
+ */
+
+/*
+ * The free inodes are managed by bitmaps.  A file system contains several
+ * blocks groups.  Each group contains 1 bitmap block for blocks, 1 bitmap
+ * block for inodes, N blocks for the inode table and data blocks.
+ *
+ * The file system contains group descriptors which are located after the
+ * super block.  Each descriptor contains the number of the bitmap block and
+ * the free blocks count in the block.
+ */
+
+
+/*
+ * Read the inode allocation bitmap for a given block_group, reading
+ * into the specified slot in the superblock's bitmap cache.
+ *
+ * Return buffer_head of bitmap on success or NULL.
+ */
+static struct buffer_head *
+read_inode_bitmap(struct super_block * sb, unsigned long block_group)
+{
+       struct ext4_group_desc *desc;
+       struct buffer_head *bh = NULL;
+
+       desc = ext4_get_group_desc(sb, block_group, NULL);
+       if (!desc)
+               goto error_out;
+
+       bh = sb_bread(sb, ext4_inode_bitmap(sb, desc));
+       if (!bh)
+               ext4_error(sb, "read_inode_bitmap",
+                           "Cannot read inode bitmap - "
+                           "block_group = %lu, inode_bitmap = %llu",
+                           block_group, ext4_inode_bitmap(sb, desc));
+error_out:
+       return bh;
+}
+
+/*
+ * NOTE! When we get the inode, we're the only people
+ * that have access to it, and as such there are no
+ * race conditions we have to worry about. The inode
+ * is not on the hash-lists, and it cannot be reached
+ * through the filesystem because the directory entry
+ * has been deleted earlier.
+ *
+ * HOWEVER: we must make sure that we get no aliases,
+ * which means that we have to call "clear_inode()"
+ * _before_ we mark the inode not in use in the inode
+ * bitmaps. Otherwise a newly created file might use
+ * the same inode number (not actually the same pointer
+ * though), and then we'd have two inodes sharing the
+ * same inode number and space on the harddisk.
+ */
+void ext4_free_inode (handle_t *handle, struct inode * inode)
+{
+       struct super_block * sb = inode->i_sb;
+       int is_directory;
+       unsigned long ino;
+       struct buffer_head *bitmap_bh = NULL;
+       struct buffer_head *bh2;
+       unsigned long block_group;
+       unsigned long bit;
+       struct ext4_group_desc * gdp;
+       struct ext4_super_block * es;
+       struct ext4_sb_info *sbi;
+       int fatal = 0, err;
+
+       if (atomic_read(&inode->i_count) > 1) {
+               printk ("ext4_free_inode: inode has count=%d\n",
+                                       atomic_read(&inode->i_count));
+               return;
+       }
+       if (inode->i_nlink) {
+               printk ("ext4_free_inode: inode has nlink=%d\n",
+                       inode->i_nlink);
+               return;
+       }
+       if (!sb) {
+               printk("ext4_free_inode: inode on nonexistent device\n");
+               return;
+       }
+       sbi = EXT4_SB(sb);
+
+       ino = inode->i_ino;
+       ext4_debug ("freeing inode %lu\n", ino);
+
+       /*
+        * Note: we must free any quota before locking the superblock,
+        * as writing the quota to disk may need the lock as well.
+        */
+       DQUOT_INIT(inode);
+       ext4_xattr_delete_inode(handle, inode);
+       DQUOT_FREE_INODE(inode);
+       DQUOT_DROP(inode);
+
+       is_directory = S_ISDIR(inode->i_mode);
+
+       /* Do this BEFORE marking the inode not in use or returning an error */
+       clear_inode (inode);
+
+       es = EXT4_SB(sb)->s_es;
+       if (ino < EXT4_FIRST_INO(sb) || ino > le32_to_cpu(es->s_inodes_count)) {
+               ext4_error (sb, "ext4_free_inode",
+                           "reserved or nonexistent inode %lu", ino);
+               goto error_return;
+       }
+       block_group = (ino - 1) / EXT4_INODES_PER_GROUP(sb);
+       bit = (ino - 1) % EXT4_INODES_PER_GROUP(sb);
+       bitmap_bh = read_inode_bitmap(sb, block_group);
+       if (!bitmap_bh)
+               goto error_return;
+
+       BUFFER_TRACE(bitmap_bh, "get_write_access");
+       fatal = ext4_journal_get_write_access(handle, bitmap_bh);
+       if (fatal)
+               goto error_return;
+
+       /* Ok, now we can actually update the inode bitmaps.. */
+       if (!ext4_clear_bit_atomic(sb_bgl_lock(sbi, block_group),
+                                       bit, bitmap_bh->b_data))
+               ext4_error (sb, "ext4_free_inode",
+                             "bit already cleared for inode %lu", ino);
+       else {
+               gdp = ext4_get_group_desc (sb, block_group, &bh2);
+
+               BUFFER_TRACE(bh2, "get_write_access");
+               fatal = ext4_journal_get_write_access(handle, bh2);
+               if (fatal) goto error_return;
+
+               if (gdp) {
+                       spin_lock(sb_bgl_lock(sbi, block_group));
+                       gdp->bg_free_inodes_count = cpu_to_le16(
+                               le16_to_cpu(gdp->bg_free_inodes_count) + 1);
+                       if (is_directory)
+                               gdp->bg_used_dirs_count = cpu_to_le16(
+                                 le16_to_cpu(gdp->bg_used_dirs_count) - 1);
+                       spin_unlock(sb_bgl_lock(sbi, block_group));
+                       percpu_counter_inc(&sbi->s_freeinodes_counter);
+                       if (is_directory)
+                               percpu_counter_dec(&sbi->s_dirs_counter);
+
+               }
+               BUFFER_TRACE(bh2, "call ext4_journal_dirty_metadata");
+               err = ext4_journal_dirty_metadata(handle, bh2);
+               if (!fatal) fatal = err;
+       }
+       BUFFER_TRACE(bitmap_bh, "call ext4_journal_dirty_metadata");
+       err = ext4_journal_dirty_metadata(handle, bitmap_bh);
+       if (!fatal)
+               fatal = err;
+       sb->s_dirt = 1;
+error_return:
+       brelse(bitmap_bh);
+       ext4_std_error(sb, fatal);
+}
+
+/*
+ * There are two policies for allocating an inode.  If the new inode is
+ * a directory, then a forward search is made for a block group with both
+ * free space and a low directory-to-inode ratio; if that fails, then of
+ * the groups with above-average free space, that group with the fewest
+ * directories already is chosen.
+ *
+ * For other inodes, search forward from the parent directory\'s block
+ * group to find a free inode.
+ */
+static int find_group_dir(struct super_block *sb, struct inode *parent)
+{
+       int ngroups = EXT4_SB(sb)->s_groups_count;
+       unsigned int freei, avefreei;
+       struct ext4_group_desc *desc, *best_desc = NULL;
+       struct buffer_head *bh;
+       int group, best_group = -1;
+
+       freei = percpu_counter_read_positive(&EXT4_SB(sb)->s_freeinodes_counter);
+       avefreei = freei / ngroups;
+
+       for (group = 0; group < ngroups; group++) {
+               desc = ext4_get_group_desc (sb, group, &bh);
+               if (!desc || !desc->bg_free_inodes_count)
+                       continue;
+               if (le16_to_cpu(desc->bg_free_inodes_count) < avefreei)
+                       continue;
+               if (!best_desc ||
+                   (le16_to_cpu(desc->bg_free_blocks_count) >
+                    le16_to_cpu(best_desc->bg_free_blocks_count))) {
+                       best_group = group;
+                       best_desc = desc;
+               }
+       }
+       return best_group;
+}
+
+/*
+ * Orlov's allocator for directories.
+ *
+ * We always try to spread first-level directories.
+ *
+ * If there are blockgroups with both free inodes and free blocks counts
+ * not worse than average we return one with smallest directory count.
+ * Otherwise we simply return a random group.
+ *
+ * For the rest rules look so:
+ *
+ * It's OK to put directory into a group unless
+ * it has too many directories already (max_dirs) or
+ * it has too few free inodes left (min_inodes) or
+ * it has too few free blocks left (min_blocks) or
+ * it's already running too large debt (max_debt).
+ * Parent's group is prefered, if it doesn't satisfy these
+ * conditions we search cyclically through the rest. If none
+ * of the groups look good we just look for a group with more
+ * free inodes than average (starting at parent's group).
+ *
+ * Debt is incremented each time we allocate a directory and decremented
+ * when we allocate an inode, within 0--255.
+ */
+
+#define INODE_COST 64
+#define BLOCK_COST 256
+
+static int find_group_orlov(struct super_block *sb, struct inode *parent)
+{
+       int parent_group = EXT4_I(parent)->i_block_group;
+       struct ext4_sb_info *sbi = EXT4_SB(sb);
+       struct ext4_super_block *es = sbi->s_es;
+       int ngroups = sbi->s_groups_count;
+       int inodes_per_group = EXT4_INODES_PER_GROUP(sb);
+       unsigned int freei, avefreei;
+       ext4_fsblk_t freeb, avefreeb;
+       ext4_fsblk_t blocks_per_dir;
+       unsigned int ndirs;
+       int max_debt, max_dirs, min_inodes;
+       ext4_grpblk_t min_blocks;
+       int group = -1, i;
+       struct ext4_group_desc *desc;
+       struct buffer_head *bh;
+
+       freei = percpu_counter_read_positive(&sbi->s_freeinodes_counter);
+       avefreei = freei / ngroups;
+       freeb = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
+       avefreeb = freeb;
+       do_div(avefreeb, ngroups);
+       ndirs = percpu_counter_read_positive(&sbi->s_dirs_counter);
+
+       if ((parent == sb->s_root->d_inode) ||
+           (EXT4_I(parent)->i_flags & EXT4_TOPDIR_FL)) {
+               int best_ndir = inodes_per_group;
+               int best_group = -1;
+
+               get_random_bytes(&group, sizeof(group));
+               parent_group = (unsigned)group % ngroups;
+               for (i = 0; i < ngroups; i++) {
+                       group = (parent_group + i) % ngroups;
+                       desc = ext4_get_group_desc (sb, group, &bh);
+                       if (!desc || !desc->bg_free_inodes_count)
+                               continue;
+                       if (le16_to_cpu(desc->bg_used_dirs_count) >= best_ndir)
+                               continue;
+                       if (le16_to_cpu(desc->bg_free_inodes_count) < avefreei)
+                               continue;
+                       if (le16_to_cpu(desc->bg_free_blocks_count) < avefreeb)
+                               continue;
+                       best_group = group;
+                       best_ndir = le16_to_cpu(desc->bg_used_dirs_count);
+               }
+               if (best_group >= 0)
+                       return best_group;
+               goto fallback;
+       }
+
+       blocks_per_dir = ext4_blocks_count(es) - freeb;
+       do_div(blocks_per_dir, ndirs);
+
+       max_dirs = ndirs / ngroups + inodes_per_group / 16;
+       min_inodes = avefreei - inodes_per_group / 4;
+       min_blocks = avefreeb - EXT4_BLOCKS_PER_GROUP(sb) / 4;
+
+       max_debt = EXT4_BLOCKS_PER_GROUP(sb);
+       max_debt /= max_t(int, blocks_per_dir, BLOCK_COST);
+       if (max_debt * INODE_COST > inodes_per_group)
+               max_debt = inodes_per_group / INODE_COST;
+       if (max_debt > 255)
+               max_debt = 255;
+       if (max_debt == 0)
+               max_debt = 1;
+
+       for (i = 0; i < ngroups; i++) {
+               group = (parent_group + i) % ngroups;
+               desc = ext4_get_group_desc (sb, group, &bh);
+               if (!desc || !desc->bg_free_inodes_count)
+                       continue;
+               if (le16_to_cpu(desc->bg_used_dirs_count) >= max_dirs)
+                       continue;
+               if (le16_to_cpu(desc->bg_free_inodes_count) < min_inodes)
+                       continue;
+               if (le16_to_cpu(desc->bg_free_blocks_count) < min_blocks)
+                       continue;
+               return group;
+       }
+
+fallback:
+       for (i = 0; i < ngroups; i++) {
+               group = (parent_group + i) % ngroups;
+               desc = ext4_get_group_desc (sb, group, &bh);
+               if (!desc || !desc->bg_free_inodes_count)
+                       continue;
+               if (le16_to_cpu(desc->bg_free_inodes_count) >= avefreei)
+                       return group;
+       }
+
+       if (avefreei) {
+               /*
+                * The free-inodes counter is approximate, and for really small
+                * filesystems the above test can fail to find any blockgroups
+                */
+               avefreei = 0;
+               goto fallback;
+       }
+
+       return -1;
+}
+
+static int find_group_other(struct super_block *sb, struct inode *parent)
+{
+       int parent_group = EXT4_I(parent)->i_block_group;
+       int ngroups = EXT4_SB(sb)->s_groups_count;
+       struct ext4_group_desc *desc;
+       struct buffer_head *bh;
+       int group, i;
+
+       /*
+        * Try to place the inode in its parent directory
+        */
+       group = parent_group;
+       desc = ext4_get_group_desc (sb, group, &bh);
+       if (desc && le16_to_cpu(desc->bg_free_inodes_count) &&
+                       le16_to_cpu(desc->bg_free_blocks_count))
+               return group;
+
+       /*
+        * We're going to place this inode in a different blockgroup from its
+        * parent.  We want to cause files in a common directory to all land in
+        * the same blockgroup.  But we want files which are in a different
+        * directory which shares a blockgroup with our parent to land in a
+        * different blockgroup.
+        *
+        * So add our directory's i_ino into the starting point for the hash.
+        */
+       group = (group + parent->i_ino) % ngroups;
+
+       /*
+        * Use a quadratic hash to find a group with a free inode and some free
+        * blocks.
+        */
+       for (i = 1; i < ngroups; i <<= 1) {
+               group += i;
+               if (group >= ngroups)
+                       group -= ngroups;
+               desc = ext4_get_group_desc (sb, group, &bh);
+               if (desc && le16_to_cpu(desc->bg_free_inodes_count) &&
+                               le16_to_cpu(desc->bg_free_blocks_count))
+                       return group;
+       }
+
+       /*
+        * That failed: try linear search for a free inode, even if that group
+        * has no free blocks.
+        */
+       group = parent_group;
+       for (i = 0; i < ngroups; i++) {
+               if (++group >= ngroups)
+                       group = 0;
+               desc = ext4_get_group_desc (sb, group, &bh);
+               if (desc && le16_to_cpu(desc->bg_free_inodes_count))
+                       return group;
+       }
+
+       return -1;
+}
+
+/*
+ * There are two policies for allocating an inode.  If the new inode is
+ * a directory, then a forward search is made for a block group with both
+ * free space and a low directory-to-inode ratio; if that fails, then of
+ * the groups with above-average free space, that group with the fewest
+ * directories already is chosen.
+ *
+ * For other inodes, search forward from the parent directory's block
+ * group to find a free inode.
+ */
+struct inode *ext4_new_inode(handle_t *handle, struct inode * dir, int mode)
+{
+       struct super_block *sb;
+       struct buffer_head *bitmap_bh = NULL;
+       struct buffer_head *bh2;
+       int group;
+       unsigned long ino = 0;
+       struct inode * inode;
+       struct ext4_group_desc * gdp = NULL;
+       struct ext4_super_block * es;
+       struct ext4_inode_info *ei;
+       struct ext4_sb_info *sbi;
+       int err = 0;
+       struct inode *ret;
+       int i;
+
+       /* Cannot create files in a deleted directory */
+       if (!dir || !dir->i_nlink)
+               return ERR_PTR(-EPERM);
+
+       sb = dir->i_sb;
+       inode = new_inode(sb);
+       if (!inode)
+               return ERR_PTR(-ENOMEM);
+       ei = EXT4_I(inode);
+
+       sbi = EXT4_SB(sb);
+       es = sbi->s_es;
+       if (S_ISDIR(mode)) {
+               if (test_opt (sb, OLDALLOC))
+                       group = find_group_dir(sb, dir);
+               else
+                       group = find_group_orlov(sb, dir);
+       } else
+               group = find_group_other(sb, dir);
+
+       err = -ENOSPC;
+       if (group == -1)
+               goto out;
+
+       for (i = 0; i < sbi->s_groups_count; i++) {
+               err = -EIO;
+
+               gdp = ext4_get_group_desc(sb, group, &bh2);
+               if (!gdp)
+                       goto fail;
+
+               brelse(bitmap_bh);
+               bitmap_bh = read_inode_bitmap(sb, group);
+               if (!bitmap_bh)
+                       goto fail;
+
+               ino = 0;
+
+repeat_in_this_group:
+               ino = ext4_find_next_zero_bit((unsigned long *)
+                               bitmap_bh->b_data, EXT4_INODES_PER_GROUP(sb), ino);
+               if (ino < EXT4_INODES_PER_GROUP(sb)) {
+
+                       BUFFER_TRACE(bitmap_bh, "get_write_access");
+                       err = ext4_journal_get_write_access(handle, bitmap_bh);
+                       if (err)
+                               goto fail;
+
+                       if (!ext4_set_bit_atomic(sb_bgl_lock(sbi, group),
+                                               ino, bitmap_bh->b_data)) {
+                               /* we won it */
+                               BUFFER_TRACE(bitmap_bh,
+                                       "call ext4_journal_dirty_metadata");
+                               err = ext4_journal_dirty_metadata(handle,
+                                                               bitmap_bh);
+                               if (err)
+                                       goto fail;
+                               goto got;
+                       }
+                       /* we lost it */
+                       jbd2_journal_release_buffer(handle, bitmap_bh);
+
+                       if (++ino < EXT4_INODES_PER_GROUP(sb))
+                               goto repeat_in_this_group;
+               }
+
+               /*
+                * This case is possible in concurrent environment.  It is very
+                * rare.  We cannot repeat the find_group_xxx() call because
+                * that will simply return the same blockgroup, because the
+                * group descriptor metadata has not yet been updated.
+                * So we just go onto the next blockgroup.
+                */
+               if (++group == sbi->s_groups_count)
+                       group = 0;
+       }
+       err = -ENOSPC;
+       goto out;
+
+got:
+       ino += group * EXT4_INODES_PER_GROUP(sb) + 1;
+       if (ino < EXT4_FIRST_INO(sb) || ino > le32_to_cpu(es->s_inodes_count)) {
+               ext4_error (sb, "ext4_new_inode",
+                           "reserved inode or inode > inodes count - "
+                           "block_group = %d, inode=%lu", group, ino);
+               err = -EIO;
+               goto fail;
+       }
+
+       BUFFER_TRACE(bh2, "get_write_access");
+       err = ext4_journal_get_write_access(handle, bh2);
+       if (err) goto fail;
+       spin_lock(sb_bgl_lock(sbi, group));
+       gdp->bg_free_inodes_count =
+               cpu_to_le16(le16_to_cpu(gdp->bg_free_inodes_count) - 1);
+       if (S_ISDIR(mode)) {
+               gdp->bg_used_dirs_count =
+                       cpu_to_le16(le16_to_cpu(gdp->bg_used_dirs_count) + 1);
+       }
+       spin_unlock(sb_bgl_lock(sbi, group));
+       BUFFER_TRACE(bh2, "call ext4_journal_dirty_metadata");
+       err = ext4_journal_dirty_metadata(handle, bh2);
+       if (err) goto fail;
+
+       percpu_counter_dec(&sbi->s_freeinodes_counter);
+       if (S_ISDIR(mode))
+               percpu_counter_inc(&sbi->s_dirs_counter);
+       sb->s_dirt = 1;
+
+       inode->i_uid = current->fsuid;
+       if (test_opt (sb, GRPID))
+               inode->i_gid = dir->i_gid;
+       else if (dir->i_mode & S_ISGID) {
+               inode->i_gid = dir->i_gid;
+               if (S_ISDIR(mode))
+                       mode |= S_ISGID;
+       } else
+               inode->i_gid = current->fsgid;
+       inode->i_mode = mode;
+
+       inode->i_ino = ino;
+       /* This is the optimal IO size (for stat), not the fs block size */
+       inode->i_blocks = 0;
+       inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
+
+       memset(ei->i_data, 0, sizeof(ei->i_data));
+       ei->i_dir_start_lookup = 0;
+       ei->i_disksize = 0;
+
+       ei->i_flags = EXT4_I(dir)->i_flags & ~EXT4_INDEX_FL;
+       if (S_ISLNK(mode))
+               ei->i_flags &= ~(EXT4_IMMUTABLE_FL|EXT4_APPEND_FL);
+       /* dirsync only applies to directories */
+       if (!S_ISDIR(mode))
+               ei->i_flags &= ~EXT4_DIRSYNC_FL;
+#ifdef EXT4_FRAGMENTS
+       ei->i_faddr = 0;
+       ei->i_frag_no = 0;
+       ei->i_frag_size = 0;
+#endif
+       ei->i_file_acl = 0;
+       ei->i_dir_acl = 0;
+       ei->i_dtime = 0;
+       ei->i_block_alloc_info = NULL;
+       ei->i_block_group = group;
+
+       ext4_set_inode_flags(inode);
+       if (IS_DIRSYNC(inode))
+               handle->h_sync = 1;
+       insert_inode_hash(inode);
+       spin_lock(&sbi->s_next_gen_lock);
+       inode->i_generation = sbi->s_next_generation++;
+       spin_unlock(&sbi->s_next_gen_lock);
+
+       ei->i_state = EXT4_STATE_NEW;
+       ei->i_extra_isize =
+               (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE) ?
+               sizeof(struct ext4_inode) - EXT4_GOOD_OLD_INODE_SIZE : 0;
+
+       ret = inode;
+       if(DQUOT_ALLOC_INODE(inode)) {
+               err = -EDQUOT;
+               goto fail_drop;
+       }
+
+       err = ext4_init_acl(handle, inode, dir);
+       if (err)
+               goto fail_free_drop;
+
+       err = ext4_init_security(handle,inode, dir);
+       if (err)
+               goto fail_free_drop;
+
+       err = ext4_mark_inode_dirty(handle, inode);
+       if (err) {
+               ext4_std_error(sb, err);
+               goto fail_free_drop;
+       }
+       if (test_opt(sb, EXTENTS)) {
+               EXT4_I(inode)->i_flags |= EXT4_EXTENTS_FL;
+               ext4_ext_tree_init(handle, inode);
+               if (!EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_EXTENTS)) {
+                       err = ext4_journal_get_write_access(handle, EXT4_SB(sb)->s_sbh);
+                       if (err) goto fail;
+                       EXT4_SET_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_EXTENTS);
+                       BUFFER_TRACE(EXT4_SB(sb)->s_sbh, "call ext4_journal_dirty_metadata");
+                       err = ext4_journal_dirty_metadata(handle, EXT4_SB(sb)->s_sbh);
+               }
+       }
+
+       ext4_debug("allocating inode %lu\n", inode->i_ino);
+       goto really_out;
+fail:
+       ext4_std_error(sb, err);
+out:
+       iput(inode);
+       ret = ERR_PTR(err);
+really_out:
+       brelse(bitmap_bh);
+       return ret;
+
+fail_free_drop:
+       DQUOT_FREE_INODE(inode);
+
+fail_drop:
+       DQUOT_DROP(inode);
+       inode->i_flags |= S_NOQUOTA;
+       inode->i_nlink = 0;
+       iput(inode);
+       brelse(bitmap_bh);
+       return ERR_PTR(err);
+}
+
+/* Verify that we are loading a valid orphan from disk */
+struct inode *ext4_orphan_get(struct super_block *sb, unsigned long ino)
+{
+       unsigned long max_ino = le32_to_cpu(EXT4_SB(sb)->s_es->s_inodes_count);
+       unsigned long block_group;
+       int bit;
+       struct buffer_head *bitmap_bh = NULL;
+       struct inode *inode = NULL;
+
+       /* Error cases - e2fsck has already cleaned up for us */
+       if (ino > max_ino) {
+               ext4_warning(sb, __FUNCTION__,
+                            "bad orphan ino %lu!  e2fsck was run?", ino);
+               goto out;
+       }
+
+       block_group = (ino - 1) / EXT4_INODES_PER_GROUP(sb);
+       bit = (ino - 1) % EXT4_INODES_PER_GROUP(sb);
+       bitmap_bh = read_inode_bitmap(sb, block_group);
+       if (!bitmap_bh) {
+               ext4_warning(sb, __FUNCTION__,
+                            "inode bitmap error for orphan %lu", ino);
+               goto out;
+       }
+
+       /* Having the inode bit set should be a 100% indicator that this
+        * is a valid orphan (no e2fsck run on fs).  Orphans also include
+        * inodes that were being truncated, so we can't check i_nlink==0.
+        */
+       if (!ext4_test_bit(bit, bitmap_bh->b_data) ||
+                       !(inode = iget(sb, ino)) || is_bad_inode(inode) ||
+                       NEXT_ORPHAN(inode) > max_ino) {
+               ext4_warning(sb, __FUNCTION__,
+                            "bad orphan inode %lu!  e2fsck was run?", ino);
+               printk(KERN_NOTICE "ext4_test_bit(bit=%d, block=%llu) = %d\n",
+                      bit, (unsigned long long)bitmap_bh->b_blocknr,
+                      ext4_test_bit(bit, bitmap_bh->b_data));
+               printk(KERN_NOTICE "inode=%p\n", inode);
+               if (inode) {
+                       printk(KERN_NOTICE "is_bad_inode(inode)=%d\n",
+                              is_bad_inode(inode));
+                       printk(KERN_NOTICE "NEXT_ORPHAN(inode)=%u\n",
+                              NEXT_ORPHAN(inode));
+                       printk(KERN_NOTICE "max_ino=%lu\n", max_ino);
+               }
+               /* Avoid freeing blocks if we got a bad deleted inode */
+               if (inode && inode->i_nlink == 0)
+                       inode->i_blocks = 0;
+               iput(inode);
+               inode = NULL;
+       }
+out:
+       brelse(bitmap_bh);
+       return inode;
+}
+
+unsigned long ext4_count_free_inodes (struct super_block * sb)
+{
+       unsigned long desc_count;
+       struct ext4_group_desc *gdp;
+       int i;
+#ifdef EXT4FS_DEBUG
+       struct ext4_super_block *es;
+       unsigned long bitmap_count, x;
+       struct buffer_head *bitmap_bh = NULL;
+
+       es = EXT4_SB(sb)->s_es;
+       desc_count = 0;
+       bitmap_count = 0;
+       gdp = NULL;
+       for (i = 0; i < EXT4_SB(sb)->s_groups_count; i++) {
+               gdp = ext4_get_group_desc (sb, i, NULL);
+               if (!gdp)
+                       continue;
+               desc_count += le16_to_cpu(gdp->bg_free_inodes_count);
+               brelse(bitmap_bh);
+               bitmap_bh = read_inode_bitmap(sb, i);
+               if (!bitmap_bh)
+                       continue;
+
+               x = ext4_count_free(bitmap_bh, EXT4_INODES_PER_GROUP(sb) / 8);
+               printk("group %d: stored = %d, counted = %lu\n",
+                       i, le16_to_cpu(gdp->bg_free_inodes_count), x);
+               bitmap_count += x;
+       }
+       brelse(bitmap_bh);
+       printk("ext4_count_free_inodes: stored = %u, computed = %lu, %lu\n",
+               le32_to_cpu(es->s_free_inodes_count), desc_count, bitmap_count);
+       return desc_count;
+#else
+       desc_count = 0;
+       for (i = 0; i < EXT4_SB(sb)->s_groups_count; i++) {
+               gdp = ext4_get_group_desc (sb, i, NULL);
+               if (!gdp)
+                       continue;
+               desc_count += le16_to_cpu(gdp->bg_free_inodes_count);
+               cond_resched();
+       }
+       return desc_count;
+#endif
+}
+
+/* Called at mount-time, super-block is locked */
+unsigned long ext4_count_dirs (struct super_block * sb)
+{
+       unsigned long count = 0;
+       int i;
+
+       for (i = 0; i < EXT4_SB(sb)->s_groups_count; i++) {
+               struct ext4_group_desc *gdp = ext4_get_group_desc (sb, i, NULL);
+               if (!gdp)
+                       continue;
+               count += le16_to_cpu(gdp->bg_used_dirs_count);
+       }
+       return count;
+}
+
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
new file mode 100644 (file)
index 0000000..0a60ec5
--- /dev/null
@@ -0,0 +1,3233 @@
+/*
+ *  linux/fs/ext4/inode.c
+ *
+ * Copyright (C) 1992, 1993, 1994, 1995
+ * Remy Card (card@masi.ibp.fr)
+ * Laboratoire MASI - Institut Blaise Pascal
+ * Universite Pierre et Marie Curie (Paris VI)
+ *
+ *  from
+ *
+ *  linux/fs/minix/inode.c
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ *
+ *  Goal-directed block allocation by Stephen Tweedie
+ *     (sct@redhat.com), 1993, 1998
+ *  Big-endian to little-endian byte-swapping/bitmaps by
+ *        David S. Miller (davem@caip.rutgers.edu), 1995
+ *  64-bit file support on 64-bit platforms by Jakub Jelinek
+ *     (jj@sunsite.ms.mff.cuni.cz)
+ *
+ *  Assorted race fixes, rewrite of ext4_get_block() by Al Viro, 2000
+ */
+
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/time.h>
+#include <linux/ext4_jbd2.h>
+#include <linux/jbd2.h>
+#include <linux/smp_lock.h>
+#include <linux/highuid.h>
+#include <linux/pagemap.h>
+#include <linux/quotaops.h>
+#include <linux/string.h>
+#include <linux/buffer_head.h>
+#include <linux/writeback.h>
+#include <linux/mpage.h>
+#include <linux/uio.h>
+#include <linux/bio.h>
+#include "xattr.h"
+#include "acl.h"
+
+/*
+ * Test whether an inode is a fast symlink.
+ */
+static int ext4_inode_is_fast_symlink(struct inode *inode)
+{
+       int ea_blocks = EXT4_I(inode)->i_file_acl ?
+               (inode->i_sb->s_blocksize >> 9) : 0;
+
+       return (S_ISLNK(inode->i_mode) && inode->i_blocks - ea_blocks == 0);
+}
+
+/*
+ * The ext4 forget function must perform a revoke if we are freeing data
+ * which has been journaled.  Metadata (eg. indirect blocks) must be
+ * revoked in all cases.
+ *
+ * "bh" may be NULL: a metadata block may have been freed from memory
+ * but there may still be a record of it in the journal, and that record
+ * still needs to be revoked.
+ */
+int ext4_forget(handle_t *handle, int is_metadata, struct inode *inode,
+                       struct buffer_head *bh, ext4_fsblk_t blocknr)
+{
+       int err;
+
+       might_sleep();
+
+       BUFFER_TRACE(bh, "enter");
+
+       jbd_debug(4, "forgetting bh %p: is_metadata = %d, mode %o, "
+                 "data mode %lx\n",
+                 bh, is_metadata, inode->i_mode,
+                 test_opt(inode->i_sb, DATA_FLAGS));
+
+       /* Never use the revoke function if we are doing full data
+        * journaling: there is no need to, and a V1 superblock won't
+        * support it.  Otherwise, only skip the revoke on un-journaled
+        * data blocks. */
+
+       if (test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA ||
+           (!is_metadata && !ext4_should_journal_data(inode))) {
+               if (bh) {
+                       BUFFER_TRACE(bh, "call jbd2_journal_forget");
+                       return ext4_journal_forget(handle, bh);
+               }
+               return 0;
+       }
+
+       /*
+        * data!=journal && (is_metadata || should_journal_data(inode))
+        */
+       BUFFER_TRACE(bh, "call ext4_journal_revoke");
+       err = ext4_journal_revoke(handle, blocknr, bh);
+       if (err)
+               ext4_abort(inode->i_sb, __FUNCTION__,
+                          "error %d when attempting revoke", err);
+       BUFFER_TRACE(bh, "exit");
+       return err;
+}
+
+/*
+ * Work out how many blocks we need to proceed with the next chunk of a
+ * truncate transaction.
+ */
+static unsigned long blocks_for_truncate(struct inode *inode)
+{
+       unsigned long needed;
+
+       needed = inode->i_blocks >> (inode->i_sb->s_blocksize_bits - 9);
+
+       /* Give ourselves just enough room to cope with inodes in which
+        * i_blocks is corrupt: we've seen disk corruptions in the past
+        * which resulted in random data in an inode which looked enough
+        * like a regular file for ext4 to try to delete it.  Things
+        * will go a bit crazy if that happens, but at least we should
+        * try not to panic the whole kernel. */
+       if (needed < 2)
+               needed = 2;
+
+       /* But we need to bound the transaction so we don't overflow the
+        * journal. */
+       if (needed > EXT4_MAX_TRANS_DATA)
+               needed = EXT4_MAX_TRANS_DATA;
+
+       return EXT4_DATA_TRANS_BLOCKS(inode->i_sb) + needed;
+}
+
+/*
+ * Truncate transactions can be complex and absolutely huge.  So we need to
+ * be able to restart the transaction at a conventient checkpoint to make
+ * sure we don't overflow the journal.
+ *
+ * start_transaction gets us a new handle for a truncate transaction,
+ * and extend_transaction tries to extend the existing one a bit.  If
+ * extend fails, we need to propagate the failure up and restart the
+ * transaction in the top-level truncate loop. --sct
+ */
+static handle_t *start_transaction(struct inode *inode)
+{
+       handle_t *result;
+
+       result = ext4_journal_start(inode, blocks_for_truncate(inode));
+       if (!IS_ERR(result))
+               return result;
+
+       ext4_std_error(inode->i_sb, PTR_ERR(result));
+       return result;
+}
+
+/*
+ * Try to extend this transaction for the purposes of truncation.
+ *
+ * Returns 0 if we managed to create more room.  If we can't create more
+ * room, and the transaction must be restarted we return 1.
+ */
+static int try_to_extend_transaction(handle_t *handle, struct inode *inode)
+{
+       if (handle->h_buffer_credits > EXT4_RESERVE_TRANS_BLOCKS)
+               return 0;
+       if (!ext4_journal_extend(handle, blocks_for_truncate(inode)))
+               return 0;
+       return 1;
+}
+
+/*
+ * Restart the transaction associated with *handle.  This does a commit,
+ * so before we call here everything must be consistently dirtied against
+ * this transaction.
+ */
+static int ext4_journal_test_restart(handle_t *handle, struct inode *inode)
+{
+       jbd_debug(2, "restarting handle %p\n", handle);
+       return ext4_journal_restart(handle, blocks_for_truncate(inode));
+}
+
+/*
+ * Called at the last iput() if i_nlink is zero.
+ */
+void ext4_delete_inode (struct inode * inode)
+{
+       handle_t *handle;
+
+       truncate_inode_pages(&inode->i_data, 0);
+
+       if (is_bad_inode(inode))
+               goto no_delete;
+
+       handle = start_transaction(inode);
+       if (IS_ERR(handle)) {
+               /*
+                * If we're going to skip the normal cleanup, we still need to
+                * make sure that the in-core orphan linked list is properly
+                * cleaned up.
+                */
+               ext4_orphan_del(NULL, inode);
+               goto no_delete;
+       }
+
+       if (IS_SYNC(inode))
+               handle->h_sync = 1;
+       inode->i_size = 0;
+       if (inode->i_blocks)
+               ext4_truncate(inode);
+       /*
+        * Kill off the orphan record which ext4_truncate created.
+        * AKPM: I think this can be inside the above `if'.
+        * Note that ext4_orphan_del() has to be able to cope with the
+        * deletion of a non-existent orphan - this is because we don't
+        * know if ext4_truncate() actually created an orphan record.
+        * (Well, we could do this if we need to, but heck - it works)
+        */
+       ext4_orphan_del(handle, inode);
+       EXT4_I(inode)->i_dtime  = get_seconds();
+
+       /*
+        * One subtle ordering requirement: if anything has gone wrong
+        * (transaction abort, IO errors, whatever), then we can still
+        * do these next steps (the fs will already have been marked as
+        * having errors), but we can't free the inode if the mark_dirty
+        * fails.
+        */
+       if (ext4_mark_inode_dirty(handle, inode))
+               /* If that failed, just do the required in-core inode clear. */
+               clear_inode(inode);
+       else
+               ext4_free_inode(handle, inode);
+       ext4_journal_stop(handle);
+       return;
+no_delete:
+       clear_inode(inode);     /* We must guarantee clearing of inode... */
+}
+
+typedef struct {
+       __le32  *p;
+       __le32  key;
+       struct buffer_head *bh;
+} Indirect;
+
+static inline void add_chain(Indirect *p, struct buffer_head *bh, __le32 *v)
+{
+       p->key = *(p->p = v);
+       p->bh = bh;
+}
+
+static int verify_chain(Indirect *from, Indirect *to)
+{
+       while (from <= to && from->key == *from->p)
+               from++;
+       return (from > to);
+}
+
+/**
+ *     ext4_block_to_path - parse the block number into array of offsets
+ *     @inode: inode in question (we are only interested in its superblock)
+ *     @i_block: block number to be parsed
+ *     @offsets: array to store the offsets in
+ *      @boundary: set this non-zero if the referred-to block is likely to be
+ *             followed (on disk) by an indirect block.
+ *
+ *     To store the locations of file's data ext4 uses a data structure common
+ *     for UNIX filesystems - tree of pointers anchored in the inode, with
+ *     data blocks at leaves and indirect blocks in intermediate nodes.
+ *     This function translates the block number into path in that tree -
+ *     return value is the path length and @offsets[n] is the offset of
+ *     pointer to (n+1)th node in the nth one. If @block is out of range
+ *     (negative or too large) warning is printed and zero returned.
+ *
+ *     Note: function doesn't find node addresses, so no IO is needed. All
+ *     we need to know is the capacity of indirect blocks (taken from the
+ *     inode->i_sb).
+ */
+
+/*
+ * Portability note: the last comparison (check that we fit into triple
+ * indirect block) is spelled differently, because otherwise on an
+ * architecture with 32-bit longs and 8Kb pages we might get into trouble
+ * if our filesystem had 8Kb blocks. We might use long long, but that would
+ * kill us on x86. Oh, well, at least the sign propagation does not matter -
+ * i_block would have to be negative in the very beginning, so we would not
+ * get there at all.
+ */
+
+static int ext4_block_to_path(struct inode *inode,
+                       long i_block, int offsets[4], int *boundary)
+{
+       int ptrs = EXT4_ADDR_PER_BLOCK(inode->i_sb);
+       int ptrs_bits = EXT4_ADDR_PER_BLOCK_BITS(inode->i_sb);
+       const long direct_blocks = EXT4_NDIR_BLOCKS,
+               indirect_blocks = ptrs,
+               double_blocks = (1 << (ptrs_bits * 2));
+       int n = 0;
+       int final = 0;
+
+       if (i_block < 0) {
+               ext4_warning (inode->i_sb, "ext4_block_to_path", "block < 0");
+       } else if (i_block < direct_blocks) {
+               offsets[n++] = i_block;
+               final = direct_blocks;
+       } else if ( (i_block -= direct_blocks) < indirect_blocks) {
+               offsets[n++] = EXT4_IND_BLOCK;
+               offsets[n++] = i_block;
+               final = ptrs;
+       } else if ((i_block -= indirect_blocks) < double_blocks) {
+               offsets[n++] = EXT4_DIND_BLOCK;
+               offsets[n++] = i_block >> ptrs_bits;
+               offsets[n++] = i_block & (ptrs - 1);
+               final = ptrs;
+       } else if (((i_block -= double_blocks) >> (ptrs_bits * 2)) < ptrs) {
+               offsets[n++] = EXT4_TIND_BLOCK;
+               offsets[n++] = i_block >> (ptrs_bits * 2);
+               offsets[n++] = (i_block >> ptrs_bits) & (ptrs - 1);
+               offsets[n++] = i_block & (ptrs - 1);
+               final = ptrs;
+       } else {
+               ext4_warning(inode->i_sb, "ext4_block_to_path", "block > big");
+       }
+       if (boundary)
+               *boundary = final - 1 - (i_block & (ptrs - 1));
+       return n;
+}
+
+/**
+ *     ext4_get_branch - read the chain of indirect blocks leading to data
+ *     @inode: inode in question
+ *     @depth: depth of the chain (1 - direct pointer, etc.)
+ *     @offsets: offsets of pointers in inode/indirect blocks
+ *     @chain: place to store the result
+ *     @err: here we store the error value
+ *
+ *     Function fills the array of triples <key, p, bh> and returns %NULL
+ *     if everything went OK or the pointer to the last filled triple
+ *     (incomplete one) otherwise. Upon the return chain[i].key contains
+ *     the number of (i+1)-th block in the chain (as it is stored in memory,
+ *     i.e. little-endian 32-bit), chain[i].p contains the address of that
+ *     number (it points into struct inode for i==0 and into the bh->b_data
+ *     for i>0) and chain[i].bh points to the buffer_head of i-th indirect
+ *     block for i>0 and NULL for i==0. In other words, it holds the block
+ *     numbers of the chain, addresses they were taken from (and where we can
+ *     verify that chain did not change) and buffer_heads hosting these
+ *     numbers.
+ *
+ *     Function stops when it stumbles upon zero pointer (absent block)
+ *             (pointer to last triple returned, *@err == 0)
+ *     or when it gets an IO error reading an indirect block
+ *             (ditto, *@err == -EIO)
+ *     or when it notices that chain had been changed while it was reading
+ *             (ditto, *@err == -EAGAIN)
+ *     or when it reads all @depth-1 indirect blocks successfully and finds
+ *     the whole chain, all way to the data (returns %NULL, *err == 0).
+ */
+static Indirect *ext4_get_branch(struct inode *inode, int depth, int *offsets,
+                                Indirect chain[4], int *err)
+{
+       struct super_block *sb = inode->i_sb;
+       Indirect *p = chain;
+       struct buffer_head *bh;
+
+       *err = 0;
+       /* i_data is not going away, no lock needed */
+       add_chain (chain, NULL, EXT4_I(inode)->i_data + *offsets);
+       if (!p->key)
+               goto no_block;
+       while (--depth) {
+               bh = sb_bread(sb, le32_to_cpu(p->key));
+               if (!bh)
+                       goto failure;
+               /* Reader: pointers */
+               if (!verify_chain(chain, p))
+                       goto changed;
+               add_chain(++p, bh, (__le32*)bh->b_data + *++offsets);
+               /* Reader: end */
+               if (!p->key)
+                       goto no_block;
+       }
+       return NULL;
+
+changed:
+       brelse(bh);
+       *err = -EAGAIN;
+       goto no_block;
+failure:
+       *err = -EIO;
+no_block:
+       return p;
+}
+
+/**
+ *     ext4_find_near - find a place for allocation with sufficient locality
+ *     @inode: owner
+ *     @ind: descriptor of indirect block.
+ *
+ *     This function returns the prefered place for block allocation.
+ *     It is used when heuristic for sequential allocation fails.
+ *     Rules are:
+ *       + if there is a block to the left of our position - allocate near it.
+ *       + if pointer will live in indirect block - allocate near that block.
+ *       + if pointer will live in inode - allocate in the same
+ *         cylinder group.
+ *
+ * In the latter case we colour the starting block by the callers PID to
+ * prevent it from clashing with concurrent allocations for a different inode
+ * in the same block group.   The PID is used here so that functionally related
+ * files will be close-by on-disk.
+ *
+ *     Caller must make sure that @ind is valid and will stay that way.
+ */
+static ext4_fsblk_t ext4_find_near(struct inode *inode, Indirect *ind)
+{
+       struct ext4_inode_info *ei = EXT4_I(inode);
+       __le32 *start = ind->bh ? (__le32*) ind->bh->b_data : ei->i_data;
+       __le32 *p;
+       ext4_fsblk_t bg_start;
+       ext4_grpblk_t colour;
+
+       /* Try to find previous block */
+       for (p = ind->p - 1; p >= start; p--) {
+               if (*p)
+                       return le32_to_cpu(*p);
+       }
+
+       /* No such thing, so let's try location of indirect block */
+       if (ind->bh)
+               return ind->bh->b_blocknr;
+
+       /*
+        * It is going to be referred to from the inode itself? OK, just put it
+        * into the same cylinder group then.
+        */
+       bg_start = ext4_group_first_block_no(inode->i_sb, ei->i_block_group);
+       colour = (current->pid % 16) *
+                       (EXT4_BLOCKS_PER_GROUP(inode->i_sb) / 16);
+       return bg_start + colour;
+}
+
+/**
+ *     ext4_find_goal - find a prefered place for allocation.
+ *     @inode: owner
+ *     @block:  block we want
+ *     @chain:  chain of indirect blocks
+ *     @partial: pointer to the last triple within a chain
+ *     @goal:  place to store the result.
+ *
+ *     Normally this function find the prefered place for block allocation,
+ *     stores it in *@goal and returns zero.
+ */
+
+static ext4_fsblk_t ext4_find_goal(struct inode *inode, long block,
+               Indirect chain[4], Indirect *partial)
+{
+       struct ext4_block_alloc_info *block_i;
+
+       block_i =  EXT4_I(inode)->i_block_alloc_info;
+
+       /*
+        * try the heuristic for sequential allocation,
+        * failing that at least try to get decent locality.
+        */
+       if (block_i && (block == block_i->last_alloc_logical_block + 1)
+               && (block_i->last_alloc_physical_block != 0)) {
+               return block_i->last_alloc_physical_block + 1;
+       }
+
+       return ext4_find_near(inode, partial);
+}
+
+/**
+ *     ext4_blks_to_allocate: Look up the block map and count the number
+ *     of direct blocks need to be allocated for the given branch.
+ *
+ *     @branch: chain of indirect blocks
+ *     @k: number of blocks need for indirect blocks
+ *     @blks: number of data blocks to be mapped.
+ *     @blocks_to_boundary:  the offset in the indirect block
+ *
+ *     return the total number of blocks to be allocate, including the
+ *     direct and indirect blocks.
+ */
+static int ext4_blks_to_allocate(Indirect *branch, int k, unsigned long blks,
+               int blocks_to_boundary)
+{
+       unsigned long count = 0;
+
+       /*
+        * Simple case, [t,d]Indirect block(s) has not allocated yet
+        * then it's clear blocks on that path have not allocated
+        */
+       if (k > 0) {
+               /* right now we don't handle cross boundary allocation */
+               if (blks < blocks_to_boundary + 1)
+                       count += blks;
+               else
+                       count += blocks_to_boundary + 1;
+               return count;
+       }
+
+       count++;
+       while (count < blks && count <= blocks_to_boundary &&
+               le32_to_cpu(*(branch[0].p + count)) == 0) {
+               count++;
+       }
+       return count;
+}
+
+/**
+ *     ext4_alloc_blocks: multiple allocate blocks needed for a branch
+ *     @indirect_blks: the number of blocks need to allocate for indirect
+ *                     blocks
+ *
+ *     @new_blocks: on return it will store the new block numbers for
+ *     the indirect blocks(if needed) and the first direct block,
+ *     @blks:  on return it will store the total number of allocated
+ *             direct blocks
+ */
+static int ext4_alloc_blocks(handle_t *handle, struct inode *inode,
+                       ext4_fsblk_t goal, int indirect_blks, int blks,
+                       ext4_fsblk_t new_blocks[4], int *err)
+{
+       int target, i;
+       unsigned long count = 0;
+       int index = 0;
+       ext4_fsblk_t current_block = 0;
+       int ret = 0;
+
+       /*
+        * Here we try to allocate the requested multiple blocks at once,
+        * on a best-effort basis.
+        * To build a branch, we should allocate blocks for
+        * the indirect blocks(if not allocated yet), and at least
+        * the first direct block of this branch.  That's the
+        * minimum number of blocks need to allocate(required)
+        */
+       target = blks + indirect_blks;
+
+       while (1) {
+               count = target;
+               /* allocating blocks for indirect blocks and direct blocks */
+               current_block = ext4_new_blocks(handle,inode,goal,&count,err);
+               if (*err)
+                       goto failed_out;
+
+               target -= count;
+               /* allocate blocks for indirect blocks */
+               while (index < indirect_blks && count) {
+                       new_blocks[index++] = current_block++;
+                       count--;
+               }
+
+               if (count > 0)
+                       break;
+       }
+
+       /* save the new block number for the first direct block */
+       new_blocks[index] = current_block;
+
+       /* total number of blocks allocated for direct blocks */
+       ret = count;
+       *err = 0;
+       return ret;
+failed_out:
+       for (i = 0; i <index; i++)
+               ext4_free_blocks(handle, inode, new_blocks[i], 1);
+       return ret;
+}
+
+/**
+ *     ext4_alloc_branch - allocate and set up a chain of blocks.
+ *     @inode: owner
+ *     @indirect_blks: number of allocated indirect blocks
+ *     @blks: number of allocated direct blocks
+ *     @offsets: offsets (in the blocks) to store the pointers to next.
+ *     @branch: place to store the chain in.
+ *
+ *     This function allocates blocks, zeroes out all but the last one,
+ *     links them into chain and (if we are synchronous) writes them to disk.
+ *     In other words, it prepares a branch that can be spliced onto the
+ *     inode. It stores the information about that chain in the branch[], in
+ *     the same format as ext4_get_branch() would do. We are calling it after
+ *     we had read the existing part of chain and partial points to the last
+ *     triple of that (one with zero ->key). Upon the exit we have the same
+ *     picture as after the successful ext4_get_block(), except that in one
+ *     place chain is disconnected - *branch->p is still zero (we did not
+ *     set the last link), but branch->key contains the number that should
+ *     be placed into *branch->p to fill that gap.
+ *
+ *     If allocation fails we free all blocks we've allocated (and forget
+ *     their buffer_heads) and return the error value the from failed
+ *     ext4_alloc_block() (normally -ENOSPC). Otherwise we set the chain
+ *     as described above and return 0.
+ */
+static int ext4_alloc_branch(handle_t *handle, struct inode *inode,
+                       int indirect_blks, int *blks, ext4_fsblk_t goal,
+                       int *offsets, Indirect *branch)
+{
+       int blocksize = inode->i_sb->s_blocksize;
+       int i, n = 0;
+       int err = 0;
+       struct buffer_head *bh;
+       int num;
+       ext4_fsblk_t new_blocks[4];
+       ext4_fsblk_t current_block;
+
+       num = ext4_alloc_blocks(handle, inode, goal, indirect_blks,
+                               *blks, new_blocks, &err);
+       if (err)
+               return err;
+
+       branch[0].key = cpu_to_le32(new_blocks[0]);
+       /*
+        * metadata blocks and data blocks are allocated.
+        */
+       for (n = 1; n <= indirect_blks;  n++) {
+               /*
+                * Get buffer_head for parent block, zero it out
+                * and set the pointer to new one, then send
+                * parent to disk.
+                */
+               bh = sb_getblk(inode->i_sb, new_blocks[n-1]);
+               branch[n].bh = bh;
+               lock_buffer(bh);
+               BUFFER_TRACE(bh, "call get_create_access");
+               err = ext4_journal_get_create_access(handle, bh);
+               if (err) {
+                       unlock_buffer(bh);
+                       brelse(bh);
+                       goto failed;
+               }
+
+               memset(bh->b_data, 0, blocksize);
+               branch[n].p = (__le32 *) bh->b_data + offsets[n];
+               branch[n].key = cpu_to_le32(new_blocks[n]);
+               *branch[n].p = branch[n].key;
+               if ( n == indirect_blks) {
+                       current_block = new_blocks[n];
+                       /*
+                        * End of chain, update the last new metablock of
+                        * the chain to point to the new allocated
+                        * data blocks numbers
+                        */
+                       for (i=1; i < num; i++)
+                               *(branch[n].p + i) = cpu_to_le32(++current_block);
+               }
+               BUFFER_TRACE(bh, "marking uptodate");
+               set_buffer_uptodate(bh);
+               unlock_buffer(bh);
+
+               BUFFER_TRACE(bh, "call ext4_journal_dirty_metadata");
+               err = ext4_journal_dirty_metadata(handle, bh);
+               if (err)
+                       goto failed;
+       }
+       *blks = num;
+       return err;
+failed:
+       /* Allocation failed, free what we already allocated */
+       for (i = 1; i <= n ; i++) {
+               BUFFER_TRACE(branch[i].bh, "call jbd2_journal_forget");
+               ext4_journal_forget(handle, branch[i].bh);
+       }
+       for (i = 0; i <indirect_blks; i++)
+               ext4_free_blocks(handle, inode, new_blocks[i], 1);
+
+       ext4_free_blocks(handle, inode, new_blocks[i], num);
+
+       return err;
+}
+
+/**
+ * ext4_splice_branch - splice the allocated branch onto inode.
+ * @inode: owner
+ * @block: (logical) number of block we are adding
+ * @chain: chain of indirect blocks (with a missing link - see
+ *     ext4_alloc_branch)
+ * @where: location of missing link
+ * @num:   number of indirect blocks we are adding
+ * @blks:  number of direct blocks we are adding
+ *
+ * This function fills the missing link and does all housekeeping needed in
+ * inode (->i_blocks, etc.). In case of success we end up with the full
+ * chain to new block and return 0.
+ */
+static int ext4_splice_branch(handle_t *handle, struct inode *inode,
+                       long block, Indirect *where, int num, int blks)
+{
+       int i;
+       int err = 0;
+       struct ext4_block_alloc_info *block_i;
+       ext4_fsblk_t current_block;
+
+       block_i = EXT4_I(inode)->i_block_alloc_info;
+       /*
+        * If we're splicing into a [td]indirect block (as opposed to the
+        * inode) then we need to get write access to the [td]indirect block
+        * before the splice.
+        */
+       if (where->bh) {
+               BUFFER_TRACE(where->bh, "get_write_access");
+               err = ext4_journal_get_write_access(handle, where->bh);
+               if (err)
+                       goto err_out;
+       }
+       /* That's it */
+
+       *where->p = where->key;
+
+       /*
+        * Update the host buffer_head or inode to point to more just allocated
+        * direct blocks blocks
+        */
+       if (num == 0 && blks > 1) {
+               current_block = le32_to_cpu(where->key) + 1;
+               for (i = 1; i < blks; i++)
+                       *(where->p + i ) = cpu_to_le32(current_block++);
+       }
+
+       /*
+        * update the most recently allocated logical & physical block
+        * in i_block_alloc_info, to assist find the proper goal block for next
+        * allocation
+        */
+       if (block_i) {
+               block_i->last_alloc_logical_block = block + blks - 1;
+               block_i->last_alloc_physical_block =
+                               le32_to_cpu(where[num].key) + blks - 1;
+       }
+
+       /* We are done with atomic stuff, now do the rest of housekeeping */
+
+       inode->i_ctime = CURRENT_TIME_SEC;
+       ext4_mark_inode_dirty(handle, inode);
+
+       /* had we spliced it onto indirect block? */
+       if (where->bh) {
+               /*
+                * If we spliced it onto an indirect block, we haven't
+                * altered the inode.  Note however that if it is being spliced
+                * onto an indirect block at the very end of the file (the
+                * file is growing) then we *will* alter the inode to reflect
+                * the new i_size.  But that is not done here - it is done in
+                * generic_commit_write->__mark_inode_dirty->ext4_dirty_inode.
+                */
+               jbd_debug(5, "splicing indirect only\n");
+               BUFFER_TRACE(where->bh, "call ext4_journal_dirty_metadata");
+               err = ext4_journal_dirty_metadata(handle, where->bh);
+               if (err)
+                       goto err_out;
+       } else {
+               /*
+                * OK, we spliced it into the inode itself on a direct block.
+                * Inode was dirtied above.
+                */
+               jbd_debug(5, "splicing direct\n");
+       }
+       return err;
+
+err_out:
+       for (i = 1; i <= num; i++) {
+               BUFFER_TRACE(where[i].bh, "call jbd2_journal_forget");
+               ext4_journal_forget(handle, where[i].bh);
+               ext4_free_blocks(handle,inode,le32_to_cpu(where[i-1].key),1);
+       }
+       ext4_free_blocks(handle, inode, le32_to_cpu(where[num].key), blks);
+
+       return err;
+}
+
+/*
+ * Allocation strategy is simple: if we have to allocate something, we will
+ * have to go the whole way to leaf. So let's do it before attaching anything
+ * to tree, set linkage between the newborn blocks, write them if sync is
+ * required, recheck the path, free and repeat if check fails, otherwise
+ * set the last missing link (that will protect us from any truncate-generated
+ * removals - all blocks on the path are immune now) and possibly force the
+ * write on the parent block.
+ * That has a nice additional property: no special recovery from the failed
+ * allocations is needed - we simply release blocks and do not touch anything
+ * reachable from inode.
+ *
+ * `handle' can be NULL if create == 0.
+ *
+ * The BKL may not be held on entry here.  Be sure to take it early.
+ * return > 0, # of blocks mapped or allocated.
+ * return = 0, if plain lookup failed.
+ * return < 0, error case.
+ */
+int ext4_get_blocks_handle(handle_t *handle, struct inode *inode,
+               sector_t iblock, unsigned long maxblocks,
+               struct buffer_head *bh_result,
+               int create, int extend_disksize)
+{
+       int err = -EIO;
+       int offsets[4];
+       Indirect chain[4];
+       Indirect *partial;
+       ext4_fsblk_t goal;
+       int indirect_blks;
+       int blocks_to_boundary = 0;
+       int depth;
+       struct ext4_inode_info *ei = EXT4_I(inode);
+       int count = 0;
+       ext4_fsblk_t first_block = 0;
+
+
+       J_ASSERT(!(EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL));
+       J_ASSERT(handle != NULL || create == 0);
+       depth = ext4_block_to_path(inode,iblock,offsets,&blocks_to_boundary);
+
+       if (depth == 0)
+               goto out;
+
+       partial = ext4_get_branch(inode, depth, offsets, chain, &err);
+
+       /* Simplest case - block found, no allocation needed */
+       if (!partial) {
+               first_block = le32_to_cpu(chain[depth - 1].key);
+               clear_buffer_new(bh_result);
+               count++;
+               /*map more blocks*/
+               while (count < maxblocks && count <= blocks_to_boundary) {
+                       ext4_fsblk_t blk;
+
+                       if (!verify_chain(chain, partial)) {
+                               /*
+                                * Indirect block might be removed by
+                                * truncate while we were reading it.
+                                * Handling of that case: forget what we've
+                                * got now. Flag the err as EAGAIN, so it
+                                * will reread.
+                                */
+                               err = -EAGAIN;
+                               count = 0;
+                               break;
+                       }
+                       blk = le32_to_cpu(*(chain[depth-1].p + count));
+
+                       if (blk == first_block + count)
+                               count++;
+                       else
+                               break;
+               }
+               if (err != -EAGAIN)
+                       goto got_it;
+       }
+
+       /* Next simple case - plain lookup or failed read of indirect block */
+       if (!create || err == -EIO)
+               goto cleanup;
+
+       mutex_lock(&ei->truncate_mutex);
+
+       /*
+        * If the indirect block is missing while we are reading
+        * the chain(ext4_get_branch() returns -EAGAIN err), or
+        * if the chain has been changed after we grab the semaphore,
+        * (either because another process truncated this branch, or
+        * another get_block allocated this branch) re-grab the chain to see if
+        * the request block has been allocated or not.
+        *
+        * Since we already block the truncate/other get_block
+        * at this point, we will have the current copy of the chain when we
+        * splice the branch into the tree.
+        */
+       if (err == -EAGAIN || !verify_chain(chain, partial)) {
+               while (partial > chain) {
+                       brelse(partial->bh);
+                       partial--;
+               }
+               partial = ext4_get_branch(inode, depth, offsets, chain, &err);
+               if (!partial) {
+                       count++;
+                       mutex_unlock(&ei->truncate_mutex);
+                       if (err)
+                               goto cleanup;
+                       clear_buffer_new(bh_result);
+                       goto got_it;
+               }
+       }
+
+       /*
+        * Okay, we need to do block allocation.  Lazily initialize the block
+        * allocation info here if necessary
+       */
+       if (S_ISREG(inode->i_mode) && (!ei->i_block_alloc_info))
+               ext4_init_block_alloc_info(inode);
+
+       goal = ext4_find_goal(inode, iblock, chain, partial);
+
+       /* the number of blocks need to allocate for [d,t]indirect blocks */
+       indirect_blks = (chain + depth) - partial - 1;
+
+       /*
+        * Next look up the indirect map to count the totoal number of
+        * direct blocks to allocate for this branch.
+        */
+       count = ext4_blks_to_allocate(partial, indirect_blks,
+                                       maxblocks, blocks_to_boundary);
+       /*
+        * Block out ext4_truncate while we alter the tree
+        */
+       err = ext4_alloc_branch(handle, inode, indirect_blks, &count, goal,
+                               offsets + (partial - chain), partial);
+
+       /*
+        * The ext4_splice_branch call will free and forget any buffers
+        * on the new chain if there is a failure, but that risks using
+        * up transaction credits, especially for bitmaps where the
+        * credits cannot be returned.  Can we handle this somehow?  We
+        * may need to return -EAGAIN upwards in the worst case.  --sct
+        */
+       if (!err)
+               err = ext4_splice_branch(handle, inode, iblock,
+                                       partial, indirect_blks, count);
+       /*
+        * i_disksize growing is protected by truncate_mutex.  Don't forget to
+        * protect it if you're about to implement concurrent
+        * ext4_get_block() -bzzz
+       */
+       if (!err && extend_disksize && inode->i_size > ei->i_disksize)
+               ei->i_disksize = inode->i_size;
+       mutex_unlock(&ei->truncate_mutex);
+       if (err)
+               goto cleanup;
+
+       set_buffer_new(bh_result);
+got_it:
+       map_bh(bh_result, inode->i_sb, le32_to_cpu(chain[depth-1].key));
+       if (count > blocks_to_boundary)
+               set_buffer_boundary(bh_result);
+       err = count;
+       /* Clean up and exit */
+       partial = chain + depth - 1;    /* the whole chain */
+cleanup:
+       while (partial > chain) {
+               BUFFER_TRACE(partial->bh, "call brelse");
+               brelse(partial->bh);
+               partial--;
+       }
+       BUFFER_TRACE(bh_result, "returned");
+out:
+       return err;
+}
+
+#define DIO_CREDITS (EXT4_RESERVE_TRANS_BLOCKS + 32)
+
+static int ext4_get_block(struct inode *inode, sector_t iblock,
+                       struct buffer_head *bh_result, int create)
+{
+       handle_t *handle = journal_current_handle();
+       int ret = 0;
+       unsigned max_blocks = bh_result->b_size >> inode->i_blkbits;
+
+       if (!create)
+               goto get_block;         /* A read */
+
+       if (max_blocks == 1)
+               goto get_block;         /* A single block get */
+
+       if (handle->h_transaction->t_state == T_LOCKED) {
+               /*
+                * Huge direct-io writes can hold off commits for long
+                * periods of time.  Let this commit run.
+                */
+               ext4_journal_stop(handle);
+               handle = ext4_journal_start(inode, DIO_CREDITS);
+               if (IS_ERR(handle))
+                       ret = PTR_ERR(handle);
+               goto get_block;
+       }
+
+       if (handle->h_buffer_credits <= EXT4_RESERVE_TRANS_BLOCKS) {
+               /*
+                * Getting low on buffer credits...
+                */
+               ret = ext4_journal_extend(handle, DIO_CREDITS);
+               if (ret > 0) {
+                       /*
+                        * Couldn't extend the transaction.  Start a new one.
+                        */
+                       ret = ext4_journal_restart(handle, DIO_CREDITS);
+               }
+       }
+
+get_block:
+       if (ret == 0) {
+               ret = ext4_get_blocks_wrap(handle, inode, iblock,
+                                       max_blocks, bh_result, create, 0);
+               if (ret > 0) {
+                       bh_result->b_size = (ret << inode->i_blkbits);
+                       ret = 0;
+               }
+       }
+       return ret;
+}
+
+/*
+ * `handle' can be NULL if create is zero
+ */
+struct buffer_head *ext4_getblk(handle_t *handle, struct inode *inode,
+                               long block, int create, int *errp)
+{
+       struct buffer_head dummy;
+       int fatal = 0, err;
+
+       J_ASSERT(handle != NULL || create == 0);
+
+       dummy.b_state = 0;
+       dummy.b_blocknr = -1000;
+       buffer_trace_init(&dummy.b_history);
+       err = ext4_get_blocks_wrap(handle, inode, block, 1,
+                                       &dummy, create, 1);
+       /*
+        * ext4_get_blocks_handle() returns number of blocks
+        * mapped. 0 in case of a HOLE.
+        */
+       if (err > 0) {
+               if (err > 1)
+                       WARN_ON(1);
+               err = 0;
+       }
+       *errp = err;
+       if (!err && buffer_mapped(&dummy)) {
+               struct buffer_head *bh;
+               bh = sb_getblk(inode->i_sb, dummy.b_blocknr);
+               if (!bh) {
+                       *errp = -EIO;
+                       goto err;
+               }
+               if (buffer_new(&dummy)) {
+                       J_ASSERT(create != 0);
+                       J_ASSERT(handle != 0);
+
+                       /*
+                        * Now that we do not always journal data, we should
+                        * keep in mind whether this should always journal the
+                        * new buffer as metadata.  For now, regular file
+                        * writes use ext4_get_block instead, so it's not a
+                        * problem.
+                        */
+                       lock_buffer(bh);
+                       BUFFER_TRACE(bh, "call get_create_access");
+                       fatal = ext4_journal_get_create_access(handle, bh);
+                       if (!fatal && !buffer_uptodate(bh)) {
+                               memset(bh->b_data,0,inode->i_sb->s_blocksize);
+                               set_buffer_uptodate(bh);
+                       }
+                       unlock_buffer(bh);
+                       BUFFER_TRACE(bh, "call ext4_journal_dirty_metadata");
+                       err = ext4_journal_dirty_metadata(handle, bh);
+                       if (!fatal)
+                               fatal = err;
+               } else {
+                       BUFFER_TRACE(bh, "not a new buffer");
+               }
+               if (fatal) {
+                       *errp = fatal;
+                       brelse(bh);
+                       bh = NULL;
+               }
+               return bh;
+       }
+err:
+       return NULL;
+}
+
+struct buffer_head *ext4_bread(handle_t *handle, struct inode *inode,
+                              int block, int create, int *err)
+{
+       struct buffer_head * bh;
+
+       bh = ext4_getblk(handle, inode, block, create, err);
+       if (!bh)
+               return bh;
+       if (buffer_uptodate(bh))
+               return bh;
+       ll_rw_block(READ_META, 1, &bh);
+       wait_on_buffer(bh);
+       if (buffer_uptodate(bh))
+               return bh;
+       put_bh(bh);
+       *err = -EIO;
+       return NULL;
+}
+
+static int walk_page_buffers(  handle_t *handle,
+                               struct buffer_head *head,
+                               unsigned from,
+                               unsigned to,
+                               int *partial,
+                               int (*fn)(      handle_t *handle,
+                                               struct buffer_head *bh))
+{
+       struct buffer_head *bh;
+       unsigned block_start, block_end;
+       unsigned blocksize = head->b_size;
+       int err, ret = 0;
+       struct buffer_head *next;
+
+       for (   bh = head, block_start = 0;
+               ret == 0 && (bh != head || !block_start);
+               block_start = block_end, bh = next)
+       {
+               next = bh->b_this_page;
+               block_end = block_start + blocksize;
+               if (block_end <= from || block_start >= to) {
+                       if (partial && !buffer_uptodate(bh))
+                               *partial = 1;
+                       continue;
+               }
+               err = (*fn)(handle, bh);
+               if (!ret)
+                       ret = err;
+       }
+       return ret;
+}
+
+/*
+ * To preserve ordering, it is essential that the hole instantiation and
+ * the data write be encapsulated in a single transaction.  We cannot
+ * close off a transaction and start a new one between the ext4_get_block()
+ * and the commit_write().  So doing the jbd2_journal_start at the start of
+ * prepare_write() is the right place.
+ *
+ * Also, this function can nest inside ext4_writepage() ->
+ * block_write_full_page(). In that case, we *know* that ext4_writepage()
+ * has generated enough buffer credits to do the whole page.  So we won't
+ * block on the journal in that case, which is good, because the caller may
+ * be PF_MEMALLOC.
+ *
+ * By accident, ext4 can be reentered when a transaction is open via
+ * quota file writes.  If we were to commit the transaction while thus
+ * reentered, there can be a deadlock - we would be holding a quota
+ * lock, and the commit would never complete if another thread had a
+ * transaction open and was blocking on the quota lock - a ranking
+ * violation.
+ *
+ * So what we do is to rely on the fact that jbd2_journal_stop/journal_start
+ * will _not_ run commit under these circumstances because handle->h_ref
+ * is elevated.  We'll still have enough credits for the tiny quotafile
+ * write.
+ */
+static int do_journal_get_write_access(handle_t *handle,
+                                       struct buffer_head *bh)
+{
+       if (!buffer_mapped(bh) || buffer_freed(bh))
+               return 0;
+       return ext4_journal_get_write_access(handle, bh);
+}
+
+static int ext4_prepare_write(struct file *file, struct page *page,
+                             unsigned from, unsigned to)
+{
+       struct inode *inode = page->mapping->host;
+       int ret, needed_blocks = ext4_writepage_trans_blocks(inode);
+       handle_t *handle;
+       int retries = 0;
+
+retry:
+       handle = ext4_journal_start(inode, needed_blocks);
+       if (IS_ERR(handle)) {
+               ret = PTR_ERR(handle);
+               goto out;
+       }
+       if (test_opt(inode->i_sb, NOBH) && ext4_should_writeback_data(inode))
+               ret = nobh_prepare_write(page, from, to, ext4_get_block);
+       else
+               ret = block_prepare_write(page, from, to, ext4_get_block);
+       if (ret)
+               goto prepare_write_failed;
+
+       if (ext4_should_journal_data(inode)) {
+               ret = walk_page_buffers(handle, page_buffers(page),
+                               from, to, NULL, do_journal_get_write_access);
+       }
+prepare_write_failed:
+       if (ret)
+               ext4_journal_stop(handle);
+       if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries))
+               goto retry;
+out:
+       return ret;
+}
+
+int ext4_journal_dirty_data(handle_t *handle, struct buffer_head *bh)
+{
+       int err = jbd2_journal_dirty_data(handle, bh);
+       if (err)
+               ext4_journal_abort_handle(__FUNCTION__, __FUNCTION__,
+                                               bh, handle,err);
+       return err;
+}
+
+/* For commit_write() in data=journal mode */
+static int commit_write_fn(handle_t *handle, struct buffer_head *bh)
+{
+       if (!buffer_mapped(bh) || buffer_freed(bh))
+               return 0;
+       set_buffer_uptodate(bh);
+       return ext4_journal_dirty_metadata(handle, bh);
+}
+
+/*
+ * We need to pick up the new inode size which generic_commit_write gave us
+ * `file' can be NULL - eg, when called from page_symlink().
+ *
+ * ext4 never places buffers on inode->i_mapping->private_list.  metadata
+ * buffers are managed internally.
+ */
+static int ext4_ordered_commit_write(struct file *file, struct page *page,
+                            unsigned from, unsigned to)
+{
+       handle_t *handle = ext4_journal_current_handle();
+       struct inode *inode = page->mapping->host;
+       int ret = 0, ret2;
+
+       ret = walk_page_buffers(handle, page_buffers(page),
+               from, to, NULL, ext4_journal_dirty_data);
+
+       if (ret == 0) {
+               /*
+                * generic_commit_write() will run mark_inode_dirty() if i_size
+                * changes.  So let's piggyback the i_disksize mark_inode_dirty
+                * into that.
+                */
+               loff_t new_i_size;
+
+               new_i_size = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
+               if (new_i_size > EXT4_I(inode)->i_disksize)
+                       EXT4_I(inode)->i_disksize = new_i_size;
+               ret = generic_commit_write(file, page, from, to);
+       }
+       ret2 = ext4_journal_stop(handle);
+       if (!ret)
+               ret = ret2;
+       return ret;
+}
+
+static int ext4_writeback_commit_write(struct file *file, struct page *page,
+                            unsigned from, unsigned to)
+{
+       handle_t *handle = ext4_journal_current_handle();
+       struct inode *inode = page->mapping->host;
+       int ret = 0, ret2;
+       loff_t new_i_size;
+
+       new_i_size = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
+       if (new_i_size > EXT4_I(inode)->i_disksize)
+               EXT4_I(inode)->i_disksize = new_i_size;
+
+       if (test_opt(inode->i_sb, NOBH) && ext4_should_writeback_data(inode))
+               ret = nobh_commit_write(file, page, from, to);
+       else
+               ret = generic_commit_write(file, page, from, to);
+
+       ret2 = ext4_journal_stop(handle);
+       if (!ret)
+               ret = ret2;
+       return ret;
+}
+
+static int ext4_journalled_commit_write(struct file *file,
+                       struct page *page, unsigned from, unsigned to)
+{
+       handle_t *handle = ext4_journal_current_handle();
+       struct inode *inode = page->mapping->host;
+       int ret = 0, ret2;
+       int partial = 0;
+       loff_t pos;
+
+       /*
+        * Here we duplicate the generic_commit_write() functionality
+        */
+       pos = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
+
+       ret = walk_page_buffers(handle, page_buffers(page), from,
+                               to, &partial, commit_write_fn);
+       if (!partial)
+               SetPageUptodate(page);
+       if (pos > inode->i_size)
+               i_size_write(inode, pos);
+       EXT4_I(inode)->i_state |= EXT4_STATE_JDATA;
+       if (inode->i_size > EXT4_I(inode)->i_disksize) {
+               EXT4_I(inode)->i_disksize = inode->i_size;
+               ret2 = ext4_mark_inode_dirty(handle, inode);
+               if (!ret)
+                       ret = ret2;
+       }
+       ret2 = ext4_journal_stop(handle);
+       if (!ret)
+               ret = ret2;
+       return ret;
+}
+
+/*
+ * bmap() is special.  It gets used by applications such as lilo and by
+ * the swapper to find the on-disk block of a specific piece of data.
+ *
+ * Naturally, this is dangerous if the block concerned is still in the
+ * journal.  If somebody makes a swapfile on an ext4 data-journaling
+ * filesystem and enables swap, then they may get a nasty shock when the
+ * data getting swapped to that swapfile suddenly gets overwritten by
+ * the original zero's written out previously to the journal and
+ * awaiting writeback in the kernel's buffer cache.
+ *
+ * So, if we see any bmap calls here on a modified, data-journaled file,
+ * take extra steps to flush any blocks which might be in the cache.
+ */
+static sector_t ext4_bmap(struct address_space *mapping, sector_t block)
+{
+       struct inode *inode = mapping->host;
+       journal_t *journal;
+       int err;
+
+       if (EXT4_I(inode)->i_state & EXT4_STATE_JDATA) {
+               /*
+                * This is a REALLY heavyweight approach, but the use of
+                * bmap on dirty files is expected to be extremely rare:
+                * only if we run lilo or swapon on a freshly made file
+                * do we expect this to happen.
+                *
+                * (bmap requires CAP_SYS_RAWIO so this does not
+                * represent an unprivileged user DOS attack --- we'd be
+                * in trouble if mortal users could trigger this path at
+                * will.)
+                *
+                * NB. EXT4_STATE_JDATA is not set on files other than
+                * regular files.  If somebody wants to bmap a directory
+                * or symlink and gets confused because the buffer
+                * hasn't yet been flushed to disk, they deserve
+                * everything they get.
+                */
+
+               EXT4_I(inode)->i_state &= ~EXT4_STATE_JDATA;
+               journal = EXT4_JOURNAL(inode);
+               jbd2_journal_lock_updates(journal);
+               err = jbd2_journal_flush(journal);
+               jbd2_journal_unlock_updates(journal);
+
+               if (err)
+                       return 0;
+       }
+
+       return generic_block_bmap(mapping,block,ext4_get_block);
+}
+
+static int bget_one(handle_t *handle, struct buffer_head *bh)
+{
+       get_bh(bh);
+       return 0;
+}
+
+static int bput_one(handle_t *handle, struct buffer_head *bh)
+{
+       put_bh(bh);
+       return 0;
+}
+
+static int jbd2_journal_dirty_data_fn(handle_t *handle, struct buffer_head *bh)
+{
+       if (buffer_mapped(bh))
+               return ext4_journal_dirty_data(handle, bh);
+       return 0;
+}
+
+/*
+ * Note that we always start a transaction even if we're not journalling
+ * data.  This is to preserve ordering: any hole instantiation within
+ * __block_write_full_page -> ext4_get_block() should be journalled
+ * along with the data so we don't crash and then get metadata which
+ * refers to old data.
+ *
+ * In all journalling modes block_write_full_page() will start the I/O.
+ *
+ * Problem:
+ *
+ *     ext4_writepage() -> kmalloc() -> __alloc_pages() -> page_launder() ->
+ *             ext4_writepage()
+ *
+ * Similar for:
+ *
+ *     ext4_file_write() -> generic_file_write() -> __alloc_pages() -> ...
+ *
+ * Same applies to ext4_get_block().  We will deadlock on various things like
+ * lock_journal and i_truncate_mutex.
+ *
+ * Setting PF_MEMALLOC here doesn't work - too many internal memory
+ * allocations fail.
+ *
+ * 16May01: If we're reentered then journal_current_handle() will be
+ *         non-zero. We simply *return*.
+ *
+ * 1 July 2001: @@@ FIXME:
+ *   In journalled data mode, a data buffer may be metadata against the
+ *   current transaction.  But the same file is part of a shared mapping
+ *   and someone does a writepage() on it.
+ *
+ *   We will move the buffer onto the async_data list, but *after* it has
+ *   been dirtied. So there's a small window where we have dirty data on
+ *   BJ_Metadata.
+ *
+ *   Note that this only applies to the last partial page in the file.  The
+ *   bit which block_write_full_page() uses prepare/commit for.  (That's
+ *   broken code anyway: it's wrong for msync()).
+ *
+ *   It's a rare case: affects the final partial page, for journalled data
+ *   where the file is subject to bith write() and writepage() in the same
+ *   transction.  To fix it we'll need a custom block_write_full_page().
+ *   We'll probably need that anyway for journalling writepage() output.
+ *
+ * We don't honour synchronous mounts for writepage().  That would be
+ * disastrous.  Any write() or metadata operation will sync the fs for
+ * us.
+ *
+ * AKPM2: if all the page's buffers are mapped to disk and !data=journal,
+ * we don't need to open a transaction here.
+ */
+static int ext4_ordered_writepage(struct page *page,
+                               struct writeback_control *wbc)
+{
+       struct inode *inode = page->mapping->host;
+       struct buffer_head *page_bufs;
+       handle_t *handle = NULL;
+       int ret = 0;
+       int err;
+
+       J_ASSERT(PageLocked(page));
+
+       /*
+        * We give up here if we're reentered, because it might be for a
+        * different filesystem.
+        */
+       if (ext4_journal_current_handle())
+               goto out_fail;
+
+       handle = ext4_journal_start(inode, ext4_writepage_trans_blocks(inode));
+
+       if (IS_ERR(handle)) {
+               ret = PTR_ERR(handle);
+               goto out_fail;
+       }
+
+       if (!page_has_buffers(page)) {
+               create_empty_buffers(page, inode->i_sb->s_blocksize,
+                               (1 << BH_Dirty)|(1 << BH_Uptodate));
+       }
+       page_bufs = page_buffers(page);
+       walk_page_buffers(handle, page_bufs, 0,
+                       PAGE_CACHE_SIZE, NULL, bget_one);
+
+       ret = block_write_full_page(page, ext4_get_block, wbc);
+
+       /*
+        * The page can become unlocked at any point now, and
+        * truncate can then come in and change things.  So we
+        * can't touch *page from now on.  But *page_bufs is
+        * safe due to elevated refcount.
+        */
+
+       /*
+        * And attach them to the current transaction.  But only if
+        * block_write_full_page() succeeded.  Otherwise they are unmapped,
+        * and generally junk.
+        */
+       if (ret == 0) {
+               err = walk_page_buffers(handle, page_bufs, 0, PAGE_CACHE_SIZE,
+                                       NULL, jbd2_journal_dirty_data_fn);
+               if (!ret)
+                       ret = err;
+       }
+       walk_page_buffers(handle, page_bufs, 0,
+                       PAGE_CACHE_SIZE, NULL, bput_one);
+       err = ext4_journal_stop(handle);
+       if (!ret)
+               ret = err;
+       return ret;
+
+out_fail:
+       redirty_page_for_writepage(wbc, page);
+       unlock_page(page);
+       return ret;
+}
+
+static int ext4_writeback_writepage(struct page *page,
+                               struct writeback_control *wbc)
+{
+       struct inode *inode = page->mapping->host;
+       handle_t *handle = NULL;
+       int ret = 0;
+       int err;
+
+       if (ext4_journal_current_handle())
+               goto out_fail;
+
+       handle = ext4_journal_start(inode, ext4_writepage_trans_blocks(inode));
+       if (IS_ERR(handle)) {
+               ret = PTR_ERR(handle);
+               goto out_fail;
+       }
+
+       if (test_opt(inode->i_sb, NOBH) && ext4_should_writeback_data(inode))
+               ret = nobh_writepage(page, ext4_get_block, wbc);
+       else
+               ret = block_write_full_page(page, ext4_get_block, wbc);
+
+       err = ext4_journal_stop(handle);
+       if (!ret)
+               ret = err;
+       return ret;
+
+out_fail:
+       redirty_page_for_writepage(wbc, page);
+       unlock_page(page);
+       return ret;
+}
+
+static int ext4_journalled_writepage(struct page *page,
+                               struct writeback_control *wbc)
+{
+       struct inode *inode = page->mapping->host;
+       handle_t *handle = NULL;
+       int ret = 0;
+       int err;
+
+       if (ext4_journal_current_handle())
+               goto no_write;
+
+       handle = ext4_journal_start(inode, ext4_writepage_trans_blocks(inode));
+       if (IS_ERR(handle)) {
+               ret = PTR_ERR(handle);
+               goto no_write;
+       }
+
+       if (!page_has_buffers(page) || PageChecked(page)) {
+               /*
+                * It's mmapped pagecache.  Add buffers and journal it.  There
+                * doesn't seem much point in redirtying the page here.
+                */
+               ClearPageChecked(page);
+               ret = block_prepare_write(page, 0, PAGE_CACHE_SIZE,
+                                       ext4_get_block);
+               if (ret != 0) {
+                       ext4_journal_stop(handle);
+                       goto out_unlock;
+               }
+               ret = walk_page_buffers(handle, page_buffers(page), 0,
+                       PAGE_CACHE_SIZE, NULL, do_journal_get_write_access);
+
+               err = walk_page_buffers(handle, page_buffers(page), 0,
+                               PAGE_CACHE_SIZE, NULL, commit_write_fn);
+               if (ret == 0)
+                       ret = err;
+               EXT4_I(inode)->i_state |= EXT4_STATE_JDATA;
+               unlock_page(page);
+       } else {
+               /*
+                * It may be a page full of checkpoint-mode buffers.  We don't
+                * really know unless we go poke around in the buffer_heads.
+                * But block_write_full_page will do the right thing.
+                */
+               ret = block_write_full_page(page, ext4_get_block, wbc);
+       }
+       err = ext4_journal_stop(handle);
+       if (!ret)
+               ret = err;
+out:
+       return ret;
+
+no_write:
+       redirty_page_for_writepage(wbc, page);
+out_unlock:
+       unlock_page(page);
+       goto out;
+}
+
+static int ext4_readpage(struct file *file, struct page *page)
+{
+       return mpage_readpage(page, ext4_get_block);
+}
+
+static int
+ext4_readpages(struct file *file, struct address_space *mapping,
+               struct list_head *pages, unsigned nr_pages)
+{
+       return mpage_readpages(mapping, pages, nr_pages, ext4_get_block);
+}
+
+static void ext4_invalidatepage(struct page *page, unsigned long offset)
+{
+       journal_t *journal = EXT4_JOURNAL(page->mapping->host);
+
+       /*
+        * If it's a full truncate we just forget about the pending dirtying
+        */
+       if (offset == 0)
+               ClearPageChecked(page);
+
+       jbd2_journal_invalidatepage(journal, page, offset);
+}
+
+static int ext4_releasepage(struct page *page, gfp_t wait)
+{
+       journal_t *journal = EXT4_JOURNAL(page->mapping->host);
+
+       WARN_ON(PageChecked(page));
+       if (!page_has_buffers(page))
+               return 0;
+       return jbd2_journal_try_to_free_buffers(journal, page, wait);
+}
+
+/*
+ * If the O_DIRECT write will extend the file then add this inode to the
+ * orphan list.  So recovery will truncate it back to the original size
+ * if the machine crashes during the write.
+ *
+ * If the O_DIRECT write is intantiating holes inside i_size and the machine
+ * crashes then stale disk data _may_ be exposed inside the file.
+ */
+static ssize_t ext4_direct_IO(int rw, struct kiocb *iocb,
+                       const struct iovec *iov, loff_t offset,
+                       unsigned long nr_segs)
+{
+       struct file *file = iocb->ki_filp;
+       struct inode *inode = file->f_mapping->host;
+       struct ext4_inode_info *ei = EXT4_I(inode);
+       handle_t *handle = NULL;
+       ssize_t ret;
+       int orphan = 0;
+       size_t count = iov_length(iov, nr_segs);
+
+       if (rw == WRITE) {
+               loff_t final_size = offset + count;
+
+               handle = ext4_journal_start(inode, DIO_CREDITS);
+               if (IS_ERR(handle)) {
+                       ret = PTR_ERR(handle);
+                       goto out;
+               }
+               if (final_size > inode->i_size) {
+                       ret = ext4_orphan_add(handle, inode);
+                       if (ret)
+                               goto out_stop;
+                       orphan = 1;
+                       ei->i_disksize = inode->i_size;
+               }
+       }
+
+       ret = blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
+                                offset, nr_segs,
+                                ext4_get_block, NULL);
+
+       /*
+        * Reacquire the handle: ext4_get_block() can restart the transaction
+        */
+       handle = journal_current_handle();
+
+out_stop:
+       if (handle) {
+               int err;
+
+               if (orphan && inode->i_nlink)
+                       ext4_orphan_del(handle, inode);
+               if (orphan && ret > 0) {
+                       loff_t end = offset + ret;
+                       if (end > inode->i_size) {
+                               ei->i_disksize = end;
+                               i_size_write(inode, end);
+                               /*
+                                * We're going to return a positive `ret'
+                                * here due to non-zero-length I/O, so there's
+                                * no way of reporting error returns from
+                                * ext4_mark_inode_dirty() to userspace.  So
+                                * ignore it.
+                                */
+                               ext4_mark_inode_dirty(handle, inode);
+                       }
+               }
+               err = ext4_journal_stop(handle);
+               if (ret == 0)
+                       ret = err;
+       }
+out:
+       return ret;
+}
+
+/*
+ * Pages can be marked dirty completely asynchronously from ext4's journalling
+ * activity.  By filemap_sync_pte(), try_to_unmap_one(), etc.  We cannot do
+ * much here because ->set_page_dirty is called under VFS locks.  The page is
+ * not necessarily locked.
+ *
+ * We cannot just dirty the page and leave attached buffers clean, because the
+ * buffers' dirty state is "definitive".  We cannot just set the buffers dirty
+ * or jbddirty because all the journalling code will explode.
+ *
+ * So what we do is to mark the page "pending dirty" and next time writepage
+ * is called, propagate that into the buffers appropriately.
+ */
+static int ext4_journalled_set_page_dirty(struct page *page)
+{
+       SetPageChecked(page);
+       return __set_page_dirty_nobuffers(page);
+}
+
+static const struct address_space_operations ext4_ordered_aops = {
+       .readpage       = ext4_readpage,
+       .readpages      = ext4_readpages,
+       .writepage      = ext4_ordered_writepage,
+       .sync_page      = block_sync_page,
+       .prepare_write  = ext4_prepare_write,
+       .commit_write   = ext4_ordered_commit_write,
+       .bmap           = ext4_bmap,
+       .invalidatepage = ext4_invalidatepage,
+       .releasepage    = ext4_releasepage,
+       .direct_IO      = ext4_direct_IO,
+       .migratepage    = buffer_migrate_page,
+};
+
+static const struct address_space_operations ext4_writeback_aops = {
+       .readpage       = ext4_readpage,
+       .readpages      = ext4_readpages,
+       .writepage      = ext4_writeback_writepage,
+       .sync_page      = block_sync_page,
+       .prepare_write  = ext4_prepare_write,
+       .commit_write   = ext4_writeback_commit_write,
+       .bmap           = ext4_bmap,
+       .invalidatepage = ext4_invalidatepage,
+       .releasepage    = ext4_releasepage,
+       .direct_IO      = ext4_direct_IO,
+       .migratepage    = buffer_migrate_page,
+};
+
+static const struct address_space_operations ext4_journalled_aops = {
+       .readpage       = ext4_readpage,
+       .readpages      = ext4_readpages,
+       .writepage      = ext4_journalled_writepage,
+       .sync_page      = block_sync_page,
+       .prepare_write  = ext4_prepare_write,
+       .commit_write   = ext4_journalled_commit_write,
+       .set_page_dirty = ext4_journalled_set_page_dirty,
+       .bmap           = ext4_bmap,
+       .invalidatepage = ext4_invalidatepage,
+       .releasepage    = ext4_releasepage,
+};
+
+void ext4_set_aops(struct inode *inode)
+{
+       if (ext4_should_order_data(inode))
+               inode->i_mapping->a_ops = &ext4_ordered_aops;
+       else if (ext4_should_writeback_data(inode))
+               inode->i_mapping->a_ops = &ext4_writeback_aops;
+       else
+               inode->i_mapping->a_ops = &ext4_journalled_aops;
+}
+
+/*
+ * ext4_block_truncate_page() zeroes out a mapping from file offset `from'
+ * up to the end of the block which corresponds to `from'.
+ * This required during truncate. We need to physically zero the tail end
+ * of that block so it doesn't yield old data if the file is later grown.
+ */
+int ext4_block_truncate_page(handle_t *handle, struct page *page,
+               struct address_space *mapping, loff_t from)
+{
+       ext4_fsblk_t index = from >> PAGE_CACHE_SHIFT;
+       unsigned offset = from & (PAGE_CACHE_SIZE-1);
+       unsigned blocksize, iblock, length, pos;
+       struct inode *inode = mapping->host;
+       struct buffer_head *bh;
+       int err = 0;
+       void *kaddr;
+
+       blocksize = inode->i_sb->s_blocksize;
+       length = blocksize - (offset & (blocksize - 1));
+       iblock = index << (PAGE_CACHE_SHIFT - inode->i_sb->s_blocksize_bits);
+
+       /*
+        * For "nobh" option,  we can only work if we don't need to
+        * read-in the page - otherwise we create buffers to do the IO.
+        */
+       if (!page_has_buffers(page) && test_opt(inode->i_sb, NOBH) &&
+            ext4_should_writeback_data(inode) && PageUptodate(page)) {
+               kaddr = kmap_atomic(page, KM_USER0);
+               memset(kaddr + offset, 0, length);
+               flush_dcache_page(page);
+               kunmap_atomic(kaddr, KM_USER0);
+               set_page_dirty(page);
+               goto unlock;
+       }
+
+       if (!page_has_buffers(page))
+               create_empty_buffers(page, blocksize, 0);
+
+       /* Find the buffer that contains "offset" */
+       bh = page_buffers(page);
+       pos = blocksize;
+       while (offset >= pos) {
+               bh = bh->b_this_page;
+               iblock++;
+               pos += blocksize;
+       }
+
+       err = 0;
+       if (buffer_freed(bh)) {
+               BUFFER_TRACE(bh, "freed: skip");
+               goto unlock;
+       }
+
+       if (!buffer_mapped(bh)) {
+               BUFFER_TRACE(bh, "unmapped");
+               ext4_get_block(inode, iblock, bh, 0);
+               /* unmapped? It's a hole - nothing to do */
+               if (!buffer_mapped(bh)) {
+                       BUFFER_TRACE(bh, "still unmapped");
+                       goto unlock;
+               }
+       }
+
+       /* Ok, it's mapped. Make sure it's up-to-date */
+       if (PageUptodate(page))
+               set_buffer_uptodate(bh);
+
+       if (!buffer_uptodate(bh)) {
+               err = -EIO;
+               ll_rw_block(READ, 1, &bh);
+               wait_on_buffer(bh);
+               /* Uhhuh. Read error. Complain and punt. */
+               if (!buffer_uptodate(bh))
+                       goto unlock;
+       }
+
+       if (ext4_should_journal_data(inode)) {
+               BUFFER_TRACE(bh, "get write access");
+               err = ext4_journal_get_write_access(handle, bh);
+               if (err)
+                       goto unlock;
+       }
+
+       kaddr = kmap_atomic(page, KM_USER0);
+       memset(kaddr + offset, 0, length);
+       flush_dcache_page(page);
+       kunmap_atomic(kaddr, KM_USER0);
+
+       BUFFER_TRACE(bh, "zeroed end of block");
+
+       err = 0;
+       if (ext4_should_journal_data(inode)) {
+               err = ext4_journal_dirty_metadata(handle, bh);
+       } else {
+               if (ext4_should_order_data(inode))
+                       err = ext4_journal_dirty_data(handle, bh);
+               mark_buffer_dirty(bh);
+       }
+
+unlock:
+       unlock_page(page);
+       page_cache_release(page);
+       return err;
+}
+
+/*
+ * Probably it should be a library function... search for first non-zero word
+ * or memcmp with zero_page, whatever is better for particular architecture.
+ * Linus?
+ */
+static inline int all_zeroes(__le32 *p, __le32 *q)
+{
+       while (p < q)
+               if (*p++)
+                       return 0;
+       return 1;
+}
+
+/**
+ *     ext4_find_shared - find the indirect blocks for partial truncation.
+ *     @inode:   inode in question
+ *     @depth:   depth of the affected branch
+ *     @offsets: offsets of pointers in that branch (see ext4_block_to_path)
+ *     @chain:   place to store the pointers to partial indirect blocks
+ *     @top:     place to the (detached) top of branch
+ *
+ *     This is a helper function used by ext4_truncate().
+ *
+ *     When we do truncate() we may have to clean the ends of several
+ *     indirect blocks but leave the blocks themselves alive. Block is
+ *     partially truncated if some data below the new i_size is refered
+ *     from it (and it is on the path to the first completely truncated
+ *     data block, indeed).  We have to free the top of that path along
+ *     with everything to the right of the path. Since no allocation
+ *     past the truncation point is possible until ext4_truncate()
+ *     finishes, we may safely do the latter, but top of branch may
+ *     require special attention - pageout below the truncation point
+ *     might try to populate it.
+ *
+ *     We atomically detach the top of branch from the tree, store the
+ *     block number of its root in *@top, pointers to buffer_heads of
+ *     partially truncated blocks - in @chain[].bh and pointers to
+ *     their last elements that should not be removed - in
+ *     @chain[].p. Return value is the pointer to last filled element
+ *     of @chain.
+ *
+ *     The work left to caller to do the actual freeing of subtrees:
+ *             a) free the subtree starting from *@top
+ *             b) free the subtrees whose roots are stored in
+ *                     (@chain[i].p+1 .. end of @chain[i].bh->b_data)
+ *             c) free the subtrees growing from the inode past the @chain[0].
+ *                     (no partially truncated stuff there).  */
+
+static Indirect *ext4_find_shared(struct inode *inode, int depth,
+                       int offsets[4], Indirect chain[4], __le32 *top)
+{
+       Indirect *partial, *p;
+       int k, err;
+
+       *top = 0;
+       /* Make k index the deepest non-null offest + 1 */
+       for (k = depth; k > 1 && !offsets[k-1]; k--)
+               ;
+       partial = ext4_get_branch(inode, k, offsets, chain, &err);
+       /* Writer: pointers */
+       if (!partial)
+               partial = chain + k-1;
+       /*
+        * If the branch acquired continuation since we've looked at it -
+        * fine, it should all survive and (new) top doesn't belong to us.
+        */
+       if (!partial->key && *partial->p)
+               /* Writer: end */
+               goto no_top;
+       for (p=partial; p>chain && all_zeroes((__le32*)p->bh->b_data,p->p); p--)
+               ;
+       /*
+        * OK, we've found the last block that must survive. The rest of our
+        * branch should be detached before unlocking. However, if that rest
+        * of branch is all ours and does not grow immediately from the inode
+        * it's easier to cheat and just decrement partial->p.
+        */
+       if (p == chain + k - 1 && p > chain) {
+               p->p--;
+       } else {
+               *top = *p->p;
+               /* Nope, don't do this in ext4.  Must leave the tree intact */
+#if 0
+               *p->p = 0;
+#endif
+       }
+       /* Writer: end */
+
+       while(partial > p) {
+               brelse(partial->bh);
+               partial--;
+       }
+no_top:
+       return partial;
+}
+
+/*
+ * Zero a number of block pointers in either an inode or an indirect block.
+ * If we restart the transaction we must again get write access to the
+ * indirect block for further modification.
+ *
+ * We release `count' blocks on disk, but (last - first) may be greater
+ * than `count' because there can be holes in there.
+ */
+static void ext4_clear_blocks(handle_t *handle, struct inode *inode,
+               struct buffer_head *bh, ext4_fsblk_t block_to_free,
+               unsigned long count, __le32 *first, __le32 *last)
+{
+       __le32 *p;
+       if (try_to_extend_transaction(handle, inode)) {
+               if (bh) {
+                       BUFFER_TRACE(bh, "call ext4_journal_dirty_metadata");
+                       ext4_journal_dirty_metadata(handle, bh);
+               }
+               ext4_mark_inode_dirty(handle, inode);
+               ext4_journal_test_restart(handle, inode);
+               if (bh) {
+                       BUFFER_TRACE(bh, "retaking write access");
+                       ext4_journal_get_write_access(handle, bh);
+               }
+       }
+
+       /*
+        * Any buffers which are on the journal will be in memory. We find
+        * them on the hash table so jbd2_journal_revoke() will run jbd2_journal_forget()
+        * on them.  We've already detached each block from the file, so
+        * bforget() in jbd2_journal_forget() should be safe.
+        *
+        * AKPM: turn on bforget in jbd2_journal_forget()!!!
+        */
+       for (p = first; p < last; p++) {
+               u32 nr = le32_to_cpu(*p);
+               if (nr) {
+                       struct buffer_head *bh;
+
+                       *p = 0;
+                       bh = sb_find_get_block(inode->i_sb, nr);
+                       ext4_forget(handle, 0, inode, bh, nr);
+               }
+       }
+
+       ext4_free_blocks(handle, inode, block_to_free, count);
+}
+
+/**
+ * ext4_free_data - free a list of data blocks
+ * @handle:    handle for this transaction
+ * @inode:     inode we are dealing with
+ * @this_bh:   indirect buffer_head which contains *@first and *@last
+ * @first:     array of block numbers
+ * @last:      points immediately past the end of array
+ *
+ * We are freeing all blocks refered from that array (numbers are stored as
+ * little-endian 32-bit) and updating @inode->i_blocks appropriately.
+ *
+ * We accumulate contiguous runs of blocks to free.  Conveniently, if these
+ * blocks are contiguous then releasing them at one time will only affect one
+ * or two bitmap blocks (+ group descriptor(s) and superblock) and we won't
+ * actually use a lot of journal space.
+ *
+ * @this_bh will be %NULL if @first and @last point into the inode's direct
+ * block pointers.
+ */
+static void ext4_free_data(handle_t *handle, struct inode *inode,
+                          struct buffer_head *this_bh,
+                          __le32 *first, __le32 *last)
+{
+       ext4_fsblk_t block_to_free = 0;    /* Starting block # of a run */
+       unsigned long count = 0;            /* Number of blocks in the run */
+       __le32 *block_to_free_p = NULL;     /* Pointer into inode/ind
+                                              corresponding to
+                                              block_to_free */
+       ext4_fsblk_t nr;                    /* Current block # */
+       __le32 *p;                          /* Pointer into inode/ind
+                                              for current block */
+       int err;
+
+       if (this_bh) {                          /* For indirect block */
+               BUFFER_TRACE(this_bh, "get_write_access");
+               err = ext4_journal_get_write_access(handle, this_bh);
+               /* Important: if we can't update the indirect pointers
+                * to the blocks, we can't free them. */
+               if (err)
+                       return;
+       }
+
+       for (p = first; p < last; p++) {
+               nr = le32_to_cpu(*p);
+               if (nr) {
+                       /* accumulate blocks to free if they're contiguous */
+                       if (count == 0) {
+                               block_to_free = nr;
+                               block_to_free_p = p;
+                               count = 1;
+                       } else if (nr == block_to_free + count) {
+                               count++;
+                       } else {
+                               ext4_clear_blocks(handle, inode, this_bh,
+                                                 block_to_free,
+                                                 count, block_to_free_p, p);
+                               block_to_free = nr;
+                               block_to_free_p = p;
+                               count = 1;
+                       }
+               }
+       }
+
+       if (count > 0)
+               ext4_clear_blocks(handle, inode, this_bh, block_to_free,
+                                 count, block_to_free_p, p);
+
+       if (this_bh) {
+               BUFFER_TRACE(this_bh, "call ext4_journal_dirty_metadata");
+               ext4_journal_dirty_metadata(handle, this_bh);
+       }
+}
+
+/**
+ *     ext4_free_branches - free an array of branches
+ *     @handle: JBD handle for this transaction
+ *     @inode: inode we are dealing with
+ *     @parent_bh: the buffer_head which contains *@first and *@last
+ *     @first: array of block numbers
+ *     @last:  pointer immediately past the end of array
+ *     @depth: depth of the branches to free
+ *
+ *     We are freeing all blocks refered from these branches (numbers are
+ *     stored as little-endian 32-bit) and updating @inode->i_blocks
+ *     appropriately.
+ */
+static void ext4_free_branches(handle_t *handle, struct inode *inode,
+                              struct buffer_head *parent_bh,
+                              __le32 *first, __le32 *last, int depth)
+{
+       ext4_fsblk_t nr;
+       __le32 *p;
+
+       if (is_handle_aborted(handle))
+               return;
+
+       if (depth--) {
+               struct buffer_head *bh;
+               int addr_per_block = EXT4_ADDR_PER_BLOCK(inode->i_sb);
+               p = last;
+               while (--p >= first) {
+                       nr = le32_to_cpu(*p);
+                       if (!nr)
+                               continue;               /* A hole */
+
+                       /* Go read the buffer for the next level down */
+                       bh = sb_bread(inode->i_sb, nr);
+
+                       /*
+                        * A read failure? Report error and clear slot
+                        * (should be rare).
+                        */
+                       if (!bh) {
+                               ext4_error(inode->i_sb, "ext4_free_branches",
+                                          "Read failure, inode=%lu, block=%llu",
+                                          inode->i_ino, nr);
+                               continue;
+                       }
+
+                       /* This zaps the entire block.  Bottom up. */
+                       BUFFER_TRACE(bh, "free child branches");
+                       ext4_free_branches(handle, inode, bh,
+                                          (__le32*)bh->b_data,
+                                          (__le32*)bh->b_data + addr_per_block,
+                                          depth);
+
+                       /*
+                        * We've probably journalled the indirect block several
+                        * times during the truncate.  But it's no longer
+                        * needed and we now drop it from the transaction via
+                        * jbd2_journal_revoke().
+                        *
+                        * That's easy if it's exclusively part of this
+                        * transaction.  But if it's part of the committing
+                        * transaction then jbd2_journal_forget() will simply
+                        * brelse() it.  That means that if the underlying
+                        * block is reallocated in ext4_get_block(),
+                        * unmap_underlying_metadata() will find this block
+                        * and will try to get rid of it.  damn, damn.
+                        *
+                        * If this block has already been committed to the
+                        * journal, a revoke record will be written.  And
+                        * revoke records must be emitted *before* clearing
+                        * this block's bit in the bitmaps.
+                        */
+                       ext4_forget(handle, 1, inode, bh, bh->b_blocknr);
+
+                       /*
+                        * Everything below this this pointer has been
+                        * released.  Now let this top-of-subtree go.
+                        *
+                        * We want the freeing of this indirect block to be
+                        * atomic in the journal with the updating of the
+                        * bitmap block which owns it.  So make some room in
+                        * the journal.
+                        *
+                        * We zero the parent pointer *after* freeing its
+                        * pointee in the bitmaps, so if extend_transaction()
+                        * for some reason fails to put the bitmap changes and
+                        * the release into the same transaction, recovery
+                        * will merely complain about releasing a free block,
+                        * rather than leaking blocks.
+                        */
+                       if (is_handle_aborted(handle))
+                               return;
+                       if (try_to_extend_transaction(handle, inode)) {
+                               ext4_mark_inode_dirty(handle, inode);
+                               ext4_journal_test_restart(handle, inode);
+                       }
+
+                       ext4_free_blocks(handle, inode, nr, 1);
+
+                       if (parent_bh) {
+                               /*
+                                * The block which we have just freed is
+                                * pointed to by an indirect block: journal it
+                                */
+                               BUFFER_TRACE(parent_bh, "get_write_access");
+                               if (!ext4_journal_get_write_access(handle,
+                                                                  parent_bh)){
+                                       *p = 0;
+                                       BUFFER_TRACE(parent_bh,
+                                       "call ext4_journal_dirty_metadata");
+                                       ext4_journal_dirty_metadata(handle,
+                                                                   parent_bh);
+                               }
+                       }
+               }
+       } else {
+               /* We have reached the bottom of the tree. */
+               BUFFER_TRACE(parent_bh, "free data blocks");
+               ext4_free_data(handle, inode, parent_bh, first, last);
+       }
+}
+
+/*
+ * ext4_truncate()
+ *
+ * We block out ext4_get_block() block instantiations across the entire
+ * transaction, and VFS/VM ensures that ext4_truncate() cannot run
+ * simultaneously on behalf of the same inode.
+ *
+ * As we work through the truncate and commmit bits of it to the journal there
+ * is one core, guiding principle: the file's tree must always be consistent on
+ * disk.  We must be able to restart the truncate after a crash.
+ *
+ * The file's tree may be transiently inconsistent in memory (although it
+ * probably isn't), but whenever we close off and commit a journal transaction,
+ * the contents of (the filesystem + the journal) must be consistent and
+ * restartable.  It's pretty simple, really: bottom up, right to left (although
+ * left-to-right works OK too).
+ *
+ * Note that at recovery time, journal replay occurs *before* the restart of
+ * truncate against the orphan inode list.
+ *
+ * The committed inode has the new, desired i_size (which is the same as
+ * i_disksize in this case).  After a crash, ext4_orphan_cleanup() will see
+ * that this inode's truncate did not complete and it will again call
+ * ext4_truncate() to have another go.  So there will be instantiated blocks
+ * to the right of the truncation point in a crashed ext4 filesystem.  But
+ * that's fine - as long as they are linked from the inode, the post-crash
+ * ext4_truncate() run will find them and release them.
+ */
+void ext4_truncate(struct inode *inode)
+{
+       handle_t *handle;
+       struct ext4_inode_info *ei = EXT4_I(inode);
+       __le32 *i_data = ei->i_data;
+       int addr_per_block = EXT4_ADDR_PER_BLOCK(inode->i_sb);
+       struct address_space *mapping = inode->i_mapping;
+       int offsets[4];
+       Indirect chain[4];
+       Indirect *partial;
+       __le32 nr = 0;
+       int n;
+       long last_block;
+       unsigned blocksize = inode->i_sb->s_blocksize;
+       struct page *page;
+
+       if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
+           S_ISLNK(inode->i_mode)))
+               return;
+       if (ext4_inode_is_fast_symlink(inode))
+               return;
+       if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
+               return;
+
+       /*
+        * We have to lock the EOF page here, because lock_page() nests
+        * outside jbd2_journal_start().
+        */
+       if ((inode->i_size & (blocksize - 1)) == 0) {
+               /* Block boundary? Nothing to do */
+               page = NULL;
+       } else {
+               page = grab_cache_page(mapping,
+                               inode->i_size >> PAGE_CACHE_SHIFT);
+               if (!page)
+                       return;
+       }
+
+       if (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL)
+               return ext4_ext_truncate(inode, page);
+
+       handle = start_transaction(inode);
+       if (IS_ERR(handle)) {
+               if (page) {
+                       clear_highpage(page);
+                       flush_dcache_page(page);
+                       unlock_page(page);
+                       page_cache_release(page);
+               }
+               return;         /* AKPM: return what? */
+       }
+
+       last_block = (inode->i_size + blocksize-1)
+                                       >> EXT4_BLOCK_SIZE_BITS(inode->i_sb);
+
+       if (page)
+               ext4_block_truncate_page(handle, page, mapping, inode->i_size);
+
+       n = ext4_block_to_path(inode, last_block, offsets, NULL);
+       if (n == 0)
+               goto out_stop;  /* error */
+
+       /*
+        * OK.  This truncate is going to happen.  We add the inode to the
+        * orphan list, so that if this truncate spans multiple transactions,
+        * and we crash, we will resume the truncate when the filesystem
+        * recovers.  It also marks the inode dirty, to catch the new size.
+        *
+        * Implication: the file must always be in a sane, consistent
+        * truncatable state while each transaction commits.
+        */
+       if (ext4_orphan_add(handle, inode))
+               goto out_stop;
+
+       /*
+        * The orphan list entry will now protect us from any crash which
+        * occurs before the truncate completes, so it is now safe to propagate
+        * the new, shorter inode size (held for now in i_size) into the
+        * on-disk inode. We do this via i_disksize, which is the value which
+        * ext4 *really* writes onto the disk inode.
+        */
+       ei->i_disksize = inode->i_size;
+
+       /*
+        * From here we block out all ext4_get_block() callers who want to
+        * modify the block allocation tree.
+        */
+       mutex_lock(&ei->truncate_mutex);
+
+       if (n == 1) {           /* direct blocks */
+               ext4_free_data(handle, inode, NULL, i_data+offsets[0],
+                              i_data + EXT4_NDIR_BLOCKS);
+               goto do_indirects;
+       }
+
+       partial = ext4_find_shared(inode, n, offsets, chain, &nr);
+       /* Kill the top of shared branch (not detached) */
+       if (nr) {
+               if (partial == chain) {
+                       /* Shared branch grows from the inode */
+                       ext4_free_branches(handle, inode, NULL,
+                                          &nr, &nr+1, (chain+n-1) - partial);
+                       *partial->p = 0;
+                       /*
+                        * We mark the inode dirty prior to restart,
+                        * and prior to stop.  No need for it here.
+                        */
+               } else {
+                       /* Shared branch grows from an indirect block */
+                       BUFFER_TRACE(partial->bh, "get_write_access");
+                       ext4_free_branches(handle, inode, partial->bh,
+                                       partial->p,
+                                       partial->p+1, (chain+n-1) - partial);
+               }
+       }
+       /* Clear the ends of indirect blocks on the shared branch */
+       while (partial > chain) {
+               ext4_free_branches(handle, inode, partial->bh, partial->p + 1,
+                                  (__le32*)partial->bh->b_data+addr_per_block,
+                                  (chain+n-1) - partial);
+               BUFFER_TRACE(partial->bh, "call brelse");
+               brelse (partial->bh);
+               partial--;
+       }
+do_indirects:
+       /* Kill the remaining (whole) subtrees */
+       switch (offsets[0]) {
+       default:
+               nr = i_data[EXT4_IND_BLOCK];
+               if (nr) {
+                       ext4_free_branches(handle, inode, NULL, &nr, &nr+1, 1);
+                       i_data[EXT4_IND_BLOCK] = 0;
+               }
+       case EXT4_IND_BLOCK:
+               nr = i_data[EXT4_DIND_BLOCK];
+               if (nr) {
+                       ext4_free_branches(handle, inode, NULL, &nr, &nr+1, 2);
+                       i_data[EXT4_DIND_BLOCK] = 0;
+               }
+       case EXT4_DIND_BLOCK:
+               nr = i_data[EXT4_TIND_BLOCK];
+               if (nr) {
+                       ext4_free_branches(handle, inode, NULL, &nr, &nr+1, 3);
+                       i_data[EXT4_TIND_BLOCK] = 0;
+               }
+       case EXT4_TIND_BLOCK:
+               ;
+       }
+
+       ext4_discard_reservation(inode);
+
+       mutex_unlock(&ei->truncate_mutex);
+       inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC;
+       ext4_mark_inode_dirty(handle, inode);
+
+       /*
+        * In a multi-transaction truncate, we only make the final transaction
+        * synchronous
+        */
+       if (IS_SYNC(inode))
+               handle->h_sync = 1;
+out_stop:
+       /*
+        * If this was a simple ftruncate(), and the file will remain alive
+        * then we need to clear up the orphan record which we created above.
+        * However, if this was a real unlink then we were called by
+        * ext4_delete_inode(), and we allow that function to clean up the
+        * orphan info for us.
+        */
+       if (inode->i_nlink)
+               ext4_orphan_del(handle, inode);
+
+       ext4_journal_stop(handle);
+}
+
+static ext4_fsblk_t ext4_get_inode_block(struct super_block *sb,
+               unsigned long ino, struct ext4_iloc *iloc)
+{
+       unsigned long desc, group_desc, block_group;
+       unsigned long offset;
+       ext4_fsblk_t block;
+       struct buffer_head *bh;
+       struct ext4_group_desc * gdp;
+
+       if (!ext4_valid_inum(sb, ino)) {
+               /*
+                * This error is already checked for in namei.c unless we are
+                * looking at an NFS filehandle, in which case no error
+                * report is needed
+                */
+               return 0;
+       }
+
+       block_group = (ino - 1) / EXT4_INODES_PER_GROUP(sb);
+       if (block_group >= EXT4_SB(sb)->s_groups_count) {
+               ext4_error(sb,"ext4_get_inode_block","group >= groups count");
+               return 0;
+       }
+       smp_rmb();
+       group_desc = block_group >> EXT4_DESC_PER_BLOCK_BITS(sb);
+       desc = block_group & (EXT4_DESC_PER_BLOCK(sb) - 1);
+       bh = EXT4_SB(sb)->s_group_desc[group_desc];
+       if (!bh) {
+               ext4_error (sb, "ext4_get_inode_block",
+                           "Descriptor not loaded");
+               return 0;
+       }
+
+       gdp = (struct ext4_group_desc *)((__u8 *)bh->b_data +
+               desc * EXT4_DESC_SIZE(sb));
+       /*
+        * Figure out the offset within the block group inode table
+        */
+       offset = ((ino - 1) % EXT4_INODES_PER_GROUP(sb)) *
+               EXT4_INODE_SIZE(sb);
+       block = ext4_inode_table(sb, gdp) +
+               (offset >> EXT4_BLOCK_SIZE_BITS(sb));
+
+       iloc->block_group = block_group;
+       iloc->offset = offset & (EXT4_BLOCK_SIZE(sb) - 1);
+       return block;
+}
+
+/*
+ * ext4_get_inode_loc returns with an extra refcount against the inode's
+ * underlying buffer_head on success. If 'in_mem' is true, we have all
+ * data in memory that is needed to recreate the on-disk version of this
+ * inode.
+ */
+static int __ext4_get_inode_loc(struct inode *inode,
+                               struct ext4_iloc *iloc, int in_mem)
+{
+       ext4_fsblk_t block;
+       struct buffer_head *bh;
+
+       block = ext4_get_inode_block(inode->i_sb, inode->i_ino, iloc);
+       if (!block)
+               return -EIO;
+
+       bh = sb_getblk(inode->i_sb, block);
+       if (!bh) {
+               ext4_error (inode->i_sb, "ext4_get_inode_loc",
+                               "unable to read inode block - "
+                               "inode=%lu, block=%llu",
+                                inode->i_ino, block);
+               return -EIO;
+       }
+       if (!buffer_uptodate(bh)) {
+               lock_buffer(bh);
+               if (buffer_uptodate(bh)) {
+                       /* someone brought it uptodate while we waited */
+                       unlock_buffer(bh);
+                       goto has_buffer;
+               }
+
+               /*
+                * If we have all information of the inode in memory and this
+                * is the only valid inode in the block, we need not read the
+                * block.
+                */
+               if (in_mem) {
+                       struct buffer_head *bitmap_bh;
+                       struct ext4_group_desc *desc;
+                       int inodes_per_buffer;
+                       int inode_offset, i;
+                       int block_group;
+                       int start;
+
+                       block_group = (inode->i_ino - 1) /
+                                       EXT4_INODES_PER_GROUP(inode->i_sb);
+                       inodes_per_buffer = bh->b_size /
+                               EXT4_INODE_SIZE(inode->i_sb);
+                       inode_offset = ((inode->i_ino - 1) %
+                                       EXT4_INODES_PER_GROUP(inode->i_sb));
+                       start = inode_offset & ~(inodes_per_buffer - 1);
+
+                       /* Is the inode bitmap in cache? */
+                       desc = ext4_get_group_desc(inode->i_sb,
+                                               block_group, NULL);
+                       if (!desc)
+                               goto make_io;
+
+                       bitmap_bh = sb_getblk(inode->i_sb,
+                               ext4_inode_bitmap(inode->i_sb, desc));
+                       if (!bitmap_bh)
+                               goto make_io;
+
+                       /*
+                        * If the inode bitmap isn't in cache then the
+                        * optimisation may end up performing two reads instead
+                        * of one, so skip it.
+                        */
+                       if (!buffer_uptodate(bitmap_bh)) {
+                               brelse(bitmap_bh);
+                               goto make_io;
+                       }
+                       for (i = start; i < start + inodes_per_buffer; i++) {
+                               if (i == inode_offset)
+                                       continue;
+                               if (ext4_test_bit(i, bitmap_bh->b_data))
+                                       break;
+                       }
+                       brelse(bitmap_bh);
+                       if (i == start + inodes_per_buffer) {
+                               /* all other inodes are free, so skip I/O */
+                               memset(bh->b_data, 0, bh->b_size);
+                               set_buffer_uptodate(bh);
+                               unlock_buffer(bh);
+                               goto has_buffer;
+                       }
+               }
+
+make_io:
+               /*
+                * There are other valid inodes in the buffer, this inode
+                * has in-inode xattrs, or we don't have this inode in memory.
+                * Read the block from disk.
+                */
+               get_bh(bh);
+               bh->b_end_io = end_buffer_read_sync;
+               submit_bh(READ_META, bh);
+               wait_on_buffer(bh);
+               if (!buffer_uptodate(bh)) {
+                       ext4_error(inode->i_sb, "ext4_get_inode_loc",
+                                       "unable to read inode block - "
+                                       "inode=%lu, block=%llu",
+                                       inode->i_ino, block);
+                       brelse(bh);
+                       return -EIO;
+               }
+       }
+has_buffer:
+       iloc->bh = bh;
+       return 0;
+}
+
+int ext4_get_inode_loc(struct inode *inode, struct ext4_iloc *iloc)
+{
+       /* We have all inode data except xattrs in memory here. */
+       return __ext4_get_inode_loc(inode, iloc,
+               !(EXT4_I(inode)->i_state & EXT4_STATE_XATTR));
+}
+
+void ext4_set_inode_flags(struct inode *inode)
+{
+       unsigned int flags = EXT4_I(inode)->i_flags;
+
+       inode->i_flags &= ~(S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC);
+       if (flags & EXT4_SYNC_FL)
+               inode->i_flags |= S_SYNC;
+       if (flags & EXT4_APPEND_FL)
+               inode->i_flags |= S_APPEND;
+       if (flags & EXT4_IMMUTABLE_FL)
+               inode->i_flags |= S_IMMUTABLE;
+       if (flags & EXT4_NOATIME_FL)
+               inode->i_flags |= S_NOATIME;
+       if (flags & EXT4_DIRSYNC_FL)
+               inode->i_flags |= S_DIRSYNC;
+}
+
+void ext4_read_inode(struct inode * inode)
+{
+       struct ext4_iloc iloc;
+       struct ext4_inode *raw_inode;
+       struct ext4_inode_info *ei = EXT4_I(inode);
+       struct buffer_head *bh;
+       int block;
+
+#ifdef CONFIG_EXT4DEV_FS_POSIX_ACL
+       ei->i_acl = EXT4_ACL_NOT_CACHED;
+       ei->i_default_acl = EXT4_ACL_NOT_CACHED;
+#endif
+       ei->i_block_alloc_info = NULL;
+
+       if (__ext4_get_inode_loc(inode, &iloc, 0))
+               goto bad_inode;
+       bh = iloc.bh;
+       raw_inode = ext4_raw_inode(&iloc);
+       inode->i_mode = le16_to_cpu(raw_inode->i_mode);
+       inode->i_uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low);
+       inode->i_gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low);
+       if(!(test_opt (inode->i_sb, NO_UID32))) {
+               inode->i_uid |= le16_to_cpu(raw_inode->i_uid_high) << 16;
+               inode->i_gid |= le16_to_cpu(raw_inode->i_gid_high) << 16;
+       }
+       inode->i_nlink = le16_to_cpu(raw_inode->i_links_count);
+       inode->i_size = le32_to_cpu(raw_inode->i_size);
+       inode->i_atime.tv_sec = le32_to_cpu(raw_inode->i_atime);
+       inode->i_ctime.tv_sec = le32_to_cpu(raw_inode->i_ctime);
+       inode->i_mtime.tv_sec = le32_to_cpu(raw_inode->i_mtime);
+       inode->i_atime.tv_nsec = inode->i_ctime.tv_nsec = inode->i_mtime.tv_nsec = 0;
+
+       ei->i_state = 0;
+       ei->i_dir_start_lookup = 0;
+       ei->i_dtime = le32_to_cpu(raw_inode->i_dtime);
+       /* We now have enough fields to check if the inode was active or not.
+        * This is needed because nfsd might try to access dead inodes
+        * the test is that same one that e2fsck uses
+        * NeilBrown 1999oct15
+        */
+       if (inode->i_nlink == 0) {
+               if (inode->i_mode == 0 ||
+                   !(EXT4_SB(inode->i_sb)->s_mount_state & EXT4_ORPHAN_FS)) {
+                       /* this inode is deleted */
+                       brelse (bh);
+                       goto bad_inode;
+               }
+               /* The only unlinked inodes we let through here have
+                * valid i_mode and are being read by the orphan
+                * recovery code: that's fine, we're about to complete
+                * the process of deleting those. */
+       }
+       inode->i_blocks = le32_to_cpu(raw_inode->i_blocks);
+       ei->i_flags = le32_to_cpu(raw_inode->i_flags);
+#ifdef EXT4_FRAGMENTS
+       ei->i_faddr = le32_to_cpu(raw_inode->i_faddr);
+       ei->i_frag_no = raw_inode->i_frag;
+       ei->i_frag_size = raw_inode->i_fsize;
+#endif
+       ei->i_file_acl = le32_to_cpu(raw_inode->i_file_acl);
+       if (EXT4_SB(inode->i_sb)->s_es->s_creator_os !=
+           cpu_to_le32(EXT4_OS_HURD))
+               ei->i_file_acl |=
+                       ((__u64)le16_to_cpu(raw_inode->i_file_acl_high)) << 32;
+       if (!S_ISREG(inode->i_mode)) {
+               ei->i_dir_acl = le32_to_cpu(raw_inode->i_dir_acl);
+       } else {
+               inode->i_size |=
+                       ((__u64)le32_to_cpu(raw_inode->i_size_high)) << 32;
+       }
+       ei->i_disksize = inode->i_size;
+       inode->i_generation = le32_to_cpu(raw_inode->i_generation);
+       ei->i_block_group = iloc.block_group;
+       /*
+        * NOTE! The in-memory inode i_data array is in little-endian order
+        * even on big-endian machines: we do NOT byteswap the block numbers!
+        */
+       for (block = 0; block < EXT4_N_BLOCKS; block++)
+               ei->i_data[block] = raw_inode->i_block[block];
+       INIT_LIST_HEAD(&ei->i_orphan);
+
+       if (inode->i_ino >= EXT4_FIRST_INO(inode->i_sb) + 1 &&
+           EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE) {
+               /*
+                * When mke2fs creates big inodes it does not zero out
+                * the unused bytes above EXT4_GOOD_OLD_INODE_SIZE,
+                * so ignore those first few inodes.
+                */
+               ei->i_extra_isize = le16_to_cpu(raw_inode->i_extra_isize);
+               if (EXT4_GOOD_OLD_INODE_SIZE + ei->i_extra_isize >
+                   EXT4_INODE_SIZE(inode->i_sb))
+                       goto bad_inode;
+               if (ei->i_extra_isize == 0) {
+                       /* The extra space is currently unused. Use it. */
+                       ei->i_extra_isize = sizeof(struct ext4_inode) -
+                                           EXT4_GOOD_OLD_INODE_SIZE;
+               } else {
+                       __le32 *magic = (void *)raw_inode +
+                                       EXT4_GOOD_OLD_INODE_SIZE +
+                                       ei->i_extra_isize;
+                       if (*magic == cpu_to_le32(EXT4_XATTR_MAGIC))
+                                ei->i_state |= EXT4_STATE_XATTR;
+               }
+       } else
+               ei->i_extra_isize = 0;
+
+       if (S_ISREG(inode->i_mode)) {
+               inode->i_op = &ext4_file_inode_operations;
+               inode->i_fop = &ext4_file_operations;
+               ext4_set_aops(inode);
+       } else if (S_ISDIR(inode->i_mode)) {
+               inode->i_op = &ext4_dir_inode_operations;
+               inode->i_fop = &ext4_dir_operations;
+       } else if (S_ISLNK(inode->i_mode)) {
+               if (ext4_inode_is_fast_symlink(inode))
+                       inode->i_op = &ext4_fast_symlink_inode_operations;
+               else {
+                       inode->i_op = &ext4_symlink_inode_operations;
+                       ext4_set_aops(inode);
+               }
+       } else {
+               inode->i_op = &ext4_special_inode_operations;
+               if (raw_inode->i_block[0])
+                       init_special_inode(inode, inode->i_mode,
+                          old_decode_dev(le32_to_cpu(raw_inode->i_block[0])));
+               else
+                       init_special_inode(inode, inode->i_mode,
+                          new_decode_dev(le32_to_cpu(raw_inode->i_block[1])));
+       }
+       brelse (iloc.bh);
+       ext4_set_inode_flags(inode);
+       return;
+
+bad_inode:
+       make_bad_inode(inode);
+       return;
+}
+
+/*
+ * Post the struct inode info into an on-disk inode location in the
+ * buffer-cache.  This gobbles the caller's reference to the
+ * buffer_head in the inode location struct.
+ *
+ * The caller must have write access to iloc->bh.
+ */
+static int ext4_do_update_inode(handle_t *handle,
+                               struct inode *inode,
+                               struct ext4_iloc *iloc)
+{
+       struct ext4_inode *raw_inode = ext4_raw_inode(iloc);
+       struct ext4_inode_info *ei = EXT4_I(inode);
+       struct buffer_head *bh = iloc->bh;
+       int err = 0, rc, block;
+
+       /* For fields not not tracking in the in-memory inode,
+        * initialise them to zero for new inodes. */
+       if (ei->i_state & EXT4_STATE_NEW)
+               memset(raw_inode, 0, EXT4_SB(inode->i_sb)->s_inode_size);
+
+       raw_inode->i_mode = cpu_to_le16(inode->i_mode);
+       if(!(test_opt(inode->i_sb, NO_UID32))) {
+               raw_inode->i_uid_low = cpu_to_le16(low_16_bits(inode->i_uid));
+               raw_inode->i_gid_low = cpu_to_le16(low_16_bits(inode->i_gid));
+/*
+ * Fix up interoperability with old kernels. Otherwise, old inodes get
+ * re-used with the upper 16 bits of the uid/gid intact
+ */
+               if(!ei->i_dtime) {
+                       raw_inode->i_uid_high =
+                               cpu_to_le16(high_16_bits(inode->i_uid));
+                       raw_inode->i_gid_high =
+                               cpu_to_le16(high_16_bits(inode->i_gid));
+               } else {
+                       raw_inode->i_uid_high = 0;
+                       raw_inode->i_gid_high = 0;
+               }
+       } else {
+               raw_inode->i_uid_low =
+                       cpu_to_le16(fs_high2lowuid(inode->i_uid));
+               raw_inode->i_gid_low =
+                       cpu_to_le16(fs_high2lowgid(inode->i_gid));
+               raw_inode->i_uid_high = 0;
+               raw_inode->i_gid_high = 0;
+       }
+       raw_inode->i_links_count = cpu_to_le16(inode->i_nlink);
+       raw_inode->i_size = cpu_to_le32(ei->i_disksize);
+       raw_inode->i_atime = cpu_to_le32(inode->i_atime.tv_sec);
+       raw_inode->i_ctime = cpu_to_le32(inode->i_ctime.tv_sec);
+       raw_inode->i_mtime = cpu_to_le32(inode->i_mtime.tv_sec);
+       raw_inode->i_blocks = cpu_to_le32(inode->i_blocks);
+       raw_inode->i_dtime = cpu_to_le32(ei->i_dtime);
+       raw_inode->i_flags = cpu_to_le32(ei->i_flags);
+#ifdef EXT4_FRAGMENTS
+       raw_inode->i_faddr = cpu_to_le32(ei->i_faddr);
+       raw_inode->i_frag = ei->i_frag_no;
+       raw_inode->i_fsize = ei->i_frag_size;
+#endif
+       if (EXT4_SB(inode->i_sb)->s_es->s_creator_os !=
+           cpu_to_le32(EXT4_OS_HURD))
+               raw_inode->i_file_acl_high =
+                       cpu_to_le16(ei->i_file_acl >> 32);
+       raw_inode->i_file_acl = cpu_to_le32(ei->i_file_acl);
+       if (!S_ISREG(inode->i_mode)) {
+               raw_inode->i_dir_acl = cpu_to_le32(ei->i_dir_acl);
+       } else {
+               raw_inode->i_size_high =
+                       cpu_to_le32(ei->i_disksize >> 32);
+               if (ei->i_disksize > 0x7fffffffULL) {
+                       struct super_block *sb = inode->i_sb;
+                       if (!EXT4_HAS_RO_COMPAT_FEATURE(sb,
+                                       EXT4_FEATURE_RO_COMPAT_LARGE_FILE) ||
+                           EXT4_SB(sb)->s_es->s_rev_level ==
+                                       cpu_to_le32(EXT4_GOOD_OLD_REV)) {
+                              /* If this is the first large file
+                               * created, add a flag to the superblock.
+                               */
+                               err = ext4_journal_get_write_access(handle,
+                                               EXT4_SB(sb)->s_sbh);
+                               if (err)
+                                       goto out_brelse;
+                               ext4_update_dynamic_rev(sb);
+                               EXT4_SET_RO_COMPAT_FEATURE(sb,
+                                       EXT4_FEATURE_RO_COMPAT_LARGE_FILE);
+                               sb->s_dirt = 1;
+                               handle->h_sync = 1;
+                               err = ext4_journal_dirty_metadata(handle,
+                                               EXT4_SB(sb)->s_sbh);
+                       }
+               }
+       }
+       raw_inode->i_generation = cpu_to_le32(inode->i_generation);
+       if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) {
+               if (old_valid_dev(inode->i_rdev)) {
+                       raw_inode->i_block[0] =
+                               cpu_to_le32(old_encode_dev(inode->i_rdev));
+                       raw_inode->i_block[1] = 0;
+               } else {
+                       raw_inode->i_block[0] = 0;
+                       raw_inode->i_block[1] =
+                               cpu_to_le32(new_encode_dev(inode->i_rdev));
+                       raw_inode->i_block[2] = 0;
+               }
+       } else for (block = 0; block < EXT4_N_BLOCKS; block++)
+               raw_inode->i_block[block] = ei->i_data[block];
+
+       if (ei->i_extra_isize)
+               raw_inode->i_extra_isize = cpu_to_le16(ei->i_extra_isize);
+
+       BUFFER_TRACE(bh, "call ext4_journal_dirty_metadata");
+       rc = ext4_journal_dirty_metadata(handle, bh);
+       if (!err)
+               err = rc;
+       ei->i_state &= ~EXT4_STATE_NEW;
+
+out_brelse:
+       brelse (bh);
+       ext4_std_error(inode->i_sb, err);
+       return err;
+}
+
+/*
+ * ext4_write_inode()
+ *
+ * We are called from a few places:
+ *
+ * - Within generic_file_write() for O_SYNC files.
+ *   Here, there will be no transaction running. We wait for any running
+ *   trasnaction to commit.
+ *
+ * - Within sys_sync(), kupdate and such.
+ *   We wait on commit, if tol to.
+ *
+ * - Within prune_icache() (PF_MEMALLOC == true)
+ *   Here we simply return.  We can't afford to block kswapd on the
+ *   journal commit.
+ *
+ * In all cases it is actually safe for us to return without doing anything,
+ * because the inode has been copied into a raw inode buffer in
+ * ext4_mark_inode_dirty().  This is a correctness thing for O_SYNC and for
+ * knfsd.
+ *
+ * Note that we are absolutely dependent upon all inode dirtiers doing the
+ * right thing: they *must* call mark_inode_dirty() after dirtying info in
+ * which we are interested.
+ *
+ * It would be a bug for them to not do this.  The code:
+ *
+ *     mark_inode_dirty(inode)
+ *     stuff();
+ *     inode->i_size = expr;
+ *
+ * is in error because a kswapd-driven write_inode() could occur while
+ * `stuff()' is running, and the new i_size will be lost.  Plus the inode
+ * will no longer be on the superblock's dirty inode list.
+ */
+int ext4_write_inode(struct inode *inode, int wait)
+{
+       if (current->flags & PF_MEMALLOC)
+               return 0;
+
+       if (ext4_journal_current_handle()) {
+               jbd_debug(0, "called recursively, non-PF_MEMALLOC!\n");
+               dump_stack();
+               return -EIO;
+       }
+
+       if (!wait)
+               return 0;
+
+       return ext4_force_commit(inode->i_sb);
+}
+
+/*
+ * ext4_setattr()
+ *
+ * Called from notify_change.
+ *
+ * We want to trap VFS attempts to truncate the file as soon as
+ * possible.  In particular, we want to make sure that when the VFS
+ * shrinks i_size, we put the inode on the orphan list and modify
+ * i_disksize immediately, so that during the subsequent flushing of
+ * dirty pages and freeing of disk blocks, we can guarantee that any
+ * commit will leave the blocks being flushed in an unused state on
+ * disk.  (On recovery, the inode will get truncated and the blocks will
+ * be freed, so we have a strong guarantee that no future commit will
+ * leave these blocks visible to the user.)
+ *
+ * Called with inode->sem down.
+ */
+int ext4_setattr(struct dentry *dentry, struct iattr *attr)
+{
+       struct inode *inode = dentry->d_inode;
+       int error, rc = 0;
+       const unsigned int ia_valid = attr->ia_valid;
+
+       error = inode_change_ok(inode, attr);
+       if (error)
+               return error;
+
+       if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
+               (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) {
+               handle_t *handle;
+
+               /* (user+group)*(old+new) structure, inode write (sb,
+                * inode block, ? - but truncate inode update has it) */
+               handle = ext4_journal_start(inode, 2*(EXT4_QUOTA_INIT_BLOCKS(inode->i_sb)+
+                                       EXT4_QUOTA_DEL_BLOCKS(inode->i_sb))+3);
+               if (IS_ERR(handle)) {
+                       error = PTR_ERR(handle);
+                       goto err_out;
+               }
+               error = DQUOT_TRANSFER(inode, attr) ? -EDQUOT : 0;
+               if (error) {
+                       ext4_journal_stop(handle);
+                       return error;
+               }
+               /* Update corresponding info in inode so that everything is in
+                * one transaction */
+               if (attr->ia_valid & ATTR_UID)
+                       inode->i_uid = attr->ia_uid;
+               if (attr->ia_valid & ATTR_GID)
+                       inode->i_gid = attr->ia_gid;
+               error = ext4_mark_inode_dirty(handle, inode);
+               ext4_journal_stop(handle);
+       }
+
+       if (S_ISREG(inode->i_mode) &&
+           attr->ia_valid & ATTR_SIZE && attr->ia_size < inode->i_size) {
+               handle_t *handle;
+
+               handle = ext4_journal_start(inode, 3);
+               if (IS_ERR(handle)) {
+                       error = PTR_ERR(handle);
+                       goto err_out;
+               }
+
+               error = ext4_orphan_add(handle, inode);
+               EXT4_I(inode)->i_disksize = attr->ia_size;
+               rc = ext4_mark_inode_dirty(handle, inode);
+               if (!error)
+                       error = rc;
+               ext4_journal_stop(handle);
+       }
+
+       rc = inode_setattr(inode, attr);
+
+       /* If inode_setattr's call to ext4_truncate failed to get a
+        * transaction handle at all, we need to clean up the in-core
+        * orphan list manually. */
+       if (inode->i_nlink)
+               ext4_orphan_del(NULL, inode);
+
+       if (!rc && (ia_valid & ATTR_MODE))
+               rc = ext4_acl_chmod(inode);
+
+err_out:
+       ext4_std_error(inode->i_sb, error);
+       if (!error)
+               error = rc;
+       return error;
+}
+
+
+/*
+ * How many blocks doth make a writepage()?
+ *
+ * With N blocks per page, it may be:
+ * N data blocks
+ * 2 indirect block
+ * 2 dindirect
+ * 1 tindirect
+ * N+5 bitmap blocks (from the above)
+ * N+5 group descriptor summary blocks
+ * 1 inode block
+ * 1 superblock.
+ * 2 * EXT4_SINGLEDATA_TRANS_BLOCKS for the quote files
+ *
+ * 3 * (N + 5) + 2 + 2 * EXT4_SINGLEDATA_TRANS_BLOCKS
+ *
+ * With ordered or writeback data it's the same, less the N data blocks.
+ *
+ * If the inode's direct blocks can hold an integral number of pages then a
+ * page cannot straddle two indirect blocks, and we can only touch one indirect
+ * and dindirect block, and the "5" above becomes "3".
+ *
+ * This still overestimates under most circumstances.  If we were to pass the
+ * start and end offsets in here as well we could do block_to_path() on each
+ * block and work out the exact number of indirects which are touched.  Pah.
+ */
+
+int ext4_writepage_trans_blocks(struct inode *inode)
+{
+       int bpp = ext4_journal_blocks_per_page(inode);
+       int indirects = (EXT4_NDIR_BLOCKS % bpp) ? 5 : 3;
+       int ret;
+
+       if (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL)
+               return ext4_ext_writepage_trans_blocks(inode, bpp);
+
+       if (ext4_should_journal_data(inode))
+               ret = 3 * (bpp + indirects) + 2;
+       else
+               ret = 2 * (bpp + indirects) + 2;
+
+#ifdef CONFIG_QUOTA
+       /* We know that structure was already allocated during DQUOT_INIT so
+        * we will be updating only the data blocks + inodes */
+       ret += 2*EXT4_QUOTA_TRANS_BLOCKS(inode->i_sb);
+#endif
+
+       return ret;
+}
+
+/*
+ * The caller must have previously called ext4_reserve_inode_write().
+ * Give this, we know that the caller already has write access to iloc->bh.
+ */
+int ext4_mark_iloc_dirty(handle_t *handle,
+               struct inode *inode, struct ext4_iloc *iloc)
+{
+       int err = 0;
+
+       /* the do_update_inode consumes one bh->b_count */
+       get_bh(iloc->bh);
+
+       /* ext4_do_update_inode() does jbd2_journal_dirty_metadata */
+       err = ext4_do_update_inode(handle, inode, iloc);
+       put_bh(iloc->bh);
+       return err;
+}
+
+/*
+ * On success, We end up with an outstanding reference count against
+ * iloc->bh.  This _must_ be cleaned up later.
+ */
+
+int
+ext4_reserve_inode_write(handle_t *handle, struct inode *inode,
+                        struct ext4_iloc *iloc)
+{
+       int err = 0;
+       if (handle) {
+               err = ext4_get_inode_loc(inode, iloc);
+               if (!err) {
+                       BUFFER_TRACE(iloc->bh, "get_write_access");
+                       err = ext4_journal_get_write_access(handle, iloc->bh);
+                       if (err) {
+                               brelse(iloc->bh);
+                               iloc->bh = NULL;
+                       }
+               }
+       }
+       ext4_std_error(inode->i_sb, err);
+       return err;
+}
+
+/*
+ * What we do here is to mark the in-core inode as clean with respect to inode
+ * dirtiness (it may still be data-dirty).
+ * This means that the in-core inode may be reaped by prune_icache
+ * without having to perform any I/O.  This is a very good thing,
+ * because *any* task may call prune_icache - even ones which
+ * have a transaction open against a different journal.
+ *
+ * Is this cheating?  Not really.  Sure, we haven't written the
+ * inode out, but prune_icache isn't a user-visible syncing function.
+ * Whenever the user wants stuff synced (sys_sync, sys_msync, sys_fsync)
+ * we start and wait on commits.
+ *
+ * Is this efficient/effective?  Well, we're being nice to the system
+ * by cleaning up our inodes proactively so they can be reaped
+ * without I/O.  But we are potentially leaving up to five seconds'
+ * worth of inodes floating about which prune_icache wants us to
+ * write out.  One way to fix that would be to get prune_icache()
+ * to do a write_super() to free up some memory.  It has the desired
+ * effect.
+ */
+int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode)
+{
+       struct ext4_iloc iloc;
+       int err;
+
+       might_sleep();
+       err = ext4_reserve_inode_write(handle, inode, &iloc);
+       if (!err)
+               err = ext4_mark_iloc_dirty(handle, inode, &iloc);
+       return err;
+}
+
+/*
+ * ext4_dirty_inode() is called from __mark_inode_dirty()
+ *
+ * We're really interested in the case where a file is being extended.
+ * i_size has been changed by generic_commit_write() and we thus need
+ * to include the updated inode in the current transaction.
+ *
+ * Also, DQUOT_ALLOC_SPACE() will always dirty the inode when blocks
+ * are allocated to the file.
+ *
+ * If the inode is marked synchronous, we don't honour that here - doing
+ * so would cause a commit on atime updates, which we don't bother doing.
+ * We handle synchronous inodes at the highest possible level.
+ */
+void ext4_dirty_inode(struct inode *inode)
+{
+       handle_t *current_handle = ext4_journal_current_handle();
+       handle_t *handle;
+
+       handle = ext4_journal_start(inode, 2);
+       if (IS_ERR(handle))
+               goto out;
+       if (current_handle &&
+               current_handle->h_transaction != handle->h_transaction) {
+               /* This task has a transaction open against a different fs */
+               printk(KERN_EMERG "%s: transactions do not match!\n",
+                      __FUNCTION__);
+       } else {
+               jbd_debug(5, "marking dirty.  outer handle=%p\n",
+                               current_handle);
+               ext4_mark_inode_dirty(handle, inode);
+       }
+       ext4_journal_stop(handle);
+out:
+       return;
+}
+
+#if 0
+/*
+ * Bind an inode's backing buffer_head into this transaction, to prevent
+ * it from being flushed to disk early.  Unlike
+ * ext4_reserve_inode_write, this leaves behind no bh reference and
+ * returns no iloc structure, so the caller needs to repeat the iloc
+ * lookup to mark the inode dirty later.
+ */
+static int ext4_pin_inode(handle_t *handle, struct inode *inode)
+{
+       struct ext4_iloc iloc;
+
+       int err = 0;
+       if (handle) {
+               err = ext4_get_inode_loc(inode, &iloc);
+               if (!err) {
+                       BUFFER_TRACE(iloc.bh, "get_write_access");
+                       err = jbd2_journal_get_write_access(handle, iloc.bh);
+                       if (!err)
+                               err = ext4_journal_dirty_metadata(handle,
+                                                                 iloc.bh);
+                       brelse(iloc.bh);
+               }
+       }
+       ext4_std_error(inode->i_sb, err);
+       return err;
+}
+#endif
+
+int ext4_change_inode_journal_flag(struct inode *inode, int val)
+{
+       journal_t *journal;
+       handle_t *handle;
+       int err;
+
+       /*
+        * We have to be very careful here: changing a data block's
+        * journaling status dynamically is dangerous.  If we write a
+        * data block to the journal, change the status and then delete
+        * that block, we risk forgetting to revoke the old log record
+        * from the journal and so a subsequent replay can corrupt data.
+        * So, first we make sure that the journal is empty and that
+        * nobody is changing anything.
+        */
+
+       journal = EXT4_JOURNAL(inode);
+       if (is_journal_aborted(journal) || IS_RDONLY(inode))
+               return -EROFS;
+
+       jbd2_journal_lock_updates(journal);
+       jbd2_journal_flush(journal);
+
+       /*
+        * OK, there are no updates running now, and all cached data is
+        * synced to disk.  We are now in a completely consistent state
+        * which doesn't have anything in the journal, and we know that
+        * no filesystem updates are running, so it is safe to modify
+        * the inode's in-core data-journaling state flag now.
+        */
+
+       if (val)
+               EXT4_I(inode)->i_flags |= EXT4_JOURNAL_DATA_FL;
+       else
+               EXT4_I(inode)->i_flags &= ~EXT4_JOURNAL_DATA_FL;
+       ext4_set_aops(inode);
+
+       jbd2_journal_unlock_updates(journal);
+
+       /* Finally we can mark the inode as dirty. */
+
+       handle = ext4_journal_start(inode, 1);
+       if (IS_ERR(handle))
+               return PTR_ERR(handle);
+
+       err = ext4_mark_inode_dirty(handle, inode);
+       handle->h_sync = 1;
+       ext4_journal_stop(handle);
+       ext4_std_error(inode->i_sb, err);
+
+       return err;
+}
diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
new file mode 100644 (file)
index 0000000..22a737c
--- /dev/null
@@ -0,0 +1,306 @@
+/*
+ * linux/fs/ext4/ioctl.c
+ *
+ * Copyright (C) 1993, 1994, 1995
+ * Remy Card (card@masi.ibp.fr)
+ * Laboratoire MASI - Institut Blaise Pascal
+ * Universite Pierre et Marie Curie (Paris VI)
+ */
+
+#include <linux/fs.h>
+#include <linux/jbd2.h>
+#include <linux/capability.h>
+#include <linux/ext4_fs.h>
+#include <linux/ext4_jbd2.h>
+#include <linux/time.h>
+#include <linux/compat.h>
+#include <linux/smp_lock.h>
+#include <asm/uaccess.h>
+
+int ext4_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
+               unsigned long arg)
+{
+       struct ext4_inode_info *ei = EXT4_I(inode);
+       unsigned int flags;
+       unsigned short rsv_window_size;
+
+       ext4_debug ("cmd = %u, arg = %lu\n", cmd, arg);
+
+       switch (cmd) {
+       case EXT4_IOC_GETFLAGS:
+               flags = ei->i_flags & EXT4_FL_USER_VISIBLE;
+               return put_user(flags, (int __user *) arg);
+       case EXT4_IOC_SETFLAGS: {
+               handle_t *handle = NULL;
+               int err;
+               struct ext4_iloc iloc;
+               unsigned int oldflags;
+               unsigned int jflag;
+
+               if (IS_RDONLY(inode))
+                       return -EROFS;
+
+               if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
+                       return -EACCES;
+
+               if (get_user(flags, (int __user *) arg))
+                       return -EFAULT;
+
+               if (!S_ISDIR(inode->i_mode))
+                       flags &= ~EXT4_DIRSYNC_FL;
+
+               mutex_lock(&inode->i_mutex);
+               oldflags = ei->i_flags;
+
+               /* The JOURNAL_DATA flag is modifiable only by root */
+               jflag = flags & EXT4_JOURNAL_DATA_FL;
+
+               /*
+                * The IMMUTABLE and APPEND_ONLY flags can only be changed by
+                * the relevant capability.
+                *
+                * This test looks nicer. Thanks to Pauline Middelink
+                */
+               if ((flags ^ oldflags) & (EXT4_APPEND_FL | EXT4_IMMUTABLE_FL)) {
+                       if (!capable(CAP_LINUX_IMMUTABLE)) {
+                               mutex_unlock(&inode->i_mutex);
+                               return -EPERM;
+                       }
+               }
+
+               /*
+                * The JOURNAL_DATA flag can only be changed by
+                * the relevant capability.
+                */
+               if ((jflag ^ oldflags) & (EXT4_JOURNAL_DATA_FL)) {
+                       if (!capable(CAP_SYS_RESOURCE)) {
+                               mutex_unlock(&inode->i_mutex);
+                               return -EPERM;
+                       }
+               }
+
+
+               handle = ext4_journal_start(inode, 1);
+               if (IS_ERR(handle)) {
+                       mutex_unlock(&inode->i_mutex);
+                       return PTR_ERR(handle);
+               }
+               if (IS_SYNC(inode))
+                       handle->h_sync = 1;
+               err = ext4_reserve_inode_write(handle, inode, &iloc);
+               if (err)
+                       goto flags_err;
+
+               flags = flags & EXT4_FL_USER_MODIFIABLE;
+               flags |= oldflags & ~EXT4_FL_USER_MODIFIABLE;
+               ei->i_flags = flags;
+
+               ext4_set_inode_flags(inode);
+               inode->i_ctime = CURRENT_TIME_SEC;
+
+               err = ext4_mark_iloc_dirty(handle, inode, &iloc);
+flags_err:
+               ext4_journal_stop(handle);
+               if (err) {
+                       mutex_unlock(&inode->i_mutex);
+                       return err;
+               }
+
+               if ((jflag ^ oldflags) & (EXT4_JOURNAL_DATA_FL))
+                       err = ext4_change_inode_journal_flag(inode, jflag);
+               mutex_unlock(&inode->i_mutex);
+               return err;
+       }
+       case EXT4_IOC_GETVERSION:
+       case EXT4_IOC_GETVERSION_OLD:
+               return put_user(inode->i_generation, (int __user *) arg);
+       case EXT4_IOC_SETVERSION:
+       case EXT4_IOC_SETVERSION_OLD: {
+               handle_t *handle;
+               struct ext4_iloc iloc;
+               __u32 generation;
+               int err;
+
+               if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
+                       return -EPERM;
+               if (IS_RDONLY(inode))
+                       return -EROFS;
+               if (get_user(generation, (int __user *) arg))
+                       return -EFAULT;
+
+               handle = ext4_journal_start(inode, 1);
+               if (IS_ERR(handle))
+                       return PTR_ERR(handle);
+               err = ext4_reserve_inode_write(handle, inode, &iloc);
+               if (err == 0) {
+                       inode->i_ctime = CURRENT_TIME_SEC;
+                       inode->i_generation = generation;
+                       err = ext4_mark_iloc_dirty(handle, inode, &iloc);
+               }
+               ext4_journal_stop(handle);
+               return err;
+       }
+#ifdef CONFIG_JBD_DEBUG
+       case EXT4_IOC_WAIT_FOR_READONLY:
+               /*
+                * This is racy - by the time we're woken up and running,
+                * the superblock could be released.  And the module could
+                * have been unloaded.  So sue me.
+                *
+                * Returns 1 if it slept, else zero.
+                */
+               {
+                       struct super_block *sb = inode->i_sb;
+                       DECLARE_WAITQUEUE(wait, current);
+                       int ret = 0;
+
+                       set_current_state(TASK_INTERRUPTIBLE);
+                       add_wait_queue(&EXT4_SB(sb)->ro_wait_queue, &wait);
+                       if (timer_pending(&EXT4_SB(sb)->turn_ro_timer)) {
+                               schedule();
+                               ret = 1;
+                       }
+                       remove_wait_queue(&EXT4_SB(sb)->ro_wait_queue, &wait);
+                       return ret;
+               }
+#endif
+       case EXT4_IOC_GETRSVSZ:
+               if (test_opt(inode->i_sb, RESERVATION)
+                       && S_ISREG(inode->i_mode)
+                       && ei->i_block_alloc_info) {
+                       rsv_window_size = ei->i_block_alloc_info->rsv_window_node.rsv_goal_size;
+                       return put_user(rsv_window_size, (int __user *)arg);
+               }
+               return -ENOTTY;
+       case EXT4_IOC_SETRSVSZ: {
+
+               if (!test_opt(inode->i_sb, RESERVATION) ||!S_ISREG(inode->i_mode))
+                       return -ENOTTY;
+
+               if (IS_RDONLY(inode))
+                       return -EROFS;
+
+               if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
+                       return -EACCES;
+
+               if (get_user(rsv_window_size, (int __user *)arg))
+                       return -EFAULT;
+
+               if (rsv_window_size > EXT4_MAX_RESERVE_BLOCKS)
+                       rsv_window_size = EXT4_MAX_RESERVE_BLOCKS;
+
+               /*
+                * need to allocate reservation structure for this inode
+                * before set the window size
+                */
+               mutex_lock(&ei->truncate_mutex);
+               if (!ei->i_block_alloc_info)
+                       ext4_init_block_alloc_info(inode);
+
+               if (ei->i_block_alloc_info){
+                       struct ext4_reserve_window_node *rsv = &ei->i_block_alloc_info->rsv_window_node;
+                       rsv->rsv_goal_size = rsv_window_size;
+               }
+               mutex_unlock(&ei->truncate_mutex);
+               return 0;
+       }
+       case EXT4_IOC_GROUP_EXTEND: {
+               ext4_fsblk_t n_blocks_count;
+               struct super_block *sb = inode->i_sb;
+               int err;
+
+               if (!capable(CAP_SYS_RESOURCE))
+                       return -EPERM;
+
+               if (IS_RDONLY(inode))
+                       return -EROFS;
+
+               if (get_user(n_blocks_count, (__u32 __user *)arg))
+                       return -EFAULT;
+
+               err = ext4_group_extend(sb, EXT4_SB(sb)->s_es, n_blocks_count);
+               jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal);
+               jbd2_journal_flush(EXT4_SB(sb)->s_journal);
+               jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal);
+
+               return err;
+       }
+       case EXT4_IOC_GROUP_ADD: {
+               struct ext4_new_group_data input;
+               struct super_block *sb = inode->i_sb;
+               int err;
+
+               if (!capable(CAP_SYS_RESOURCE))
+                       return -EPERM;
+
+               if (IS_RDONLY(inode))
+                       return -EROFS;
+
+               if (copy_from_user(&input, (struct ext4_new_group_input __user *)arg,
+                               sizeof(input)))
+                       return -EFAULT;
+
+               err = ext4_group_add(sb, &input);
+               jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal);
+               jbd2_journal_flush(EXT4_SB(sb)->s_journal);
+               jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal);
+
+               return err;
+       }
+
+       default:
+               return -ENOTTY;
+       }
+}
+
+#ifdef CONFIG_COMPAT
+long ext4_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+       struct inode *inode = file->f_dentry->d_inode;
+       int ret;
+
+       /* These are just misnamed, they actually get/put from/to user an int */
+       switch (cmd) {
+       case EXT4_IOC32_GETFLAGS:
+               cmd = EXT4_IOC_GETFLAGS;
+               break;
+       case EXT4_IOC32_SETFLAGS:
+               cmd = EXT4_IOC_SETFLAGS;
+               break;
+       case EXT4_IOC32_GETVERSION:
+               cmd = EXT4_IOC_GETVERSION;
+               break;
+       case EXT4_IOC32_SETVERSION:
+               cmd = EXT4_IOC_SETVERSION;
+               break;
+       case EXT4_IOC32_GROUP_EXTEND:
+               cmd = EXT4_IOC_GROUP_EXTEND;
+               break;
+       case EXT4_IOC32_GETVERSION_OLD:
+               cmd = EXT4_IOC_GETVERSION_OLD;
+               break;
+       case EXT4_IOC32_SETVERSION_OLD:
+               cmd = EXT4_IOC_SETVERSION_OLD;
+               break;
+#ifdef CONFIG_JBD_DEBUG
+       case EXT4_IOC32_WAIT_FOR_READONLY:
+               cmd = EXT4_IOC_WAIT_FOR_READONLY;
+               break;
+#endif
+       case EXT4_IOC32_GETRSVSZ:
+               cmd = EXT4_IOC_GETRSVSZ;
+               break;
+       case EXT4_IOC32_SETRSVSZ:
+               cmd = EXT4_IOC_SETRSVSZ;
+               break;
+       case EXT4_IOC_GROUP_ADD:
+               break;
+       default:
+               return -ENOIOCTLCMD;
+       }
+       lock_kernel();
+       ret = ext4_ioctl(inode, file, cmd, (unsigned long) compat_ptr(arg));
+       unlock_kernel();
+       return ret;
+}
+#endif
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
new file mode 100644 (file)
index 0000000..8b1bd03
--- /dev/null
@@ -0,0 +1,2395 @@
+/*
+ *  linux/fs/ext4/namei.c
+ *
+ * Copyright (C) 1992, 1993, 1994, 1995
+ * Remy Card (card@masi.ibp.fr)
+ * Laboratoire MASI - Institut Blaise Pascal
+ * Universite Pierre et Marie Curie (Paris VI)
+ *
+ *  from
+ *
+ *  linux/fs/minix/namei.c
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ *
+ *  Big-endian to little-endian byte-swapping/bitmaps by
+ *        David S. Miller (davem@caip.rutgers.edu), 1995
+ *  Directory entry file type support and forward compatibility hooks
+ *     for B-tree directories by Theodore Ts'o (tytso@mit.edu), 1998
+ *  Hash Tree Directory indexing (c)
+ *     Daniel Phillips, 2001
+ *  Hash Tree Directory indexing porting
+ *     Christopher Li, 2002
+ *  Hash Tree Directory indexing cleanup
+ *     Theodore Ts'o, 2002
+ */
+
+#include <linux/fs.h>
+#include <linux/pagemap.h>
+#include <linux/jbd2.h>
+#include <linux/time.h>
+#include <linux/ext4_fs.h>
+#include <linux/ext4_jbd2.h>
+#include <linux/fcntl.h>
+#include <linux/stat.h>
+#include <linux/string.h>
+#include <linux/quotaops.h>
+#include <linux/buffer_head.h>
+#include <linux/bio.h>
+#include <linux/smp_lock.h>
+
+#include "namei.h"
+#include "xattr.h"
+#include "acl.h"
+
+/*
+ * define how far ahead to read directories while searching them.
+ */
+#define NAMEI_RA_CHUNKS  2
+#define NAMEI_RA_BLOCKS  4
+#define NAMEI_RA_SIZE        (NAMEI_RA_CHUNKS * NAMEI_RA_BLOCKS)
+#define NAMEI_RA_INDEX(c,b)  (((c) * NAMEI_RA_BLOCKS) + (b))
+
+static struct buffer_head *ext4_append(handle_t *handle,
+                                       struct inode *inode,
+                                       u32 *block, int *err)
+{
+       struct buffer_head *bh;
+
+       *block = inode->i_size >> inode->i_sb->s_blocksize_bits;
+
+       if ((bh = ext4_bread(handle, inode, *block, 1, err))) {
+               inode->i_size += inode->i_sb->s_blocksize;
+               EXT4_I(inode)->i_disksize = inode->i_size;
+               ext4_journal_get_write_access(handle,bh);
+       }
+       return bh;
+}
+
+#ifndef assert
+#define assert(test) J_ASSERT(test)
+#endif
+
+#ifndef swap
+#define swap(x, y) do { typeof(x) z = x; x = y; y = z; } while (0)
+#endif
+
+#ifdef DX_DEBUG
+#define dxtrace(command) command
+#else
+#define dxtrace(command)
+#endif
+
+struct fake_dirent
+{
+       __le32 inode;
+       __le16 rec_len;
+       u8 name_len;
+       u8 file_type;
+};
+
+struct dx_countlimit
+{
+       __le16 limit;
+       __le16 count;
+};
+
+struct dx_entry
+{
+       __le32 hash;
+       __le32 block;
+};
+
+/*
+ * dx_root_info is laid out so that if it should somehow get overlaid by a
+ * dirent the two low bits of the hash version will be zero.  Therefore, the
+ * hash version mod 4 should never be 0.  Sincerely, the paranoia department.
+ */
+
+struct dx_root
+{
+       struct fake_dirent dot;
+       char dot_name[4];
+       struct fake_dirent dotdot;
+       char dotdot_name[4];
+       struct dx_root_info
+       {
+               __le32 reserved_zero;
+               u8 hash_version;
+               u8 info_length; /* 8 */
+               u8 indirect_levels;
+               u8 unused_flags;
+       }
+       info;
+       struct dx_entry entries[0];
+};
+
+struct dx_node
+{
+       struct fake_dirent fake;
+       struct dx_entry entries[0];
+};
+
+
+struct dx_frame
+{
+       struct buffer_head *bh;
+       struct dx_entry *entries;
+       struct dx_entry *at;
+};
+
+struct dx_map_entry
+{
+       u32 hash;
+       u32 offs;
+};
+
+#ifdef CONFIG_EXT4_INDEX
+static inline unsigned dx_get_block (struct dx_entry *entry);
+static void dx_set_block (struct dx_entry *entry, unsigned value);
+static inline unsigned dx_get_hash (struct dx_entry *entry);
+static void dx_set_hash (struct dx_entry *entry, unsigned value);
+static unsigned dx_get_count (struct dx_entry *entries);
+static unsigned dx_get_limit (struct dx_entry *entries);
+static void dx_set_count (struct dx_entry *entries, unsigned value);
+static void dx_set_limit (struct dx_entry *entries, unsigned value);
+static unsigned dx_root_limit (struct inode *dir, unsigned infosize);
+static unsigned dx_node_limit (struct inode *dir);
+static struct dx_frame *dx_probe(struct dentry *dentry,
+                                struct inode *dir,
+                                struct dx_hash_info *hinfo,
+                                struct dx_frame *frame,
+                                int *err);
+static void dx_release (struct dx_frame *frames);
+static int dx_make_map (struct ext4_dir_entry_2 *de, int size,
+                       struct dx_hash_info *hinfo, struct dx_map_entry map[]);
+static void dx_sort_map(struct dx_map_entry *map, unsigned count);
+static struct ext4_dir_entry_2 *dx_move_dirents (char *from, char *to,
+               struct dx_map_entry *offsets, int count);
+static struct ext4_dir_entry_2* dx_pack_dirents (char *base, int size);
+static void dx_insert_block (struct dx_frame *frame, u32 hash, u32 block);
+static int ext4_htree_next_block(struct inode *dir, __u32 hash,
+                                struct dx_frame *frame,
+                                struct dx_frame *frames,
+                                __u32 *start_hash);
+static struct buffer_head * ext4_dx_find_entry(struct dentry *dentry,
+                      struct ext4_dir_entry_2 **res_dir, int *err);
+static int ext4_dx_add_entry(handle_t *handle, struct dentry *dentry,
+                            struct inode *inode);
+
+/*
+ * Future: use high four bits of block for coalesce-on-delete flags
+ * Mask them off for now.
+ */
+
+static inline unsigned dx_get_block (struct dx_entry *entry)
+{
+       return le32_to_cpu(entry->block) & 0x00ffffff;
+}
+
+static inline void dx_set_block (struct dx_entry *entry, unsigned value)
+{
+       entry->block = cpu_to_le32(value);
+}
+
+static inline unsigned dx_get_hash (struct dx_entry *entry)
+{
+       return le32_to_cpu(entry->hash);
+}
+
+static inline void dx_set_hash (struct dx_entry *entry, unsigned value)
+{
+       entry->hash = cpu_to_le32(value);
+}
+
+static inline unsigned dx_get_count (struct dx_entry *entries)
+{
+       return le16_to_cpu(((struct dx_countlimit *) entries)->count);
+}
+
+static inline unsigned dx_get_limit (struct dx_entry *entries)
+{
+       return le16_to_cpu(((struct dx_countlimit *) entries)->limit);
+}
+
+static inline void dx_set_count (struct dx_entry *entries, unsigned value)
+{
+       ((struct dx_countlimit *) entries)->count = cpu_to_le16(value);
+}
+
+static inline void dx_set_limit (struct dx_entry *entries, unsigned value)
+{
+       ((struct dx_countlimit *) entries)->limit = cpu_to_le16(value);
+}
+
+static inline unsigned dx_root_limit (struct inode *dir, unsigned infosize)
+{
+       unsigned entry_space = dir->i_sb->s_blocksize - EXT4_DIR_REC_LEN(1) -
+               EXT4_DIR_REC_LEN(2) - infosize;
+       return 0? 20: entry_space / sizeof(struct dx_entry);
+}
+
+static inline unsigned dx_node_limit (struct inode *dir)
+{
+       unsigned entry_space = dir->i_sb->s_blocksize - EXT4_DIR_REC_LEN(0);
+       return 0? 22: entry_space / sizeof(struct dx_entry);
+}
+
+/*
+ * Debug
+ */
+#ifdef DX_DEBUG
+static void dx_show_index (char * label, struct dx_entry *entries)
+{
+       int i, n = dx_get_count (entries);
+        printk("%s index ", label);
+       for (i = 0; i < n; i++) {
+               printk("%x->%u ", i? dx_get_hash(entries + i) :
+                               0, dx_get_block(entries + i));
+       }
+       printk("\n");
+}
+
+struct stats
+{
+       unsigned names;
+       unsigned space;
+       unsigned bcount;
+};
+
+static struct stats dx_show_leaf(struct dx_hash_info *hinfo, struct ext4_dir_entry_2 *de,
+                                int size, int show_names)
+{
+       unsigned names = 0, space = 0;
+       char *base = (char *) de;
+       struct dx_hash_info h = *hinfo;
+
+       printk("names: ");
+       while ((char *) de < base + size)
+       {
+               if (de->inode)
+               {
+                       if (show_names)
+                       {
+                               int len = de->name_len;
+                               char *name = de->name;
+                               while (len--) printk("%c", *name++);
+                               ext4fs_dirhash(de->name, de->name_len, &h);
+                               printk(":%x.%u ", h.hash,
+                                      ((char *) de - base));
+                       }
+                       space += EXT4_DIR_REC_LEN(de->name_len);
+                       names++;
+               }
+               de = (struct ext4_dir_entry_2 *) ((char *) de + le16_to_cpu(de->rec_len));
+       }
+       printk("(%i)\n", names);
+       return (struct stats) { names, space, 1 };
+}
+
+struct stats dx_show_entries(struct dx_hash_info *hinfo, struct inode *dir,
+                            struct dx_entry *entries, int levels)
+{
+       unsigned blocksize = dir->i_sb->s_blocksize;
+       unsigned count = dx_get_count (entries), names = 0, space = 0, i;
+       unsigned bcount = 0;
+       struct buffer_head *bh;
+       int err;
+       printk("%i indexed blocks...\n", count);
+       for (i = 0; i < count; i++, entries++)
+       {
+               u32 block = dx_get_block(entries), hash = i? dx_get_hash(entries): 0;
+               u32 range = i < count - 1? (dx_get_hash(entries + 1) - hash): ~hash;
+               struct stats stats;
+               printk("%s%3u:%03u hash %8x/%8x ",levels?"":"   ", i, block, hash, range);
+               if (!(bh = ext4_bread (NULL,dir, block, 0,&err))) continue;
+               stats = levels?
+                  dx_show_entries(hinfo, dir, ((struct dx_node *) bh->b_data)->entries, levels - 1):
+                  dx_show_leaf(hinfo, (struct ext4_dir_entry_2 *) bh->b_data, blocksize, 0);
+               names += stats.names;
+               space += stats.space;
+               bcount += stats.bcount;
+               brelse (bh);
+       }
+       if (bcount)
+               printk("%snames %u, fullness %u (%u%%)\n", levels?"":"   ",
+                       names, space/bcount,(space/bcount)*100/blocksize);
+       return (struct stats) { names, space, bcount};
+}
+#endif /* DX_DEBUG */
+
+/*
+ * Probe for a directory leaf block to search.
+ *
+ * dx_probe can return ERR_BAD_DX_DIR, which means there was a format
+ * error in the directory index, and the caller should fall back to
+ * searching the directory normally.  The callers of dx_probe **MUST**
+ * check for this error code, and make sure it never gets reflected
+ * back to userspace.
+ */
+static struct dx_frame *
+dx_probe(struct dentry *dentry, struct inode *dir,
+        struct dx_hash_info *hinfo, struct dx_frame *frame_in, int *err)
+{
+       unsigned count, indirect;
+       struct dx_entry *at, *entries, *p, *q, *m;
+       struct dx_root *root;
+       struct buffer_head *bh;
+       struct dx_frame *frame = frame_in;
+       u32 hash;
+
+       frame->bh = NULL;
+       if (dentry)
+               dir = dentry->d_parent->d_inode;
+       if (!(bh = ext4_bread (NULL,dir, 0, 0, err)))
+               goto fail;
+       root = (struct dx_root *) bh->b_data;
+       if (root->info.hash_version != DX_HASH_TEA &&
+           root->info.hash_version != DX_HASH_HALF_MD4 &&
+           root->info.hash_version != DX_HASH_LEGACY) {
+               ext4_warning(dir->i_sb, __FUNCTION__,
+                            "Unrecognised inode hash code %d",
+                            root->info.hash_version);
+               brelse(bh);
+               *err = ERR_BAD_DX_DIR;
+               goto fail;
+       }
+       hinfo->hash_version = root->info.hash_version;
+       hinfo->seed = EXT4_SB(dir->i_sb)->s_hash_seed;
+       if (dentry)
+               ext4fs_dirhash(dentry->d_name.name, dentry->d_name.len, hinfo);
+       hash = hinfo->hash;
+
+       if (root->info.unused_flags & 1) {
+               ext4_warning(dir->i_sb, __FUNCTION__,
+                            "Unimplemented inode hash flags: %#06x",
+                            root->info.unused_flags);
+               brelse(bh);
+               *err = ERR_BAD_DX_DIR;
+               goto fail;
+       }
+
+       if ((indirect = root->info.indirect_levels) > 1) {
+               ext4_warning(dir->i_sb, __FUNCTION__,
+                            "Unimplemented inode hash depth: %#06x",
+                            root->info.indirect_levels);
+               brelse(bh);
+               *err = ERR_BAD_DX_DIR;
+               goto fail;
+       }
+
+       entries = (struct dx_entry *) (((char *)&root->info) +
+                                      root->info.info_length);
+       assert(dx_get_limit(entries) == dx_root_limit(dir,
+                                                     root->info.info_length));
+       dxtrace (printk("Look up %x", hash));
+       while (1)
+       {
+               count = dx_get_count(entries);
+               assert (count && count <= dx_get_limit(entries));
+               p = entries + 1;
+               q = entries + count - 1;
+               while (p <= q)
+               {
+                       m = p + (q - p)/2;
+                       dxtrace(printk("."));
+                       if (dx_get_hash(m) > hash)
+                               q = m - 1;
+                       else
+                               p = m + 1;
+               }
+
+               if (0) // linear search cross check
+               {
+                       unsigned n = count - 1;
+                       at = entries;
+                       while (n--)
+                       {
+                               dxtrace(printk(","));
+                               if (dx_get_hash(++at) > hash)
+                               {
+                                       at--;
+                                       break;
+                               }
+                       }
+                       assert (at == p - 1);
+               }
+
+               at = p - 1;
+               dxtrace(printk(" %x->%u\n", at == entries? 0: dx_get_hash(at), dx_get_block(at)));
+               frame->bh = bh;
+               frame->entries = entries;
+               frame->at = at;
+               if (!indirect--) return frame;
+               if (!(bh = ext4_bread (NULL,dir, dx_get_block(at), 0, err)))
+                       goto fail2;
+               at = entries = ((struct dx_node *) bh->b_data)->entries;
+               assert (dx_get_limit(entries) == dx_node_limit (dir));
+               frame++;
+       }
+fail2:
+       while (frame >= frame_in) {
+               brelse(frame->bh);
+               frame--;
+       }
+fail:
+       return NULL;
+}
+
+static void dx_release (struct dx_frame *frames)
+{
+       if (frames[0].bh == NULL)
+               return;
+
+       if (((struct dx_root *) frames[0].bh->b_data)->info.indirect_levels)
+               brelse(frames[1].bh);
+       brelse(frames[0].bh);
+}
+
+/*
+ * This function increments the frame pointer to search the next leaf
+ * block, and reads in the necessary intervening nodes if the search
+ * should be necessary.  Whether or not the search is necessary is
+ * controlled by the hash parameter.  If the hash value is even, then
+ * the search is only continued if the next block starts with that
+ * hash value.  This is used if we are searching for a specific file.
+ *
+ * If the hash value is HASH_NB_ALWAYS, then always go to the next block.
+ *
+ * This function returns 1 if the caller should continue to search,
+ * or 0 if it should not.  If there is an error reading one of the
+ * index blocks, it will a negative error code.
+ *
+ * If start_hash is non-null, it will be filled in with the starting
+ * hash of the next page.
+ */
+static int ext4_htree_next_block(struct inode *dir, __u32 hash,
+                                struct dx_frame *frame,
+                                struct dx_frame *frames,
+                                __u32 *start_hash)
+{
+       struct dx_frame *p;
+       struct buffer_head *bh;
+       int err, num_frames = 0;
+       __u32 bhash;
+
+       p = frame;
+       /*
+        * Find the next leaf page by incrementing the frame pointer.
+        * If we run out of entries in the interior node, loop around and
+        * increment pointer in the parent node.  When we break out of
+        * this loop, num_frames indicates the number of interior
+        * nodes need to be read.
+        */
+       while (1) {
+               if (++(p->at) < p->entries + dx_get_count(p->entries))
+                       break;
+               if (p == frames)
+                       return 0;
+               num_frames++;
+               p--;
+       }
+
+       /*
+        * If the hash is 1, then continue only if the next page has a
+        * continuation hash of any value.  This is used for readdir
+        * handling.  Otherwise, check to see if the hash matches the
+        * desired contiuation hash.  If it doesn't, return since
+        * there's no point to read in the successive index pages.
+        */
+       bhash = dx_get_hash(p->at);
+       if (start_hash)
+               *start_hash = bhash;
+       if ((hash & 1) == 0) {
+               if ((bhash & ~1) != hash)
+                       return 0;
+       }
+       /*
+        * If the hash is HASH_NB_ALWAYS, we always go to the next
+        * block so no check is necessary
+        */
+       while (num_frames--) {
+               if (!(bh = ext4_bread(NULL, dir, dx_get_block(p->at),
+                                     0, &err)))
+                       return err; /* Failure */
+               p++;
+               brelse (p->bh);
+               p->bh = bh;
+               p->at = p->entries = ((struct dx_node *) bh->b_data)->entries;
+       }
+       return 1;
+}
+
+
+/*
+ * p is at least 6 bytes before the end of page
+ */
+static inline struct ext4_dir_entry_2 *ext4_next_entry(struct ext4_dir_entry_2 *p)
+{
+       return (struct ext4_dir_entry_2 *)((char*)p + le16_to_cpu(p->rec_len));
+}
+
+/*
+ * This function fills a red-black tree with information from a
+ * directory block.  It returns the number directory entries loaded
+ * into the tree.  If there is an error it is returned in err.
+ */
+static int htree_dirblock_to_tree(struct file *dir_file,
+                                 struct inode *dir, int block,
+                                 struct dx_hash_info *hinfo,
+                                 __u32 start_hash, __u32 start_minor_hash)
+{
+       struct buffer_head *bh;
+       struct ext4_dir_entry_2 *de, *top;
+       int err, count = 0;
+
+       dxtrace(printk("In htree dirblock_to_tree: block %d\n", block));
+       if (!(bh = ext4_bread (NULL, dir, block, 0, &err)))
+               return err;
+
+       de = (struct ext4_dir_entry_2 *) bh->b_data;
+       top = (struct ext4_dir_entry_2 *) ((char *) de +
+                                          dir->i_sb->s_blocksize -
+                                          EXT4_DIR_REC_LEN(0));
+       for (; de < top; de = ext4_next_entry(de)) {
+               ext4fs_dirhash(de->name, de->name_len, hinfo);
+               if ((hinfo->hash < start_hash) ||
+                   ((hinfo->hash == start_hash) &&
+                    (hinfo->minor_hash < start_minor_hash)))
+                       continue;
+               if (de->inode == 0)
+                       continue;
+               if ((err = ext4_htree_store_dirent(dir_file,
+                                  hinfo->hash, hinfo->minor_hash, de)) != 0) {
+                       brelse(bh);
+                       return err;
+               }
+               count++;
+       }
+       brelse(bh);
+       return count;
+}
+
+
+/*
+ * This function fills a red-black tree with information from a
+ * directory.  We start scanning the directory in hash order, starting
+ * at start_hash and start_minor_hash.
+ *
+ * This function returns the number of entries inserted into the tree,
+ * or a negative error code.
+ */
+int ext4_htree_fill_tree(struct file *dir_file, __u32 start_hash,
+                        __u32 start_minor_hash, __u32 *next_hash)
+{
+       struct dx_hash_info hinfo;
+       struct ext4_dir_entry_2 *de;
+       struct dx_frame frames[2], *frame;
+       struct inode *dir;
+       int block, err;
+       int count = 0;
+       int ret;
+       __u32 hashval;
+
+       dxtrace(printk("In htree_fill_tree, start hash: %x:%x\n", start_hash,
+                      start_minor_hash));
+       dir = dir_file->f_dentry->d_inode;
+       if (!(EXT4_I(dir)->i_flags & EXT4_INDEX_FL)) {
+               hinfo.hash_version = EXT4_SB(dir->i_sb)->s_def_hash_version;
+               hinfo.seed = EXT4_SB(dir->i_sb)->s_hash_seed;
+               count = htree_dirblock_to_tree(dir_file, dir, 0, &hinfo,
+                                              start_hash, start_minor_hash);
+               *next_hash = ~0;
+               return count;
+       }
+       hinfo.hash = start_hash;
+       hinfo.minor_hash = 0;
+       frame = dx_probe(NULL, dir_file->f_dentry->d_inode, &hinfo, frames, &err);
+       if (!frame)
+               return err;
+
+       /* Add '.' and '..' from the htree header */
+       if (!start_hash && !start_minor_hash) {
+               de = (struct ext4_dir_entry_2 *) frames[0].bh->b_data;
+               if ((err = ext4_htree_store_dirent(dir_file, 0, 0, de)) != 0)
+                       goto errout;
+               count++;
+       }
+       if (start_hash < 2 || (start_hash ==2 && start_minor_hash==0)) {
+               de = (struct ext4_dir_entry_2 *) frames[0].bh->b_data;
+               de = ext4_next_entry(de);
+               if ((err = ext4_htree_store_dirent(dir_file, 2, 0, de)) != 0)
+                       goto errout;
+               count++;
+       }
+
+       while (1) {
+               block = dx_get_block(frame->at);
+               ret = htree_dirblock_to_tree(dir_file, dir, block, &hinfo,
+                                            start_hash, start_minor_hash);
+               if (ret < 0) {
+                       err = ret;
+                       goto errout;
+               }
+               count += ret;
+               hashval = ~0;
+               ret = ext4_htree_next_block(dir, HASH_NB_ALWAYS,
+                                           frame, frames, &hashval);
+               *next_hash = hashval;
+               if (ret < 0) {
+                       err = ret;
+                       goto errout;
+               }
+               /*
+                * Stop if:  (a) there are no more entries, or
+                * (b) we have inserted at least one entry and the
+                * next hash value is not a continuation
+                */
+               if ((ret == 0) ||
+                   (count && ((hashval & 1) == 0)))
+                       break;
+       }
+       dx_release(frames);
+       dxtrace(printk("Fill tree: returned %d entries, next hash: %x\n",
+                      count, *next_hash));
+       return count;
+errout:
+       dx_release(frames);
+       return (err);
+}
+
+
+/*
+ * Directory block splitting, compacting
+ */
+
+static int dx_make_map (struct ext4_dir_entry_2 *de, int size,
+                       struct dx_hash_info *hinfo, struct dx_map_entry *map_tail)
+{
+       int count = 0;
+       char *base = (char *) de;
+       struct dx_hash_info h = *hinfo;
+
+       while ((char *) de < base + size)
+       {
+               if (de->name_len && de->inode) {
+                       ext4fs_dirhash(de->name, de->name_len, &h);
+                       map_tail--;
+                       map_tail->hash = h.hash;
+                       map_tail->offs = (u32) ((char *) de - base);
+                       count++;
+                       cond_resched();
+               }
+               /* XXX: do we need to check rec_len == 0 case? -Chris */
+               de = (struct ext4_dir_entry_2 *) ((char *) de + le16_to_cpu(de->rec_len));
+       }
+       return count;
+}
+
+static void dx_sort_map (struct dx_map_entry *map, unsigned count)
+{
+       struct dx_map_entry *p, *q, *top = map + count - 1;
+       int more;
+       /* Combsort until bubble sort doesn't suck */
+       while (count > 2) {
+               count = count*10/13;
+               if (count - 9 < 2) /* 9, 10 -> 11 */
+                       count = 11;
+               for (p = top, q = p - count; q >= map; p--, q--)
+                       if (p->hash < q->hash)
+                               swap(*p, *q);
+       }
+       /* Garden variety bubble sort */
+       do {
+               more = 0;
+               q = top;
+               while (q-- > map) {
+                       if (q[1].hash >= q[0].hash)
+                               continue;
+                       swap(*(q+1), *q);
+                       more = 1;
+               }
+       } while(more);
+}
+
+static void dx_insert_block(struct dx_frame *frame, u32 hash, u32 block)
+{
+       struct dx_entry *entries = frame->entries;
+       struct dx_entry *old = frame->at, *new = old + 1;
+       int count = dx_get_count(entries);
+
+       assert(count < dx_get_limit(entries));
+       assert(old < entries + count);
+       memmove(new + 1, new, (char *)(entries + count) - (char *)(new));
+       dx_set_hash(new, hash);
+       dx_set_block(new, block);
+       dx_set_count(entries, count + 1);
+}
+#endif
+
+
+static void ext4_update_dx_flag(struct inode *inode)
+{
+       if (!EXT4_HAS_COMPAT_FEATURE(inode->i_sb,
+                                    EXT4_FEATURE_COMPAT_DIR_INDEX))
+               EXT4_I(inode)->i_flags &= ~EXT4_INDEX_FL;
+}
+
+/*
+ * NOTE! unlike strncmp, ext4_match returns 1 for success, 0 for failure.
+ *
+ * `len <= EXT4_NAME_LEN' is guaranteed by caller.
+ * `de != NULL' is guaranteed by caller.
+ */
+static inline int ext4_match (int len, const char * const name,
+                             struct ext4_dir_entry_2 * de)
+{
+       if (len != de->name_len)
+               return 0;
+       if (!de->inode)
+               return 0;
+       return !memcmp(name, de->name, len);
+}
+
+/*
+ * Returns 0 if not found, -1 on failure, and 1 on success
+ */
+static inline int search_dirblock(struct buffer_head * bh,
+                                 struct inode *dir,
+                                 struct dentry *dentry,
+                                 unsigned long offset,
+                                 struct ext4_dir_entry_2 ** res_dir)
+{
+       struct ext4_dir_entry_2 * de;
+       char * dlimit;
+       int de_len;
+       const char *name = dentry->d_name.name;
+       int namelen = dentry->d_name.len;
+
+       de = (struct ext4_dir_entry_2 *) bh->b_data;
+       dlimit = bh->b_data + dir->i_sb->s_blocksize;
+       while ((char *) de < dlimit) {
+               /* this code is executed quadratically often */
+               /* do minimal checking `by hand' */
+
+               if ((char *) de + namelen <= dlimit &&
+                   ext4_match (namelen, name, de)) {
+                       /* found a match - just to be sure, do a full check */
+                       if (!ext4_check_dir_entry("ext4_find_entry",
+                                                 dir, de, bh, offset))
+                               return -1;
+                       *res_dir = de;
+                       return 1;
+               }
+               /* prevent looping on a bad block */
+               de_len = le16_to_cpu(de->rec_len);
+               if (de_len <= 0)
+                       return -1;
+               offset += de_len;
+               de = (struct ext4_dir_entry_2 *) ((char *) de + de_len);
+       }
+       return 0;
+}
+
+
+/*
+ *     ext4_find_entry()
+ *
+ * finds an entry in the specified directory with the wanted name. It
+ * returns the cache buffer in which the entry was found, and the entry
+ * itself (as a parameter - res_dir). It does NOT read the inode of the
+ * entry - you'll have to do that yourself if you want to.
+ *
+ * The returned buffer_head has ->b_count elevated.  The caller is expected
+ * to brelse() it when appropriate.
+ */
+static struct buffer_head * ext4_find_entry (struct dentry *dentry,
+                                       struct ext4_dir_entry_2 ** res_dir)
+{
+       struct super_block * sb;
+       struct buffer_head * bh_use[NAMEI_RA_SIZE];
+       struct buffer_head * bh, *ret = NULL;
+       unsigned long start, block, b;
+       int ra_max = 0;         /* Number of bh's in the readahead
+                                  buffer, bh_use[] */
+       int ra_ptr = 0;         /* Current index into readahead
+                                  buffer */
+       int num = 0;
+       int nblocks, i, err;
+       struct inode *dir = dentry->d_parent->d_inode;
+       int namelen;
+       const u8 *name;
+       unsigned blocksize;
+
+       *res_dir = NULL;
+       sb = dir->i_sb;
+       blocksize = sb->s_blocksize;
+       namelen = dentry->d_name.len;
+       name = dentry->d_name.name;
+       if (namelen > EXT4_NAME_LEN)
+               return NULL;
+#ifdef CONFIG_EXT4_INDEX
+       if (is_dx(dir)) {
+               bh = ext4_dx_find_entry(dentry, res_dir, &err);
+               /*
+                * On success, or if the error was file not found,
+                * return.  Otherwise, fall back to doing a search the
+                * old fashioned way.
+                */
+               if (bh || (err != ERR_BAD_DX_DIR))
+                       return bh;
+               dxtrace(printk("ext4_find_entry: dx failed, falling back\n"));
+       }
+#endif
+       nblocks = dir->i_size >> EXT4_BLOCK_SIZE_BITS(sb);
+       start = EXT4_I(dir)->i_dir_start_lookup;
+       if (start >= nblocks)
+               start = 0;
+       block = start;
+restart:
+       do {
+               /*
+                * We deal with the read-ahead logic here.
+                */
+               if (ra_ptr >= ra_max) {
+                       /* Refill the readahead buffer */
+                       ra_ptr = 0;
+                       b = block;
+                       for (ra_max = 0; ra_max < NAMEI_RA_SIZE; ra_max++) {
+                               /*
+                                * Terminate if we reach the end of the
+                                * directory and must wrap, or if our
+                                * search has finished at this block.
+                                */
+                               if (b >= nblocks || (num && block == start)) {
+                                       bh_use[ra_max] = NULL;
+                                       break;
+                               }
+                               num++;
+                               bh = ext4_getblk(NULL, dir, b++, 0, &err);
+                               bh_use[ra_max] = bh;
+                               if (bh)
+                                       ll_rw_block(READ_META, 1, &bh);
+                       }
+               }
+               if ((bh = bh_use[ra_ptr++]) == NULL)
+                       goto next;
+               wait_on_buffer(bh);
+               if (!buffer_uptodate(bh)) {
+                       /* read error, skip block & hope for the best */
+                       ext4_error(sb, __FUNCTION__, "reading directory #%lu "
+                                  "offset %lu", dir->i_ino, block);
+                       brelse(bh);
+                       goto next;
+               }
+               i = search_dirblock(bh, dir, dentry,
+                           block << EXT4_BLOCK_SIZE_BITS(sb), res_dir);
+               if (i == 1) {
+                       EXT4_I(dir)->i_dir_start_lookup = block;
+                       ret = bh;
+                       goto cleanup_and_exit;
+               } else {
+                       brelse(bh);
+                       if (i < 0)
+                               goto cleanup_and_exit;
+               }
+       next:
+               if (++block >= nblocks)
+                       block = 0;
+       } while (block != start);
+
+       /*
+        * If the directory has grown while we were searching, then
+        * search the last part of the directory before giving up.
+        */
+       block = nblocks;
+       nblocks = dir->i_size >> EXT4_BLOCK_SIZE_BITS(sb);
+       if (block < nblocks) {
+               start = 0;
+               goto restart;
+       }
+
+cleanup_and_exit:
+       /* Clean up the read-ahead blocks */
+       for (; ra_ptr < ra_max; ra_ptr++)
+               brelse (bh_use[ra_ptr]);
+       return ret;
+}
+
+#ifdef CONFIG_EXT4_INDEX
+static struct buffer_head * ext4_dx_find_entry(struct dentry *dentry,
+                      struct ext4_dir_entry_2 **res_dir, int *err)
+{
+       struct super_block * sb;
+       struct dx_hash_info     hinfo;
+       u32 hash;
+       struct dx_frame frames[2], *frame;
+       struct ext4_dir_entry_2 *de, *top;
+       struct buffer_head *bh;
+       unsigned long block;
+       int retval;
+       int namelen = dentry->d_name.len;
+       const u8 *name = dentry->d_name.name;
+       struct inode *dir = dentry->d_parent->d_inode;
+
+       sb = dir->i_sb;
+       /* NFS may look up ".." - look at dx_root directory block */
+       if (namelen > 2 || name[0] != '.'||(name[1] != '.' && name[1] != '\0')){
+               if (!(frame = dx_probe(dentry, NULL, &hinfo, frames, err)))
+                       return NULL;
+       } else {
+               frame = frames;
+               frame->bh = NULL;                       /* for dx_release() */
+               frame->at = (struct dx_entry *)frames;  /* hack for zero entry*/
+               dx_set_block(frame->at, 0);             /* dx_root block is 0 */
+       }
+       hash = hinfo.hash;
+       do {
+               block = dx_get_block(frame->at);
+               if (!(bh = ext4_bread (NULL,dir, block, 0, err)))
+                       goto errout;
+               de = (struct ext4_dir_entry_2 *) bh->b_data;
+               top = (struct ext4_dir_entry_2 *) ((char *) de + sb->s_blocksize -
+                                      EXT4_DIR_REC_LEN(0));
+               for (; de < top; de = ext4_next_entry(de))
+               if (ext4_match (namelen, name, de)) {
+                       if (!ext4_check_dir_entry("ext4_find_entry",
+                                                 dir, de, bh,
+                                 (block<<EXT4_BLOCK_SIZE_BITS(sb))
+                                         +((char *)de - bh->b_data))) {
+                               brelse (bh);
+                               goto errout;
+                       }
+                       *res_dir = de;
+                       dx_release (frames);
+                       return bh;
+               }
+               brelse (bh);
+               /* Check to see if we should continue to search */
+               retval = ext4_htree_next_block(dir, hash, frame,
+                                              frames, NULL);
+               if (retval < 0) {
+                       ext4_warning(sb, __FUNCTION__,
+                            "error reading index page in directory #%lu",
+                            dir->i_ino);
+                       *err = retval;
+                       goto errout;
+               }
+       } while (retval == 1);
+
+       *err = -ENOENT;
+errout:
+       dxtrace(printk("%s not found\n", name));
+       dx_release (frames);
+       return NULL;
+}
+#endif
+
+static struct dentry *ext4_lookup(struct inode * dir, struct dentry *dentry, struct nameidata *nd)
+{
+       struct inode * inode;
+       struct ext4_dir_entry_2 * de;
+       struct buffer_head * bh;
+
+       if (dentry->d_name.len > EXT4_NAME_LEN)
+               return ERR_PTR(-ENAMETOOLONG);
+
+       bh = ext4_find_entry(dentry, &de);
+       inode = NULL;
+       if (bh) {
+               unsigned long ino = le32_to_cpu(de->inode);
+               brelse (bh);
+               if (!ext4_valid_inum(dir->i_sb, ino)) {
+                       ext4_error(dir->i_sb, "ext4_lookup",
+                                  "bad inode number: %lu", ino);
+                       inode = NULL;
+               } else
+                       inode = iget(dir->i_sb, ino);
+
+               if (!inode)
+                       return ERR_PTR(-EACCES);
+       }
+       return d_splice_alias(inode, dentry);
+}
+
+
+struct dentry *ext4_get_parent(struct dentry *child)
+{
+       unsigned long ino;
+       struct dentry *parent;
+       struct inode *inode;
+       struct dentry dotdot;
+       struct ext4_dir_entry_2 * de;
+       struct buffer_head *bh;
+
+       dotdot.d_name.name = "..";
+       dotdot.d_name.len = 2;
+       dotdot.d_parent = child; /* confusing, isn't it! */
+
+       bh = ext4_find_entry(&dotdot, &de);
+       inode = NULL;
+       if (!bh)
+               return ERR_PTR(-ENOENT);
+       ino = le32_to_cpu(de->inode);
+       brelse(bh);
+
+       if (!ext4_valid_inum(child->d_inode->i_sb, ino)) {
+               ext4_error(child->d_inode->i_sb, "ext4_get_parent",
+                          "bad inode number: %lu", ino);
+               inode = NULL;
+       } else
+               inode = iget(child->d_inode->i_sb, ino);
+
+       if (!inode)
+               return ERR_PTR(-EACCES);
+
+       parent = d_alloc_anon(inode);
+       if (!parent) {
+               iput(inode);
+               parent = ERR_PTR(-ENOMEM);
+       }
+       return parent;
+}
+
+#define S_SHIFT 12
+static unsigned char ext4_type_by_mode[S_IFMT >> S_SHIFT] = {
+       [S_IFREG >> S_SHIFT]    = EXT4_FT_REG_FILE,
+       [S_IFDIR >> S_SHIFT]    = EXT4_FT_DIR,
+       [S_IFCHR >> S_SHIFT]    = EXT4_FT_CHRDEV,
+       [S_IFBLK >> S_SHIFT]    = EXT4_FT_BLKDEV,
+       [S_IFIFO >> S_SHIFT]    = EXT4_FT_FIFO,
+       [S_IFSOCK >> S_SHIFT]   = EXT4_FT_SOCK,
+       [S_IFLNK >> S_SHIFT]    = EXT4_FT_SYMLINK,
+};
+
+static inline void ext4_set_de_type(struct super_block *sb,
+                               struct ext4_dir_entry_2 *de,
+                               umode_t mode) {
+       if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FILETYPE))
+               de->file_type = ext4_type_by_mode[(mode & S_IFMT)>>S_SHIFT];
+}
+
+#ifdef CONFIG_EXT4_INDEX
+static struct ext4_dir_entry_2 *
+dx_move_dirents(char *from, char *to, struct dx_map_entry *map, int count)
+{
+       unsigned rec_len = 0;
+
+       while (count--) {
+               struct ext4_dir_entry_2 *de = (struct ext4_dir_entry_2 *) (from + map->offs);
+               rec_len = EXT4_DIR_REC_LEN(de->name_len);
+               memcpy (to, de, rec_len);
+               ((struct ext4_dir_entry_2 *) to)->rec_len =
+                               cpu_to_le16(rec_len);
+               de->inode = 0;
+               map++;
+               to += rec_len;
+       }
+       return (struct ext4_dir_entry_2 *) (to - rec_len);
+}
+
+static struct ext4_dir_entry_2* dx_pack_dirents(char *base, int size)
+{
+       struct ext4_dir_entry_2 *next, *to, *prev, *de = (struct ext4_dir_entry_2 *) base;
+       unsigned rec_len = 0;
+
+       prev = to = de;
+       while ((char*)de < base + size) {
+               next = (struct ext4_dir_entry_2 *) ((char *) de +
+                                                   le16_to_cpu(de->rec_len));
+               if (de->inode && de->name_len) {
+                       rec_len = EXT4_DIR_REC_LEN(de->name_len);
+                       if (de > to)
+                               memmove(to, de, rec_len);
+                       to->rec_len = cpu_to_le16(rec_len);
+                       prev = to;
+                       to = (struct ext4_dir_entry_2 *) (((char *) to) + rec_len);
+               }
+               de = next;
+       }
+       return prev;
+}
+
+static struct ext4_dir_entry_2 *do_split(handle_t *handle, struct inode *dir,
+                       struct buffer_head **bh,struct dx_frame *frame,
+                       struct dx_hash_info *hinfo, int *error)
+{
+       unsigned blocksize = dir->i_sb->s_blocksize;
+       unsigned count, continued;
+       struct buffer_head *bh2;
+       u32 newblock;
+       u32 hash2;
+       struct dx_map_entry *map;
+       char *data1 = (*bh)->b_data, *data2;
+       unsigned split;
+       struct ext4_dir_entry_2 *de = NULL, *de2;
+       int     err;
+
+       bh2 = ext4_append (handle, dir, &newblock, error);
+       if (!(bh2)) {
+               brelse(*bh);
+               *bh = NULL;
+               goto errout;
+       }
+
+       BUFFER_TRACE(*bh, "get_write_access");
+       err = ext4_journal_get_write_access(handle, *bh);
+       if (err) {
+       journal_error:
+               brelse(*bh);
+               brelse(bh2);
+               *bh = NULL;
+               ext4_std_error(dir->i_sb, err);
+               goto errout;
+       }
+       BUFFER_TRACE(frame->bh, "get_write_access");
+       err = ext4_journal_get_write_access(handle, frame->bh);
+       if (err)
+               goto journal_error;
+
+       data2 = bh2->b_data;
+
+       /* create map in the end of data2 block */
+       map = (struct dx_map_entry *) (data2 + blocksize);
+       count = dx_make_map ((struct ext4_dir_entry_2 *) data1,
+                            blocksize, hinfo, map);
+       map -= count;
+       split = count/2; // need to adjust to actual middle
+       dx_sort_map (map, count);
+       hash2 = map[split].hash;
+       continued = hash2 == map[split - 1].hash;
+       dxtrace(printk("Split block %i at %x, %i/%i\n",
+               dx_get_block(frame->at), hash2, split, count-split));
+
+       /* Fancy dance to stay within two buffers */
+       de2 = dx_move_dirents(data1, data2, map + split, count - split);
+       de = dx_pack_dirents(data1,blocksize);
+       de->rec_len = cpu_to_le16(data1 + blocksize - (char *) de);
+       de2->rec_len = cpu_to_le16(data2 + blocksize - (char *) de2);
+       dxtrace(dx_show_leaf (hinfo, (struct ext4_dir_entry_2 *) data1, blocksize, 1));
+       dxtrace(dx_show_leaf (hinfo, (struct ext4_dir_entry_2 *) data2, blocksize, 1));
+
+       /* Which block gets the new entry? */
+       if (hinfo->hash >= hash2)
+       {
+               swap(*bh, bh2);
+               de = de2;
+       }
+       dx_insert_block (frame, hash2 + continued, newblock);
+       err = ext4_journal_dirty_metadata (handle, bh2);
+       if (err)
+               goto journal_error;
+       err = ext4_journal_dirty_metadata (handle, frame->bh);
+       if (err)
+               goto journal_error;
+       brelse (bh2);
+       dxtrace(dx_show_index ("frame", frame->entries));
+errout:
+       return de;
+}
+#endif
+
+
+/*
+ * Add a new entry into a directory (leaf) block.  If de is non-NULL,
+ * it points to a directory entry which is guaranteed to be large
+ * enough for new directory entry.  If de is NULL, then
+ * add_dirent_to_buf will attempt search the directory block for
+ * space.  It will return -ENOSPC if no space is available, and -EIO
+ * and -EEXIST if directory entry already exists.
+ *
+ * NOTE!  bh is NOT released in the case where ENOSPC is returned.  In
+ * all other cases bh is released.
+ */
+static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry,
+                            struct inode *inode, struct ext4_dir_entry_2 *de,
+                            struct buffer_head * bh)
+{
+       struct inode    *dir = dentry->d_parent->d_inode;
+       const char      *name = dentry->d_name.name;
+       int             namelen = dentry->d_name.len;
+       unsigned long   offset = 0;
+       unsigned short  reclen;
+       int             nlen, rlen, err;
+       char            *top;
+
+       reclen = EXT4_DIR_REC_LEN(namelen);
+       if (!de) {
+               de = (struct ext4_dir_entry_2 *)bh->b_data;
+               top = bh->b_data + dir->i_sb->s_blocksize - reclen;
+               while ((char *) de <= top) {
+                       if (!ext4_check_dir_entry("ext4_add_entry", dir, de,
+                                                 bh, offset)) {
+                               brelse (bh);
+                               return -EIO;
+                       }
+                       if (ext4_match (namelen, name, de)) {
+                               brelse (bh);
+                               return -EEXIST;
+                       }
+                       nlen = EXT4_DIR_REC_LEN(de->name_len);
+                       rlen = le16_to_cpu(de->rec_len);
+                       if ((de->inode? rlen - nlen: rlen) >= reclen)
+                               break;
+                       de = (struct ext4_dir_entry_2 *)((char *)de + rlen);
+                       offset += rlen;
+               }
+               if ((char *) de > top)
+                       return -ENOSPC;
+       }
+       BUFFER_TRACE(bh, "get_write_access");
+       err = ext4_journal_get_write_access(handle, bh);
+       if (err) {
+               ext4_std_error(dir->i_sb, err);
+               brelse(bh);
+               return err;
+       }
+
+       /* By now the buffer is marked for journaling */
+       nlen = EXT4_DIR_REC_LEN(de->name_len);
+       rlen = le16_to_cpu(de->rec_len);
+       if (de->inode) {
+               struct ext4_dir_entry_2 *de1 = (struct ext4_dir_entry_2 *)((char *)de + nlen);
+               de1->rec_len = cpu_to_le16(rlen - nlen);
+               de->rec_len = cpu_to_le16(nlen);
+               de = de1;
+       }
+       de->file_type = EXT4_FT_UNKNOWN;
+       if (inode) {
+               de->inode = cpu_to_le32(inode->i_ino);
+               ext4_set_de_type(dir->i_sb, de, inode->i_mode);
+       } else
+               de->inode = 0;
+       de->name_len = namelen;
+       memcpy (de->name, name, namelen);
+       /*
+        * XXX shouldn't update any times until successful
+        * completion of syscall, but too many callers depend
+        * on this.
+        *
+        * XXX similarly, too many callers depend on
+        * ext4_new_inode() setting the times, but error
+        * recovery deletes the inode, so the worst that can
+        * happen is that the times are slightly out of date
+        * and/or different from the directory change time.
+        */
+       dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
+       ext4_update_dx_flag(dir);
+       dir->i_version++;
+       ext4_mark_inode_dirty(handle, dir);
+       BUFFER_TRACE(bh, "call ext4_journal_dirty_metadata");
+       err = ext4_journal_dirty_metadata(handle, bh);
+       if (err)
+               ext4_std_error(dir->i_sb, err);
+       brelse(bh);
+       return 0;
+}
+
+#ifdef CONFIG_EXT4_INDEX
+/*
+ * This converts a one block unindexed directory to a 3 block indexed
+ * directory, and adds the dentry to the indexed directory.
+ */
+static int make_indexed_dir(handle_t *handle, struct dentry *dentry,
+                           struct inode *inode, struct buffer_head *bh)
+{
+       struct inode    *dir = dentry->d_parent->d_inode;
+       const char      *name = dentry->d_name.name;
+       int             namelen = dentry->d_name.len;
+       struct buffer_head *bh2;
+       struct dx_root  *root;
+       struct dx_frame frames[2], *frame;
+       struct dx_entry *entries;
+       struct ext4_dir_entry_2 *de, *de2;
+       char            *data1, *top;
+       unsigned        len;
+       int             retval;
+       unsigned        blocksize;
+       struct dx_hash_info hinfo;
+       u32             block;
+       struct fake_dirent *fde;
+
+       blocksize =  dir->i_sb->s_blocksize;
+       dxtrace(printk("Creating index\n"));
+       retval = ext4_journal_get_write_access(handle, bh);
+       if (retval) {
+               ext4_std_error(dir->i_sb, retval);
+               brelse(bh);
+               return retval;
+       }
+       root = (struct dx_root *) bh->b_data;
+
+       bh2 = ext4_append (handle, dir, &block, &retval);
+       if (!(bh2)) {
+               brelse(bh);
+               return retval;
+       }
+       EXT4_I(dir)->i_flags |= EXT4_INDEX_FL;
+       data1 = bh2->b_data;
+
+       /* The 0th block becomes the root, move the dirents out */
+       fde = &root->dotdot;
+       de = (struct ext4_dir_entry_2 *)((char *)fde + le16_to_cpu(fde->rec_len));
+       len = ((char *) root) + blocksize - (char *) de;
+       memcpy (data1, de, len);
+       de = (struct ext4_dir_entry_2 *) data1;
+       top = data1 + len;
+       while ((char *)(de2=(void*)de+le16_to_cpu(de->rec_len)) < top)
+               de = de2;
+       de->rec_len = cpu_to_le16(data1 + blocksize - (char *) de);
+       /* Initialize the root; the dot dirents already exist */
+       de = (struct ext4_dir_entry_2 *) (&root->dotdot);
+       de->rec_len = cpu_to_le16(blocksize - EXT4_DIR_REC_LEN(2));
+       memset (&root->info, 0, sizeof(root->info));
+       root->info.info_length = sizeof(root->info);
+       root->info.hash_version = EXT4_SB(dir->i_sb)->s_def_hash_version;
+       entries = root->entries;
+       dx_set_block (entries, 1);
+       dx_set_count (entries, 1);
+       dx_set_limit (entries, dx_root_limit(dir, sizeof(root->info)));
+
+       /* Initialize as for dx_probe */
+       hinfo.hash_version = root->info.hash_version;
+       hinfo.seed = EXT4_SB(dir->i_sb)->s_hash_seed;
+       ext4fs_dirhash(name, namelen, &hinfo);
+       frame = frames;
+       frame->entries = entries;
+       frame->at = entries;
+       frame->bh = bh;
+       bh = bh2;
+       de = do_split(handle,dir, &bh, frame, &hinfo, &retval);
+       dx_release (frames);
+       if (!(de))
+               return retval;
+
+       return add_dirent_to_buf(handle, dentry, inode, de, bh);
+}
+#endif
+
+/*
+ *     ext4_add_entry()
+ *
+ * adds a file entry to the specified directory, using the same
+ * semantics as ext4_find_entry(). It returns NULL if it failed.
+ *
+ * NOTE!! The inode part of 'de' is left at 0 - which means you
+ * may not sleep between calling this and putting something into
+ * the entry, as someone else might have used it while you slept.
+ */
+static int ext4_add_entry (handle_t *handle, struct dentry *dentry,
+       struct inode *inode)
+{
+       struct inode *dir = dentry->d_parent->d_inode;
+       unsigned long offset;
+       struct buffer_head * bh;
+       struct ext4_dir_entry_2 *de;
+       struct super_block * sb;
+       int     retval;
+#ifdef CONFIG_EXT4_INDEX
+       int     dx_fallback=0;
+#endif
+       unsigned blocksize;
+       u32 block, blocks;
+
+       sb = dir->i_sb;
+       blocksize = sb->s_blocksize;
+       if (!dentry->d_name.len)
+               return -EINVAL;
+#ifdef CONFIG_EXT4_INDEX
+       if (is_dx(dir)) {
+               retval = ext4_dx_add_entry(handle, dentry, inode);
+               if (!retval || (retval != ERR_BAD_DX_DIR))
+                       return retval;
+               EXT4_I(dir)->i_flags &= ~EXT4_INDEX_FL;
+               dx_fallback++;
+               ext4_mark_inode_dirty(handle, dir);
+       }
+#endif
+       blocks = dir->i_size >> sb->s_blocksize_bits;
+       for (block = 0, offset = 0; block < blocks; block++) {
+               bh = ext4_bread(handle, dir, block, 0, &retval);
+               if(!bh)
+                       return retval;
+               retval = add_dirent_to_buf(handle, dentry, inode, NULL, bh);
+               if (retval != -ENOSPC)
+                       return retval;
+
+#ifdef CONFIG_EXT4_INDEX
+               if (blocks == 1 && !dx_fallback &&
+                   EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_DIR_INDEX))
+                       return make_indexed_dir(handle, dentry, inode, bh);
+#endif
+               brelse(bh);
+       }
+       bh = ext4_append(handle, dir, &block, &retval);
+       if (!bh)
+               return retval;
+       de = (struct ext4_dir_entry_2 *) bh->b_data;
+       de->inode = 0;
+       de->rec_len = cpu_to_le16(blocksize);
+       return add_dirent_to_buf(handle, dentry, inode, de, bh);
+}
+
+#ifdef CONFIG_EXT4_INDEX
+/*
+ * Returns 0 for success, or a negative error value
+ */
+static int ext4_dx_add_entry(handle_t *handle, struct dentry *dentry,
+                            struct inode *inode)
+{
+       struct dx_frame frames[2], *frame;
+       struct dx_entry *entries, *at;
+       struct dx_hash_info hinfo;
+       struct buffer_head * bh;
+       struct inode *dir = dentry->d_parent->d_inode;
+       struct super_block * sb = dir->i_sb;
+       struct ext4_dir_entry_2 *de;
+       int err;
+
+       frame = dx_probe(dentry, NULL, &hinfo, frames, &err);
+       if (!frame)
+               return err;
+       entries = frame->entries;
+       at = frame->at;
+
+       if (!(bh = ext4_bread(handle,dir, dx_get_block(frame->at), 0, &err)))
+               goto cleanup;
+
+       BUFFER_TRACE(bh, "get_write_access");
+       err = ext4_journal_get_write_access(handle, bh);
+       if (err)
+               goto journal_error;
+
+       err = add_dirent_to_buf(handle, dentry, inode, NULL, bh);
+       if (err != -ENOSPC) {
+               bh = NULL;
+               goto cleanup;
+       }
+
+       /* Block full, should compress but for now just split */
+       dxtrace(printk("using %u of %u node entries\n",
+                      dx_get_count(entries), dx_get_limit(entries)));
+       /* Need to split index? */
+       if (dx_get_count(entries) == dx_get_limit(entries)) {
+               u32 newblock;
+               unsigned icount = dx_get_count(entries);
+               int levels = frame - frames;
+               struct dx_entry *entries2;
+               struct dx_node *node2;
+               struct buffer_head *bh2;
+
+               if (levels && (dx_get_count(frames->entries) ==
+                              dx_get_limit(frames->entries))) {
+                       ext4_warning(sb, __FUNCTION__,
+                                    "Directory index full!");
+                       err = -ENOSPC;
+                       goto cleanup;
+               }
+               bh2 = ext4_append (handle, dir, &newblock, &err);
+               if (!(bh2))
+                       goto cleanup;
+               node2 = (struct dx_node *)(bh2->b_data);
+               entries2 = node2->entries;
+               node2->fake.rec_len = cpu_to_le16(sb->s_blocksize);
+               node2->fake.inode = 0;
+               BUFFER_TRACE(frame->bh, "get_write_access");
+               err = ext4_journal_get_write_access(handle, frame->bh);
+               if (err)
+                       goto journal_error;
+               if (levels) {
+                       unsigned icount1 = icount/2, icount2 = icount - icount1;
+                       unsigned hash2 = dx_get_hash(entries + icount1);
+                       dxtrace(printk("Split index %i/%i\n", icount1, icount2));
+
+                       BUFFER_TRACE(frame->bh, "get_write_access"); /* index root */
+                       err = ext4_journal_get_write_access(handle,
+                                                            frames[0].bh);
+                       if (err)
+                               goto journal_error;
+
+                       memcpy ((char *) entries2, (char *) (entries + icount1),
+                               icount2 * sizeof(struct dx_entry));
+                       dx_set_count (entries, icount1);
+                       dx_set_count (entries2, icount2);
+                       dx_set_limit (entries2, dx_node_limit(dir));
+
+                       /* Which index block gets the new entry? */
+                       if (at - entries >= icount1) {
+                               frame->at = at = at - entries - icount1 + entries2;
+                               frame->entries = entries = entries2;
+                               swap(frame->bh, bh2);
+                       }
+                       dx_insert_block (frames + 0, hash2, newblock);
+                       dxtrace(dx_show_index ("node", frames[1].entries));
+                       dxtrace(dx_show_index ("node",
+                              ((struct dx_node *) bh2->b_data)->entries));
+                       err = ext4_journal_dirty_metadata(handle, bh2);
+                       if (err)
+                               goto journal_error;
+                       brelse (bh2);
+               } else {
+                       dxtrace(printk("Creating second level index...\n"));
+                       memcpy((char *) entries2, (char *) entries,
+                              icount * sizeof(struct dx_entry));
+                       dx_set_limit(entries2, dx_node_limit(dir));
+
+                       /* Set up root */
+                       dx_set_count(entries, 1);
+                       dx_set_block(entries + 0, newblock);
+                       ((struct dx_root *) frames[0].bh->b_data)->info.indirect_levels = 1;
+
+                       /* Add new access path frame */
+                       frame = frames + 1;
+                       frame->at = at = at - entries + entries2;
+                       frame->entries = entries = entries2;
+                       frame->bh = bh2;
+                       err = ext4_journal_get_write_access(handle,
+                                                            frame->bh);
+                       if (err)
+                               goto journal_error;
+               }
+               ext4_journal_dirty_metadata(handle, frames[0].bh);
+       }
+       de = do_split(handle, dir, &bh, frame, &hinfo, &err);
+       if (!de)
+               goto cleanup;
+       err = add_dirent_to_buf(handle, dentry, inode, de, bh);
+       bh = NULL;
+       goto cleanup;
+
+journal_error:
+       ext4_std_error(dir->i_sb, err);
+cleanup:
+       if (bh)
+               brelse(bh);
+       dx_release(frames);
+       return err;
+}
+#endif
+
+/*
+ * ext4_delete_entry deletes a directory entry by merging it with the
+ * previous entry
+ */
+static int ext4_delete_entry (handle_t *handle,
+                             struct inode * dir,
+                             struct ext4_dir_entry_2 * de_del,
+                             struct buffer_head * bh)
+{
+       struct ext4_dir_entry_2 * de, * pde;
+       int i;
+
+       i = 0;
+       pde = NULL;
+       de = (struct ext4_dir_entry_2 *) bh->b_data;
+       while (i < bh->b_size) {
+               if (!ext4_check_dir_entry("ext4_delete_entry", dir, de, bh, i))
+                       return -EIO;
+               if (de == de_del)  {
+                       BUFFER_TRACE(bh, "get_write_access");
+                       ext4_journal_get_write_access(handle, bh);
+                       if (pde)
+                               pde->rec_len =
+                                       cpu_to_le16(le16_to_cpu(pde->rec_len) +
+                                                   le16_to_cpu(de->rec_len));
+                       else
+                               de->inode = 0;
+                       dir->i_version++;
+                       BUFFER_TRACE(bh, "call ext4_journal_dirty_metadata");
+                       ext4_journal_dirty_metadata(handle, bh);
+                       return 0;
+               }
+               i += le16_to_cpu(de->rec_len);
+               pde = de;
+               de = (struct ext4_dir_entry_2 *)
+                       ((char *) de + le16_to_cpu(de->rec_len));
+       }
+       return -ENOENT;
+}
+
+/*
+ * ext4_mark_inode_dirty is somewhat expensive, so unlike ext2 we
+ * do not perform it in these functions.  We perform it at the call site,
+ * if it is needed.
+ */
+static inline void ext4_inc_count(handle_t *handle, struct inode *inode)
+{
+       inc_nlink(inode);
+}
+
+static inline void ext4_dec_count(handle_t *handle, struct inode *inode)
+{
+       drop_nlink(inode);
+}
+
+static int ext4_add_nondir(handle_t *handle,
+               struct dentry *dentry, struct inode *inode)
+{
+       int err = ext4_add_entry(handle, dentry, inode);
+       if (!err) {
+               ext4_mark_inode_dirty(handle, inode);
+               d_instantiate(dentry, inode);
+               return 0;
+       }
+       ext4_dec_count(handle, inode);
+       iput(inode);
+       return err;
+}
+
+/*
+ * By the time this is called, we already have created
+ * the directory cache entry for the new file, but it
+ * is so far negative - it has no inode.
+ *
+ * If the create succeeds, we fill in the inode information
+ * with d_instantiate().
+ */
+static int ext4_create (struct inode * dir, struct dentry * dentry, int mode,
+               struct nameidata *nd)
+{
+       handle_t *handle;
+       struct inode * inode;
+       int err, retries = 0;
+
+retry:
+       handle = ext4_journal_start(dir, EXT4_DATA_TRANS_BLOCKS(dir->i_sb) +
+                                       EXT4_INDEX_EXTRA_TRANS_BLOCKS + 3 +
+                                       2*EXT4_QUOTA_INIT_BLOCKS(dir->i_sb));
+       if (IS_ERR(handle))
+               return PTR_ERR(handle);
+
+       if (IS_DIRSYNC(dir))
+               handle->h_sync = 1;
+
+       inode = ext4_new_inode (handle, dir, mode);
+       err = PTR_ERR(inode);
+       if (!IS_ERR(inode)) {
+               inode->i_op = &ext4_file_inode_operations;
+               inode->i_fop = &ext4_file_operations;
+               ext4_set_aops(inode);
+               err = ext4_add_nondir(handle, dentry, inode);
+       }
+       ext4_journal_stop(handle);
+       if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries))
+               goto retry;
+       return err;
+}
+
+static int ext4_mknod (struct inode * dir, struct dentry *dentry,
+                       int mode, dev_t rdev)
+{
+       handle_t *handle;
+       struct inode *inode;
+       int err, retries = 0;
+
+       if (!new_valid_dev(rdev))
+               return -EINVAL;
+
+retry:
+       handle = ext4_journal_start(dir, EXT4_DATA_TRANS_BLOCKS(dir->i_sb) +
+                                       EXT4_INDEX_EXTRA_TRANS_BLOCKS + 3 +
+                                       2*EXT4_QUOTA_INIT_BLOCKS(dir->i_sb));
+       if (IS_ERR(handle))
+               return PTR_ERR(handle);
+
+       if (IS_DIRSYNC(dir))
+               handle->h_sync = 1;
+
+       inode = ext4_new_inode (handle, dir, mode);
+       err = PTR_ERR(inode);
+       if (!IS_ERR(inode)) {
+               init_special_inode(inode, inode->i_mode, rdev);
+#ifdef CONFIG_EXT4DEV_FS_XATTR
+               inode->i_op = &ext4_special_inode_operations;
+#endif
+               err = ext4_add_nondir(handle, dentry, inode);
+       }
+       ext4_journal_stop(handle);
+       if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries))
+               goto retry;
+       return err;
+}
+
+static int ext4_mkdir(struct inode * dir, struct dentry * dentry, int mode)
+{
+       handle_t *handle;
+       struct inode * inode;
+       struct buffer_head * dir_block;
+       struct ext4_dir_entry_2 * de;
+       int err, retries = 0;
+
+       if (dir->i_nlink >= EXT4_LINK_MAX)
+               return -EMLINK;
+
+retry:
+       handle = ext4_journal_start(dir, EXT4_DATA_TRANS_BLOCKS(dir->i_sb) +
+                                       EXT4_INDEX_EXTRA_TRANS_BLOCKS + 3 +
+                                       2*EXT4_QUOTA_INIT_BLOCKS(dir->i_sb));
+       if (IS_ERR(handle))
+               return PTR_ERR(handle);
+
+       if (IS_DIRSYNC(dir))
+               handle->h_sync = 1;
+
+       inode = ext4_new_inode (handle, dir, S_IFDIR | mode);
+       err = PTR_ERR(inode);
+       if (IS_ERR(inode))
+               goto out_stop;
+
+       inode->i_op = &ext4_dir_inode_operations;
+       inode->i_fop = &ext4_dir_operations;
+       inode->i_size = EXT4_I(inode)->i_disksize = inode->i_sb->s_blocksize;
+       dir_block = ext4_bread (handle, inode, 0, 1, &err);
+       if (!dir_block) {
+               drop_nlink(inode); /* is this nlink == 0? */
+               ext4_mark_inode_dirty(handle, inode);
+               iput (inode);
+               goto out_stop;
+       }
+       BUFFER_TRACE(dir_block, "get_write_access");
+       ext4_journal_get_write_access(handle, dir_block);
+       de = (struct ext4_dir_entry_2 *) dir_block->b_data;
+       de->inode = cpu_to_le32(inode->i_ino);
+       de->name_len = 1;
+       de->rec_len = cpu_to_le16(EXT4_DIR_REC_LEN(de->name_len));
+       strcpy (de->name, ".");
+       ext4_set_de_type(dir->i_sb, de, S_IFDIR);
+       de = (struct ext4_dir_entry_2 *)
+                       ((char *) de + le16_to_cpu(de->rec_len));
+       de->inode = cpu_to_le32(dir->i_ino);
+       de->rec_len = cpu_to_le16(inode->i_sb->s_blocksize-EXT4_DIR_REC_LEN(1));
+       de->name_len = 2;
+       strcpy (de->name, "..");
+       ext4_set_de_type(dir->i_sb, de, S_IFDIR);
+       inode->i_nlink = 2;
+       BUFFER_TRACE(dir_block, "call ext4_journal_dirty_metadata");
+       ext4_journal_dirty_metadata(handle, dir_block);
+       brelse (dir_block);
+       ext4_mark_inode_dirty(handle, inode);
+       err = ext4_add_entry (handle, dentry, inode);
+       if (err) {
+               inode->i_nlink = 0;
+               ext4_mark_inode_dirty(handle, inode);
+               iput (inode);
+               goto out_stop;
+       }
+       inc_nlink(dir);
+       ext4_update_dx_flag(dir);
+       ext4_mark_inode_dirty(handle, dir);
+       d_instantiate(dentry, inode);
+out_stop:
+       ext4_journal_stop(handle);
+       if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries))
+               goto retry;
+       return err;
+}
+
+/*
+ * routine to check that the specified directory is empty (for rmdir)
+ */
+static int empty_dir (struct inode * inode)
+{
+       unsigned long offset;
+       struct buffer_head * bh;
+       struct ext4_dir_entry_2 * de, * de1;
+       struct super_block * sb;
+       int err = 0;
+
+       sb = inode->i_sb;
+       if (inode->i_size < EXT4_DIR_REC_LEN(1) + EXT4_DIR_REC_LEN(2) ||
+           !(bh = ext4_bread (NULL, inode, 0, 0, &err))) {
+               if (err)
+                       ext4_error(inode->i_sb, __FUNCTION__,
+                                  "error %d reading directory #%lu offset 0",
+                                  err, inode->i_ino);
+               else
+                       ext4_warning(inode->i_sb, __FUNCTION__,
+                                    "bad directory (dir #%lu) - no data block",
+                                    inode->i_ino);
+               return 1;
+       }
+       de = (struct ext4_dir_entry_2 *) bh->b_data;
+       de1 = (struct ext4_dir_entry_2 *)
+                       ((char *) de + le16_to_cpu(de->rec_len));
+       if (le32_to_cpu(de->inode) != inode->i_ino ||
+                       !le32_to_cpu(de1->inode) ||
+                       strcmp (".", de->name) ||
+                       strcmp ("..", de1->name)) {
+               ext4_warning (inode->i_sb, "empty_dir",
+                             "bad directory (dir #%lu) - no `.' or `..'",
+                             inode->i_ino);
+               brelse (bh);
+               return 1;
+       }
+       offset = le16_to_cpu(de->rec_len) + le16_to_cpu(de1->rec_len);
+       de = (struct ext4_dir_entry_2 *)
+                       ((char *) de1 + le16_to_cpu(de1->rec_len));
+       while (offset < inode->i_size ) {
+               if (!bh ||
+                       (void *) de >= (void *) (bh->b_data+sb->s_blocksize)) {
+                       err = 0;
+                       brelse (bh);
+                       bh = ext4_bread (NULL, inode,
+                               offset >> EXT4_BLOCK_SIZE_BITS(sb), 0, &err);
+                       if (!bh) {
+                               if (err)
+                                       ext4_error(sb, __FUNCTION__,
+                                                  "error %d reading directory"
+                                                  " #%lu offset %lu",
+                                                  err, inode->i_ino, offset);
+                               offset += sb->s_blocksize;
+                               continue;
+                       }
+                       de = (struct ext4_dir_entry_2 *) bh->b_data;
+               }
+               if (!ext4_check_dir_entry("empty_dir", inode, de, bh, offset)) {
+                       de = (struct ext4_dir_entry_2 *)(bh->b_data +
+                                                        sb->s_blocksize);
+                       offset = (offset | (sb->s_blocksize - 1)) + 1;
+                       continue;
+               }
+               if (le32_to_cpu(de->inode)) {
+                       brelse (bh);
+                       return 0;
+               }
+               offset += le16_to_cpu(de->rec_len);
+               de = (struct ext4_dir_entry_2 *)
+                               ((char *) de + le16_to_cpu(de->rec_len));
+       }
+       brelse (bh);
+       return 1;
+}
+
+/* ext4_orphan_add() links an unlinked or truncated inode into a list of
+ * such inodes, starting at the superblock, in case we crash before the
+ * file is closed/deleted, or in case the inode truncate spans multiple
+ * transactions and the last transaction is not recovered after a crash.
+ *
+ * At filesystem recovery time, we walk this list deleting unlinked
+ * inodes and truncating linked inodes in ext4_orphan_cleanup().
+ */
+int ext4_orphan_add(handle_t *handle, struct inode *inode)
+{
+       struct super_block *sb = inode->i_sb;
+       struct ext4_iloc iloc;
+       int err = 0, rc;
+
+       lock_super(sb);
+       if (!list_empty(&EXT4_I(inode)->i_orphan))
+               goto out_unlock;
+
+       /* Orphan handling is only valid for files with data blocks
+        * being truncated, or files being unlinked. */
+
+       /* @@@ FIXME: Observation from aviro:
+        * I think I can trigger J_ASSERT in ext4_orphan_add().  We block
+        * here (on lock_super()), so race with ext4_link() which might bump
+        * ->i_nlink. For, say it, character device. Not a regular file,
+        * not a directory, not a symlink and ->i_nlink > 0.
+        */
+       J_ASSERT ((S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
+               S_ISLNK(inode->i_mode)) || inode->i_nlink == 0);
+
+       BUFFER_TRACE(EXT4_SB(sb)->s_sbh, "get_write_access");
+       err = ext4_journal_get_write_access(handle, EXT4_SB(sb)->s_sbh);
+       if (err)
+               goto out_unlock;
+
+       err = ext4_reserve_inode_write(handle, inode, &iloc);
+       if (err)
+               goto out_unlock;
+
+       /* Insert this inode at the head of the on-disk orphan list... */
+       NEXT_ORPHAN(inode) = le32_to_cpu(EXT4_SB(sb)->s_es->s_last_orphan);
+       EXT4_SB(sb)->s_es->s_last_orphan = cpu_to_le32(inode->i_ino);
+       err = ext4_journal_dirty_metadata(handle, EXT4_SB(sb)->s_sbh);
+       rc = ext4_mark_iloc_dirty(handle, inode, &iloc);
+       if (!err)
+               err = rc;
+
+       /* Only add to the head of the in-memory list if all the
+        * previous operations succeeded.  If the orphan_add is going to
+        * fail (possibly taking the journal offline), we can't risk
+        * leaving the inode on the orphan list: stray orphan-list
+        * entries can cause panics at unmount time.
+        *
+        * This is safe: on error we're going to ignore the orphan list
+        * anyway on the next recovery. */
+       if (!err)
+               list_add(&EXT4_I(inode)->i_orphan, &EXT4_SB(sb)->s_orphan);
+
+       jbd_debug(4, "superblock will point to %lu\n", inode->i_ino);
+       jbd_debug(4, "orphan inode %lu will point to %d\n",
+                       inode->i_ino, NEXT_ORPHAN(inode));
+out_unlock:
+       unlock_super(sb);
+       ext4_std_error(inode->i_sb, err);
+       return err;
+}
+
+/*
+ * ext4_orphan_del() removes an unlinked or truncated inode from the list
+ * of such inodes stored on disk, because it is finally being cleaned up.
+ */
+int ext4_orphan_del(handle_t *handle, struct inode *inode)
+{
+       struct list_head *prev;
+       struct ext4_inode_info *ei = EXT4_I(inode);
+       struct ext4_sb_info *sbi;
+       unsigned long ino_next;
+       struct ext4_iloc iloc;
+       int err = 0;
+
+       lock_super(inode->i_sb);
+       if (list_empty(&ei->i_orphan)) {
+               unlock_super(inode->i_sb);
+               return 0;
+       }
+
+       ino_next = NEXT_ORPHAN(inode);
+       prev = ei->i_orphan.prev;
+       sbi = EXT4_SB(inode->i_sb);
+
+       jbd_debug(4, "remove inode %lu from orphan list\n", inode->i_ino);
+
+       list_del_init(&ei->i_orphan);
+
+       /* If we're on an error path, we may not have a valid
+        * transaction handle with which to update the orphan list on
+        * disk, but we still need to remove the inode from the linked
+        * list in memory. */
+       if (!handle)
+               goto out;
+
+       err = ext4_reserve_inode_write(handle, inode, &iloc);
+       if (err)
+               goto out_err;
+
+       if (prev == &sbi->s_orphan) {
+               jbd_debug(4, "superblock will point to %lu\n", ino_next);
+               BUFFER_TRACE(sbi->s_sbh, "get_write_access");
+               err = ext4_journal_get_write_access(handle, sbi->s_sbh);
+               if (err)
+                       goto out_brelse;
+               sbi->s_es->s_last_orphan = cpu_to_le32(ino_next);
+               err = ext4_journal_dirty_metadata(handle, sbi->s_sbh);
+       } else {
+               struct ext4_iloc iloc2;
+               struct inode *i_prev =
+                       &list_entry(prev, struct ext4_inode_info, i_orphan)->vfs_inode;
+
+               jbd_debug(4, "orphan inode %lu will point to %lu\n",
+                         i_prev->i_ino, ino_next);
+               err = ext4_reserve_inode_write(handle, i_prev, &iloc2);
+               if (err)
+                       goto out_brelse;
+               NEXT_ORPHAN(i_prev) = ino_next;
+               err = ext4_mark_iloc_dirty(handle, i_prev, &iloc2);
+       }
+       if (err)
+               goto out_brelse;
+       NEXT_ORPHAN(inode) = 0;
+       err = ext4_mark_iloc_dirty(handle, inode, &iloc);
+
+out_err:
+       ext4_std_error(inode->i_sb, err);
+out:
+       unlock_super(inode->i_sb);
+       return err;
+
+out_brelse:
+       brelse(iloc.bh);
+       goto out_err;
+}
+
+static int ext4_rmdir (struct inode * dir, struct dentry *dentry)
+{
+       int retval;
+       struct inode * inode;
+       struct buffer_head * bh;
+       struct ext4_dir_entry_2 * de;
+       handle_t *handle;
+
+       /* Initialize quotas before so that eventual writes go in
+        * separate transaction */
+       DQUOT_INIT(dentry->d_inode);
+       handle = ext4_journal_start(dir, EXT4_DELETE_TRANS_BLOCKS(dir->i_sb));
+       if (IS_ERR(handle))
+               return PTR_ERR(handle);
+
+       retval = -ENOENT;
+       bh = ext4_find_entry (dentry, &de);
+       if (!bh)
+               goto end_rmdir;
+
+       if (IS_DIRSYNC(dir))
+               handle->h_sync = 1;
+
+       inode = dentry->d_inode;
+
+       retval = -EIO;
+       if (le32_to_cpu(de->inode) != inode->i_ino)
+               goto end_rmdir;
+
+       retval = -ENOTEMPTY;
+       if (!empty_dir (inode))
+               goto end_rmdir;
+
+       retval = ext4_delete_entry(handle, dir, de, bh);
+       if (retval)
+               goto end_rmdir;
+       if (inode->i_nlink != 2)
+               ext4_warning (inode->i_sb, "ext4_rmdir",
+                             "empty directory has nlink!=2 (%d)",
+                             inode->i_nlink);
+       inode->i_version++;
+       clear_nlink(inode);
+       /* There's no need to set i_disksize: the fact that i_nlink is
+        * zero will ensure that the right thing happens during any
+        * recovery. */
+       inode->i_size = 0;
+       ext4_orphan_add(handle, inode);
+       inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
+       ext4_mark_inode_dirty(handle, inode);
+       drop_nlink(dir);
+       ext4_update_dx_flag(dir);
+       ext4_mark_inode_dirty(handle, dir);
+
+end_rmdir:
+       ext4_journal_stop(handle);
+       brelse (bh);
+       return retval;
+}
+
+static int ext4_unlink(struct inode * dir, struct dentry *dentry)
+{
+       int retval;
+       struct inode * inode;
+       struct buffer_head * bh;
+       struct ext4_dir_entry_2 * de;
+       handle_t *handle;
+
+       /* Initialize quotas before so that eventual writes go
+        * in separate transaction */
+       DQUOT_INIT(dentry->d_inode);
+       handle = ext4_journal_start(dir, EXT4_DELETE_TRANS_BLOCKS(dir->i_sb));
+       if (IS_ERR(handle))
+               return PTR_ERR(handle);
+
+       if (IS_DIRSYNC(dir))
+               handle->h_sync = 1;
+
+       retval = -ENOENT;
+       bh = ext4_find_entry (dentry, &de);
+       if (!bh)
+               goto end_unlink;
+
+       inode = dentry->d_inode;
+
+       retval = -EIO;
+       if (le32_to_cpu(de->inode) != inode->i_ino)
+               goto end_unlink;
+
+       if (!inode->i_nlink) {
+               ext4_warning (inode->i_sb, "ext4_unlink",
+                             "Deleting nonexistent file (%lu), %d",
+                             inode->i_ino, inode->i_nlink);
+               inode->i_nlink = 1;
+       }
+       retval = ext4_delete_entry(handle, dir, de, bh);
+       if (retval)
+               goto end_unlink;
+       dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
+       ext4_update_dx_flag(dir);
+       ext4_mark_inode_dirty(handle, dir);
+       drop_nlink(inode);
+       if (!inode->i_nlink)
+               ext4_orphan_add(handle, inode);
+       inode->i_ctime = dir->i_ctime;
+       ext4_mark_inode_dirty(handle, inode);
+       retval = 0;
+
+end_unlink:
+       ext4_journal_stop(handle);
+       brelse (bh);
+       return retval;
+}
+
+static int ext4_symlink (struct inode * dir,
+               struct dentry *dentry, const char * symname)
+{
+       handle_t *handle;
+       struct inode * inode;
+       int l, err, retries = 0;
+
+       l = strlen(symname)+1;
+       if (l > dir->i_sb->s_blocksize)
+               return -ENAMETOOLONG;
+
+retry:
+       handle = ext4_journal_start(dir, EXT4_DATA_TRANS_BLOCKS(dir->i_sb) +
+                                       EXT4_INDEX_EXTRA_TRANS_BLOCKS + 5 +
+                                       2*EXT4_QUOTA_INIT_BLOCKS(dir->i_sb));
+       if (IS_ERR(handle))
+               return PTR_ERR(handle);
+
+       if (IS_DIRSYNC(dir))
+               handle->h_sync = 1;
+
+       inode = ext4_new_inode (handle, dir, S_IFLNK|S_IRWXUGO);
+       err = PTR_ERR(inode);
+       if (IS_ERR(inode))
+               goto out_stop;
+
+       if (l > sizeof (EXT4_I(inode)->i_data)) {
+               inode->i_op = &ext4_symlink_inode_operations;
+               ext4_set_aops(inode);
+               /*
+                * page_symlink() calls into ext4_prepare/commit_write.
+                * We have a transaction open.  All is sweetness.  It also sets
+                * i_size in generic_commit_write().
+                */
+               err = __page_symlink(inode, symname, l,
+                               mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS);
+               if (err) {
+                       ext4_dec_count(handle, inode);
+                       ext4_mark_inode_dirty(handle, inode);
+                       iput (inode);
+                       goto out_stop;
+               }
+       } else {
+               inode->i_op = &ext4_fast_symlink_inode_operations;
+               memcpy((char*)&EXT4_I(inode)->i_data,symname,l);
+               inode->i_size = l-1;
+       }
+       EXT4_I(inode)->i_disksize = inode->i_size;
+       err = ext4_add_nondir(handle, dentry, inode);
+out_stop:
+       ext4_journal_stop(handle);
+       if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries))
+               goto retry;
+       return err;
+}
+
+static int ext4_link (struct dentry * old_dentry,
+               struct inode * dir, struct dentry *dentry)
+{
+       handle_t *handle;
+       struct inode *inode = old_dentry->d_inode;
+       int err, retries = 0;
+
+       if (inode->i_nlink >= EXT4_LINK_MAX)
+               return -EMLINK;
+
+retry:
+       handle = ext4_journal_start(dir, EXT4_DATA_TRANS_BLOCKS(dir->i_sb) +
+                                       EXT4_INDEX_EXTRA_TRANS_BLOCKS);
+       if (IS_ERR(handle))
+               return PTR_ERR(handle);
+
+       if (IS_DIRSYNC(dir))
+               handle->h_sync = 1;
+
+       inode->i_ctime = CURRENT_TIME_SEC;
+       ext4_inc_count(handle, inode);
+       atomic_inc(&inode->i_count);
+
+       err = ext4_add_nondir(handle, dentry, inode);
+       ext4_journal_stop(handle);
+       if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries))
+               goto retry;
+       return err;
+}
+
+#define PARENT_INO(buffer) \
+       ((struct ext4_dir_entry_2 *) ((char *) buffer + \
+       le16_to_cpu(((struct ext4_dir_entry_2 *) buffer)->rec_len)))->inode
+
+/*
+ * Anybody can rename anything with this: the permission checks are left to the
+ * higher-level routines.
+ */
+static int ext4_rename (struct inode * old_dir, struct dentry *old_dentry,
+                          struct inode * new_dir,struct dentry *new_dentry)
+{
+       handle_t *handle;
+       struct inode * old_inode, * new_inode;
+       struct buffer_head * old_bh, * new_bh, * dir_bh;
+       struct ext4_dir_entry_2 * old_de, * new_de;
+       int retval;
+
+       old_bh = new_bh = dir_bh = NULL;
+
+       /* Initialize quotas before so that eventual writes go
+        * in separate transaction */
+       if (new_dentry->d_inode)
+               DQUOT_INIT(new_dentry->d_inode);
+       handle = ext4_journal_start(old_dir, 2 *
+                                       EXT4_DATA_TRANS_BLOCKS(old_dir->i_sb) +
+                                       EXT4_INDEX_EXTRA_TRANS_BLOCKS + 2);
+       if (IS_ERR(handle))
+               return PTR_ERR(handle);
+
+       if (IS_DIRSYNC(old_dir) || IS_DIRSYNC(new_dir))
+               handle->h_sync = 1;
+
+       old_bh = ext4_find_entry (old_dentry, &old_de);
+       /*
+        *  Check for inode number is _not_ due to possible IO errors.
+        *  We might rmdir the source, keep it as pwd of some process
+        *  and merrily kill the link to whatever was created under the
+        *  same name. Goodbye sticky bit ;-<
+        */
+       old_inode = old_dentry->d_inode;
+       retval = -ENOENT;
+       if (!old_bh || le32_to_cpu(old_de->inode) != old_inode->i_ino)
+               goto end_rename;
+
+       new_inode = new_dentry->d_inode;
+       new_bh = ext4_find_entry (new_dentry, &new_de);
+       if (new_bh) {
+               if (!new_inode) {
+                       brelse (new_bh);
+                       new_bh = NULL;
+               }
+       }
+       if (S_ISDIR(old_inode->i_mode)) {
+               if (new_inode) {
+                       retval = -ENOTEMPTY;
+                       if (!empty_dir (new_inode))
+                               goto end_rename;
+               }
+               retval = -EIO;
+               dir_bh = ext4_bread (handle, old_inode, 0, 0, &retval);
+               if (!dir_bh)
+                       goto end_rename;
+               if (le32_to_cpu(PARENT_INO(dir_bh->b_data)) != old_dir->i_ino)
+                       goto end_rename;
+               retval = -EMLINK;
+               if (!new_inode && new_dir!=old_dir &&
+                               new_dir->i_nlink >= EXT4_LINK_MAX)
+                       goto end_rename;
+       }
+       if (!new_bh) {
+               retval = ext4_add_entry (handle, new_dentry, old_inode);
+               if (retval)
+                       goto end_rename;
+       } else {
+               BUFFER_TRACE(new_bh, "get write access");
+               ext4_journal_get_write_access(handle, new_bh);
+               new_de->inode = cpu_to_le32(old_inode->i_ino);
+               if (EXT4_HAS_INCOMPAT_FEATURE(new_dir->i_sb,
+                                             EXT4_FEATURE_INCOMPAT_FILETYPE))
+                       new_de->file_type = old_de->file_type;
+               new_dir->i_version++;
+               BUFFER_TRACE(new_bh, "call ext4_journal_dirty_metadata");
+               ext4_journal_dirty_metadata(handle, new_bh);
+               brelse(new_bh);
+               new_bh = NULL;
+       }
+
+       /*
+        * Like most other Unix systems, set the ctime for inodes on a
+        * rename.
+        */
+       old_inode->i_ctime = CURRENT_TIME_SEC;
+       ext4_mark_inode_dirty(handle, old_inode);
+
+       /*
+        * ok, that's it
+        */
+       if (le32_to_cpu(old_de->inode) != old_inode->i_ino ||
+           old_de->name_len != old_dentry->d_name.len ||
+           strncmp(old_de->name, old_dentry->d_name.name, old_de->name_len) ||
+           (retval = ext4_delete_entry(handle, old_dir,
+                                       old_de, old_bh)) == -ENOENT) {
+               /* old_de could have moved from under us during htree split, so
+                * make sure that we are deleting the right entry.  We might
+                * also be pointing to a stale entry in the unused part of
+                * old_bh so just checking inum and the name isn't enough. */
+               struct buffer_head *old_bh2;
+               struct ext4_dir_entry_2 *old_de2;
+
+               old_bh2 = ext4_find_entry(old_dentry, &old_de2);
+               if (old_bh2) {
+                       retval = ext4_delete_entry(handle, old_dir,
+                                                  old_de2, old_bh2);
+                       brelse(old_bh2);
+               }
+       }
+       if (retval) {
+               ext4_warning(old_dir->i_sb, "ext4_rename",
+                               "Deleting old file (%lu), %d, error=%d",
+                               old_dir->i_ino, old_dir->i_nlink, retval);
+       }
+
+       if (new_inode) {
+               drop_nlink(new_inode);
+               new_inode->i_ctime = CURRENT_TIME_SEC;
+       }
+       old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME_SEC;
+       ext4_update_dx_flag(old_dir);
+       if (dir_bh) {
+               BUFFER_TRACE(dir_bh, "get_write_access");
+               ext4_journal_get_write_access(handle, dir_bh);
+               PARENT_INO(dir_bh->b_data) = cpu_to_le32(new_dir->i_ino);
+               BUFFER_TRACE(dir_bh, "call ext4_journal_dirty_metadata");
+               ext4_journal_dirty_metadata(handle, dir_bh);
+               drop_nlink(old_dir);
+               if (new_inode) {
+                       drop_nlink(new_inode);
+               } else {
+                       inc_nlink(new_dir);
+                       ext4_update_dx_flag(new_dir);
+                       ext4_mark_inode_dirty(handle, new_dir);
+               }
+       }
+       ext4_mark_inode_dirty(handle, old_dir);
+       if (new_inode) {
+               ext4_mark_inode_dirty(handle, new_inode);
+               if (!new_inode->i_nlink)
+                       ext4_orphan_add(handle, new_inode);
+       }
+       retval = 0;
+
+end_rename:
+       brelse (dir_bh);
+       brelse (old_bh);
+       brelse (new_bh);
+       ext4_journal_stop(handle);
+       return retval;
+}
+
+/*
+ * directories can handle most operations...
+ */
+struct inode_operations ext4_dir_inode_operations = {
+       .create         = ext4_create,
+       .lookup         = ext4_lookup,
+       .link           = ext4_link,
+       .unlink         = ext4_unlink,
+       .symlink        = ext4_symlink,
+       .mkdir          = ext4_mkdir,
+       .rmdir          = ext4_rmdir,
+       .mknod          = ext4_mknod,
+       .rename         = ext4_rename,
+       .setattr        = ext4_setattr,
+#ifdef CONFIG_EXT4DEV_FS_XATTR
+       .setxattr       = generic_setxattr,
+       .getxattr       = generic_getxattr,
+       .listxattr      = ext4_listxattr,
+       .removexattr    = generic_removexattr,
+#endif
+       .permission     = ext4_permission,
+};
+
+struct inode_operations ext4_special_inode_operations = {
+       .setattr        = ext4_setattr,
+#ifdef CONFIG_EXT4DEV_FS_XATTR
+       .setxattr       = generic_setxattr,
+       .getxattr       = generic_getxattr,
+       .listxattr      = ext4_listxattr,
+       .removexattr    = generic_removexattr,
+#endif
+       .permission     = ext4_permission,
+};
diff --git a/fs/ext4/namei.h b/fs/ext4/namei.h
new file mode 100644 (file)
index 0000000..5e4dfff
--- /dev/null
@@ -0,0 +1,8 @@
+/*  linux/fs/ext4/namei.h
+ *
+ * Copyright (C) 2005 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+*/
+
+extern struct dentry *ext4_get_parent(struct dentry *child);
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
new file mode 100644 (file)
index 0000000..1e95780
--- /dev/null
@@ -0,0 +1,1045 @@
+/*
+ *  linux/fs/ext4/resize.c
+ *
+ * Support for resizing an ext4 filesystem while it is mounted.
+ *
+ * Copyright (C) 2001, 2002 Andreas Dilger <adilger@clusterfs.com>
+ *
+ * This could probably be made into a module, because it is not often in use.
+ */
+
+
+#define EXT4FS_DEBUG
+
+#include <linux/sched.h>
+#include <linux/smp_lock.h>
+#include <linux/ext4_jbd2.h>
+
+#include <linux/errno.h>
+#include <linux/slab.h>
+
+
+#define outside(b, first, last)        ((b) < (first) || (b) >= (last))
+#define inside(b, first, last) ((b) >= (first) && (b) < (last))
+
+static int verify_group_input(struct super_block *sb,
+                             struct ext4_new_group_data *input)
+{
+       struct ext4_sb_info *sbi = EXT4_SB(sb);
+       struct ext4_super_block *es = sbi->s_es;
+       ext4_fsblk_t start = ext4_blocks_count(es);
+       ext4_fsblk_t end = start + input->blocks_count;
+       unsigned group = input->group;
+       ext4_fsblk_t itend = input->inode_table + sbi->s_itb_per_group;
+       unsigned overhead = ext4_bg_has_super(sb, group) ?
+               (1 + ext4_bg_num_gdb(sb, group) +
+                le16_to_cpu(es->s_reserved_gdt_blocks)) : 0;
+       ext4_fsblk_t metaend = start + overhead;
+       struct buffer_head *bh = NULL;
+       ext4_grpblk_t free_blocks_count, offset;
+       int err = -EINVAL;
+
+       input->free_blocks_count = free_blocks_count =
+               input->blocks_count - 2 - overhead - sbi->s_itb_per_group;
+
+       if (test_opt(sb, DEBUG))
+               printk(KERN_DEBUG "EXT4-fs: adding %s group %u: %u blocks "
+                      "(%d free, %u reserved)\n",
+                      ext4_bg_has_super(sb, input->group) ? "normal" :
+                      "no-super", input->group, input->blocks_count,
+                      free_blocks_count, input->reserved_blocks);
+
+       ext4_get_group_no_and_offset(sb, start, NULL, &offset);
+       if (group != sbi->s_groups_count)
+               ext4_warning(sb, __FUNCTION__,
+                            "Cannot add at group %u (only %lu groups)",
+                            input->group, sbi->s_groups_count);
+       else if (offset != 0)
+                       ext4_warning(sb, __FUNCTION__, "Last group not full");
+       else if (input->reserved_blocks > input->blocks_count / 5)
+               ext4_warning(sb, __FUNCTION__, "Reserved blocks too high (%u)",
+                            input->reserved_blocks);
+       else if (free_blocks_count < 0)
+               ext4_warning(sb, __FUNCTION__, "Bad blocks count %u",
+                            input->blocks_count);
+       else if (!(bh = sb_bread(sb, end - 1)))
+               ext4_warning(sb, __FUNCTION__,
+                            "Cannot read last block (%llu)",
+                            end - 1);
+       else if (outside(input->block_bitmap, start, end))
+               ext4_warning(sb, __FUNCTION__,
+                            "Block bitmap not in group (block %llu)",
+                            input->block_bitmap);
+       else if (outside(input->inode_bitmap, start, end))
+               ext4_warning(sb, __FUNCTION__,
+                            "Inode bitmap not in group (block %llu)",
+                            input->inode_bitmap);
+       else if (outside(input->inode_table, start, end) ||
+                outside(itend - 1, start, end))
+               ext4_warning(sb, __FUNCTION__,
+                            "Inode table not in group (blocks %llu-%llu)",
+                            input->inode_table, itend - 1);
+       else if (input->inode_bitmap == input->block_bitmap)
+               ext4_warning(sb, __FUNCTION__,
+                            "Block bitmap same as inode bitmap (%llu)",
+                            input->block_bitmap);
+       else if (inside(input->block_bitmap, input->inode_table, itend))
+               ext4_warning(sb, __FUNCTION__,
+                            "Block bitmap (%llu) in inode table (%llu-%llu)",
+                            input->block_bitmap, input->inode_table, itend-1);
+       else if (inside(input->inode_bitmap, input->inode_table, itend))
+               ext4_warning(sb, __FUNCTION__,
+                            "Inode bitmap (%llu) in inode table (%llu-%llu)",
+                            input->inode_bitmap, input->inode_table, itend-1);
+       else if (inside(input->block_bitmap, start, metaend))
+               ext4_warning(sb, __FUNCTION__,
+                            "Block bitmap (%llu) in GDT table"
+                            " (%llu-%llu)",
+                            input->block_bitmap, start, metaend - 1);
+       else if (inside(input->inode_bitmap, start, metaend))
+               ext4_warning(sb, __FUNCTION__,
+                            "Inode bitmap (%llu) in GDT table"
+                            " (%llu-%llu)",
+                            input->inode_bitmap, start, metaend - 1);
+       else if (inside(input->inode_table, start, metaend) ||
+                inside(itend - 1, start, metaend))
+               ext4_warning(sb, __FUNCTION__,
+                            "Inode table (%llu-%llu) overlaps"
+                            "GDT table (%llu-%llu)",
+                            input->inode_table, itend - 1, start, metaend - 1);
+       else
+               err = 0;
+       brelse(bh);
+
+       return err;
+}
+
+static struct buffer_head *bclean(handle_t *handle, struct super_block *sb,
+                                 ext4_fsblk_t blk)
+{
+       struct buffer_head *bh;
+       int err;
+
+       bh = sb_getblk(sb, blk);
+       if (!bh)
+               return ERR_PTR(-EIO);
+       if ((err = ext4_journal_get_write_access(handle, bh))) {
+               brelse(bh);
+               bh = ERR_PTR(err);
+       } else {
+               lock_buffer(bh);
+               memset(bh->b_data, 0, sb->s_blocksize);
+               set_buffer_uptodate(bh);
+               unlock_buffer(bh);
+       }
+
+       return bh;
+}
+
+/*
+ * To avoid calling the atomic setbit hundreds or thousands of times, we only
+ * need to use it within a single byte (to ensure we get endianness right).
+ * We can use memset for the rest of the bitmap as there are no other users.
+ */
+static void mark_bitmap_end(int start_bit, int end_bit, char *bitmap)
+{
+       int i;
+
+       if (start_bit >= end_bit)
+               return;
+
+       ext4_debug("mark end bits +%d through +%d used\n", start_bit, end_bit);
+       for (i = start_bit; i < ((start_bit + 7) & ~7UL); i++)
+               ext4_set_bit(i, bitmap);
+       if (i < end_bit)
+               memset(bitmap + (i >> 3), 0xff, (end_bit - i) >> 3);
+}
+
+/*
+ * Set up the block and inode bitmaps, and the inode table for the new group.
+ * This doesn't need to be part of the main transaction, since we are only
+ * changing blocks outside the actual filesystem.  We still do journaling to
+ * ensure the recovery is correct in case of a failure just after resize.
+ * If any part of this fails, we simply abort the resize.
+ */
+static int setup_new_group_blocks(struct super_block *sb,
+                                 struct ext4_new_group_data *input)
+{
+       struct ext4_sb_info *sbi = EXT4_SB(sb);
+       ext4_fsblk_t start = ext4_group_first_block_no(sb, input->group);
+       int reserved_gdb = ext4_bg_has_super(sb, input->group) ?
+               le16_to_cpu(sbi->s_es->s_reserved_gdt_blocks) : 0;
+       unsigned long gdblocks = ext4_bg_num_gdb(sb, input->group);
+       struct buffer_head *bh;
+       handle_t *handle;
+       ext4_fsblk_t block;
+       ext4_grpblk_t bit;
+       int i;
+       int err = 0, err2;
+
+       handle = ext4_journal_start_sb(sb, reserved_gdb + gdblocks +
+                                      2 + sbi->s_itb_per_group);
+       if (IS_ERR(handle))
+               return PTR_ERR(handle);
+
+       lock_super(sb);
+       if (input->group != sbi->s_groups_count) {
+               err = -EBUSY;
+               goto exit_journal;
+       }
+
+       if (IS_ERR(bh = bclean(handle, sb, input->block_bitmap))) {
+               err = PTR_ERR(bh);
+               goto exit_journal;
+       }
+
+       if (ext4_bg_has_super(sb, input->group)) {
+               ext4_debug("mark backup superblock %#04lx (+0)\n", start);
+               ext4_set_bit(0, bh->b_data);
+       }
+
+       /* Copy all of the GDT blocks into the backup in this group */
+       for (i = 0, bit = 1, block = start + 1;
+            i < gdblocks; i++, block++, bit++) {
+               struct buffer_head *gdb;
+
+               ext4_debug("update backup group %#04lx (+%d)\n", block, bit);
+
+               gdb = sb_getblk(sb, block);
+               if (!gdb) {
+                       err = -EIO;
+                       goto exit_bh;
+               }
+               if ((err = ext4_journal_get_write_access(handle, gdb))) {
+                       brelse(gdb);
+                       goto exit_bh;
+               }
+               lock_buffer(bh);
+               memcpy(gdb->b_data, sbi->s_group_desc[i]->b_data, bh->b_size);
+               set_buffer_uptodate(gdb);
+               unlock_buffer(bh);
+               ext4_journal_dirty_metadata(handle, gdb);
+               ext4_set_bit(bit, bh->b_data);
+               brelse(gdb);
+       }
+
+       /* Zero out all of the reserved backup group descriptor table blocks */
+       for (i = 0, bit = gdblocks + 1, block = start + bit;
+            i < reserved_gdb; i++, block++, bit++) {
+               struct buffer_head *gdb;
+
+               ext4_debug("clear reserved block %#04lx (+%d)\n", block, bit);
+
+               if (IS_ERR(gdb = bclean(handle, sb, block))) {
+                       err = PTR_ERR(bh);
+                       goto exit_bh;
+               }
+               ext4_journal_dirty_metadata(handle, gdb);
+               ext4_set_bit(bit, bh->b_data);
+               brelse(gdb);
+       }
+       ext4_debug("mark block bitmap %#04x (+%ld)\n", input->block_bitmap,
+                  input->block_bitmap - start);
+       ext4_set_bit(input->block_bitmap - start, bh->b_data);
+       ext4_debug("mark inode bitmap %#04x (+%ld)\n", input->inode_bitmap,
+                  input->inode_bitmap - start);
+       ext4_set_bit(input->inode_bitmap - start, bh->b_data);
+
+       /* Zero out all of the inode table blocks */
+       for (i = 0, block = input->inode_table, bit = block - start;
+            i < sbi->s_itb_per_group; i++, bit++, block++) {
+               struct buffer_head *it;
+
+               ext4_debug("clear inode block %#04lx (+%d)\n", block, bit);
+               if (IS_ERR(it = bclean(handle, sb, block))) {
+                       err = PTR_ERR(it);
+                       goto exit_bh;
+               }
+               ext4_journal_dirty_metadata(handle, it);
+               brelse(it);
+               ext4_set_bit(bit, bh->b_data);
+       }
+       mark_bitmap_end(input->blocks_count, EXT4_BLOCKS_PER_GROUP(sb),
+                       bh->b_data);
+       ext4_journal_dirty_metadata(handle, bh);
+       brelse(bh);
+
+       /* Mark unused entries in inode bitmap used */
+       ext4_debug("clear inode bitmap %#04x (+%ld)\n",
+                  input->inode_bitmap, input->inode_bitmap - start);
+       if (IS_ERR(bh = bclean(handle, sb, input->inode_bitmap))) {
+               err = PTR_ERR(bh);
+               goto exit_journal;
+       }
+
+       mark_bitmap_end(EXT4_INODES_PER_GROUP(sb), EXT4_BLOCKS_PER_GROUP(sb),
+                       bh->b_data);
+       ext4_journal_dirty_metadata(handle, bh);
+exit_bh:
+       brelse(bh);
+
+exit_journal:
+       unlock_super(sb);
+       if ((err2 = ext4_journal_stop(handle)) && !err)
+               err = err2;
+
+       return err;
+}
+
+
+/*
+ * Iterate through the groups which hold BACKUP superblock/GDT copies in an
+ * ext4 filesystem.  The counters should be initialized to 1, 5, and 7 before
+ * calling this for the first time.  In a sparse filesystem it will be the
+ * sequence of powers of 3, 5, and 7: 1, 3, 5, 7, 9, 25, 27, 49, 81, ...
+ * For a non-sparse filesystem it will be every group: 1, 2, 3, 4, ...
+ */
+static unsigned ext4_list_backups(struct super_block *sb, unsigned *three,
+                                 unsigned *five, unsigned *seven)
+{
+       unsigned *min = three;
+       int mult = 3;
+       unsigned ret;
+
+       if (!EXT4_HAS_RO_COMPAT_FEATURE(sb,
+                                       EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER)) {
+               ret = *min;
+               *min += 1;
+               return ret;
+       }
+
+       if (*five < *min) {
+               min = five;
+               mult = 5;
+       }
+       if (*seven < *min) {
+               min = seven;
+               mult = 7;
+       }
+
+       ret = *min;
+       *min *= mult;
+
+       return ret;
+}
+
+/*
+ * Check that all of the backup GDT blocks are held in the primary GDT block.
+ * It is assumed that they are stored in group order.  Returns the number of
+ * groups in current filesystem that have BACKUPS, or -ve error code.
+ */
+static int verify_reserved_gdb(struct super_block *sb,
+                              struct buffer_head *primary)
+{
+       const ext4_fsblk_t blk = primary->b_blocknr;
+       const unsigned long end = EXT4_SB(sb)->s_groups_count;
+       unsigned three = 1;
+       unsigned five = 5;
+       unsigned seven = 7;
+       unsigned grp;
+       __le32 *p = (__le32 *)primary->b_data;
+       int gdbackups = 0;
+
+       while ((grp = ext4_list_backups(sb, &three, &five, &seven)) < end) {
+               if (le32_to_cpu(*p++) !=
+                   grp * EXT4_BLOCKS_PER_GROUP(sb) + blk){
+                       ext4_warning(sb, __FUNCTION__,
+                                    "reserved GDT %llu"
+                                    " missing grp %d (%llu)",
+                                    blk, grp,
+                                    grp *
+                                    (ext4_fsblk_t)EXT4_BLOCKS_PER_GROUP(sb) +
+                                    blk);
+                       return -EINVAL;
+               }
+               if (++gdbackups > EXT4_ADDR_PER_BLOCK(sb))
+                       return -EFBIG;
+       }
+
+       return gdbackups;
+}
+
+/*
+ * Called when we need to bring a reserved group descriptor table block into
+ * use from the resize inode.  The primary copy of the new GDT block currently
+ * is an indirect block (under the double indirect block in the resize inode).
+ * The new backup GDT blocks will be stored as leaf blocks in this indirect
+ * block, in group order.  Even though we know all the block numbers we need,
+ * we check to ensure that the resize inode has actually reserved these blocks.
+ *
+ * Don't need to update the block bitmaps because the blocks are still in use.
+ *
+ * We get all of the error cases out of the way, so that we are sure to not
+ * fail once we start modifying the data on disk, because JBD has no rollback.
+ */
+static int add_new_gdb(handle_t *handle, struct inode *inode,
+                      struct ext4_new_group_data *input,
+                      struct buffer_head **primary)
+{
+       struct super_block *sb = inode->i_sb;
+       struct ext4_super_block *es = EXT4_SB(sb)->s_es;
+       unsigned long gdb_num = input->group / EXT4_DESC_PER_BLOCK(sb);
+       ext4_fsblk_t gdblock = EXT4_SB(sb)->s_sbh->b_blocknr + 1 + gdb_num;
+       struct buffer_head **o_group_desc, **n_group_desc;
+       struct buffer_head *dind;
+       int gdbackups;
+       struct ext4_iloc iloc;
+       __le32 *data;
+       int err;
+
+       if (test_opt(sb, DEBUG))
+               printk(KERN_DEBUG
+                      "EXT4-fs: ext4_add_new_gdb: adding group block %lu\n",
+                      gdb_num);
+
+       /*
+        * If we are not using the primary superblock/GDT copy don't resize,
+        * because the user tools have no way of handling this.  Probably a
+        * bad time to do it anyways.
+        */
+       if (EXT4_SB(sb)->s_sbh->b_blocknr !=
+           le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block)) {
+               ext4_warning(sb, __FUNCTION__,
+                       "won't resize using backup superblock at %llu",
+                       (unsigned long long)EXT4_SB(sb)->s_sbh->b_blocknr);
+               return -EPERM;
+       }
+
+       *primary = sb_bread(sb, gdblock);
+       if (!*primary)
+               return -EIO;
+
+       if ((gdbackups = verify_reserved_gdb(sb, *primary)) < 0) {
+               err = gdbackups;
+               goto exit_bh;
+       }
+
+       data = EXT4_I(inode)->i_data + EXT4_DIND_BLOCK;
+       dind = sb_bread(sb, le32_to_cpu(*data));
+       if (!dind) {
+               err = -EIO;
+               goto exit_bh;
+       }
+
+       data = (__le32 *)dind->b_data;
+       if (le32_to_cpu(data[gdb_num % EXT4_ADDR_PER_BLOCK(sb)]) != gdblock) {
+               ext4_warning(sb, __FUNCTION__,
+                            "new group %u GDT block %llu not reserved",
+                            input->group, gdblock);
+               err = -EINVAL;
+               goto exit_dind;
+       }
+
+       if ((err = ext4_journal_get_write_access(handle, EXT4_SB(sb)->s_sbh)))
+               goto exit_dind;
+
+       if ((err = ext4_journal_get_write_access(handle, *primary)))
+               goto exit_sbh;
+
+       if ((err = ext4_journal_get_write_access(handle, dind)))
+               goto exit_primary;
+
+       /* ext4_reserve_inode_write() gets a reference on the iloc */
+       if ((err = ext4_reserve_inode_write(handle, inode, &iloc)))
+               goto exit_dindj;
+
+       n_group_desc = kmalloc((gdb_num + 1) * sizeof(struct buffer_head *),
+                       GFP_KERNEL);
+       if (!n_group_desc) {
+               err = -ENOMEM;
+               ext4_warning (sb, __FUNCTION__,
+                             "not enough memory for %lu groups", gdb_num + 1);
+               goto exit_inode;
+       }
+
+       /*
+        * Finally, we have all of the possible failures behind us...
+        *
+        * Remove new GDT block from inode double-indirect block and clear out
+        * the new GDT block for use (which also "frees" the backup GDT blocks
+        * from the reserved inode).  We don't need to change the bitmaps for
+        * these blocks, because they are marked as in-use from being in the
+        * reserved inode, and will become GDT blocks (primary and backup).
+        */
+       data[gdb_num % EXT4_ADDR_PER_BLOCK(sb)] = 0;
+       ext4_journal_dirty_metadata(handle, dind);
+       brelse(dind);
+       inode->i_blocks -= (gdbackups + 1) * sb->s_blocksize >> 9;
+       ext4_mark_iloc_dirty(handle, inode, &iloc);
+       memset((*primary)->b_data, 0, sb->s_blocksize);
+       ext4_journal_dirty_metadata(handle, *primary);
+
+       o_group_desc = EXT4_SB(sb)->s_group_desc;
+       memcpy(n_group_desc, o_group_desc,
+              EXT4_SB(sb)->s_gdb_count * sizeof(struct buffer_head *));
+       n_group_desc[gdb_num] = *primary;
+       EXT4_SB(sb)->s_group_desc = n_group_desc;
+       EXT4_SB(sb)->s_gdb_count++;
+       kfree(o_group_desc);
+
+       es->s_reserved_gdt_blocks =
+               cpu_to_le16(le16_to_cpu(es->s_reserved_gdt_blocks) - 1);
+       ext4_journal_dirty_metadata(handle, EXT4_SB(sb)->s_sbh);
+
+       return 0;
+
+exit_inode:
+       //ext4_journal_release_buffer(handle, iloc.bh);
+       brelse(iloc.bh);
+exit_dindj:
+       //ext4_journal_release_buffer(handle, dind);
+exit_primary:
+       //ext4_journal_release_buffer(handle, *primary);
+exit_sbh:
+       //ext4_journal_release_buffer(handle, *primary);
+exit_dind:
+       brelse(dind);
+exit_bh:
+       brelse(*primary);
+
+       ext4_debug("leaving with error %d\n", err);
+       return err;
+}
+
+/*
+ * Called when we are adding a new group which has a backup copy of each of
+ * the GDT blocks (i.e. sparse group) and there are reserved GDT blocks.
+ * We need to add these reserved backup GDT blocks to the resize inode, so
+ * that they are kept for future resizing and not allocated to files.
+ *
+ * Each reserved backup GDT block will go into a different indirect block.
+ * The indirect blocks are actually the primary reserved GDT blocks,
+ * so we know in advance what their block numbers are.  We only get the
+ * double-indirect block to verify it is pointing to the primary reserved
+ * GDT blocks so we don't overwrite a data block by accident.  The reserved
+ * backup GDT blocks are stored in their reserved primary GDT block.
+ */
+static int reserve_backup_gdb(handle_t *handle, struct inode *inode,
+                             struct ext4_new_group_data *input)
+{
+       struct super_block *sb = inode->i_sb;
+       int reserved_gdb =le16_to_cpu(EXT4_SB(sb)->s_es->s_reserved_gdt_blocks);
+       struct buffer_head **primary;
+       struct buffer_head *dind;
+       struct ext4_iloc iloc;
+       ext4_fsblk_t blk;
+       __le32 *data, *end;
+       int gdbackups = 0;
+       int res, i;
+       int err;
+
+       primary = kmalloc(reserved_gdb * sizeof(*primary), GFP_KERNEL);
+       if (!primary)
+               return -ENOMEM;
+
+       data = EXT4_I(inode)->i_data + EXT4_DIND_BLOCK;
+       dind = sb_bread(sb, le32_to_cpu(*data));
+       if (!dind) {
+               err = -EIO;
+               goto exit_free;
+       }
+
+       blk = EXT4_SB(sb)->s_sbh->b_blocknr + 1 + EXT4_SB(sb)->s_gdb_count;
+       data = (__le32 *)dind->b_data + EXT4_SB(sb)->s_gdb_count;
+       end = (__le32 *)dind->b_data + EXT4_ADDR_PER_BLOCK(sb);
+
+       /* Get each reserved primary GDT block and verify it holds backups */
+       for (res = 0; res < reserved_gdb; res++, blk++) {
+               if (le32_to_cpu(*data) != blk) {
+                       ext4_warning(sb, __FUNCTION__,
+                                    "reserved block %llu"
+                                    " not at offset %ld",
+                                    blk,
+                                    (long)(data - (__le32 *)dind->b_data));
+                       err = -EINVAL;
+                       goto exit_bh;
+               }
+               primary[res] = sb_bread(sb, blk);
+               if (!primary[res]) {
+                       err = -EIO;
+                       goto exit_bh;
+               }
+               if ((gdbackups = verify_reserved_gdb(sb, primary[res])) < 0) {
+                       brelse(primary[res]);
+                       err = gdbackups;
+                       goto exit_bh;
+               }
+               if (++data >= end)
+                       data = (__le32 *)dind->b_data;
+       }
+
+       for (i = 0; i < reserved_gdb; i++) {
+               if ((err = ext4_journal_get_write_access(handle, primary[i]))) {
+                       /*
+                       int j;
+                       for (j = 0; j < i; j++)
+                               ext4_journal_release_buffer(handle, primary[j]);
+                        */
+                       goto exit_bh;
+               }
+       }
+
+       if ((err = ext4_reserve_inode_write(handle, inode, &iloc)))
+               goto exit_bh;
+
+       /*
+        * Finally we can add each of the reserved backup GDT blocks from
+        * the new group to its reserved primary GDT block.
+        */
+       blk = input->group * EXT4_BLOCKS_PER_GROUP(sb);
+       for (i = 0; i < reserved_gdb; i++) {
+               int err2;
+               data = (__le32 *)primary[i]->b_data;
+               /* printk("reserving backup %lu[%u] = %lu\n",
+                      primary[i]->b_blocknr, gdbackups,
+                      blk + primary[i]->b_blocknr); */
+               data[gdbackups] = cpu_to_le32(blk + primary[i]->b_blocknr);
+               err2 = ext4_journal_dirty_metadata(handle, primary[i]);
+               if (!err)
+                       err = err2;
+       }
+       inode->i_blocks += reserved_gdb * sb->s_blocksize >> 9;
+       ext4_mark_iloc_dirty(handle, inode, &iloc);
+
+exit_bh:
+       while (--res >= 0)
+               brelse(primary[res]);
+       brelse(dind);
+
+exit_free:
+       kfree(primary);
+
+       return err;
+}
+
+/*
+ * Update the backup copies of the ext4 metadata.  These don't need to be part
+ * of the main resize transaction, because e2fsck will re-write them if there
+ * is a problem (basically only OOM will cause a problem).  However, we
+ * _should_ update the backups if possible, in case the primary gets trashed
+ * for some reason and we need to run e2fsck from a backup superblock.  The
+ * important part is that the new block and inode counts are in the backup
+ * superblocks, and the location of the new group metadata in the GDT backups.
+ *
+ * We do not need lock_super() for this, because these blocks are not
+ * otherwise touched by the filesystem code when it is mounted.  We don't
+ * need to worry about last changing from sbi->s_groups_count, because the
+ * worst that can happen is that we do not copy the full number of backups
+ * at this time.  The resize which changed s_groups_count will backup again.
+ */
+static void update_backups(struct super_block *sb,
+                          int blk_off, char *data, int size)
+{
+       struct ext4_sb_info *sbi = EXT4_SB(sb);
+       const unsigned long last = sbi->s_groups_count;
+       const int bpg = EXT4_BLOCKS_PER_GROUP(sb);
+       unsigned three = 1;
+       unsigned five = 5;
+       unsigned seven = 7;
+       unsigned group;
+       int rest = sb->s_blocksize - size;
+       handle_t *handle;
+       int err = 0, err2;
+
+       handle = ext4_journal_start_sb(sb, EXT4_MAX_TRANS_DATA);
+       if (IS_ERR(handle)) {
+               group = 1;
+               err = PTR_ERR(handle);
+               goto exit_err;
+       }
+
+       while ((group = ext4_list_backups(sb, &three, &five, &seven)) < last) {
+               struct buffer_head *bh;
+
+               /* Out of journal space, and can't get more - abort - so sad */
+               if (handle->h_buffer_credits == 0 &&
+                   ext4_journal_extend(handle, EXT4_MAX_TRANS_DATA) &&
+                   (err = ext4_journal_restart(handle, EXT4_MAX_TRANS_DATA)))
+                       break;
+
+               bh = sb_getblk(sb, group * bpg + blk_off);
+               if (!bh) {
+                       err = -EIO;
+                       break;
+               }
+               ext4_debug("update metadata backup %#04lx\n",
+                         (unsigned long)bh->b_blocknr);
+               if ((err = ext4_journal_get_write_access(handle, bh)))
+                       break;
+               lock_buffer(bh);
+               memcpy(bh->b_data, data, size);
+               if (rest)
+                       memset(bh->b_data + size, 0, rest);
+               set_buffer_uptodate(bh);
+               unlock_buffer(bh);
+               ext4_journal_dirty_metadata(handle, bh);
+               brelse(bh);
+       }
+       if ((err2 = ext4_journal_stop(handle)) && !err)
+               err = err2;
+
+       /*
+        * Ugh! Need to have e2fsck write the backup copies.  It is too
+        * late to revert the resize, we shouldn't fail just because of
+        * the backup copies (they are only needed in case of corruption).
+        *
+        * However, if we got here we have a journal problem too, so we
+        * can't really start a transaction to mark the superblock.
+        * Chicken out and just set the flag on the hope it will be written
+        * to disk, and if not - we will simply wait until next fsck.
+        */
+exit_err:
+       if (err) {
+               ext4_warning(sb, __FUNCTION__,
+                            "can't update backup for group %d (err %d), "
+                            "forcing fsck on next reboot", group, err);
+               sbi->s_mount_state &= ~EXT4_VALID_FS;
+               sbi->s_es->s_state &= cpu_to_le16(~EXT4_VALID_FS);
+               mark_buffer_dirty(sbi->s_sbh);
+       }
+}
+
+/* Add group descriptor data to an existing or new group descriptor block.
+ * Ensure we handle all possible error conditions _before_ we start modifying
+ * the filesystem, because we cannot abort the transaction and not have it
+ * write the data to disk.
+ *
+ * If we are on a GDT block boundary, we need to get the reserved GDT block.
+ * Otherwise, we may need to add backup GDT blocks for a sparse group.
+ *
+ * We only need to hold the superblock lock while we are actually adding
+ * in the new group's counts to the superblock.  Prior to that we have
+ * not really "added" the group at all.  We re-check that we are still
+ * adding in the last group in case things have changed since verifying.
+ */
+int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input)
+{
+       struct ext4_sb_info *sbi = EXT4_SB(sb);
+       struct ext4_super_block *es = sbi->s_es;
+       int reserved_gdb = ext4_bg_has_super(sb, input->group) ?
+               le16_to_cpu(es->s_reserved_gdt_blocks) : 0;
+       struct buffer_head *primary = NULL;
+       struct ext4_group_desc *gdp;
+       struct inode *inode = NULL;
+       handle_t *handle;
+       int gdb_off, gdb_num;
+       int err, err2;
+
+       gdb_num = input->group / EXT4_DESC_PER_BLOCK(sb);
+       gdb_off = input->group % EXT4_DESC_PER_BLOCK(sb);
+
+       if (gdb_off == 0 && !EXT4_HAS_RO_COMPAT_FEATURE(sb,
+                                       EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER)) {
+               ext4_warning(sb, __FUNCTION__,
+                            "Can't resize non-sparse filesystem further");
+               return -EPERM;
+       }
+
+       if (ext4_blocks_count(es) + input->blocks_count <
+           ext4_blocks_count(es)) {
+               ext4_warning(sb, __FUNCTION__, "blocks_count overflow\n");
+               return -EINVAL;
+       }
+
+       if (le32_to_cpu(es->s_inodes_count) + EXT4_INODES_PER_GROUP(sb) <
+           le32_to_cpu(es->s_inodes_count)) {
+               ext4_warning(sb, __FUNCTION__, "inodes_count overflow\n");
+               return -EINVAL;
+       }
+
+       if (reserved_gdb || gdb_off == 0) {
+               if (!EXT4_HAS_COMPAT_FEATURE(sb,
+                                            EXT4_FEATURE_COMPAT_RESIZE_INODE)){
+                       ext4_warning(sb, __FUNCTION__,
+                                    "No reserved GDT blocks, can't resize");
+                       return -EPERM;
+               }
+               inode = iget(sb, EXT4_RESIZE_INO);
+               if (!inode || is_bad_inode(inode)) {
+                       ext4_warning(sb, __FUNCTION__,
+                                    "Error opening resize inode");
+                       iput(inode);
+                       return -ENOENT;
+               }
+       }
+
+       if ((err = verify_group_input(sb, input)))
+               goto exit_put;
+
+       if ((err = setup_new_group_blocks(sb, input)))
+               goto exit_put;
+
+       /*
+        * We will always be modifying at least the superblock and a GDT
+        * block.  If we are adding a group past the last current GDT block,
+        * we will also modify the inode and the dindirect block.  If we
+        * are adding a group with superblock/GDT backups  we will also
+        * modify each of the reserved GDT dindirect blocks.
+        */
+       handle = ext4_journal_start_sb(sb,
+                                      ext4_bg_has_super(sb, input->group) ?
+                                      3 + reserved_gdb : 4);
+       if (IS_ERR(handle)) {
+               err = PTR_ERR(handle);
+               goto exit_put;
+       }
+
+       lock_super(sb);
+       if (input->group != sbi->s_groups_count) {
+               ext4_warning(sb, __FUNCTION__,
+                            "multiple resizers run on filesystem!");
+               err = -EBUSY;
+               goto exit_journal;
+       }
+
+       if ((err = ext4_journal_get_write_access(handle, sbi->s_sbh)))
+               goto exit_journal;
+
+       /*
+        * We will only either add reserved group blocks to a backup group
+        * or remove reserved blocks for the first group in a new group block.
+        * Doing both would be mean more complex code, and sane people don't
+        * use non-sparse filesystems anymore.  This is already checked above.
+        */
+       if (gdb_off) {
+               primary = sbi->s_group_desc[gdb_num];
+               if ((err = ext4_journal_get_write_access(handle, primary)))
+                       goto exit_journal;
+
+               if (reserved_gdb && ext4_bg_num_gdb(sb, input->group) &&
+                   (err = reserve_backup_gdb(handle, inode, input)))
+                       goto exit_journal;
+       } else if ((err = add_new_gdb(handle, inode, input, &primary)))
+               goto exit_journal;
+
+       /*
+        * OK, now we've set up the new group.  Time to make it active.
+        *
+        * Current kernels don't lock all allocations via lock_super(),
+        * so we have to be safe wrt. concurrent accesses the group
+        * data.  So we need to be careful to set all of the relevant
+        * group descriptor data etc. *before* we enable the group.
+        *
+        * The key field here is sbi->s_groups_count: as long as
+        * that retains its old value, nobody is going to access the new
+        * group.
+        *
+        * So first we update all the descriptor metadata for the new
+        * group; then we update the total disk blocks count; then we
+        * update the groups count to enable the group; then finally we
+        * update the free space counts so that the system can start
+        * using the new disk blocks.
+        */
+
+       /* Update group descriptor block for new group */
+       gdp = (struct ext4_group_desc *)primary->b_data + gdb_off;
+
+       ext4_block_bitmap_set(sb, gdp, input->block_bitmap); /* LV FIXME */
+       ext4_inode_bitmap_set(sb, gdp, input->inode_bitmap); /* LV FIXME */
+       ext4_inode_table_set(sb, gdp, input->inode_table); /* LV FIXME */
+       gdp->bg_free_blocks_count = cpu_to_le16(input->free_blocks_count);
+       gdp->bg_free_inodes_count = cpu_to_le16(EXT4_INODES_PER_GROUP(sb));
+
+       /*
+        * Make the new blocks and inodes valid next.  We do this before
+        * increasing the group count so that once the group is enabled,
+        * all of its blocks and inodes are already valid.
+        *
+        * We always allocate group-by-group, then block-by-block or
+        * inode-by-inode within a group, so enabling these
+        * blocks/inodes before the group is live won't actually let us
+        * allocate the new space yet.
+        */
+       ext4_blocks_count_set(es, ext4_blocks_count(es) +
+               input->blocks_count);
+       es->s_inodes_count = cpu_to_le32(le32_to_cpu(es->s_inodes_count) +
+               EXT4_INODES_PER_GROUP(sb));
+
+       /*
+        * We need to protect s_groups_count against other CPUs seeing
+        * inconsistent state in the superblock.
+        *
+        * The precise rules we use are:
+        *
+        * * Writers of s_groups_count *must* hold lock_super
+        * AND
+        * * Writers must perform a smp_wmb() after updating all dependent
+        *   data and before modifying the groups count
+        *
+        * * Readers must hold lock_super() over the access
+        * OR
+        * * Readers must perform an smp_rmb() after reading the groups count
+        *   and before reading any dependent data.
+        *
+        * NB. These rules can be relaxed when checking the group count
+        * while freeing data, as we can only allocate from a block
+        * group after serialising against the group count, and we can
+        * only then free after serialising in turn against that
+        * allocation.
+        */
+       smp_wmb();
+
+       /* Update the global fs size fields */
+       sbi->s_groups_count++;
+
+       ext4_journal_dirty_metadata(handle, primary);
+
+       /* Update the reserved block counts only once the new group is
+        * active. */
+       ext4_r_blocks_count_set(es, ext4_r_blocks_count(es) +
+               input->reserved_blocks);
+
+       /* Update the free space counts */
+       percpu_counter_mod(&sbi->s_freeblocks_counter,
+                          input->free_blocks_count);
+       percpu_counter_mod(&sbi->s_freeinodes_counter,
+                          EXT4_INODES_PER_GROUP(sb));
+
+       ext4_journal_dirty_metadata(handle, sbi->s_sbh);
+       sb->s_dirt = 1;
+
+exit_journal:
+       unlock_super(sb);
+       if ((err2 = ext4_journal_stop(handle)) && !err)
+               err = err2;
+       if (!err) {
+               update_backups(sb, sbi->s_sbh->b_blocknr, (char *)es,
+                              sizeof(struct ext4_super_block));
+               update_backups(sb, primary->b_blocknr, primary->b_data,
+                              primary->b_size);
+       }
+exit_put:
+       iput(inode);
+       return err;
+} /* ext4_group_add */
+
+/* Extend the filesystem to the new number of blocks specified.  This entry
+ * point is only used to extend the current filesystem to the end of the last
+ * existing group.  It can be accessed via ioctl, or by "remount,resize=<size>"
+ * for emergencies (because it has no dependencies on reserved blocks).
+ *
+ * If we _really_ wanted, we could use default values to call ext4_group_add()
+ * allow the "remount" trick to work for arbitrary resizing, assuming enough
+ * GDT blocks are reserved to grow to the desired size.
+ */
+int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es,
+                     ext4_fsblk_t n_blocks_count)
+{
+       ext4_fsblk_t o_blocks_count;
+       unsigned long o_groups_count;
+       ext4_grpblk_t last;
+       ext4_grpblk_t add;
+       struct buffer_head * bh;
+       handle_t *handle;
+       int err;
+       unsigned long freed_blocks;
+
+       /* We don't need to worry about locking wrt other resizers just
+        * yet: we're going to revalidate es->s_blocks_count after
+        * taking lock_super() below. */
+       o_blocks_count = ext4_blocks_count(es);
+       o_groups_count = EXT4_SB(sb)->s_groups_count;
+
+       if (test_opt(sb, DEBUG))
+               printk(KERN_DEBUG "EXT4-fs: extending last group from %llu uto %llu blocks\n",
+                      o_blocks_count, n_blocks_count);
+
+       if (n_blocks_count == 0 || n_blocks_count == o_blocks_count)
+               return 0;
+
+       if (n_blocks_count > (sector_t)(~0ULL) >> (sb->s_blocksize_bits - 9)) {
+               printk(KERN_ERR "EXT4-fs: filesystem on %s:"
+                       " too large to resize to %llu blocks safely\n",
+                       sb->s_id, n_blocks_count);
+               if (sizeof(sector_t) < 8)
+                       ext4_warning(sb, __FUNCTION__,
+                       "CONFIG_LBD not enabled\n");
+               return -EINVAL;
+       }
+
+       if (n_blocks_count < o_blocks_count) {
+               ext4_warning(sb, __FUNCTION__,
+                            "can't shrink FS - resize aborted");
+               return -EBUSY;
+       }
+
+       /* Handle the remaining blocks in the last group only. */
+       ext4_get_group_no_and_offset(sb, o_blocks_count, NULL, &last);
+
+       if (last == 0) {
+               ext4_warning(sb, __FUNCTION__,
+                            "need to use ext2online to resize further");
+               return -EPERM;
+       }
+
+       add = EXT4_BLOCKS_PER_GROUP(sb) - last;
+
+       if (o_blocks_count + add < o_blocks_count) {
+               ext4_warning(sb, __FUNCTION__, "blocks_count overflow");
+               return -EINVAL;
+       }
+
+       if (o_blocks_count + add > n_blocks_count)
+               add = n_blocks_count - o_blocks_count;
+
+       if (o_blocks_count + add < n_blocks_count)
+               ext4_warning(sb, __FUNCTION__,
+                            "will only finish group (%llu"
+                            " blocks, %u new)",
+                            o_blocks_count + add, add);
+
+       /* See if the device is actually as big as what was requested */
+       bh = sb_bread(sb, o_blocks_count + add -1);
+       if (!bh) {
+               ext4_warning(sb, __FUNCTION__,
+                            "can't read last block, resize aborted");
+               return -ENOSPC;
+       }
+       brelse(bh);
+
+       /* We will update the superblock, one block bitmap, and
+        * one group descriptor via ext4_free_blocks().
+        */
+       handle = ext4_journal_start_sb(sb, 3);
+       if (IS_ERR(handle)) {
+               err = PTR_ERR(handle);
+               ext4_warning(sb, __FUNCTION__, "error %d on journal start",err);
+               goto exit_put;
+       }
+
+       lock_super(sb);
+       if (o_blocks_count != ext4_blocks_count(es)) {
+               ext4_warning(sb, __FUNCTION__,
+                            "multiple resizers run on filesystem!");
+               unlock_super(sb);
+               err = -EBUSY;
+               goto exit_put;
+       }
+
+       if ((err = ext4_journal_get_write_access(handle,
+                                                EXT4_SB(sb)->s_sbh))) {
+               ext4_warning(sb, __FUNCTION__,
+                            "error %d on journal write access", err);
+               unlock_super(sb);
+               ext4_journal_stop(handle);
+               goto exit_put;
+       }
+       ext4_blocks_count_set(es, o_blocks_count + add);
+       ext4_journal_dirty_metadata(handle, EXT4_SB(sb)->s_sbh);
+       sb->s_dirt = 1;
+       unlock_super(sb);
+       ext4_debug("freeing blocks %lu through %llu\n", o_blocks_count,
+                  o_blocks_count + add);
+       ext4_free_blocks_sb(handle, sb, o_blocks_count, add, &freed_blocks);
+       ext4_debug("freed blocks %llu through %llu\n", o_blocks_count,
+                  o_blocks_count + add);
+       if ((err = ext4_journal_stop(handle)))
+               goto exit_put;
+       if (test_opt(sb, DEBUG))
+               printk(KERN_DEBUG "EXT4-fs: extended group to %llu blocks\n",
+                      ext4_blocks_count(es));
+       update_backups(sb, EXT4_SB(sb)->s_sbh->b_blocknr, (char *)es,
+                      sizeof(struct ext4_super_block));
+exit_put:
+       return err;
+} /* ext4_group_extend */
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
new file mode 100644 (file)
index 0000000..b4b022a
--- /dev/null
@@ -0,0 +1,2829 @@
+/*
+ *  linux/fs/ext4/super.c
+ *
+ * Copyright (C) 1992, 1993, 1994, 1995
+ * Remy Card (card@masi.ibp.fr)
+ * Laboratoire MASI - Institut Blaise Pascal
+ * Universite Pierre et Marie Curie (Paris VI)
+ *
+ *  from
+ *
+ *  linux/fs/minix/inode.c
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ *
+ *  Big-endian to little-endian byte-swapping/bitmaps by
+ *        David S. Miller (davem@caip.rutgers.edu), 1995
+ */
+
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/fs.h>
+#include <linux/time.h>
+#include <linux/jbd2.h>
+#include <linux/ext4_fs.h>
+#include <linux/ext4_jbd2.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/blkdev.h>
+#include <linux/parser.h>
+#include <linux/smp_lock.h>
+#include <linux/buffer_head.h>
+#include <linux/vfs.h>
+#include <linux/random.h>
+#include <linux/mount.h>
+#include <linux/namei.h>
+#include <linux/quotaops.h>
+#include <linux/seq_file.h>
+
+#include <asm/uaccess.h>
+
+#include "xattr.h"
+#include "acl.h"
+#include "namei.h"
+
+static int ext4_load_journal(struct super_block *, struct ext4_super_block *,
+                            unsigned long journal_devnum);
+static int ext4_create_journal(struct super_block *, struct ext4_super_block *,
+                              unsigned int);
+static void ext4_commit_super (struct super_block * sb,
+                              struct ext4_super_block * es,
+                              int sync);
+static void ext4_mark_recovery_complete(struct super_block * sb,
+                                       struct ext4_super_block * es);
+static void ext4_clear_journal_err(struct super_block * sb,
+                                  struct ext4_super_block * es);
+static int ext4_sync_fs(struct super_block *sb, int wait);
+static const char *ext4_decode_error(struct super_block * sb, int errno,
+                                    char nbuf[16]);
+static int ext4_remount (struct super_block * sb, int * flags, char * data);
+static int ext4_statfs (struct dentry * dentry, struct kstatfs * buf);
+static void ext4_unlockfs(struct super_block *sb);
+static void ext4_write_super (struct super_block * sb);
+static void ext4_write_super_lockfs(struct super_block *sb);
+
+
+ext4_fsblk_t ext4_block_bitmap(struct super_block *sb,
+                              struct ext4_group_desc *bg)
+{
+       return le32_to_cpu(bg->bg_block_bitmap) |
+               (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ?
+                (ext4_fsblk_t)le32_to_cpu(bg->bg_block_bitmap_hi) << 32 : 0);
+}
+
+ext4_fsblk_t ext4_inode_bitmap(struct super_block *sb,
+                              struct ext4_group_desc *bg)
+{
+       return le32_to_cpu(bg->bg_inode_bitmap) |
+               (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ?
+                (ext4_fsblk_t)le32_to_cpu(bg->bg_inode_bitmap_hi) << 32 : 0);
+}
+
+ext4_fsblk_t ext4_inode_table(struct super_block *sb,
+                             struct ext4_group_desc *bg)
+{
+       return le32_to_cpu(bg->bg_inode_table) |
+               (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ?
+                (ext4_fsblk_t)le32_to_cpu(bg->bg_inode_table_hi) << 32 : 0);
+}
+
+void ext4_block_bitmap_set(struct super_block *sb,
+                          struct ext4_group_desc *bg, ext4_fsblk_t blk)
+{
+       bg->bg_block_bitmap = cpu_to_le32((u32)blk);
+       if (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT)
+               bg->bg_block_bitmap_hi = cpu_to_le32(blk >> 32);
+}
+
+void ext4_inode_bitmap_set(struct super_block *sb,
+                          struct ext4_group_desc *bg, ext4_fsblk_t blk)
+{
+       bg->bg_inode_bitmap  = cpu_to_le32((u32)blk);
+       if (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT)
+               bg->bg_inode_bitmap_hi = cpu_to_le32(blk >> 32);
+}
+
+void ext4_inode_table_set(struct super_block *sb,
+                         struct ext4_group_desc *bg, ext4_fsblk_t blk)
+{
+       bg->bg_inode_table = cpu_to_le32((u32)blk);
+       if (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT)
+               bg->bg_inode_table_hi = cpu_to_le32(blk >> 32);
+}
+
+/*
+ * Wrappers for jbd2_journal_start/end.
+ *
+ * The only special thing we need to do here is to make sure that all
+ * journal_end calls result in the superblock being marked dirty, so
+ * that sync() will call the filesystem's write_super callback if
+ * appropriate.
+ */
+handle_t *ext4_journal_start_sb(struct super_block *sb, int nblocks)
+{
+       journal_t *journal;
+
+       if (sb->s_flags & MS_RDONLY)
+               return ERR_PTR(-EROFS);
+
+       /* Special case here: if the journal has aborted behind our
+        * backs (eg. EIO in the commit thread), then we still need to
+        * take the FS itself readonly cleanly. */
+       journal = EXT4_SB(sb)->s_journal;
+       if (is_journal_aborted(journal)) {
+               ext4_abort(sb, __FUNCTION__,
+                          "Detected aborted journal");
+               return ERR_PTR(-EROFS);
+       }
+
+       return jbd2_journal_start(journal, nblocks);
+}
+
+/*
+ * The only special thing we need to do here is to make sure that all
+ * jbd2_journal_stop calls result in the superblock being marked dirty, so
+ * that sync() will call the filesystem's write_super callback if
+ * appropriate.
+ */
+int __ext4_journal_stop(const char *where, handle_t *handle)
+{
+       struct super_block *sb;
+       int err;
+       int rc;
+
+       sb = handle->h_transaction->t_journal->j_private;
+       err = handle->h_err;
+       rc = jbd2_journal_stop(handle);
+
+       if (!err)
+               err = rc;
+       if (err)
+               __ext4_std_error(sb, where, err);
+       return err;
+}
+
+void ext4_journal_abort_handle(const char *caller, const char *err_fn,
+               struct buffer_head *bh, handle_t *handle, int err)
+{
+       char nbuf[16];
+       const char *errstr = ext4_decode_error(NULL, err, nbuf);
+
+       if (bh)
+               BUFFER_TRACE(bh, "abort");
+
+       if (!handle->h_err)
+               handle->h_err = err;
+
+       if (is_handle_aborted(handle))
+               return;
+
+       printk(KERN_ERR "%s: aborting transaction: %s in %s\n",
+              caller, errstr, err_fn);
+
+       jbd2_journal_abort_handle(handle);
+}
+
+/* Deal with the reporting of failure conditions on a filesystem such as
+ * inconsistencies detected or read IO failures.
+ *
+ * On ext2, we can store the error state of the filesystem in the
+ * superblock.  That is not possible on ext4, because we may have other
+ * write ordering constraints on the superblock which prevent us from
+ * writing it out straight away; and given that the journal is about to
+ * be aborted, we can't rely on the current, or future, transactions to
+ * write out the superblock safely.
+ *
+ * We'll just use the jbd2_journal_abort() error code to record an error in
+ * the journal instead.  On recovery, the journal will compain about
+ * that error until we've noted it down and cleared it.
+ */
+
+static void ext4_handle_error(struct super_block *sb)
+{
+       struct ext4_super_block *es = EXT4_SB(sb)->s_es;
+
+       EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS;
+       es->s_state |= cpu_to_le16(EXT4_ERROR_FS);
+
+       if (sb->s_flags & MS_RDONLY)
+               return;
+
+       if (!test_opt (sb, ERRORS_CONT)) {
+               journal_t *journal = EXT4_SB(sb)->s_journal;
+
+               EXT4_SB(sb)->s_mount_opt |= EXT4_MOUNT_ABORT;
+               if (journal)
+                       jbd2_journal_abort(journal, -EIO);
+       }
+       if (test_opt (sb, ERRORS_RO)) {
+               printk (KERN_CRIT "Remounting filesystem read-only\n");
+               sb->s_flags |= MS_RDONLY;
+       }
+       ext4_commit_super(sb, es, 1);
+       if (test_opt(sb, ERRORS_PANIC))
+               panic("EXT4-fs (device %s): panic forced after error\n",
+                       sb->s_id);
+}
+
+void ext4_error (struct super_block * sb, const char * function,
+                const char * fmt, ...)
+{
+       va_list args;
+
+       va_start(args, fmt);
+       printk(KERN_CRIT "EXT4-fs error (device %s): %s: ",sb->s_id, function);
+       vprintk(fmt, args);
+       printk("\n");
+       va_end(args);
+
+       ext4_handle_error(sb);
+}
+
+static const char *ext4_decode_error(struct super_block * sb, int errno,
+                                    char nbuf[16])
+{
+       char *errstr = NULL;
+
+       switch (errno) {
+       case -EIO:
+               errstr = "IO failure";
+               break;
+       case -ENOMEM:
+               errstr = "Out of memory";
+               break;
+       case -EROFS:
+               if (!sb || EXT4_SB(sb)->s_journal->j_flags & JBD2_ABORT)
+                       errstr = "Journal has aborted";
+               else
+                       errstr = "Readonly filesystem";
+               break;
+       default:
+               /* If the caller passed in an extra buffer for unknown
+                * errors, textualise them now.  Else we just return
+                * NULL. */
+               if (nbuf) {
+                       /* Check for truncated error codes... */
+                       if (snprintf(nbuf, 16, "error %d", -errno) >= 0)
+                               errstr = nbuf;
+               }
+               break;
+       }
+
+       return errstr;
+}
+
+/* __ext4_std_error decodes expected errors from journaling functions
+ * automatically and invokes the appropriate error response.  */
+
+void __ext4_std_error (struct super_block * sb, const char * function,
+                      int errno)
+{
+       char nbuf[16];
+       const char *errstr;
+
+       /* Special case: if the error is EROFS, and we're not already
+        * inside a transaction, then there's really no point in logging
+        * an error. */
+       if (errno == -EROFS && journal_current_handle() == NULL &&
+           (sb->s_flags & MS_RDONLY))
+               return;
+
+       errstr = ext4_decode_error(sb, errno, nbuf);
+       printk (KERN_CRIT "EXT4-fs error (device %s) in %s: %s\n",
+               sb->s_id, function, errstr);
+
+       ext4_handle_error(sb);
+}
+
+/*
+ * ext4_abort is a much stronger failure handler than ext4_error.  The
+ * abort function may be used to deal with unrecoverable failures such
+ * as journal IO errors or ENOMEM at a critical moment in log management.
+ *
+ * We unconditionally force the filesystem into an ABORT|READONLY state,
+ * unless the error response on the fs has been set to panic in which
+ * case we take the easy way out and panic immediately.
+ */
+
+void ext4_abort (struct super_block * sb, const char * function,
+                const char * fmt, ...)
+{
+       va_list args;
+
+       printk (KERN_CRIT "ext4_abort called.\n");
+
+       va_start(args, fmt);
+       printk(KERN_CRIT "EXT4-fs error (device %s): %s: ",sb->s_id, function);
+       vprintk(fmt, args);
+       printk("\n");
+       va_end(args);
+
+       if (test_opt(sb, ERRORS_PANIC))
+               panic("EXT4-fs panic from previous error\n");
+
+       if (sb->s_flags & MS_RDONLY)
+               return;
+
+       printk(KERN_CRIT "Remounting filesystem read-only\n");
+       EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS;
+       sb->s_flags |= MS_RDONLY;
+       EXT4_SB(sb)->s_mount_opt |= EXT4_MOUNT_ABORT;
+       jbd2_journal_abort(EXT4_SB(sb)->s_journal, -EIO);
+}
+
+void ext4_warning (struct super_block * sb, const char * function,
+                  const char * fmt, ...)
+{
+       va_list args;
+
+       va_start(args, fmt);
+       printk(KERN_WARNING "EXT4-fs warning (device %s): %s: ",
+              sb->s_id, function);
+       vprintk(fmt, args);
+       printk("\n");
+       va_end(args);
+}
+
+void ext4_update_dynamic_rev(struct super_block *sb)
+{
+       struct ext4_super_block *es = EXT4_SB(sb)->s_es;
+
+       if (le32_to_cpu(es->s_rev_level) > EXT4_GOOD_OLD_REV)
+               return;
+
+       ext4_warning(sb, __FUNCTION__,
+                    "updating to rev %d because of new feature flag, "
+                    "running e2fsck is recommended",
+                    EXT4_DYNAMIC_REV);
+
+       es->s_first_ino = cpu_to_le32(EXT4_GOOD_OLD_FIRST_INO);
+       es->s_inode_size = cpu_to_le16(EXT4_GOOD_OLD_INODE_SIZE);
+       es->s_rev_level = cpu_to_le32(EXT4_DYNAMIC_REV);
+       /* leave es->s_feature_*compat flags alone */
+       /* es->s_uuid will be set by e2fsck if empty */
+
+       /*
+        * The rest of the superblock fields should be zero, and if not it
+        * means they are likely already in use, so leave them alone.  We
+        * can leave it up to e2fsck to clean up any inconsistencies there.
+        */
+}
+
+/*
+ * Open the external journal device
+ */
+static struct block_device *ext4_blkdev_get(dev_t dev)
+{
+       struct block_device *bdev;
+       char b[BDEVNAME_SIZE];
+
+       bdev = open_by_devnum(dev, FMODE_READ|FMODE_WRITE);
+       if (IS_ERR(bdev))
+               goto fail;
+       return bdev;
+
+fail:
+       printk(KERN_ERR "EXT4: failed to open journal device %s: %ld\n",
+                       __bdevname(dev, b), PTR_ERR(bdev));
+       return NULL;
+}
+
+/*
+ * Release the journal device
+ */
+static int ext4_blkdev_put(struct block_device *bdev)
+{
+       bd_release(bdev);
+       return blkdev_put(bdev);
+}
+
+static int ext4_blkdev_remove(struct ext4_sb_info *sbi)
+{
+       struct block_device *bdev;
+       int ret = -ENODEV;
+
+       bdev = sbi->journal_bdev;
+       if (bdev) {
+               ret = ext4_blkdev_put(bdev);
+               sbi->journal_bdev = NULL;
+       }
+       return ret;
+}
+
+static inline struct inode *orphan_list_entry(struct list_head *l)
+{
+       return &list_entry(l, struct ext4_inode_info, i_orphan)->vfs_inode;
+}
+
+static void dump_orphan_list(struct super_block *sb, struct ext4_sb_info *sbi)
+{
+       struct list_head *l;
+
+       printk(KERN_ERR "sb orphan head is %d\n",
+              le32_to_cpu(sbi->s_es->s_last_orphan));
+
+       printk(KERN_ERR "sb_info orphan list:\n");
+       list_for_each(l, &sbi->s_orphan) {
+               struct inode *inode = orphan_list_entry(l);
+               printk(KERN_ERR "  "
+                      "inode %s:%lu at %p: mode %o, nlink %d, next %d\n",
+                      inode->i_sb->s_id, inode->i_ino, inode,
+                      inode->i_mode, inode->i_nlink,
+                      NEXT_ORPHAN(inode));
+       }
+}
+
+static void ext4_put_super (struct super_block * sb)
+{
+       struct ext4_sb_info *sbi = EXT4_SB(sb);
+       struct ext4_super_block *es = sbi->s_es;
+       int i;
+
+       ext4_ext_release(sb);
+       ext4_xattr_put_super(sb);
+       jbd2_journal_destroy(sbi->s_journal);
+       if (!(sb->s_flags & MS_RDONLY)) {
+               EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
+               es->s_state = cpu_to_le16(sbi->s_mount_state);
+               BUFFER_TRACE(sbi->s_sbh, "marking dirty");
+               mark_buffer_dirty(sbi->s_sbh);
+               ext4_commit_super(sb, es, 1);
+       }
+
+       for (i = 0; i < sbi->s_gdb_count; i++)
+               brelse(sbi->s_group_desc[i]);
+       kfree(sbi->s_group_desc);
+       percpu_counter_destroy(&sbi->s_freeblocks_counter);
+       percpu_counter_destroy(&sbi->s_freeinodes_counter);
+       percpu_counter_destroy(&sbi->s_dirs_counter);
+       brelse(sbi->s_sbh);
+#ifdef CONFIG_QUOTA
+       for (i = 0; i < MAXQUOTAS; i++)
+               kfree(sbi->s_qf_names[i]);
+#endif
+
+       /* Debugging code just in case the in-memory inode orphan list
+        * isn't empty.  The on-disk one can be non-empty if we've
+        * detected an error and taken the fs readonly, but the
+        * in-memory list had better be clean by this point. */
+       if (!list_empty(&sbi->s_orphan))
+               dump_orphan_list(sb, sbi);
+       J_ASSERT(list_empty(&sbi->s_orphan));
+
+       invalidate_bdev(sb->s_bdev, 0);
+       if (sbi->journal_bdev && sbi->journal_bdev != sb->s_bdev) {
+               /*
+                * Invalidate the journal device's buffers.  We don't want them
+                * floating about in memory - the physical journal device may
+                * hotswapped, and it breaks the `ro-after' testing code.
+                */
+               sync_blockdev(sbi->journal_bdev);
+               invalidate_bdev(sbi->journal_bdev, 0);
+               ext4_blkdev_remove(sbi);
+       }
+       sb->s_fs_info = NULL;
+       kfree(sbi);
+       return;
+}
+
+static kmem_cache_t *ext4_inode_cachep;
+
+/*
+ * Called inside transaction, so use GFP_NOFS
+ */
+static struct inode *ext4_alloc_inode(struct super_block *sb)
+{
+       struct ext4_inode_info *ei;
+
+       ei = kmem_cache_alloc(ext4_inode_cachep, SLAB_NOFS);
+       if (!ei)
+               return NULL;
+#ifdef CONFIG_EXT4DEV_FS_POSIX_ACL
+       ei->i_acl = EXT4_ACL_NOT_CACHED;
+       ei->i_default_acl = EXT4_ACL_NOT_CACHED;
+#endif
+       ei->i_block_alloc_info = NULL;
+       ei->vfs_inode.i_version = 1;
+       memset(&ei->i_cached_extent, 0, sizeof(struct ext4_ext_cache));
+       return &ei->vfs_inode;
+}
+
+static void ext4_destroy_inode(struct inode *inode)
+{
+       kmem_cache_free(ext4_inode_cachep, EXT4_I(inode));
+}
+
+static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
+{
+       struct ext4_inode_info *ei = (struct ext4_inode_info *) foo;
+
+       if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
+           SLAB_CTOR_CONSTRUCTOR) {
+               INIT_LIST_HEAD(&ei->i_orphan);
+#ifdef CONFIG_EXT4DEV_FS_XATTR
+               init_rwsem(&ei->xattr_sem);
+#endif
+               mutex_init(&ei->truncate_mutex);
+               inode_init_once(&ei->vfs_inode);
+       }
+}
+
+static int init_inodecache(void)
+{
+       ext4_inode_cachep = kmem_cache_create("ext4_inode_cache",
+                                            sizeof(struct ext4_inode_info),
+                                            0, (SLAB_RECLAIM_ACCOUNT|
+                                               SLAB_MEM_SPREAD),
+                                            init_once, NULL);
+       if (ext4_inode_cachep == NULL)
+               return -ENOMEM;
+       return 0;
+}
+
+static void destroy_inodecache(void)
+{
+       kmem_cache_destroy(ext4_inode_cachep);
+}
+
+static void ext4_clear_inode(struct inode *inode)
+{
+       struct ext4_block_alloc_info *rsv = EXT4_I(inode)->i_block_alloc_info;
+#ifdef CONFIG_EXT4DEV_FS_POSIX_ACL
+       if (EXT4_I(inode)->i_acl &&
+                       EXT4_I(inode)->i_acl != EXT4_ACL_NOT_CACHED) {
+               posix_acl_release(EXT4_I(inode)->i_acl);
+               EXT4_I(inode)->i_acl = EXT4_ACL_NOT_CACHED;
+       }
+       if (EXT4_I(inode)->i_default_acl &&
+                       EXT4_I(inode)->i_default_acl != EXT4_ACL_NOT_CACHED) {
+               posix_acl_release(EXT4_I(inode)->i_default_acl);
+               EXT4_I(inode)->i_default_acl = EXT4_ACL_NOT_CACHED;
+       }
+#endif
+       ext4_discard_reservation(inode);
+       EXT4_I(inode)->i_block_alloc_info = NULL;
+       if (unlikely(rsv))
+               kfree(rsv);
+}
+
+static inline void ext4_show_quota_options(struct seq_file *seq, struct super_block *sb)
+{
+#if defined(CONFIG_QUOTA)
+       struct ext4_sb_info *sbi = EXT4_SB(sb);
+
+       if (sbi->s_jquota_fmt)
+               seq_printf(seq, ",jqfmt=%s",
+               (sbi->s_jquota_fmt == QFMT_VFS_OLD) ? "vfsold": "vfsv0");
+
+       if (sbi->s_qf_names[USRQUOTA])
+               seq_printf(seq, ",usrjquota=%s", sbi->s_qf_names[USRQUOTA]);
+
+       if (sbi->s_qf_names[GRPQUOTA])
+               seq_printf(seq, ",grpjquota=%s", sbi->s_qf_names[GRPQUOTA]);
+
+       if (sbi->s_mount_opt & EXT4_MOUNT_USRQUOTA)
+               seq_puts(seq, ",usrquota");
+
+       if (sbi->s_mount_opt & EXT4_MOUNT_GRPQUOTA)
+               seq_puts(seq, ",grpquota");
+#endif
+}
+
+static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs)
+{
+       struct super_block *sb = vfs->mnt_sb;
+
+       if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA)
+               seq_puts(seq, ",data=journal");
+       else if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_ORDERED_DATA)
+               seq_puts(seq, ",data=ordered");
+       else if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_WRITEBACK_DATA)
+               seq_puts(seq, ",data=writeback");
+
+       ext4_show_quota_options(seq, sb);
+
+       return 0;
+}
+
+
+static struct dentry *ext4_get_dentry(struct super_block *sb, void *vobjp)
+{
+       __u32 *objp = vobjp;
+       unsigned long ino = objp[0];
+       __u32 generation = objp[1];
+       struct inode *inode;
+       struct dentry *result;
+
+       if (ino < EXT4_FIRST_INO(sb) && ino != EXT4_ROOT_INO)
+               return ERR_PTR(-ESTALE);
+       if (ino > le32_to_cpu(EXT4_SB(sb)->s_es->s_inodes_count))
+               return ERR_PTR(-ESTALE);
+
+       /* iget isn't really right if the inode is currently unallocated!!
+        *
+        * ext4_read_inode will return a bad_inode if the inode had been
+        * deleted, so we should be safe.
+        *
+        * Currently we don't know the generation for parent directory, so
+        * a generation of 0 means "accept any"
+        */
+       inode = iget(sb, ino);
+       if (inode == NULL)
+               return ERR_PTR(-ENOMEM);
+       if (is_bad_inode(inode) ||
+           (generation && inode->i_generation != generation)) {
+               iput(inode);
+               return ERR_PTR(-ESTALE);
+       }
+       /* now to find a dentry.
+        * If possible, get a well-connected one
+        */
+       result = d_alloc_anon(inode);
+       if (!result) {
+               iput(inode);
+               return ERR_PTR(-ENOMEM);
+       }
+       return result;
+}
+
+#ifdef CONFIG_QUOTA
+#define QTYPE2NAME(t) ((t)==USRQUOTA?"user":"group")
+#define QTYPE2MOPT(on, t) ((t)==USRQUOTA?((on)##USRJQUOTA):((on)##GRPJQUOTA))
+
+static int ext4_dquot_initialize(struct inode *inode, int type);
+static int ext4_dquot_drop(struct inode *inode);
+static int ext4_write_dquot(struct dquot *dquot);
+static int ext4_acquire_dquot(struct dquot *dquot);
+static int ext4_release_dquot(struct dquot *dquot);
+static int ext4_mark_dquot_dirty(struct dquot *dquot);
+static int ext4_write_info(struct super_block *sb, int type);
+static int ext4_quota_on(struct super_block *sb, int type, int format_id, char *path);
+static int ext4_quota_on_mount(struct super_block *sb, int type);
+static ssize_t ext4_quota_read(struct super_block *sb, int type, char *data,
+                              size_t len, loff_t off);
+static ssize_t ext4_quota_write(struct super_block *sb, int type,
+                               const char *data, size_t len, loff_t off);
+
+static struct dquot_operations ext4_quota_operations = {
+       .initialize     = ext4_dquot_initialize,
+       .drop           = ext4_dquot_drop,
+       .alloc_space    = dquot_alloc_space,
+       .alloc_inode    = dquot_alloc_inode,
+       .free_space     = dquot_free_space,
+       .free_inode     = dquot_free_inode,
+       .transfer       = dquot_transfer,
+       .write_dquot    = ext4_write_dquot,
+       .acquire_dquot  = ext4_acquire_dquot,
+       .release_dquot  = ext4_release_dquot,
+       .mark_dirty     = ext4_mark_dquot_dirty,
+       .write_info     = ext4_write_info
+};
+
+static struct quotactl_ops ext4_qctl_operations = {
+       .quota_on       = ext4_quota_on,
+       .quota_off      = vfs_quota_off,
+       .quota_sync     = vfs_quota_sync,
+       .get_info       = vfs_get_dqinfo,
+       .set_info       = vfs_set_dqinfo,
+       .get_dqblk      = vfs_get_dqblk,
+       .set_dqblk      = vfs_set_dqblk
+};
+#endif
+
+static struct super_operations ext4_sops = {
+       .alloc_inode    = ext4_alloc_inode,
+       .destroy_inode  = ext4_destroy_inode,
+       .read_inode     = ext4_read_inode,
+       .write_inode    = ext4_write_inode,
+       .dirty_inode    = ext4_dirty_inode,
+       .delete_inode   = ext4_delete_inode,
+       .put_super      = ext4_put_super,
+       .write_super    = ext4_write_super,
+       .sync_fs        = ext4_sync_fs,
+       .write_super_lockfs = ext4_write_super_lockfs,
+       .unlockfs       = ext4_unlockfs,
+       .statfs         = ext4_statfs,
+       .remount_fs     = ext4_remount,
+       .clear_inode    = ext4_clear_inode,
+       .show_options   = ext4_show_options,
+#ifdef CONFIG_QUOTA
+       .quota_read     = ext4_quota_read,
+       .quota_write    = ext4_quota_write,
+#endif
+};
+
+static struct export_operations ext4_export_ops = {
+       .get_parent = ext4_get_parent,
+       .get_dentry = ext4_get_dentry,
+};
+
+enum {
+       Opt_bsd_df, Opt_minix_df, Opt_grpid, Opt_nogrpid,
+       Opt_resgid, Opt_resuid, Opt_sb, Opt_err_cont, Opt_err_panic, Opt_err_ro,
+       Opt_nouid32, Opt_nocheck, Opt_debug, Opt_oldalloc, Opt_orlov,
+       Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl,
+       Opt_reservation, Opt_noreservation, Opt_noload, Opt_nobh, Opt_bh,
+       Opt_commit, Opt_journal_update, Opt_journal_inum, Opt_journal_dev,
+       Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback,
+       Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota,
+       Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota,
+       Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota,
+       Opt_grpquota, Opt_extents,
+};
+
+static match_table_t tokens = {
+       {Opt_bsd_df, "bsddf"},
+       {Opt_minix_df, "minixdf"},
+       {Opt_grpid, "grpid"},
+       {Opt_grpid, "bsdgroups"},
+       {Opt_nogrpid, "nogrpid"},
+       {Opt_nogrpid, "sysvgroups"},
+       {Opt_resgid, "resgid=%u"},
+       {Opt_resuid, "resuid=%u"},
+       {Opt_sb, "sb=%u"},
+       {Opt_err_cont, "errors=continue"},
+       {Opt_err_panic, "errors=panic"},
+       {Opt_err_ro, "errors=remount-ro"},
+       {Opt_nouid32, "nouid32"},
+       {Opt_nocheck, "nocheck"},
+       {Opt_nocheck, "check=none"},
+       {Opt_debug, "debug"},
+       {Opt_oldalloc, "oldalloc"},
+       {Opt_orlov, "orlov"},
+       {Opt_user_xattr, "user_xattr"},
+       {Opt_nouser_xattr, "nouser_xattr"},
+       {Opt_acl, "acl"},
+       {Opt_noacl, "noacl"},
+       {Opt_reservation, "reservation"},
+       {Opt_noreservation, "noreservation"},
+       {Opt_noload, "noload"},
+       {Opt_nobh, "nobh"},
+       {Opt_bh, "bh"},
+       {Opt_commit, "commit=%u"},
+       {Opt_journal_update, "journal=update"},
+       {Opt_journal_inum, "journal=%u"},
+       {Opt_journal_dev, "journal_dev=%u"},
+       {Opt_abort, "abort"},
+       {Opt_data_journal, "data=journal"},
+       {Opt_data_ordered, "data=ordered"},
+       {Opt_data_writeback, "data=writeback"},
+       {Opt_offusrjquota, "usrjquota="},
+       {Opt_usrjquota, "usrjquota=%s"},
+       {Opt_offgrpjquota, "grpjquota="},
+       {Opt_grpjquota, "grpjquota=%s"},
+       {Opt_jqfmt_vfsold, "jqfmt=vfsold"},
+       {Opt_jqfmt_vfsv0, "jqfmt=vfsv0"},
+       {Opt_grpquota, "grpquota"},
+       {Opt_noquota, "noquota"},
+       {Opt_quota, "quota"},
+       {Opt_usrquota, "usrquota"},
+       {Opt_barrier, "barrier=%u"},
+       {Opt_extents, "extents"},
+       {Opt_err, NULL},
+       {Opt_resize, "resize"},
+};
+
+static ext4_fsblk_t get_sb_block(void **data)
+{
+       ext4_fsblk_t    sb_block;
+       char            *options = (char *) *data;
+
+       if (!options || strncmp(options, "sb=", 3) != 0)
+               return 1;       /* Default location */
+       options += 3;
+       /*todo: use simple_strtoll with >32bit ext4 */
+       sb_block = simple_strtoul(options, &options, 0);
+       if (*options && *options != ',') {
+               printk("EXT4-fs: Invalid sb specification: %s\n",
+                      (char *) *data);
+               return 1;
+       }
+       if (*options == ',')
+               options++;
+       *data = (void *) options;
+       return sb_block;
+}
+
+static int parse_options (char *options, struct super_block *sb,
+                         unsigned int *inum, unsigned long *journal_devnum,
+                         ext4_fsblk_t *n_blocks_count, int is_remount)
+{
+       struct ext4_sb_info *sbi = EXT4_SB(sb);
+       char * p;
+       substring_t args[MAX_OPT_ARGS];
+       int data_opt = 0;
+       int option;
+#ifdef CONFIG_QUOTA
+       int qtype;
+       char *qname;
+#endif
+
+       if (!options)
+               return 1;
+
+       while ((p = strsep (&options, ",")) != NULL) {
+               int token;
+               if (!*p)
+                       continue;
+
+               token = match_token(p, tokens, args);
+               switch (token) {
+               case Opt_bsd_df:
+                       clear_opt (sbi->s_mount_opt, MINIX_DF);
+                       break;
+               case Opt_minix_df:
+                       set_opt (sbi->s_mount_opt, MINIX_DF);
+                       break;
+               case Opt_grpid:
+                       set_opt (sbi->s_mount_opt, GRPID);
+                       break;
+               case Opt_nogrpid:
+                       clear_opt (sbi->s_mount_opt, GRPID);
+                       break;
+               case Opt_resuid:
+                       if (match_int(&args[0], &option))
+                               return 0;
+                       sbi->s_resuid = option;
+                       break;
+               case Opt_resgid:
+                       if (match_int(&args[0], &option))
+                               return 0;
+                       sbi->s_resgid = option;
+                       break;
+               case Opt_sb:
+                       /* handled by get_sb_block() instead of here */
+                       /* *sb_block = match_int(&args[0]); */
+                       break;
+               case Opt_err_panic:
+                       clear_opt (sbi->s_mount_opt, ERRORS_CONT);
+                       clear_opt (sbi->s_mount_opt, ERRORS_RO);
+                       set_opt (sbi->s_mount_opt, ERRORS_PANIC);
+                       break;
+               case Opt_err_ro:
+                       clear_opt (sbi->s_mount_opt, ERRORS_CONT);
+                       clear_opt (sbi->s_mount_opt, ERRORS_PANIC);
+                       set_opt (sbi->s_mount_opt, ERRORS_RO);
+                       break;
+               case Opt_err_cont:
+                       clear_opt (sbi->s_mount_opt, ERRORS_RO);
+                       clear_opt (sbi->s_mount_opt, ERRORS_PANIC);
+                       set_opt (sbi->s_mount_opt, ERRORS_CONT);
+                       break;
+               case Opt_nouid32:
+                       set_opt (sbi->s_mount_opt, NO_UID32);
+                       break;
+               case Opt_nocheck:
+                       clear_opt (sbi->s_mount_opt, CHECK);
+                       break;
+               case Opt_debug:
+                       set_opt (sbi->s_mount_opt, DEBUG);
+                       break;
+               case Opt_oldalloc:
+                       set_opt (sbi->s_mount_opt, OLDALLOC);
+                       break;
+               case Opt_orlov:
+                       clear_opt (sbi->s_mount_opt, OLDALLOC);
+                       break;
+#ifdef CONFIG_EXT4DEV_FS_XATTR
+               case Opt_user_xattr:
+                       set_opt (sbi->s_mount_opt, XATTR_USER);
+                       break;
+               case Opt_nouser_xattr:
+                       clear_opt (sbi->s_mount_opt, XATTR_USER);
+                       break;
+#else
+               case Opt_user_xattr:
+               case Opt_nouser_xattr:
+                       printk("EXT4 (no)user_xattr options not supported\n");
+                       break;
+#endif
+#ifdef CONFIG_EXT4DEV_FS_POSIX_ACL
+               case Opt_acl:
+                       set_opt(sbi->s_mount_opt, POSIX_ACL);
+                       break;
+               case Opt_noacl:
+                       clear_opt(sbi->s_mount_opt, POSIX_ACL);
+                       break;
+#else
+               case Opt_acl:
+               case Opt_noacl:
+                       printk("EXT4 (no)acl options not supported\n");
+                       break;
+#endif
+               case Opt_reservation:
+                       set_opt(sbi->s_mount_opt, RESERVATION);
+                       break;
+               case Opt_noreservation:
+                       clear_opt(sbi->s_mount_opt, RESERVATION);
+                       break;
+               case Opt_journal_update:
+                       /* @@@ FIXME */
+                       /* Eventually we will want to be able to create
+                          a journal file here.  For now, only allow the
+                          user to specify an existing inode to be the
+                          journal file. */
+                       if (is_remount) {
+                               printk(KERN_ERR "EXT4-fs: cannot specify "
+                                      "journal on remount\n");
+                               return 0;
+                       }
+                       set_opt (sbi->s_mount_opt, UPDATE_JOURNAL);
+                       break;
+               case Opt_journal_inum:
+                       if (is_remount) {
+                               printk(KERN_ERR "EXT4-fs: cannot specify "
+                                      "journal on remount\n");
+                               return 0;
+                       }
+                       if (match_int(&args[0], &option))
+                               return 0;
+                       *inum = option;
+                       break;
+               case Opt_journal_dev:
+                       if (is_remount) {
+                               printk(KERN_ERR "EXT4-fs: cannot specify "
+                                      "journal on remount\n");
+                               return 0;
+                       }
+                       if (match_int(&args[0], &option))
+                               return 0;
+                       *journal_devnum = option;
+                       break;
+               case Opt_noload:
+                       set_opt (sbi->s_mount_opt, NOLOAD);
+                       break;
+               case Opt_commit:
+                       if (match_int(&args[0], &option))
+                               return 0;
+                       if (option < 0)
+                               return 0;
+                       if (option == 0)
+                               option = JBD_DEFAULT_MAX_COMMIT_AGE;
+                       sbi->s_commit_interval = HZ * option;
+                       break;
+               case Opt_data_journal:
+                       data_opt = EXT4_MOUNT_JOURNAL_DATA;
+                       goto datacheck;
+               case Opt_data_ordered:
+                       data_opt = EXT4_MOUNT_ORDERED_DATA;
+                       goto datacheck;
+               case Opt_data_writeback:
+                       data_opt = EXT4_MOUNT_WRITEBACK_DATA;
+               datacheck:
+                       if (is_remount) {
+                               if ((sbi->s_mount_opt & EXT4_MOUNT_DATA_FLAGS)
+                                               != data_opt) {
+                                       printk(KERN_ERR
+                                               "EXT4-fs: cannot change data "
+                                               "mode on remount\n");
+                                       return 0;
+                               }
+                       } else {
+                               sbi->s_mount_opt &= ~EXT4_MOUNT_DATA_FLAGS;
+                               sbi->s_mount_opt |= data_opt;
+                       }
+                       break;
+#ifdef CONFIG_QUOTA
+               case Opt_usrjquota:
+                       qtype = USRQUOTA;
+                       goto set_qf_name;
+               case Opt_grpjquota:
+                       qtype = GRPQUOTA;
+set_qf_name:
+                       if (sb_any_quota_enabled(sb)) {
+                               printk(KERN_ERR
+                                       "EXT4-fs: Cannot change journalled "
+                                       "quota options when quota turned on.\n");
+                               return 0;
+                       }
+                       qname = match_strdup(&args[0]);
+                       if (!qname) {
+                               printk(KERN_ERR
+                                       "EXT4-fs: not enough memory for "
+                                       "storing quotafile name.\n");
+                               return 0;
+                       }
+                       if (sbi->s_qf_names[qtype] &&
+                           strcmp(sbi->s_qf_names[qtype], qname)) {
+                               printk(KERN_ERR
+                                       "EXT4-fs: %s quota file already "
+                                       "specified.\n", QTYPE2NAME(qtype));
+                               kfree(qname);
+                               return 0;
+                       }
+                       sbi->s_qf_names[qtype] = qname;
+                       if (strchr(sbi->s_qf_names[qtype], '/')) {
+                               printk(KERN_ERR
+                                       "EXT4-fs: quotafile must be on "
+                                       "filesystem root.\n");
+                               kfree(sbi->s_qf_names[qtype]);
+                               sbi->s_qf_names[qtype] = NULL;
+                               return 0;
+                       }
+                       set_opt(sbi->s_mount_opt, QUOTA);
+                       break;
+               case Opt_offusrjquota:
+                       qtype = USRQUOTA;
+                       goto clear_qf_name;
+               case Opt_offgrpjquota:
+                       qtype = GRPQUOTA;
+clear_qf_name:
+                       if (sb_any_quota_enabled(sb)) {
+                               printk(KERN_ERR "EXT4-fs: Cannot change "
+                                       "journalled quota options when "
+                                       "quota turned on.\n");
+                               return 0;
+                       }
+                       /*
+                        * The space will be released later when all options
+                        * are confirmed to be correct
+                        */
+                       sbi->s_qf_names[qtype] = NULL;
+                       break;
+               case Opt_jqfmt_vfsold:
+                       sbi->s_jquota_fmt = QFMT_VFS_OLD;
+                       break;
+               case Opt_jqfmt_vfsv0:
+                       sbi->s_jquota_fmt = QFMT_VFS_V0;
+                       break;
+               case Opt_quota:
+               case Opt_usrquota:
+                       set_opt(sbi->s_mount_opt, QUOTA);
+                       set_opt(sbi->s_mount_opt, USRQUOTA);
+                       break;
+               case Opt_grpquota:
+                       set_opt(sbi->s_mount_opt, QUOTA);
+                       set_opt(sbi->s_mount_opt, GRPQUOTA);
+                       break;
+               case Opt_noquota:
+                       if (sb_any_quota_enabled(sb)) {
+                               printk(KERN_ERR "EXT4-fs: Cannot change quota "
+                                       "options when quota turned on.\n");
+                               return 0;
+                       }
+                       clear_opt(sbi->s_mount_opt, QUOTA);
+                       clear_opt(sbi->s_mount_opt, USRQUOTA);
+                       clear_opt(sbi->s_mount_opt, GRPQUOTA);
+                       break;
+#else
+               case Opt_quota:
+               case Opt_usrquota:
+               case Opt_grpquota:
+               case Opt_usrjquota:
+               case Opt_grpjquota:
+               case Opt_offusrjquota:
+               case Opt_offgrpjquota:
+               case Opt_jqfmt_vfsold:
+               case Opt_jqfmt_vfsv0:
+                       printk(KERN_ERR
+                               "EXT4-fs: journalled quota options not "
+                               "supported.\n");
+                       break;
+               case Opt_noquota:
+                       break;
+#endif
+               case Opt_abort:
+                       set_opt(sbi->s_mount_opt, ABORT);
+                       break;
+               case Opt_barrier:
+                       if (match_int(&args[0], &option))
+                               return 0;
+                       if (option)
+                               set_opt(sbi->s_mount_opt, BARRIER);
+                       else
+                               clear_opt(sbi->s_mount_opt, BARRIER);
+                       break;
+               case Opt_ignore:
+                       break;
+               case Opt_resize:
+                       if (!is_remount) {
+                               printk("EXT4-fs: resize option only available "
+                                       "for remount\n");
+                               return 0;
+                       }
+                       if (match_int(&args[0], &option) != 0)
+                               return 0;
+                       *n_blocks_count = option;
+                       break;
+               case Opt_nobh:
+                       set_opt(sbi->s_mount_opt, NOBH);
+                       break;
+               case Opt_bh:
+                       clear_opt(sbi->s_mount_opt, NOBH);
+                       break;
+               case Opt_extents:
+                       set_opt (sbi->s_mount_opt, EXTENTS);
+                       break;
+               default:
+                       printk (KERN_ERR
+                               "EXT4-fs: Unrecognized mount option \"%s\" "
+                               "or missing value\n", p);
+                       return 0;
+               }
+       }
+#ifdef CONFIG_QUOTA
+       if (sbi->s_qf_names[USRQUOTA] || sbi->s_qf_names[GRPQUOTA]) {
+               if ((sbi->s_mount_opt & EXT4_MOUNT_USRQUOTA) &&
+                    sbi->s_qf_names[USRQUOTA])
+                       clear_opt(sbi->s_mount_opt, USRQUOTA);
+
+               if ((sbi->s_mount_opt & EXT4_MOUNT_GRPQUOTA) &&
+                    sbi->s_qf_names[GRPQUOTA])
+                       clear_opt(sbi->s_mount_opt, GRPQUOTA);
+
+               if ((sbi->s_qf_names[USRQUOTA] &&
+                               (sbi->s_mount_opt & EXT4_MOUNT_GRPQUOTA)) ||
+                   (sbi->s_qf_names[GRPQUOTA] &&
+                               (sbi->s_mount_opt & EXT4_MOUNT_USRQUOTA))) {
+                       printk(KERN_ERR "EXT4-fs: old and new quota "
+                                       "format mixing.\n");
+                       return 0;
+               }
+
+               if (!sbi->s_jquota_fmt) {
+                       printk(KERN_ERR "EXT4-fs: journalled quota format "
+                                       "not specified.\n");
+                       return 0;
+               }
+       } else {
+               if (sbi->s_jquota_fmt) {
+                       printk(KERN_ERR "EXT4-fs: journalled quota format "
+                                       "specified with no journalling "
+                                       "enabled.\n");
+                       return 0;
+               }
+       }
+#endif
+       return 1;
+}
+
+static int ext4_setup_super(struct super_block *sb, struct ext4_super_block *es,
+                           int read_only)
+{
+       struct ext4_sb_info *sbi = EXT4_SB(sb);
+       int res = 0;
+
+       if (le32_to_cpu(es->s_rev_level) > EXT4_MAX_SUPP_REV) {
+               printk (KERN_ERR "EXT4-fs warning: revision level too high, "
+                       "forcing read-only mode\n");
+               res = MS_RDONLY;
+       }
+       if (read_only)
+               return res;
+       if (!(sbi->s_mount_state & EXT4_VALID_FS))
+               printk (KERN_WARNING "EXT4-fs warning: mounting unchecked fs, "
+                       "running e2fsck is recommended\n");
+       else if ((sbi->s_mount_state & EXT4_ERROR_FS))
+               printk (KERN_WARNING
+                       "EXT4-fs warning: mounting fs with errors, "
+                       "running e2fsck is recommended\n");
+       else if ((__s16) le16_to_cpu(es->s_max_mnt_count) >= 0 &&
+                le16_to_cpu(es->s_mnt_count) >=
+                (unsigned short) (__s16) le16_to_cpu(es->s_max_mnt_count))
+               printk (KERN_WARNING
+                       "EXT4-fs warning: maximal mount count reached, "
+                       "running e2fsck is recommended\n");
+       else if (le32_to_cpu(es->s_checkinterval) &&
+               (le32_to_cpu(es->s_lastcheck) +
+                       le32_to_cpu(es->s_checkinterval) <= get_seconds()))
+               printk (KERN_WARNING
+                       "EXT4-fs warning: checktime reached, "
+                       "running e2fsck is recommended\n");
+#if 0
+               /* @@@ We _will_ want to clear the valid bit if we find
+                * inconsistencies, to force a fsck at reboot.  But for
+                * a plain journaled filesystem we can keep it set as
+                * valid forever! :)
+                */
+       es->s_state = cpu_to_le16(le16_to_cpu(es->s_state) & ~EXT4_VALID_FS);
+#endif
+       if (!(__s16) le16_to_cpu(es->s_max_mnt_count))
+               es->s_max_mnt_count = cpu_to_le16(EXT4_DFL_MAX_MNT_COUNT);
+       es->s_mnt_count=cpu_to_le16(le16_to_cpu(es->s_mnt_count) + 1);
+       es->s_mtime = cpu_to_le32(get_seconds());
+       ext4_update_dynamic_rev(sb);
+       EXT4_SET_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
+
+       ext4_commit_super(sb, es, 1);
+       if (test_opt(sb, DEBUG))
+               printk(KERN_INFO "[EXT4 FS bs=%lu, gc=%lu, "
+                               "bpg=%lu, ipg=%lu, mo=%04lx]\n",
+                       sb->s_blocksize,
+                       sbi->s_groups_count,
+                       EXT4_BLOCKS_PER_GROUP(sb),
+                       EXT4_INODES_PER_GROUP(sb),
+                       sbi->s_mount_opt);
+
+       printk(KERN_INFO "EXT4 FS on %s, ", sb->s_id);
+       if (EXT4_SB(sb)->s_journal->j_inode == NULL) {
+               char b[BDEVNAME_SIZE];
+
+               printk("external journal on %s\n",
+                       bdevname(EXT4_SB(sb)->s_journal->j_dev, b));
+       } else {
+               printk("internal journal\n");
+       }
+       return res;
+}
+
+/* Called at mount-time, super-block is locked */
+static int ext4_check_descriptors (struct super_block * sb)
+{
+       struct ext4_sb_info *sbi = EXT4_SB(sb);
+       ext4_fsblk_t first_block = le32_to_cpu(sbi->s_es->s_first_data_block);
+       ext4_fsblk_t last_block;
+       ext4_fsblk_t block_bitmap;
+       ext4_fsblk_t inode_bitmap;
+       ext4_fsblk_t inode_table;
+       struct ext4_group_desc * gdp = NULL;
+       int desc_block = 0;
+       int i;
+
+       ext4_debug ("Checking group descriptors");
+
+       for (i = 0; i < sbi->s_groups_count; i++)
+       {
+               if (i == sbi->s_groups_count - 1)
+                       last_block = ext4_blocks_count(sbi->s_es) - 1;
+               else
+                       last_block = first_block +
+                               (EXT4_BLOCKS_PER_GROUP(sb) - 1);
+
+               if ((i % EXT4_DESC_PER_BLOCK(sb)) == 0)
+                       gdp = (struct ext4_group_desc *)
+                                       sbi->s_group_desc[desc_block++]->b_data;
+               block_bitmap = ext4_block_bitmap(sb, gdp);
+               if (block_bitmap < first_block || block_bitmap > last_block)
+               {
+                       ext4_error (sb, "ext4_check_descriptors",
+                                   "Block bitmap for group %d"
+                                   " not in group (block %llu)!",
+                                   i, block_bitmap);
+                       return 0;
+               }
+               inode_bitmap = ext4_inode_bitmap(sb, gdp);
+               if (inode_bitmap < first_block || inode_bitmap > last_block)
+               {
+                       ext4_error (sb, "ext4_check_descriptors",
+                                   "Inode bitmap for group %d"
+                                   " not in group (block %llu)!",
+                                   i, inode_bitmap);
+                       return 0;
+               }
+               inode_table = ext4_inode_table(sb, gdp);
+               if (inode_table < first_block ||
+                   inode_table + sbi->s_itb_per_group > last_block)
+               {
+                       ext4_error (sb, "ext4_check_descriptors",
+                                   "Inode table for group %d"
+                                   " not in group (block %llu)!",
+                                   i, inode_table);
+                       return 0;
+               }
+               first_block += EXT4_BLOCKS_PER_GROUP(sb);
+               gdp = (struct ext4_group_desc *)
+                       ((__u8 *)gdp + EXT4_DESC_SIZE(sb));
+       }
+
+       ext4_free_blocks_count_set(sbi->s_es, ext4_count_free_blocks(sb));
+       sbi->s_es->s_free_inodes_count=cpu_to_le32(ext4_count_free_inodes(sb));
+       return 1;
+}
+
+
+/* ext4_orphan_cleanup() walks a singly-linked list of inodes (starting at
+ * the superblock) which were deleted from all directories, but held open by
+ * a process at the time of a crash.  We walk the list and try to delete these
+ * inodes at recovery time (only with a read-write filesystem).
+ *
+ * In order to keep the orphan inode chain consistent during traversal (in
+ * case of crash during recovery), we link each inode into the superblock
+ * orphan list_head and handle it the same way as an inode deletion during
+ * normal operation (which journals the operations for us).
+ *
+ * We only do an iget() and an iput() on each inode, which is very safe if we
+ * accidentally point at an in-use or already deleted inode.  The worst that
+ * can happen in this case is that we get a "bit already cleared" message from
+ * ext4_free_inode().  The only reason we would point at a wrong inode is if
+ * e2fsck was run on this filesystem, and it must have already done the orphan
+ * inode cleanup for us, so we can safely abort without any further action.
+ */
+static void ext4_orphan_cleanup (struct super_block * sb,
+                                struct ext4_super_block * es)
+{
+       unsigned int s_flags = sb->s_flags;
+       int nr_orphans = 0, nr_truncates = 0;
+#ifdef CONFIG_QUOTA
+       int i;
+#endif
+       if (!es->s_last_orphan) {
+               jbd_debug(4, "no orphan inodes to clean up\n");
+               return;
+       }
+
+       if (EXT4_SB(sb)->s_mount_state & EXT4_ERROR_FS) {
+               if (es->s_last_orphan)
+                       jbd_debug(1, "Errors on filesystem, "
+                                 "clearing orphan list.\n");
+               es->s_last_orphan = 0;
+               jbd_debug(1, "Skipping orphan recovery on fs with errors.\n");
+               return;
+       }
+
+       if (s_flags & MS_RDONLY) {
+               printk(KERN_INFO "EXT4-fs: %s: orphan cleanup on readonly fs\n",
+                      sb->s_id);
+               sb->s_flags &= ~MS_RDONLY;
+       }
+#ifdef CONFIG_QUOTA
+       /* Needed for iput() to work correctly and not trash data */
+       sb->s_flags |= MS_ACTIVE;
+       /* Turn on quotas so that they are updated correctly */
+       for (i = 0; i < MAXQUOTAS; i++) {
+               if (EXT4_SB(sb)->s_qf_names[i]) {
+                       int ret = ext4_quota_on_mount(sb, i);
+                       if (ret < 0)
+                               printk(KERN_ERR
+                                       "EXT4-fs: Cannot turn on journalled "
+                                       "quota: error %d\n", ret);
+               }
+       }
+#endif
+
+       while (es->s_last_orphan) {
+               struct inode *inode;
+
+               if (!(inode =
+                     ext4_orphan_get(sb, le32_to_cpu(es->s_last_orphan)))) {
+                       es->s_last_orphan = 0;
+                       break;
+               }
+
+               list_add(&EXT4_I(inode)->i_orphan, &EXT4_SB(sb)->s_orphan);
+               DQUOT_INIT(inode);
+               if (inode->i_nlink) {
+                       printk(KERN_DEBUG
+                               "%s: truncating inode %lu to %Ld bytes\n",
+                               __FUNCTION__, inode->i_ino, inode->i_size);
+                       jbd_debug(2, "truncating inode %lu to %Ld bytes\n",
+                                 inode->i_ino, inode->i_size);
+                       ext4_truncate(inode);
+                       nr_truncates++;
+               } else {
+                       printk(KERN_DEBUG
+                               "%s: deleting unreferenced inode %lu\n",
+                               __FUNCTION__, inode->i_ino);
+                       jbd_debug(2, "deleting unreferenced inode %lu\n",
+                                 inode->i_ino);
+                       nr_orphans++;
+               }
+               iput(inode);  /* The delete magic happens here! */
+       }
+
+#define PLURAL(x) (x), ((x)==1) ? "" : "s"
+
+       if (nr_orphans)
+               printk(KERN_INFO "EXT4-fs: %s: %d orphan inode%s deleted\n",
+                      sb->s_id, PLURAL(nr_orphans));
+       if (nr_truncates)
+               printk(KERN_INFO "EXT4-fs: %s: %d truncate%s cleaned up\n",
+                      sb->s_id, PLURAL(nr_truncates));
+#ifdef CONFIG_QUOTA
+       /* Turn quotas off */
+       for (i = 0; i < MAXQUOTAS; i++) {
+               if (sb_dqopt(sb)->files[i])
+                       vfs_quota_off(sb, i);
+       }
+#endif
+       sb->s_flags = s_flags; /* Restore MS_RDONLY status */
+}
+
+#define log2(n) ffz(~(n))
+
+/*
+ * Maximal file size.  There is a direct, and {,double-,triple-}indirect
+ * block limit, and also a limit of (2^32 - 1) 512-byte sectors in i_blocks.
+ * We need to be 1 filesystem block less than the 2^32 sector limit.
+ */
+static loff_t ext4_max_size(int bits)
+{
+       loff_t res = EXT4_NDIR_BLOCKS;
+       /* This constant is calculated to be the largest file size for a
+        * dense, 4k-blocksize file such that the total number of
+        * sectors in the file, including data and all indirect blocks,
+        * does not exceed 2^32. */
+       const loff_t upper_limit = 0x1ff7fffd000LL;
+
+       res += 1LL << (bits-2);
+       res += 1LL << (2*(bits-2));
+       res += 1LL << (3*(bits-2));
+       res <<= bits;
+       if (res > upper_limit)
+               res = upper_limit;
+       return res;
+}
+
+static ext4_fsblk_t descriptor_loc(struct super_block *sb,
+                               ext4_fsblk_t logical_sb_block, int nr)
+{
+       struct ext4_sb_info *sbi = EXT4_SB(sb);
+       unsigned long bg, first_meta_bg;
+       int has_super = 0;
+
+       first_meta_bg = le32_to_cpu(sbi->s_es->s_first_meta_bg);
+
+       if (!EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_META_BG) ||
+           nr < first_meta_bg)
+               return logical_sb_block + nr + 1;
+       bg = sbi->s_desc_per_block * nr;
+       if (ext4_bg_has_super(sb, bg))
+               has_super = 1;
+       return (has_super + ext4_group_first_block_no(sb, bg));
+}
+
+
+static int ext4_fill_super (struct super_block *sb, void *data, int silent)
+{
+       struct buffer_head * bh;
+       struct ext4_super_block *es = NULL;
+       struct ext4_sb_info *sbi;
+       ext4_fsblk_t block;
+       ext4_fsblk_t sb_block = get_sb_block(&data);
+       ext4_fsblk_t logical_sb_block;
+       unsigned long offset = 0;
+       unsigned int journal_inum = 0;
+       unsigned long journal_devnum = 0;
+       unsigned long def_mount_opts;
+       struct inode *root;
+       int blocksize;
+       int hblock;
+       int db_count;
+       int i;
+       int needs_recovery;
+       __le32 features;
+       __u64 blocks_count;
+
+       sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
+       if (!sbi)
+               return -ENOMEM;
+       sb->s_fs_info = sbi;
+       sbi->s_mount_opt = 0;
+       sbi->s_resuid = EXT4_DEF_RESUID;
+       sbi->s_resgid = EXT4_DEF_RESGID;
+
+       unlock_kernel();
+
+       blocksize = sb_min_blocksize(sb, EXT4_MIN_BLOCK_SIZE);
+       if (!blocksize) {
+               printk(KERN_ERR "EXT4-fs: unable to set blocksize\n");
+               goto out_fail;
+       }
+
+       /*
+        * The ext4 superblock will not be buffer aligned for other than 1kB
+        * block sizes.  We need to calculate the offset from buffer start.
+        */
+       if (blocksize != EXT4_MIN_BLOCK_SIZE) {
+               logical_sb_block = sb_block * EXT4_MIN_BLOCK_SIZE;
+               offset = do_div(logical_sb_block, blocksize);
+       } else {
+               logical_sb_block = sb_block;
+       }
+
+       if (!(bh = sb_bread(sb, logical_sb_block))) {
+               printk (KERN_ERR "EXT4-fs: unable to read superblock\n");
+               goto out_fail;
+       }
+       /*
+        * Note: s_es must be initialized as soon as possible because
+        *       some ext4 macro-instructions depend on its value
+        */
+       es = (struct ext4_super_block *) (((char *)bh->b_data) + offset);
+       sbi->s_es = es;
+       sb->s_magic = le16_to_cpu(es->s_magic);
+       if (sb->s_magic != EXT4_SUPER_MAGIC)
+               goto cantfind_ext4;
+
+       /* Set defaults before we parse the mount options */
+       def_mount_opts = le32_to_cpu(es->s_default_mount_opts);
+       if (def_mount_opts & EXT4_DEFM_DEBUG)
+               set_opt(sbi->s_mount_opt, DEBUG);
+       if (def_mount_opts & EXT4_DEFM_BSDGROUPS)
+               set_opt(sbi->s_mount_opt, GRPID);
+       if (def_mount_opts & EXT4_DEFM_UID16)
+               set_opt(sbi->s_mount_opt, NO_UID32);
+       if (def_mount_opts & EXT4_DEFM_XATTR_USER)
+               set_opt(sbi->s_mount_opt, XATTR_USER);
+       if (def_mount_opts & EXT4_DEFM_ACL)
+               set_opt(sbi->s_mount_opt, POSIX_ACL);
+       if ((def_mount_opts & EXT4_DEFM_JMODE) == EXT4_DEFM_JMODE_DATA)
+               sbi->s_mount_opt |= EXT4_MOUNT_JOURNAL_DATA;
+       else if ((def_mount_opts & EXT4_DEFM_JMODE) == EXT4_DEFM_JMODE_ORDERED)
+               sbi->s_mount_opt |= EXT4_MOUNT_ORDERED_DATA;
+       else if ((def_mount_opts & EXT4_DEFM_JMODE) == EXT4_DEFM_JMODE_WBACK)
+               sbi->s_mount_opt |= EXT4_MOUNT_WRITEBACK_DATA;
+
+       if (le16_to_cpu(sbi->s_es->s_errors) == EXT4_ERRORS_PANIC)
+               set_opt(sbi->s_mount_opt, ERRORS_PANIC);
+       else if (le16_to_cpu(sbi->s_es->s_errors) == EXT4_ERRORS_RO)
+               set_opt(sbi->s_mount_opt, ERRORS_RO);
+       else
+               set_opt(sbi->s_mount_opt, ERRORS_CONT);
+
+       sbi->s_resuid = le16_to_cpu(es->s_def_resuid);
+       sbi->s_resgid = le16_to_cpu(es->s_def_resgid);
+
+       set_opt(sbi->s_mount_opt, RESERVATION);
+
+       if (!parse_options ((char *) data, sb, &journal_inum, &journal_devnum,
+                           NULL, 0))
+               goto failed_mount;
+
+       sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
+               ((sbi->s_mount_opt & EXT4_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0);
+
+       if (le32_to_cpu(es->s_rev_level) == EXT4_GOOD_OLD_REV &&
+           (EXT4_HAS_COMPAT_FEATURE(sb, ~0U) ||
+            EXT4_HAS_RO_COMPAT_FEATURE(sb, ~0U) ||
+            EXT4_HAS_INCOMPAT_FEATURE(sb, ~0U)))
+               printk(KERN_WARNING
+                      "EXT4-fs warning: feature flags set on rev 0 fs, "
+                      "running e2fsck is recommended\n");
+       /*
+        * Check feature flags regardless of the revision level, since we
+        * previously didn't change the revision level when setting the flags,
+        * so there is a chance incompat flags are set on a rev 0 filesystem.
+        */
+       features = EXT4_HAS_INCOMPAT_FEATURE(sb, ~EXT4_FEATURE_INCOMPAT_SUPP);
+       if (features) {
+               printk(KERN_ERR "EXT4-fs: %s: couldn't mount because of "
+                      "unsupported optional features (%x).\n",
+                      sb->s_id, le32_to_cpu(features));
+               goto failed_mount;
+       }
+       features = EXT4_HAS_RO_COMPAT_FEATURE(sb, ~EXT4_FEATURE_RO_COMPAT_SUPP);
+       if (!(sb->s_flags & MS_RDONLY) && features) {
+               printk(KERN_ERR "EXT4-fs: %s: couldn't mount RDWR because of "
+                      "unsupported optional features (%x).\n",
+                      sb->s_id, le32_to_cpu(features));
+               goto failed_mount;
+       }
+       blocksize = BLOCK_SIZE << le32_to_cpu(es->s_log_block_size);
+
+       if (blocksize < EXT4_MIN_BLOCK_SIZE ||
+           blocksize > EXT4_MAX_BLOCK_SIZE) {
+               printk(KERN_ERR
+                      "EXT4-fs: Unsupported filesystem blocksize %d on %s.\n",
+                      blocksize, sb->s_id);
+               goto failed_mount;
+       }
+
+       hblock = bdev_hardsect_size(sb->s_bdev);
+       if (sb->s_blocksize != blocksize) {
+               /*
+                * Make sure the blocksize for the filesystem is larger
+                * than the hardware sectorsize for the machine.
+                */
+               if (blocksize < hblock) {
+                       printk(KERN_ERR "EXT4-fs: blocksize %d too small for "
+                              "device blocksize %d.\n", blocksize, hblock);
+                       goto failed_mount;
+               }
+
+               brelse (bh);
+               sb_set_blocksize(sb, blocksize);
+               logical_sb_block = sb_block * EXT4_MIN_BLOCK_SIZE;
+               offset = do_div(logical_sb_block, blocksize);
+               bh = sb_bread(sb, logical_sb_block);
+               if (!bh) {
+                       printk(KERN_ERR
+                              "EXT4-fs: Can't read superblock on 2nd try.\n");
+                       goto failed_mount;
+               }
+               es = (struct ext4_super_block *)(((char *)bh->b_data) + offset);
+               sbi->s_es = es;
+               if (es->s_magic != cpu_to_le16(EXT4_SUPER_MAGIC)) {
+                       printk (KERN_ERR
+                               "EXT4-fs: Magic mismatch, very weird !\n");
+                       goto failed_mount;
+               }
+       }
+
+       sb->s_maxbytes = ext4_max_size(sb->s_blocksize_bits);
+
+       if (le32_to_cpu(es->s_rev_level) == EXT4_GOOD_OLD_REV) {
+               sbi->s_inode_size = EXT4_GOOD_OLD_INODE_SIZE;
+               sbi->s_first_ino = EXT4_GOOD_OLD_FIRST_INO;
+       } else {
+               sbi->s_inode_size = le16_to_cpu(es->s_inode_size);
+               sbi->s_first_ino = le32_to_cpu(es->s_first_ino);
+               if ((sbi->s_inode_size < EXT4_GOOD_OLD_INODE_SIZE) ||
+                   (sbi->s_inode_size & (sbi->s_inode_size - 1)) ||
+                   (sbi->s_inode_size > blocksize)) {
+                       printk (KERN_ERR
+                               "EXT4-fs: unsupported inode size: %d\n",
+                               sbi->s_inode_size);
+                       goto failed_mount;
+               }
+       }
+       sbi->s_frag_size = EXT4_MIN_FRAG_SIZE <<
+                                  le32_to_cpu(es->s_log_frag_size);
+       if (blocksize != sbi->s_frag_size) {
+               printk(KERN_ERR
+                      "EXT4-fs: fragsize %lu != blocksize %u (unsupported)\n",
+                      sbi->s_frag_size, blocksize);
+               goto failed_mount;
+       }
+       sbi->s_desc_size = le16_to_cpu(es->s_desc_size);
+       if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_64BIT)) {
+               if (sbi->s_desc_size < EXT4_MIN_DESC_SIZE_64BIT ||
+                   sbi->s_desc_size > EXT4_MAX_DESC_SIZE ||
+                   sbi->s_desc_size & (sbi->s_desc_size - 1)) {
+                       printk(KERN_ERR
+                              "EXT4-fs: unsupported descriptor size %lu\n",
+                              sbi->s_desc_size);
+                       goto failed_mount;
+               }
+       } else
+               sbi->s_desc_size = EXT4_MIN_DESC_SIZE;
+       sbi->s_blocks_per_group = le32_to_cpu(es->s_blocks_per_group);
+       sbi->s_frags_per_group = le32_to_cpu(es->s_frags_per_group);
+       sbi->s_inodes_per_group = le32_to_cpu(es->s_inodes_per_group);
+       if (EXT4_INODE_SIZE(sb) == 0)
+               goto cantfind_ext4;
+       sbi->s_inodes_per_block = blocksize / EXT4_INODE_SIZE(sb);
+       if (sbi->s_inodes_per_block == 0)
+               goto cantfind_ext4;
+       sbi->s_itb_per_group = sbi->s_inodes_per_group /
+                                       sbi->s_inodes_per_block;
+       sbi->s_desc_per_block = blocksize / EXT4_DESC_SIZE(sb);
+       sbi->s_sbh = bh;
+       sbi->s_mount_state = le16_to_cpu(es->s_state);
+       sbi->s_addr_per_block_bits = log2(EXT4_ADDR_PER_BLOCK(sb));
+       sbi->s_desc_per_block_bits = log2(EXT4_DESC_PER_BLOCK(sb));
+       for (i=0; i < 4; i++)
+               sbi->s_hash_seed[i] = le32_to_cpu(es->s_hash_seed[i]);
+       sbi->s_def_hash_version = es->s_def_hash_version;
+
+       if (sbi->s_blocks_per_group > blocksize * 8) {
+               printk (KERN_ERR
+                       "EXT4-fs: #blocks per group too big: %lu\n",
+                       sbi->s_blocks_per_group);
+               goto failed_mount;
+       }
+       if (sbi->s_frags_per_group > blocksize * 8) {
+               printk (KERN_ERR
+                       "EXT4-fs: #fragments per group too big: %lu\n",
+                       sbi->s_frags_per_group);
+               goto failed_mount;
+       }
+       if (sbi->s_inodes_per_group > blocksize * 8) {
+               printk (KERN_ERR
+                       "EXT4-fs: #inodes per group too big: %lu\n",
+                       sbi->s_inodes_per_group);
+               goto failed_mount;
+       }
+
+       if (ext4_blocks_count(es) >
+                   (sector_t)(~0ULL) >> (sb->s_blocksize_bits - 9)) {
+               printk(KERN_ERR "EXT4-fs: filesystem on %s:"
+                       " too large to mount safely\n", sb->s_id);
+               if (sizeof(sector_t) < 8)
+                       printk(KERN_WARNING "EXT4-fs: CONFIG_LBD not "
+                                       "enabled\n");
+               goto failed_mount;
+       }
+
+       if (EXT4_BLOCKS_PER_GROUP(sb) == 0)
+               goto cantfind_ext4;
+       blocks_count = (ext4_blocks_count(es) -
+                       le32_to_cpu(es->s_first_data_block) +
+                       EXT4_BLOCKS_PER_GROUP(sb) - 1);
+       do_div(blocks_count, EXT4_BLOCKS_PER_GROUP(sb));
+       sbi->s_groups_count = blocks_count;
+       db_count = (sbi->s_groups_count + EXT4_DESC_PER_BLOCK(sb) - 1) /
+                  EXT4_DESC_PER_BLOCK(sb);
+       sbi->s_group_desc = kmalloc(db_count * sizeof (struct buffer_head *),
+                                   GFP_KERNEL);
+       if (sbi->s_group_desc == NULL) {
+               printk (KERN_ERR "EXT4-fs: not enough memory\n");
+               goto failed_mount;
+       }
+
+       bgl_lock_init(&sbi->s_blockgroup_lock);
+
+       for (i = 0; i < db_count; i++) {
+               block = descriptor_loc(sb, logical_sb_block, i);
+               sbi->s_group_desc[i] = sb_bread(sb, block);
+               if (!sbi->s_group_desc[i]) {
+                       printk (KERN_ERR "EXT4-fs: "
+                               "can't read group descriptor %d\n", i);
+                       db_count = i;
+                       goto failed_mount2;
+               }
+       }
+       if (!ext4_check_descriptors (sb)) {
+               printk(KERN_ERR "EXT4-fs: group descriptors corrupted!\n");
+               goto failed_mount2;
+       }
+       sbi->s_gdb_count = db_count;
+       get_random_bytes(&sbi->s_next_generation, sizeof(u32));
+       spin_lock_init(&sbi->s_next_gen_lock);
+
+       percpu_counter_init(&sbi->s_freeblocks_counter,
+               ext4_count_free_blocks(sb));
+       percpu_counter_init(&sbi->s_freeinodes_counter,
+               ext4_count_free_inodes(sb));
+       percpu_counter_init(&sbi->s_dirs_counter,
+               ext4_count_dirs(sb));
+
+       /* per fileystem reservation list head & lock */
+       spin_lock_init(&sbi->s_rsv_window_lock);
+       sbi->s_rsv_window_root = RB_ROOT;
+       /* Add a single, static dummy reservation to the start of the
+        * reservation window list --- it gives us a placeholder for
+        * append-at-start-of-list which makes the allocation logic
+        * _much_ simpler. */
+       sbi->s_rsv_window_head.rsv_start = EXT4_RESERVE_WINDOW_NOT_ALLOCATED;
+       sbi->s_rsv_window_head.rsv_end = EXT4_RESERVE_WINDOW_NOT_ALLOCATED;
+       sbi->s_rsv_window_head.rsv_alloc_hit = 0;
+       sbi->s_rsv_window_head.rsv_goal_size = 0;
+       ext4_rsv_window_add(sb, &sbi->s_rsv_window_head);
+
+       /*
+        * set up enough so that it can read an inode
+        */
+       sb->s_op = &ext4_sops;
+       sb->s_export_op = &ext4_export_ops;
+       sb->s_xattr = ext4_xattr_handlers;
+#ifdef CONFIG_QUOTA
+       sb->s_qcop = &ext4_qctl_operations;
+       sb->dq_op = &ext4_quota_operations;
+#endif
+       INIT_LIST_HEAD(&sbi->s_orphan); /* unlinked but open files */
+
+       sb->s_root = NULL;
+
+       needs_recovery = (es->s_last_orphan != 0 ||
+                         EXT4_HAS_INCOMPAT_FEATURE(sb,
+                                   EXT4_FEATURE_INCOMPAT_RECOVER));
+
+       /*
+        * The first inode we look at is the journal inode.  Don't try
+        * root first: it may be modified in the journal!
+        */
+       if (!test_opt(sb, NOLOAD) &&
+           EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL)) {
+               if (ext4_load_journal(sb, es, journal_devnum))
+                       goto failed_mount3;
+       } else if (journal_inum) {
+               if (ext4_create_journal(sb, es, journal_inum))
+                       goto failed_mount3;
+       } else {
+               if (!silent)
+                       printk (KERN_ERR
+                               "ext4: No journal on filesystem on %s\n",
+                               sb->s_id);
+               goto failed_mount3;
+       }
+
+       /* We have now updated the journal if required, so we can
+        * validate the data journaling mode. */
+       switch (test_opt(sb, DATA_FLAGS)) {
+       case 0:
+               /* No mode set, assume a default based on the journal
+                * capabilities: ORDERED_DATA if the journal can
+                * cope, else JOURNAL_DATA
+                */
+               if (jbd2_journal_check_available_features
+                   (sbi->s_journal, 0, 0, JBD2_FEATURE_INCOMPAT_REVOKE))
+                       set_opt(sbi->s_mount_opt, ORDERED_DATA);
+               else
+                       set_opt(sbi->s_mount_opt, JOURNAL_DATA);
+               break;
+
+       case EXT4_MOUNT_ORDERED_DATA:
+       case EXT4_MOUNT_WRITEBACK_DATA:
+               if (!jbd2_journal_check_available_features
+                   (sbi->s_journal, 0, 0, JBD2_FEATURE_INCOMPAT_REVOKE)) {
+                       printk(KERN_ERR "EXT4-fs: Journal does not support "
+                              "requested data journaling mode\n");
+                       goto failed_mount4;
+               }
+       default:
+               break;
+       }
+
+       if (test_opt(sb, NOBH)) {
+               if (!(test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_WRITEBACK_DATA)) {
+                       printk(KERN_WARNING "EXT4-fs: Ignoring nobh option - "
+                               "its supported only with writeback mode\n");
+                       clear_opt(sbi->s_mount_opt, NOBH);
+               }
+       }
+       /*
+        * The jbd2_journal_load will have done any necessary log recovery,
+        * so we can safely mount the rest of the filesystem now.
+        */
+
+       root = iget(sb, EXT4_ROOT_INO);
+       sb->s_root = d_alloc_root(root);
+       if (!sb->s_root) {
+               printk(KERN_ERR "EXT4-fs: get root inode failed\n");
+               iput(root);
+               goto failed_mount4;
+       }
+       if (!S_ISDIR(root->i_mode) || !root->i_blocks || !root->i_size) {
+               dput(sb->s_root);
+               sb->s_root = NULL;
+               printk(KERN_ERR "EXT4-fs: corrupt root inode, run e2fsck\n");
+               goto failed_mount4;
+       }
+
+       ext4_setup_super (sb, es, sb->s_flags & MS_RDONLY);
+       /*
+        * akpm: core read_super() calls in here with the superblock locked.
+        * That deadlocks, because orphan cleanup needs to lock the superblock
+        * in numerous places.  Here we just pop the lock - it's relatively
+        * harmless, because we are now ready to accept write_super() requests,
+        * and aviro says that's the only reason for hanging onto the
+        * superblock lock.
+        */
+       EXT4_SB(sb)->s_mount_state |= EXT4_ORPHAN_FS;
+       ext4_orphan_cleanup(sb, es);
+       EXT4_SB(sb)->s_mount_state &= ~EXT4_ORPHAN_FS;
+       if (needs_recovery)
+               printk (KERN_INFO "EXT4-fs: recovery complete.\n");
+       ext4_mark_recovery_complete(sb, es);
+       printk (KERN_INFO "EXT4-fs: mounted filesystem with %s data mode.\n",
+               test_opt(sb,DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA ? "journal":
+               test_opt(sb,DATA_FLAGS) == EXT4_MOUNT_ORDERED_DATA ? "ordered":
+               "writeback");
+
+       ext4_ext_init(sb);
+
+       lock_kernel();
+       return 0;
+
+cantfind_ext4:
+       if (!silent)
+               printk(KERN_ERR "VFS: Can't find ext4 filesystem on dev %s.\n",
+                      sb->s_id);
+       goto failed_mount;
+
+failed_mount4:
+       jbd2_journal_destroy(sbi->s_journal);
+failed_mount3:
+       percpu_counter_destroy(&sbi->s_freeblocks_counter);
+       percpu_counter_destroy(&sbi->s_freeinodes_counter);
+       percpu_counter_destroy(&sbi->s_dirs_counter);
+failed_mount2:
+       for (i = 0; i < db_count; i++)
+               brelse(sbi->s_group_desc[i]);
+       kfree(sbi->s_group_desc);
+failed_mount:
+#ifdef CONFIG_QUOTA
+       for (i = 0; i < MAXQUOTAS; i++)
+               kfree(sbi->s_qf_names[i]);
+#endif
+       ext4_blkdev_remove(sbi);
+       brelse(bh);
+out_fail:
+       sb->s_fs_info = NULL;
+       kfree(sbi);
+       lock_kernel();
+       return -EINVAL;
+}
+
+/*
+ * Setup any per-fs journal parameters now.  We'll do this both on
+ * initial mount, once the journal has been initialised but before we've
+ * done any recovery; and again on any subsequent remount.
+ */
+static void ext4_init_journal_params(struct super_block *sb, journal_t *journal)
+{
+       struct ext4_sb_info *sbi = EXT4_SB(sb);
+
+       if (sbi->s_commit_interval)
+               journal->j_commit_interval = sbi->s_commit_interval;
+       /* We could also set up an ext4-specific default for the commit
+        * interval here, but for now we'll just fall back to the jbd
+        * default. */
+
+       spin_lock(&journal->j_state_lock);
+       if (test_opt(sb, BARRIER))
+               journal->j_flags |= JBD2_BARRIER;
+       else
+               journal->j_flags &= ~JBD2_BARRIER;
+       spin_unlock(&journal->j_state_lock);
+}
+
+static journal_t *ext4_get_journal(struct super_block *sb,
+                                  unsigned int journal_inum)
+{
+       struct inode *journal_inode;
+       journal_t *journal;
+
+       /* First, test for the existence of a valid inode on disk.  Bad
+        * things happen if we iget() an unused inode, as the subsequent
+        * iput() will try to delete it. */
+
+       journal_inode = iget(sb, journal_inum);
+       if (!journal_inode) {
+               printk(KERN_ERR "EXT4-fs: no journal found.\n");
+               return NULL;
+       }
+       if (!journal_inode->i_nlink) {
+               make_bad_inode(journal_inode);
+               iput(journal_inode);
+               printk(KERN_ERR "EXT4-fs: journal inode is deleted.\n");
+               return NULL;
+       }
+
+       jbd_debug(2, "Journal inode found at %p: %Ld bytes\n",
+                 journal_inode, journal_inode->i_size);
+       if (is_bad_inode(journal_inode) || !S_ISREG(journal_inode->i_mode)) {
+               printk(KERN_ERR "EXT4-fs: invalid journal inode.\n");
+               iput(journal_inode);
+               return NULL;
+       }
+
+       journal = jbd2_journal_init_inode(journal_inode);
+       if (!journal) {
+               printk(KERN_ERR "EXT4-fs: Could not load journal inode\n");
+               iput(journal_inode);
+               return NULL;
+       }
+       journal->j_private = sb;
+       ext4_init_journal_params(sb, journal);
+       return journal;
+}
+
+static journal_t *ext4_get_dev_journal(struct super_block *sb,
+                                      dev_t j_dev)
+{
+       struct buffer_head * bh;
+       journal_t *journal;
+       ext4_fsblk_t start;
+       ext4_fsblk_t len;
+       int hblock, blocksize;
+       ext4_fsblk_t sb_block;
+       unsigned long offset;
+       struct ext4_super_block * es;
+       struct block_device *bdev;
+
+       bdev = ext4_blkdev_get(j_dev);
+       if (bdev == NULL)
+               return NULL;
+
+       if (bd_claim(bdev, sb)) {
+               printk(KERN_ERR
+                       "EXT4: failed to claim external journal device.\n");
+               blkdev_put(bdev);
+               return NULL;
+       }
+
+       blocksize = sb->s_blocksize;
+       hblock = bdev_hardsect_size(bdev);
+       if (blocksize < hblock) {
+               printk(KERN_ERR
+                       "EXT4-fs: blocksize too small for journal device.\n");
+               goto out_bdev;
+       }
+
+       sb_block = EXT4_MIN_BLOCK_SIZE / blocksize;
+       offset = EXT4_MIN_BLOCK_SIZE % blocksize;
+       set_blocksize(bdev, blocksize);
+       if (!(bh = __bread(bdev, sb_block, blocksize))) {
+               printk(KERN_ERR "EXT4-fs: couldn't read superblock of "
+                      "external journal\n");
+               goto out_bdev;
+       }
+
+       es = (struct ext4_super_block *) (((char *)bh->b_data) + offset);
+       if ((le16_to_cpu(es->s_magic) != EXT4_SUPER_MAGIC) ||
+           !(le32_to_cpu(es->s_feature_incompat) &
+             EXT4_FEATURE_INCOMPAT_JOURNAL_DEV)) {
+               printk(KERN_ERR "EXT4-fs: external journal has "
+                                       "bad superblock\n");
+               brelse(bh);
+               goto out_bdev;
+       }
+
+       if (memcmp(EXT4_SB(sb)->s_es->s_journal_uuid, es->s_uuid, 16)) {
+               printk(KERN_ERR "EXT4-fs: journal UUID does not match\n");
+               brelse(bh);
+               goto out_bdev;
+       }
+
+       len = ext4_blocks_count(es);
+       start = sb_block + 1;
+       brelse(bh);     /* we're done with the superblock */
+
+       journal = jbd2_journal_init_dev(bdev, sb->s_bdev,
+                                       start, len, blocksize);
+       if (!journal) {
+               printk(KERN_ERR "EXT4-fs: failed to create device journal\n");
+               goto out_bdev;
+       }
+       journal->j_private = sb;
+       ll_rw_block(READ, 1, &journal->j_sb_buffer);
+       wait_on_buffer(journal->j_sb_buffer);
+       if (!buffer_uptodate(journal->j_sb_buffer)) {
+               printk(KERN_ERR "EXT4-fs: I/O error on journal device\n");
+               goto out_journal;
+       }
+       if (be32_to_cpu(journal->j_superblock->s_nr_users) != 1) {
+               printk(KERN_ERR "EXT4-fs: External journal has more than one "
+                                       "user (unsupported) - %d\n",
+                       be32_to_cpu(journal->j_superblock->s_nr_users));
+               goto out_journal;
+       }
+       EXT4_SB(sb)->journal_bdev = bdev;
+       ext4_init_journal_params(sb, journal);
+       return journal;
+out_journal:
+       jbd2_journal_destroy(journal);
+out_bdev:
+       ext4_blkdev_put(bdev);
+       return NULL;
+}
+
+static int ext4_load_journal(struct super_block *sb,
+                            struct ext4_super_block *es,
+                            unsigned long journal_devnum)
+{
+       journal_t *journal;
+       unsigned int journal_inum = le32_to_cpu(es->s_journal_inum);
+       dev_t journal_dev;
+       int err = 0;
+       int really_read_only;
+
+       if (journal_devnum &&
+           journal_devnum != le32_to_cpu(es->s_journal_dev)) {
+               printk(KERN_INFO "EXT4-fs: external journal device major/minor "
+                       "numbers have changed\n");
+               journal_dev = new_decode_dev(journal_devnum);
+       } else
+               journal_dev = new_decode_dev(le32_to_cpu(es->s_journal_dev));
+
+       really_read_only = bdev_read_only(sb->s_bdev);
+
+       /*
+        * Are we loading a blank journal or performing recovery after a
+        * crash?  For recovery, we need to check in advance whether we
+        * can get read-write access to the device.
+        */
+
+       if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER)) {
+               if (sb->s_flags & MS_RDONLY) {
+                       printk(KERN_INFO "EXT4-fs: INFO: recovery "
+                                       "required on readonly filesystem.\n");
+                       if (really_read_only) {
+                               printk(KERN_ERR "EXT4-fs: write access "
+                                       "unavailable, cannot proceed.\n");
+                               return -EROFS;
+                       }
+                       printk (KERN_INFO "EXT4-fs: write access will "
+                                       "be enabled during recovery.\n");
+               }
+       }
+
+       if (journal_inum && journal_dev) {
+               printk(KERN_ERR "EXT4-fs: filesystem has both journal "
+                      "and inode journals!\n");
+               return -EINVAL;
+       }
+
+       if (journal_inum) {
+               if (!(journal = ext4_get_journal(sb, journal_inum)))
+                       return -EINVAL;
+       } else {
+               if (!(journal = ext4_get_dev_journal(sb, journal_dev)))
+                       return -EINVAL;
+       }
+
+       if (!really_read_only && test_opt(sb, UPDATE_JOURNAL)) {
+               err = jbd2_journal_update_format(journal);
+               if (err)  {
+                       printk(KERN_ERR "EXT4-fs: error updating journal.\n");
+                       jbd2_journal_destroy(journal);
+                       return err;
+               }
+       }
+
+       if (!EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER))
+               err = jbd2_journal_wipe(journal, !really_read_only);
+       if (!err)
+               err = jbd2_journal_load(journal);
+
+       if (err) {
+               printk(KERN_ERR "EXT4-fs: error loading journal.\n");
+               jbd2_journal_destroy(journal);
+               return err;
+       }
+
+       EXT4_SB(sb)->s_journal = journal;
+       ext4_clear_journal_err(sb, es);
+
+       if (journal_devnum &&
+           journal_devnum != le32_to_cpu(es->s_journal_dev)) {
+               es->s_journal_dev = cpu_to_le32(journal_devnum);
+               sb->s_dirt = 1;
+
+               /* Make sure we flush the recovery flag to disk. */
+               ext4_commit_super(sb, es, 1);
+       }
+
+       return 0;
+}
+
+static int ext4_create_journal(struct super_block * sb,
+                              struct ext4_super_block * es,
+                              unsigned int journal_inum)
+{
+       journal_t *journal;
+
+       if (sb->s_flags & MS_RDONLY) {
+               printk(KERN_ERR "EXT4-fs: readonly filesystem when trying to "
+                               "create journal.\n");
+               return -EROFS;
+       }
+
+       if (!(journal = ext4_get_journal(sb, journal_inum)))
+               return -EINVAL;
+
+       printk(KERN_INFO "EXT4-fs: creating new journal on inode %u\n",
+              journal_inum);
+
+       if (jbd2_journal_create(journal)) {
+               printk(KERN_ERR "EXT4-fs: error creating journal.\n");
+               jbd2_journal_destroy(journal);
+               return -EIO;
+       }
+
+       EXT4_SB(sb)->s_journal = journal;
+
+       ext4_update_dynamic_rev(sb);
+       EXT4_SET_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
+       EXT4_SET_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL);
+
+       es->s_journal_inum = cpu_to_le32(journal_inum);
+       sb->s_dirt = 1;
+
+       /* Make sure we flush the recovery flag to disk. */
+       ext4_commit_super(sb, es, 1);
+
+       return 0;
+}
+
+static void ext4_commit_super (struct super_block * sb,
+                              struct ext4_super_block * es,
+                              int sync)
+{
+       struct buffer_head *sbh = EXT4_SB(sb)->s_sbh;
+
+       if (!sbh)
+               return;
+       es->s_wtime = cpu_to_le32(get_seconds());
+       ext4_free_blocks_count_set(es, ext4_count_free_blocks(sb));
+       es->s_free_inodes_count = cpu_to_le32(ext4_count_free_inodes(sb));
+       BUFFER_TRACE(sbh, "marking dirty");
+       mark_buffer_dirty(sbh);
+       if (sync)
+               sync_dirty_buffer(sbh);
+}
+
+
+/*
+ * Have we just finished recovery?  If so, and if we are mounting (or
+ * remounting) the filesystem readonly, then we will end up with a
+ * consistent fs on disk.  Record that fact.
+ */
+static void ext4_mark_recovery_complete(struct super_block * sb,
+                                       struct ext4_super_block * es)
+{
+       journal_t *journal = EXT4_SB(sb)->s_journal;
+
+       jbd2_journal_lock_updates(journal);
+       jbd2_journal_flush(journal);
+       if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER) &&
+           sb->s_flags & MS_RDONLY) {
+               EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
+               sb->s_dirt = 0;
+               ext4_commit_super(sb, es, 1);
+       }
+       jbd2_journal_unlock_updates(journal);
+}
+
+/*
+ * If we are mounting (or read-write remounting) a filesystem whose journal
+ * has recorded an error from a previous lifetime, move that error to the
+ * main filesystem now.
+ */
+static void ext4_clear_journal_err(struct super_block * sb,
+                                  struct ext4_super_block * es)
+{
+       journal_t *journal;
+       int j_errno;
+       const char *errstr;
+
+       journal = EXT4_SB(sb)->s_journal;
+
+       /*
+        * Now check for any error status which may have been recorded in the
+        * journal by a prior ext4_error() or ext4_abort()
+        */
+
+       j_errno = jbd2_journal_errno(journal);
+       if (j_errno) {
+               char nbuf[16];
+
+               errstr = ext4_decode_error(sb, j_errno, nbuf);
+               ext4_warning(sb, __FUNCTION__, "Filesystem error recorded "
+                            "from previous mount: %s", errstr);
+               ext4_warning(sb, __FUNCTION__, "Marking fs in need of "
+                            "filesystem check.");
+
+               EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS;
+               es->s_state |= cpu_to_le16(EXT4_ERROR_FS);
+               ext4_commit_super (sb, es, 1);
+
+               jbd2_journal_clear_err(journal);
+       }
+}
+
+/*
+ * Force the running and committing transactions to commit,
+ * and wait on the commit.
+ */
+int ext4_force_commit(struct super_block *sb)
+{
+       journal_t *journal;
+       int ret;
+
+       if (sb->s_flags & MS_RDONLY)
+               return 0;
+
+       journal = EXT4_SB(sb)->s_journal;
+       sb->s_dirt = 0;
+       ret = ext4_journal_force_commit(journal);
+       return ret;
+}
+
+/*
+ * Ext4 always journals updates to the superblock itself, so we don't
+ * have to propagate any other updates to the superblock on disk at this
+ * point.  Just start an async writeback to get the buffers on their way
+ * to the disk.
+ *
+ * This implicitly triggers the writebehind on sync().
+ */
+
+static void ext4_write_super (struct super_block * sb)
+{
+       if (mutex_trylock(&sb->s_lock) != 0)
+               BUG();
+       sb->s_dirt = 0;
+}
+
+static int ext4_sync_fs(struct super_block *sb, int wait)
+{
+       tid_t target;
+
+       sb->s_dirt = 0;
+       if (jbd2_journal_start_commit(EXT4_SB(sb)->s_journal, &target)) {
+               if (wait)
+                       jbd2_log_wait_commit(EXT4_SB(sb)->s_journal, target);
+       }
+       return 0;
+}
+
+/*
+ * LVM calls this function before a (read-only) snapshot is created.  This
+ * gives us a chance to flush the journal completely and mark the fs clean.
+ */
+static void ext4_write_super_lockfs(struct super_block *sb)
+{
+       sb->s_dirt = 0;
+
+       if (!(sb->s_flags & MS_RDONLY)) {
+               journal_t *journal = EXT4_SB(sb)->s_journal;
+
+               /* Now we set up the journal barrier. */
+               jbd2_journal_lock_updates(journal);
+               jbd2_journal_flush(journal);
+
+               /* Journal blocked and flushed, clear needs_recovery flag. */
+               EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
+               ext4_commit_super(sb, EXT4_SB(sb)->s_es, 1);
+       }
+}
+
+/*
+ * Called by LVM after the snapshot is done.  We need to reset the RECOVER
+ * flag here, even though the filesystem is not technically dirty yet.
+ */
+static void ext4_unlockfs(struct super_block *sb)
+{
+       if (!(sb->s_flags & MS_RDONLY)) {
+               lock_super(sb);
+               /* Reser the needs_recovery flag before the fs is unlocked. */
+               EXT4_SET_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
+               ext4_commit_super(sb, EXT4_SB(sb)->s_es, 1);
+               unlock_super(sb);
+               jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal);
+       }
+}
+
+static int ext4_remount (struct super_block * sb, int * flags, char * data)
+{
+       struct ext4_super_block * es;
+       struct ext4_sb_info *sbi = EXT4_SB(sb);
+       ext4_fsblk_t n_blocks_count = 0;
+       unsigned long old_sb_flags;
+       struct ext4_mount_options old_opts;
+       int err;
+#ifdef CONFIG_QUOTA
+       int i;
+#endif
+
+       /* Store the original options */
+       old_sb_flags = sb->s_flags;
+       old_opts.s_mount_opt = sbi->s_mount_opt;
+       old_opts.s_resuid = sbi->s_resuid;
+       old_opts.s_resgid = sbi->s_resgid;
+       old_opts.s_commit_interval = sbi->s_commit_interval;
+#ifdef CONFIG_QUOTA
+       old_opts.s_jquota_fmt = sbi->s_jquota_fmt;
+       for (i = 0; i < MAXQUOTAS; i++)
+               old_opts.s_qf_names[i] = sbi->s_qf_names[i];
+#endif
+
+       /*
+        * Allow the "check" option to be passed as a remount option.
+        */
+       if (!parse_options(data, sb, NULL, NULL, &n_blocks_count, 1)) {
+               err = -EINVAL;
+               goto restore_opts;
+       }
+
+       if (sbi->s_mount_opt & EXT4_MOUNT_ABORT)
+               ext4_abort(sb, __FUNCTION__, "Abort forced by user");
+
+       sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
+               ((sbi->s_mount_opt & EXT4_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0);
+
+       es = sbi->s_es;
+
+       ext4_init_journal_params(sb, sbi->s_journal);
+
+       if ((*flags & MS_RDONLY) != (sb->s_flags & MS_RDONLY) ||
+               n_blocks_count > ext4_blocks_count(es)) {
+               if (sbi->s_mount_opt & EXT4_MOUNT_ABORT) {
+                       err = -EROFS;
+                       goto restore_opts;
+               }
+
+               if (*flags & MS_RDONLY) {
+                       /*
+                        * First of all, the unconditional stuff we have to do
+                        * to disable replay of the journal when we next remount
+                        */
+                       sb->s_flags |= MS_RDONLY;
+
+                       /*
+                        * OK, test if we are remounting a valid rw partition
+                        * readonly, and if so set the rdonly flag and then
+                        * mark the partition as valid again.
+                        */
+                       if (!(es->s_state & cpu_to_le16(EXT4_VALID_FS)) &&
+                           (sbi->s_mount_state & EXT4_VALID_FS))
+                               es->s_state = cpu_to_le16(sbi->s_mount_state);
+
+                       ext4_mark_recovery_complete(sb, es);
+               } else {
+                       __le32 ret;
+                       if ((ret = EXT4_HAS_RO_COMPAT_FEATURE(sb,
+                                       ~EXT4_FEATURE_RO_COMPAT_SUPP))) {
+                               printk(KERN_WARNING "EXT4-fs: %s: couldn't "
+                                      "remount RDWR because of unsupported "
+                                      "optional features (%x).\n",
+                                      sb->s_id, le32_to_cpu(ret));
+                               err = -EROFS;
+                               goto restore_opts;
+                       }
+                       /*
+                        * Mounting a RDONLY partition read-write, so reread
+                        * and store the current valid flag.  (It may have
+                        * been changed by e2fsck since we originally mounted
+                        * the partition.)
+                        */
+                       ext4_clear_journal_err(sb, es);
+                       sbi->s_mount_state = le16_to_cpu(es->s_state);
+                       if ((err = ext4_group_extend(sb, es, n_blocks_count)))
+                               goto restore_opts;
+                       if (!ext4_setup_super (sb, es, 0))
+                               sb->s_flags &= ~MS_RDONLY;
+               }
+       }
+#ifdef CONFIG_QUOTA
+       /* Release old quota file names */
+       for (i = 0; i < MAXQUOTAS; i++)
+               if (old_opts.s_qf_names[i] &&
+                   old_opts.s_qf_names[i] != sbi->s_qf_names[i])
+                       kfree(old_opts.s_qf_names[i]);
+#endif
+       return 0;
+restore_opts:
+       sb->s_flags = old_sb_flags;
+       sbi->s_mount_opt = old_opts.s_mount_opt;
+       sbi->s_resuid = old_opts.s_resuid;
+       sbi->s_resgid = old_opts.s_resgid;
+       sbi->s_commit_interval = old_opts.s_commit_interval;
+#ifdef CONFIG_QUOTA
+       sbi->s_jquota_fmt = old_opts.s_jquota_fmt;
+       for (i = 0; i < MAXQUOTAS; i++) {
+               if (sbi->s_qf_names[i] &&
+                   old_opts.s_qf_names[i] != sbi->s_qf_names[i])
+                       kfree(sbi->s_qf_names[i]);
+               sbi->s_qf_names[i] = old_opts.s_qf_names[i];
+       }
+#endif
+       return err;
+}
+
+static int ext4_statfs (struct dentry * dentry, struct kstatfs * buf)
+{
+       struct super_block *sb = dentry->d_sb;
+       struct ext4_sb_info *sbi = EXT4_SB(sb);
+       struct ext4_super_block *es = sbi->s_es;
+       ext4_fsblk_t overhead;
+       int i;
+
+       if (test_opt (sb, MINIX_DF))
+               overhead = 0;
+       else {
+               unsigned long ngroups;
+               ngroups = EXT4_SB(sb)->s_groups_count;
+               smp_rmb();
+
+               /*
+                * Compute the overhead (FS structures)
+                */
+
+               /*
+                * All of the blocks before first_data_block are
+                * overhead
+                */
+               overhead = le32_to_cpu(es->s_first_data_block);
+
+               /*
+                * Add the overhead attributed to the superblock and
+                * block group descriptors.  If the sparse superblocks
+                * feature is turned on, then not all groups have this.
+                */
+               for (i = 0; i < ngroups; i++) {
+                       overhead += ext4_bg_has_super(sb, i) +
+                               ext4_bg_num_gdb(sb, i);
+                       cond_resched();
+               }
+
+               /*
+                * Every block group has an inode bitmap, a block
+                * bitmap, and an inode table.
+                */
+               overhead += (ngroups * (2 + EXT4_SB(sb)->s_itb_per_group));
+       }
+
+       buf->f_type = EXT4_SUPER_MAGIC;
+       buf->f_bsize = sb->s_blocksize;
+       buf->f_blocks = ext4_blocks_count(es) - overhead;
+       buf->f_bfree = percpu_counter_sum(&sbi->s_freeblocks_counter);
+       buf->f_bavail = buf->f_bfree - ext4_r_blocks_count(es);
+       if (buf->f_bfree < ext4_r_blocks_count(es))
+               buf->f_bavail = 0;
+       buf->f_files = le32_to_cpu(es->s_inodes_count);
+       buf->f_ffree = percpu_counter_sum(&sbi->s_freeinodes_counter);
+       buf->f_namelen = EXT4_NAME_LEN;
+       return 0;
+}
+
+/* Helper function for writing quotas on sync - we need to start transaction before quota file
+ * is locked for write. Otherwise the are possible deadlocks:
+ * Process 1                         Process 2
+ * ext4_create()                     quota_sync()
+ *   jbd2_journal_start()                   write_dquot()
+ *   DQUOT_INIT()                        down(dqio_mutex)
+ *     down(dqio_mutex)                    jbd2_journal_start()
+ *
+ */
+
+#ifdef CONFIG_QUOTA
+
+static inline struct inode *dquot_to_inode(struct dquot *dquot)
+{
+       return sb_dqopt(dquot->dq_sb)->files[dquot->dq_type];
+}
+
+static int ext4_dquot_initialize(struct inode *inode, int type)
+{
+       handle_t *handle;
+       int ret, err;
+
+       /* We may create quota structure so we need to reserve enough blocks */
+       handle = ext4_journal_start(inode, 2*EXT4_QUOTA_INIT_BLOCKS(inode->i_sb));
+       if (IS_ERR(handle))
+               return PTR_ERR(handle);
+       ret = dquot_initialize(inode, type);
+       err = ext4_journal_stop(handle);
+       if (!ret)
+               ret = err;
+       return ret;
+}
+
+static int ext4_dquot_drop(struct inode *inode)
+{
+       handle_t *handle;
+       int ret, err;
+
+       /* We may delete quota structure so we need to reserve enough blocks */
+       handle = ext4_journal_start(inode, 2*EXT4_QUOTA_DEL_BLOCKS(inode->i_sb));
+       if (IS_ERR(handle))
+               return PTR_ERR(handle);
+       ret = dquot_drop(inode);
+       err = ext4_journal_stop(handle);
+       if (!ret)
+               ret = err;
+       return ret;
+}
+
+static int ext4_write_dquot(struct dquot *dquot)
+{
+       int ret, err;
+       handle_t *handle;
+       struct inode *inode;
+
+       inode = dquot_to_inode(dquot);
+       handle = ext4_journal_start(inode,
+                                       EXT4_QUOTA_TRANS_BLOCKS(dquot->dq_sb));
+       if (IS_ERR(handle))
+               return PTR_ERR(handle);
+       ret = dquot_commit(dquot);
+       err = ext4_journal_stop(handle);
+       if (!ret)
+               ret = err;
+       return ret;
+}
+
+static int ext4_acquire_dquot(struct dquot *dquot)
+{
+       int ret, err;
+       handle_t *handle;
+
+       handle = ext4_journal_start(dquot_to_inode(dquot),
+                                       EXT4_QUOTA_INIT_BLOCKS(dquot->dq_sb));
+       if (IS_ERR(handle))
+               return PTR_ERR(handle);
+       ret = dquot_acquire(dquot);
+       err = ext4_journal_stop(handle);
+       if (!ret)
+               ret = err;
+       return ret;
+}
+
+static int ext4_release_dquot(struct dquot *dquot)
+{
+       int ret, err;
+       handle_t *handle;
+
+       handle = ext4_journal_start(dquot_to_inode(dquot),
+                                       EXT4_QUOTA_DEL_BLOCKS(dquot->dq_sb));
+       if (IS_ERR(handle))
+               return PTR_ERR(handle);
+       ret = dquot_release(dquot);
+       err = ext4_journal_stop(handle);
+       if (!ret)
+               ret = err;
+       return ret;
+}
+
+static int ext4_mark_dquot_dirty(struct dquot *dquot)
+{
+       /* Are we journalling quotas? */
+       if (EXT4_SB(dquot->dq_sb)->s_qf_names[USRQUOTA] ||
+           EXT4_SB(dquot->dq_sb)->s_qf_names[GRPQUOTA]) {
+               dquot_mark_dquot_dirty(dquot);
+               return ext4_write_dquot(dquot);
+       } else {
+               return dquot_mark_dquot_dirty(dquot);
+       }
+}
+
+static int ext4_write_info(struct super_block *sb, int type)
+{
+       int ret, err;
+       handle_t *handle;
+
+       /* Data block + inode block */
+       handle = ext4_journal_start(sb->s_root->d_inode, 2);
+       if (IS_ERR(handle))
+               return PTR_ERR(handle);
+       ret = dquot_commit_info(sb, type);
+       err = ext4_journal_stop(handle);
+       if (!ret)
+               ret = err;
+       return ret;
+}
+
+/*
+ * Turn on quotas during mount time - we need to find
+ * the quota file and such...
+ */
+static int ext4_quota_on_mount(struct super_block *sb, int type)
+{
+       return vfs_quota_on_mount(sb, EXT4_SB(sb)->s_qf_names[type],
+                       EXT4_SB(sb)->s_jquota_fmt, type);
+}
+
+/*
+ * Standard function to be called on quota_on
+ */
+static int ext4_quota_on(struct super_block *sb, int type, int format_id,
+                        char *path)
+{
+       int err;
+       struct nameidata nd;
+
+       if (!test_opt(sb, QUOTA))
+               return -EINVAL;
+       /* Not journalling quota? */
+       if (!EXT4_SB(sb)->s_qf_names[USRQUOTA] &&
+           !EXT4_SB(sb)->s_qf_names[GRPQUOTA])
+               return vfs_quota_on(sb, type, format_id, path);
+       err = path_lookup(path, LOOKUP_FOLLOW, &nd);
+       if (err)
+               return err;
+       /* Quotafile not on the same filesystem? */
+       if (nd.mnt->mnt_sb != sb) {
+               path_release(&nd);
+               return -EXDEV;
+       }
+       /* Quotafile not of fs root? */
+       if (nd.dentry->d_parent->d_inode != sb->s_root->d_inode)
+               printk(KERN_WARNING
+                       "EXT4-fs: Quota file not on filesystem root. "
+                       "Journalled quota will not work.\n");
+       path_release(&nd);
+       return vfs_quota_on(sb, type, format_id, path);
+}
+
+/* Read data from quotafile - avoid pagecache and such because we cannot afford
+ * acquiring the locks... As quota files are never truncated and quota code
+ * itself serializes the operations (and noone else should touch the files)
+ * we don't have to be afraid of races */
+static ssize_t ext4_quota_read(struct super_block *sb, int type, char *data,
+                              size_t len, loff_t off)
+{
+       struct inode *inode = sb_dqopt(sb)->files[type];
+       sector_t blk = off >> EXT4_BLOCK_SIZE_BITS(sb);
+       int err = 0;
+       int offset = off & (sb->s_blocksize - 1);
+       int tocopy;
+       size_t toread;
+       struct buffer_head *bh;
+       loff_t i_size = i_size_read(inode);
+
+       if (off > i_size)
+               return 0;
+       if (off+len > i_size)
+               len = i_size-off;
+       toread = len;
+       while (toread > 0) {
+               tocopy = sb->s_blocksize - offset < toread ?
+                               sb->s_blocksize - offset : toread;
+               bh = ext4_bread(NULL, inode, blk, 0, &err);
+               if (err)
+                       return err;
+               if (!bh)        /* A hole? */
+                       memset(data, 0, tocopy);
+               else
+                       memcpy(data, bh->b_data+offset, tocopy);
+               brelse(bh);
+               offset = 0;
+               toread -= tocopy;
+               data += tocopy;
+               blk++;
+       }
+       return len;
+}
+
+/* Write to quotafile (we know the transaction is already started and has
+ * enough credits) */
+static ssize_t ext4_quota_write(struct super_block *sb, int type,
+                               const char *data, size_t len, loff_t off)
+{
+       struct inode *inode = sb_dqopt(sb)->files[type];
+       sector_t blk = off >> EXT4_BLOCK_SIZE_BITS(sb);
+       int err = 0;
+       int offset = off & (sb->s_blocksize - 1);
+       int tocopy;
+       int journal_quota = EXT4_SB(sb)->s_qf_names[type] != NULL;
+       size_t towrite = len;
+       struct buffer_head *bh;
+       handle_t *handle = journal_current_handle();
+
+       mutex_lock_nested(&inode->i_mutex, I_MUTEX_QUOTA);
+       while (towrite > 0) {
+               tocopy = sb->s_blocksize - offset < towrite ?
+                               sb->s_blocksize - offset : towrite;
+               bh = ext4_bread(handle, inode, blk, 1, &err);
+               if (!bh)
+                       goto out;
+               if (journal_quota) {
+                       err = ext4_journal_get_write_access(handle, bh);
+                       if (err) {
+                               brelse(bh);
+                               goto out;
+                       }
+               }
+               lock_buffer(bh);
+               memcpy(bh->b_data+offset, data, tocopy);
+               flush_dcache_page(bh->b_page);
+               unlock_buffer(bh);
+               if (journal_quota)
+                       err = ext4_journal_dirty_metadata(handle, bh);
+               else {
+                       /* Always do at least ordered writes for quotas */
+                       err = ext4_journal_dirty_data(handle, bh);
+                       mark_buffer_dirty(bh);
+               }
+               brelse(bh);
+               if (err)
+                       goto out;
+               offset = 0;
+               towrite -= tocopy;
+               data += tocopy;
+               blk++;
+       }
+out:
+       if (len == towrite)
+               return err;
+       if (inode->i_size < off+len-towrite) {
+               i_size_write(inode, off+len-towrite);
+               EXT4_I(inode)->i_disksize = inode->i_size;
+       }
+       inode->i_version++;
+       inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+       ext4_mark_inode_dirty(handle, inode);
+       mutex_unlock(&inode->i_mutex);
+       return len - towrite;
+}
+
+#endif
+
+static int ext4_get_sb(struct file_system_type *fs_type,
+       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
+{
+       return get_sb_bdev(fs_type, flags, dev_name, data, ext4_fill_super, mnt);
+}
+
+static struct file_system_type ext4dev_fs_type = {
+       .owner          = THIS_MODULE,
+       .name           = "ext4dev",
+       .get_sb         = ext4_get_sb,
+       .kill_sb        = kill_block_super,
+       .fs_flags       = FS_REQUIRES_DEV,
+};
+
+static int __init init_ext4_fs(void)
+{
+       int err = init_ext4_xattr();
+       if (err)
+               return err;
+       err = init_inodecache();
+       if (err)
+               goto out1;
+       err = register_filesystem(&ext4dev_fs_type);
+       if (err)
+               goto out;
+       return 0;
+out:
+       destroy_inodecache();
+out1:
+       exit_ext4_xattr();
+       return err;
+}
+
+static void __exit exit_ext4_fs(void)
+{
+       unregister_filesystem(&ext4dev_fs_type);
+       destroy_inodecache();
+       exit_ext4_xattr();
+}
+
+MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others");
+MODULE_DESCRIPTION("Fourth Extended Filesystem with extents");
+MODULE_LICENSE("GPL");
+module_init(init_ext4_fs)
+module_exit(exit_ext4_fs)
diff --git a/fs/ext4/symlink.c b/fs/ext4/symlink.c
new file mode 100644 (file)
index 0000000..fcf5272
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ *  linux/fs/ext4/symlink.c
+ *
+ * Only fast symlinks left here - the rest is done by generic code. AV, 1999
+ *
+ * Copyright (C) 1992, 1993, 1994, 1995
+ * Remy Card (card@masi.ibp.fr)
+ * Laboratoire MASI - Institut Blaise Pascal
+ * Universite Pierre et Marie Curie (Paris VI)
+ *
+ *  from
+ *
+ *  linux/fs/minix/symlink.c
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ *
+ *  ext4 symlink handling code
+ */
+
+#include <linux/fs.h>
+#include <linux/jbd2.h>
+#include <linux/ext4_fs.h>
+#include <linux/namei.h>
+#include "xattr.h"
+
+static void * ext4_follow_link(struct dentry *dentry, struct nameidata *nd)
+{
+       struct ext4_inode_info *ei = EXT4_I(dentry->d_inode);
+       nd_set_link(nd, (char*)ei->i_data);
+       return NULL;
+}
+
+struct inode_operations ext4_symlink_inode_operations = {
+       .readlink       = generic_readlink,
+       .follow_link    = page_follow_link_light,
+       .put_link       = page_put_link,
+#ifdef CONFIG_EXT4DEV_FS_XATTR
+       .setxattr       = generic_setxattr,
+       .getxattr       = generic_getxattr,
+       .listxattr      = ext4_listxattr,
+       .removexattr    = generic_removexattr,
+#endif
+};
+
+struct inode_operations ext4_fast_symlink_inode_operations = {
+       .readlink       = generic_readlink,
+       .follow_link    = ext4_follow_link,
+#ifdef CONFIG_EXT4DEV_FS_XATTR
+       .setxattr       = generic_setxattr,
+       .getxattr       = generic_getxattr,
+       .listxattr      = ext4_listxattr,
+       .removexattr    = generic_removexattr,
+#endif
+};
diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
new file mode 100644 (file)
index 0000000..63233cd
--- /dev/null
@@ -0,0 +1,1317 @@
+/*
+ * linux/fs/ext4/xattr.c
+ *
+ * Copyright (C) 2001-2003 Andreas Gruenbacher, <agruen@suse.de>
+ *
+ * Fix by Harrison Xing <harrison@mountainviewdata.com>.
+ * Ext4 code with a lot of help from Eric Jarman <ejarman@acm.org>.
+ * Extended attributes for symlinks and special files added per
+ *  suggestion of Luka Renko <luka.renko@hermes.si>.
+ * xattr consolidation Copyright (c) 2004 James Morris <jmorris@redhat.com>,
+ *  Red Hat Inc.
+ * ea-in-inode support by Alex Tomas <alex@clusterfs.com> aka bzzz
+ *  and Andreas Gruenbacher <agruen@suse.de>.
+ */
+
+/*
+ * Extended attributes are stored directly in inodes (on file systems with
+ * inodes bigger than 128 bytes) and on additional disk blocks. The i_file_acl
+ * field contains the block number if an inode uses an additional block. All
+ * attributes must fit in the inode and one additional block. Blocks that
+ * contain the identical set of attributes may be shared among several inodes.
+ * Identical blocks are detected by keeping a cache of blocks that have
+ * recently been accessed.
+ *
+ * The attributes in inodes and on blocks have a different header; the entries
+ * are stored in the same format:
+ *
+ *   +------------------+
+ *   | header           |
+ *   | entry 1          | |
+ *   | entry 2          | | growing downwards
+ *   | entry 3          | v
+ *   | four null bytes  |
+ *   | . . .            |
+ *   | value 1          | ^
+ *   | value 3          | | growing upwards
+ *   | value 2          | |
+ *   +------------------+
+ *
+ * The header is followed by multiple entry descriptors. In disk blocks, the
+ * entry descriptors are kept sorted. In inodes, they are unsorted. The
+ * attribute values are aligned to the end of the block in no specific order.
+ *
+ * Locking strategy
+ * ----------------
+ * EXT4_I(inode)->i_file_acl is protected by EXT4_I(inode)->xattr_sem.
+ * EA blocks are only changed if they are exclusive to an inode, so
+ * holding xattr_sem also means that nothing but the EA block's reference
+ * count can change. Multiple writers to the same block are synchronized
+ * by the buffer lock.
+ */
+
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/ext4_jbd2.h>
+#include <linux/ext4_fs.h>
+#include <linux/mbcache.h>
+#include <linux/quotaops.h>
+#include <linux/rwsem.h>
+#include "xattr.h"
+#include "acl.h"
+
+#define BHDR(bh) ((struct ext4_xattr_header *)((bh)->b_data))
+#define ENTRY(ptr) ((struct ext4_xattr_entry *)(ptr))
+#define BFIRST(bh) ENTRY(BHDR(bh)+1)
+#define IS_LAST_ENTRY(entry) (*(__u32 *)(entry) == 0)
+
+#define IHDR(inode, raw_inode) \
+       ((struct ext4_xattr_ibody_header *) \
+               ((void *)raw_inode + \
+                EXT4_GOOD_OLD_INODE_SIZE + \
+                EXT4_I(inode)->i_extra_isize))
+#define IFIRST(hdr) ((struct ext4_xattr_entry *)((hdr)+1))
+
+#ifdef EXT4_XATTR_DEBUG
+# define ea_idebug(inode, f...) do { \
+               printk(KERN_DEBUG "inode %s:%lu: ", \
+                       inode->i_sb->s_id, inode->i_ino); \
+               printk(f); \
+               printk("\n"); \
+       } while (0)
+# define ea_bdebug(bh, f...) do { \
+               char b[BDEVNAME_SIZE]; \
+               printk(KERN_DEBUG "block %s:%lu: ", \
+                       bdevname(bh->b_bdev, b), \
+                       (unsigned long) bh->b_blocknr); \
+               printk(f); \
+               printk("\n"); \
+       } while (0)
+#else
+# define ea_idebug(f...)
+# define ea_bdebug(f...)
+#endif
+
+static void ext4_xattr_cache_insert(struct buffer_head *);
+static struct buffer_head *ext4_xattr_cache_find(struct inode *,
+                                                struct ext4_xattr_header *,
+                                                struct mb_cache_entry **);
+static void ext4_xattr_rehash(struct ext4_xattr_header *,
+                             struct ext4_xattr_entry *);
+
+static struct mb_cache *ext4_xattr_cache;
+
+static struct xattr_handler *ext4_xattr_handler_map[] = {
+       [EXT4_XATTR_INDEX_USER]              = &ext4_xattr_user_handler,
+#ifdef CONFIG_EXT4DEV_FS_POSIX_ACL
+       [EXT4_XATTR_INDEX_POSIX_ACL_ACCESS]  = &ext4_xattr_acl_access_handler,
+       [EXT4_XATTR_INDEX_POSIX_ACL_DEFAULT] = &ext4_xattr_acl_default_handler,
+#endif
+       [EXT4_XATTR_INDEX_TRUSTED]           = &ext4_xattr_trusted_handler,
+#ifdef CONFIG_EXT4DEV_FS_SECURITY
+       [EXT4_XATTR_INDEX_SECURITY]          = &ext4_xattr_security_handler,
+#endif
+};
+
+struct xattr_handler *ext4_xattr_handlers[] = {
+       &ext4_xattr_user_handler,
+       &ext4_xattr_trusted_handler,
+#ifdef CONFIG_EXT4DEV_FS_POSIX_ACL
+       &ext4_xattr_acl_access_handler,
+       &ext4_xattr_acl_default_handler,
+#endif
+#ifdef CONFIG_EXT4DEV_FS_SECURITY
+       &ext4_xattr_security_handler,
+#endif
+       NULL
+};
+
+static inline struct xattr_handler *
+ext4_xattr_handler(int name_index)
+{
+       struct xattr_handler *handler = NULL;
+
+       if (name_index > 0 && name_index < ARRAY_SIZE(ext4_xattr_handler_map))
+               handler = ext4_xattr_handler_map[name_index];
+       return handler;
+}
+
+/*
+ * Inode operation listxattr()
+ *
+ * dentry->d_inode->i_mutex: don't care
+ */
+ssize_t
+ext4_listxattr(struct dentry *dentry, char *buffer, size_t size)
+{
+       return ext4_xattr_list(dentry->d_inode, buffer, size);
+}
+
+static int
+ext4_xattr_check_names(struct ext4_xattr_entry *entry, void *end)
+{
+       while (!IS_LAST_ENTRY(entry)) {
+               struct ext4_xattr_entry *next = EXT4_XATTR_NEXT(entry);
+               if ((void *)next >= end)
+                       return -EIO;
+               entry = next;
+       }
+       return 0;
+}
+
+static inline int
+ext4_xattr_check_block(struct buffer_head *bh)
+{
+       int error;
+
+       if (BHDR(bh)->h_magic != cpu_to_le32(EXT4_XATTR_MAGIC) ||
+           BHDR(bh)->h_blocks != cpu_to_le32(1))
+               return -EIO;
+       error = ext4_xattr_check_names(BFIRST(bh), bh->b_data + bh->b_size);
+       return error;
+}
+
+static inline int
+ext4_xattr_check_entry(struct ext4_xattr_entry *entry, size_t size)
+{
+       size_t value_size = le32_to_cpu(entry->e_value_size);
+
+       if (entry->e_value_block != 0 || value_size > size ||
+           le16_to_cpu(entry->e_value_offs) + value_size > size)
+               return -EIO;
+       return 0;
+}
+
+static int
+ext4_xattr_find_entry(struct ext4_xattr_entry **pentry, int name_index,
+                     const char *name, size_t size, int sorted)
+{
+       struct ext4_xattr_entry *entry;
+       size_t name_len;
+       int cmp = 1;
+
+       if (name == NULL)
+               return -EINVAL;
+       name_len = strlen(name);
+       entry = *pentry;
+       for (; !IS_LAST_ENTRY(entry); entry = EXT4_XATTR_NEXT(entry)) {
+               cmp = name_index - entry->e_name_index;
+               if (!cmp)
+                       cmp = name_len - entry->e_name_len;
+               if (!cmp)
+                       cmp = memcmp(name, entry->e_name, name_len);
+               if (cmp <= 0 && (sorted || cmp == 0))
+                       break;
+       }
+       *pentry = entry;
+       if (!cmp && ext4_xattr_check_entry(entry, size))
+                       return -EIO;
+       return cmp ? -ENODATA : 0;
+}
+
+static int
+ext4_xattr_block_get(struct inode *inode, int name_index, const char *name,
+                    void *buffer, size_t buffer_size)
+{
+       struct buffer_head *bh = NULL;
+       struct ext4_xattr_entry *entry;
+       size_t size;
+       int error;
+
+       ea_idebug(inode, "name=%d.%s, buffer=%p, buffer_size=%ld",
+                 name_index, name, buffer, (long)buffer_size);
+
+       error = -ENODATA;
+       if (!EXT4_I(inode)->i_file_acl)
+               goto cleanup;
+       ea_idebug(inode, "reading block %u", EXT4_I(inode)->i_file_acl);
+       bh = sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl);
+       if (!bh)
+               goto cleanup;
+       ea_bdebug(bh, "b_count=%d, refcount=%d",
+               atomic_read(&(bh->b_count)), le32_to_cpu(BHDR(bh)->h_refcount));
+       if (ext4_xattr_check_block(bh)) {
+bad_block:     ext4_error(inode->i_sb, __FUNCTION__,
+                          "inode %lu: bad block %llu", inode->i_ino,
+                          EXT4_I(inode)->i_file_acl);
+               error = -EIO;
+               goto cleanup;
+       }
+       ext4_xattr_cache_insert(bh);
+       entry = BFIRST(bh);
+       error = ext4_xattr_find_entry(&entry, name_index, name, bh->b_size, 1);
+       if (error == -EIO)
+               goto bad_block;
+       if (error)
+               goto cleanup;
+       size = le32_to_cpu(entry->e_value_size);
+       if (buffer) {
+               error = -ERANGE;
+               if (size > buffer_size)
+                       goto cleanup;
+               memcpy(buffer, bh->b_data + le16_to_cpu(entry->e_value_offs),
+                      size);
+       }
+       error = size;
+
+cleanup:
+       brelse(bh);
+       return error;
+}
+
+static int
+ext4_xattr_ibody_get(struct inode *inode, int name_index, const char *name,
+                    void *buffer, size_t buffer_size)
+{
+       struct ext4_xattr_ibody_header *header;
+       struct ext4_xattr_entry *entry;
+       struct ext4_inode *raw_inode;
+       struct ext4_iloc iloc;
+       size_t size;
+       void *end;
+       int error;
+
+       if (!(EXT4_I(inode)->i_state & EXT4_STATE_XATTR))
+               return -ENODATA;
+       error = ext4_get_inode_loc(inode, &iloc);
+       if (error)
+               return error;
+       raw_inode = ext4_raw_inode(&iloc);
+       header = IHDR(inode, raw_inode);
+       entry = IFIRST(header);
+       end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size;
+       error = ext4_xattr_check_names(entry, end);
+       if (error)
+               goto cleanup;
+       error = ext4_xattr_find_entry(&entry, name_index, name,
+                                     end - (void *)entry, 0);
+       if (error)
+               goto cleanup;
+       size = le32_to_cpu(entry->e_value_size);
+       if (buffer) {
+               error = -ERANGE;
+               if (size > buffer_size)
+                       goto cleanup;
+               memcpy(buffer, (void *)IFIRST(header) +
+                      le16_to_cpu(entry->e_value_offs), size);
+       }
+       error = size;
+
+cleanup:
+       brelse(iloc.bh);
+       return error;
+}
+
+/*
+ * ext4_xattr_get()
+ *
+ * Copy an extended attribute into the buffer
+ * provided, or compute the buffer size required.
+ * Buffer is NULL to compute the size of the buffer required.
+ *
+ * Returns a negative error number on failure, or the number of bytes
+ * used / required on success.
+ */
+int
+ext4_xattr_get(struct inode *inode, int name_index, const char *name,
+              void *buffer, size_t buffer_size)
+{
+       int error;
+
+       down_read(&EXT4_I(inode)->xattr_sem);
+       error = ext4_xattr_ibody_get(inode, name_index, name, buffer,
+                                    buffer_size);
+       if (error == -ENODATA)
+               error = ext4_xattr_block_get(inode, name_index, name, buffer,
+                                            buffer_size);
+       up_read(&EXT4_I(inode)->xattr_sem);
+       return error;
+}
+
+static int
+ext4_xattr_list_entries(struct inode *inode, struct ext4_xattr_entry *entry,
+                       char *buffer, size_t buffer_size)
+{
+       size_t rest = buffer_size;
+
+       for (; !IS_LAST_ENTRY(entry); entry = EXT4_XATTR_NEXT(entry)) {
+               struct xattr_handler *handler =
+                       ext4_xattr_handler(entry->e_name_index);
+
+               if (handler) {
+                       size_t size = handler->list(inode, buffer, rest,
+                                                   entry->e_name,
+                                                   entry->e_name_len);
+                       if (buffer) {
+                               if (size > rest)
+                                       return -ERANGE;
+                               buffer += size;
+                       }
+                       rest -= size;
+               }
+       }
+       return buffer_size - rest;
+}
+
+static int
+ext4_xattr_block_list(struct inode *inode, char *buffer, size_t buffer_size)
+{
+       struct buffer_head *bh = NULL;
+       int error;
+
+       ea_idebug(inode, "buffer=%p, buffer_size=%ld",
+                 buffer, (long)buffer_size);
+
+       error = 0;
+       if (!EXT4_I(inode)->i_file_acl)
+               goto cleanup;
+       ea_idebug(inode, "reading block %u", EXT4_I(inode)->i_file_acl);
+       bh = sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl);
+       error = -EIO;
+       if (!bh)
+               goto cleanup;
+       ea_bdebug(bh, "b_count=%d, refcount=%d",
+               atomic_read(&(bh->b_count)), le32_to_cpu(BHDR(bh)->h_refcount));
+       if (ext4_xattr_check_block(bh)) {
+               ext4_error(inode->i_sb, __FUNCTION__,
+                          "inode %lu: bad block %llu", inode->i_ino,
+                          EXT4_I(inode)->i_file_acl);
+               error = -EIO;
+               goto cleanup;
+       }
+       ext4_xattr_cache_insert(bh);
+       error = ext4_xattr_list_entries(inode, BFIRST(bh), buffer, buffer_size);
+
+cleanup:
+       brelse(bh);
+
+       return error;
+}
+
+static int
+ext4_xattr_ibody_list(struct inode *inode, char *buffer, size_t buffer_size)
+{
+       struct ext4_xattr_ibody_header *header;
+       struct ext4_inode *raw_inode;
+       struct ext4_iloc iloc;
+       void *end;
+       int error;
+
+       if (!(EXT4_I(inode)->i_state & EXT4_STATE_XATTR))
+               return 0;
+       error = ext4_get_inode_loc(inode, &iloc);
+       if (error)
+               return error;
+       raw_inode = ext4_raw_inode(&iloc);
+       header = IHDR(inode, raw_inode);
+       end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size;
+       error = ext4_xattr_check_names(IFIRST(header), end);
+       if (error)
+               goto cleanup;
+       error = ext4_xattr_list_entries(inode, IFIRST(header),
+                                       buffer, buffer_size);
+
+cleanup:
+       brelse(iloc.bh);
+       return error;
+}
+
+/*
+ * ext4_xattr_list()
+ *
+ * Copy a list of attribute names into the buffer
+ * provided, or compute the buffer size required.
+ * Buffer is NULL to compute the size of the buffer required.
+ *
+ * Returns a negative error number on failure, or the number of bytes
+ * used / required on success.
+ */
+int
+ext4_xattr_list(struct inode *inode, char *buffer, size_t buffer_size)
+{
+       int i_error, b_error;
+
+       down_read(&EXT4_I(inode)->xattr_sem);
+       i_error = ext4_xattr_ibody_list(inode, buffer, buffer_size);
+       if (i_error < 0) {
+               b_error = 0;
+       } else {
+               if (buffer) {
+                       buffer += i_error;
+                       buffer_size -= i_error;
+               }
+               b_error = ext4_xattr_block_list(inode, buffer, buffer_size);
+               if (b_error < 0)
+                       i_error = 0;
+       }
+       up_read(&EXT4_I(inode)->xattr_sem);
+       return i_error + b_error;
+}
+
+/*
+ * If the EXT4_FEATURE_COMPAT_EXT_ATTR feature of this file system is
+ * not set, set it.
+ */
+static void ext4_xattr_update_super_block(handle_t *handle,
+                                         struct super_block *sb)
+{
+       if (EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_EXT_ATTR))
+               return;
+
+       lock_super(sb);
+       if (ext4_journal_get_write_access(handle, EXT4_SB(sb)->s_sbh) == 0) {
+               EXT4_SB(sb)->s_es->s_feature_compat |=
+                       cpu_to_le32(EXT4_FEATURE_COMPAT_EXT_ATTR);
+               sb->s_dirt = 1;
+               ext4_journal_dirty_metadata(handle, EXT4_SB(sb)->s_sbh);
+       }
+       unlock_super(sb);
+}
+
+/*
+ * Release the xattr block BH: If the reference count is > 1, decrement
+ * it; otherwise free the block.
+ */
+static void
+ext4_xattr_release_block(handle_t *handle, struct inode *inode,
+                        struct buffer_head *bh)
+{
+       struct mb_cache_entry *ce = NULL;
+
+       ce = mb_cache_entry_get(ext4_xattr_cache, bh->b_bdev, bh->b_blocknr);
+       if (BHDR(bh)->h_refcount == cpu_to_le32(1)) {
+               ea_bdebug(bh, "refcount now=0; freeing");
+               if (ce)
+                       mb_cache_entry_free(ce);
+               ext4_free_blocks(handle, inode, bh->b_blocknr, 1);
+               get_bh(bh);
+               ext4_forget(handle, 1, inode, bh, bh->b_blocknr);
+       } else {
+               if (ext4_journal_get_write_access(handle, bh) == 0) {
+                       lock_buffer(bh);
+                       BHDR(bh)->h_refcount = cpu_to_le32(
+                               le32_to_cpu(BHDR(bh)->h_refcount) - 1);
+                       ext4_journal_dirty_metadata(handle, bh);
+                       if (IS_SYNC(inode))
+                               handle->h_sync = 1;
+                       DQUOT_FREE_BLOCK(inode, 1);
+                       unlock_buffer(bh);
+                       ea_bdebug(bh, "refcount now=%d; releasing",
+                                 le32_to_cpu(BHDR(bh)->h_refcount));
+               }
+               if (ce)
+                       mb_cache_entry_release(ce);
+       }
+}
+
+struct ext4_xattr_info {
+       int name_index;
+       const char *name;
+       const void *value;
+       size_t value_len;
+};
+
+struct ext4_xattr_search {
+       struct ext4_xattr_entry *first;
+       void *base;
+       void *end;
+       struct ext4_xattr_entry *here;
+       int not_found;
+};
+
+static int
+ext4_xattr_set_entry(struct ext4_xattr_info *i, struct ext4_xattr_search *s)
+{
+       struct ext4_xattr_entry *last;
+       size_t free, min_offs = s->end - s->base, name_len = strlen(i->name);
+
+       /* Compute min_offs and last. */
+       last = s->first;
+       for (; !IS_LAST_ENTRY(last); last = EXT4_XATTR_NEXT(last)) {
+               if (!last->e_value_block && last->e_value_size) {
+                       size_t offs = le16_to_cpu(last->e_value_offs);
+                       if (offs < min_offs)
+                               min_offs = offs;
+               }
+       }
+       free = min_offs - ((void *)last - s->base) - sizeof(__u32);
+       if (!s->not_found) {
+               if (!s->here->e_value_block && s->here->e_value_size) {
+                       size_t size = le32_to_cpu(s->here->e_value_size);
+                       free += EXT4_XATTR_SIZE(size);
+               }
+               free += EXT4_XATTR_LEN(name_len);
+       }
+       if (i->value) {
+               if (free < EXT4_XATTR_SIZE(i->value_len) ||
+                   free < EXT4_XATTR_LEN(name_len) +
+                          EXT4_XATTR_SIZE(i->value_len))
+                       return -ENOSPC;
+       }
+
+       if (i->value && s->not_found) {
+               /* Insert the new name. */
+               size_t size = EXT4_XATTR_LEN(name_len);
+               size_t rest = (void *)last - (void *)s->here + sizeof(__u32);
+               memmove((void *)s->here + size, s->here, rest);
+               memset(s->here, 0, size);
+               s->here->e_name_index = i->name_index;
+               s->here->e_name_len = name_len;
+               memcpy(s->here->e_name, i->name, name_len);
+       } else {
+               if (!s->here->e_value_block && s->here->e_value_size) {
+                       void *first_val = s->base + min_offs;
+                       size_t offs = le16_to_cpu(s->here->e_value_offs);
+                       void *val = s->base + offs;
+                       size_t size = EXT4_XATTR_SIZE(
+                               le32_to_cpu(s->here->e_value_size));
+
+                       if (i->value && size == EXT4_XATTR_SIZE(i->value_len)) {
+                               /* The old and the new value have the same
+                                  size. Just replace. */
+                               s->here->e_value_size =
+                                       cpu_to_le32(i->value_len);
+                               memset(val + size - EXT4_XATTR_PAD, 0,
+                                      EXT4_XATTR_PAD); /* Clear pad bytes. */
+                               memcpy(val, i->value, i->value_len);
+                               return 0;
+                       }
+
+                       /* Remove the old value. */
+                       memmove(first_val + size, first_val, val - first_val);
+                       memset(first_val, 0, size);
+                       s->here->e_value_size = 0;
+                       s->here->e_value_offs = 0;
+                       min_offs += size;
+
+                       /* Adjust all value offsets. */
+                       last = s->first;
+                       while (!IS_LAST_ENTRY(last)) {
+                               size_t o = le16_to_cpu(last->e_value_offs);
+                               if (!last->e_value_block &&
+                                   last->e_value_size && o < offs)
+                                       last->e_value_offs =
+                                               cpu_to_le16(o + size);
+                               last = EXT4_XATTR_NEXT(last);
+                       }
+               }
+               if (!i->value) {
+                       /* Remove the old name. */
+                       size_t size = EXT4_XATTR_LEN(name_len);
+                       last = ENTRY((void *)last - size);
+                       memmove(s->here, (void *)s->here + size,
+                               (void *)last - (void *)s->here + sizeof(__u32));
+                       memset(last, 0, size);
+               }
+       }
+
+       if (i->value) {
+               /* Insert the new value. */
+               s->here->e_value_size = cpu_to_le32(i->value_len);
+               if (i->value_len) {
+                       size_t size = EXT4_XATTR_SIZE(i->value_len);
+                       void *val = s->base + min_offs - size;
+                       s->here->e_value_offs = cpu_to_le16(min_offs - size);
+                       memset(val + size - EXT4_XATTR_PAD, 0,
+                              EXT4_XATTR_PAD); /* Clear the pad bytes. */
+                       memcpy(val, i->value, i->value_len);
+               }
+       }
+       return 0;
+}
+
+struct ext4_xattr_block_find {
+       struct ext4_xattr_search s;
+       struct buffer_head *bh;
+};
+
+static int
+ext4_xattr_block_find(struct inode *inode, struct ext4_xattr_info *i,
+                     struct ext4_xattr_block_find *bs)
+{
+       struct super_block *sb = inode->i_sb;
+       int error;
+
+       ea_idebug(inode, "name=%d.%s, value=%p, value_len=%ld",
+                 i->name_index, i->name, i->value, (long)i->value_len);
+
+       if (EXT4_I(inode)->i_file_acl) {
+               /* The inode already has an extended attribute block. */
+               bs->bh = sb_bread(sb, EXT4_I(inode)->i_file_acl);
+               error = -EIO;
+               if (!bs->bh)
+                       goto cleanup;
+               ea_bdebug(bs->bh, "b_count=%d, refcount=%d",
+                       atomic_read(&(bs->bh->b_count)),
+                       le32_to_cpu(BHDR(bs->bh)->h_refcount));
+               if (ext4_xattr_check_block(bs->bh)) {
+                       ext4_error(sb, __FUNCTION__,
+                               "inode %lu: bad block %llu", inode->i_ino,
+                               EXT4_I(inode)->i_file_acl);
+                       error = -EIO;
+                       goto cleanup;
+               }
+               /* Find the named attribute. */
+               bs->s.base = BHDR(bs->bh);
+               bs->s.first = BFIRST(bs->bh);
+               bs->s.end = bs->bh->b_data + bs->bh->b_size;
+               bs->s.here = bs->s.first;
+               error = ext4_xattr_find_entry(&bs->s.here, i->name_index,
+                                             i->name, bs->bh->b_size, 1);
+               if (error && error != -ENODATA)
+                       goto cleanup;
+               bs->s.not_found = error;
+       }
+       error = 0;
+
+cleanup:
+       return error;
+}
+
+static int
+ext4_xattr_block_set(handle_t *handle, struct inode *inode,
+                    struct ext4_xattr_info *i,
+                    struct ext4_xattr_block_find *bs)
+{
+       struct super_block *sb = inode->i_sb;
+       struct buffer_head *new_bh = NULL;
+       struct ext4_xattr_search *s = &bs->s;
+       struct mb_cache_entry *ce = NULL;
+       int error;
+
+#define header(x) ((struct ext4_xattr_header *)(x))
+
+       if (i->value && i->value_len > sb->s_blocksize)
+               return -ENOSPC;
+       if (s->base) {
+               ce = mb_cache_entry_get(ext4_xattr_cache, bs->bh->b_bdev,
+                                       bs->bh->b_blocknr);
+               if (header(s->base)->h_refcount == cpu_to_le32(1)) {
+                       if (ce) {
+                               mb_cache_entry_free(ce);
+                               ce = NULL;
+                       }
+                       ea_bdebug(bs->bh, "modifying in-place");
+                       error = ext4_journal_get_write_access(handle, bs->bh);
+                       if (error)
+                               goto cleanup;
+                       lock_buffer(bs->bh);
+                       error = ext4_xattr_set_entry(i, s);
+                       if (!error) {
+                               if (!IS_LAST_ENTRY(s->first))
+                                       ext4_xattr_rehash(header(s->base),
+                                                         s->here);
+                               ext4_xattr_cache_insert(bs->bh);
+                       }
+                       unlock_buffer(bs->bh);
+                       if (error == -EIO)
+                               goto bad_block;
+                       if (!error)
+                               error = ext4_journal_dirty_metadata(handle,
+                                                                   bs->bh);
+                       if (error)
+                               goto cleanup;
+                       goto inserted;
+               } else {
+                       int offset = (char *)s->here - bs->bh->b_data;
+
+                       if (ce) {
+                               mb_cache_entry_release(ce);
+                               ce = NULL;
+                       }
+                       ea_bdebug(bs->bh, "cloning");
+                       s->base = kmalloc(bs->bh->b_size, GFP_KERNEL);
+                       error = -ENOMEM;
+                       if (s->base == NULL)
+                               goto cleanup;
+                       memcpy(s->base, BHDR(bs->bh), bs->bh->b_size);
+                       s->first = ENTRY(header(s->base)+1);
+                       header(s->base)->h_refcount = cpu_to_le32(1);
+                       s->here = ENTRY(s->base + offset);
+                       s->end = s->base + bs->bh->b_size;
+               }
+       } else {
+               /* Allocate a buffer where we construct the new block. */
+               s->base = kmalloc(sb->s_blocksize, GFP_KERNEL);
+               /* assert(header == s->base) */
+               error = -ENOMEM;
+               if (s->base == NULL)
+                       goto cleanup;
+               memset(s->base, 0, sb->s_blocksize);
+               header(s->base)->h_magic = cpu_to_le32(EXT4_XATTR_MAGIC);
+               header(s->base)->h_blocks = cpu_to_le32(1);
+               header(s->base)->h_refcount = cpu_to_le32(1);
+               s->first = ENTRY(header(s->base)+1);
+               s->here = ENTRY(header(s->base)+1);
+               s->end = s->base + sb->s_blocksize;
+       }
+
+       error = ext4_xattr_set_entry(i, s);
+       if (error == -EIO)
+               goto bad_block;
+       if (error)
+               goto cleanup;
+       if (!IS_LAST_ENTRY(s->first))
+               ext4_xattr_rehash(header(s->base), s->here);
+
+inserted:
+       if (!IS_LAST_ENTRY(s->first)) {
+               new_bh = ext4_xattr_cache_find(inode, header(s->base), &ce);
+               if (new_bh) {
+                       /* We found an identical block in the cache. */
+                       if (new_bh == bs->bh)
+                               ea_bdebug(new_bh, "keeping");
+                       else {
+                               /* The old block is released after updating
+                                  the inode. */
+                               error = -EDQUOT;
+                               if (DQUOT_ALLOC_BLOCK(inode, 1))
+                                       goto cleanup;
+                               error = ext4_journal_get_write_access(handle,
+                                                                     new_bh);
+                               if (error)
+                                       goto cleanup_dquot;
+                               lock_buffer(new_bh);
+                               BHDR(new_bh)->h_refcount = cpu_to_le32(1 +
+                                       le32_to_cpu(BHDR(new_bh)->h_refcount));
+                               ea_bdebug(new_bh, "reusing; refcount now=%d",
+                                       le32_to_cpu(BHDR(new_bh)->h_refcount));
+                               unlock_buffer(new_bh);
+                               error = ext4_journal_dirty_metadata(handle,
+                                                                   new_bh);
+                               if (error)
+                                       goto cleanup_dquot;
+                       }
+                       mb_cache_entry_release(ce);
+                       ce = NULL;
+               } else if (bs->bh && s->base == bs->bh->b_data) {
+                       /* We were modifying this block in-place. */
+                       ea_bdebug(bs->bh, "keeping this block");
+                       new_bh = bs->bh;
+                       get_bh(new_bh);
+               } else {
+                       /* We need to allocate a new block */
+                       ext4_fsblk_t goal = le32_to_cpu(
+                                       EXT4_SB(sb)->s_es->s_first_data_block) +
+                               (ext4_fsblk_t)EXT4_I(inode)->i_block_group *
+                               EXT4_BLOCKS_PER_GROUP(sb);
+                       ext4_fsblk_t block = ext4_new_block(handle, inode,
+                                                       goal, &error);
+                       if (error)
+                               goto cleanup;
+                       ea_idebug(inode, "creating block %d", block);
+
+                       new_bh = sb_getblk(sb, block);
+                       if (!new_bh) {
+getblk_failed:
+                               ext4_free_blocks(handle, inode, block, 1);
+                               error = -EIO;
+                               goto cleanup;
+                       }
+                       lock_buffer(new_bh);
+                       error = ext4_journal_get_create_access(handle, new_bh);
+                       if (error) {
+                               unlock_buffer(new_bh);
+                               goto getblk_failed;
+                       }
+                       memcpy(new_bh->b_data, s->base, new_bh->b_size);
+                       set_buffer_uptodate(new_bh);
+                       unlock_buffer(new_bh);
+                       ext4_xattr_cache_insert(new_bh);
+                       error = ext4_journal_dirty_metadata(handle, new_bh);
+                       if (error)
+                               goto cleanup;
+               }
+       }
+
+       /* Update the inode. */
+       EXT4_I(inode)->i_file_acl = new_bh ? new_bh->b_blocknr : 0;
+
+       /* Drop the previous xattr block. */
+       if (bs->bh && bs->bh != new_bh)
+               ext4_xattr_release_block(handle, inode, bs->bh);
+       error = 0;
+
+cleanup:
+       if (ce)
+               mb_cache_entry_release(ce);
+       brelse(new_bh);
+       if (!(bs->bh && s->base == bs->bh->b_data))
+               kfree(s->base);
+
+       return error;
+
+cleanup_dquot:
+       DQUOT_FREE_BLOCK(inode, 1);
+       goto cleanup;
+
+bad_block:
+       ext4_error(inode->i_sb, __FUNCTION__,
+                  "inode %lu: bad block %llu", inode->i_ino,
+                  EXT4_I(inode)->i_file_acl);
+       goto cleanup;
+
+#undef header
+}
+
+struct ext4_xattr_ibody_find {
+       struct ext4_xattr_search s;
+       struct ext4_iloc iloc;
+};
+
+static int
+ext4_xattr_ibody_find(struct inode *inode, struct ext4_xattr_info *i,
+                     struct ext4_xattr_ibody_find *is)
+{
+       struct ext4_xattr_ibody_header *header;
+       struct ext4_inode *raw_inode;
+       int error;
+
+       if (EXT4_I(inode)->i_extra_isize == 0)
+               return 0;
+       raw_inode = ext4_raw_inode(&is->iloc);
+       header = IHDR(inode, raw_inode);
+       is->s.base = is->s.first = IFIRST(header);
+       is->s.here = is->s.first;
+       is->s.end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size;
+       if (EXT4_I(inode)->i_state & EXT4_STATE_XATTR) {
+               error = ext4_xattr_check_names(IFIRST(header), is->s.end);
+               if (error)
+                       return error;
+               /* Find the named attribute. */
+               error = ext4_xattr_find_entry(&is->s.here, i->name_index,
+                                             i->name, is->s.end -
+                                             (void *)is->s.base, 0);
+               if (error && error != -ENODATA)
+                       return error;
+               is->s.not_found = error;
+       }
+       return 0;
+}
+
+static int
+ext4_xattr_ibody_set(handle_t *handle, struct inode *inode,
+                    struct ext4_xattr_info *i,
+                    struct ext4_xattr_ibody_find *is)
+{
+       struct ext4_xattr_ibody_header *header;
+       struct ext4_xattr_search *s = &is->s;
+       int error;
+
+       if (EXT4_I(inode)->i_extra_isize == 0)
+               return -ENOSPC;
+       error = ext4_xattr_set_entry(i, s);
+       if (error)
+               return error;
+       header = IHDR(inode, ext4_raw_inode(&is->iloc));
+       if (!IS_LAST_ENTRY(s->first)) {
+               header->h_magic = cpu_to_le32(EXT4_XATTR_MAGIC);
+               EXT4_I(inode)->i_state |= EXT4_STATE_XATTR;
+       } else {
+               header->h_magic = cpu_to_le32(0);
+               EXT4_I(inode)->i_state &= ~EXT4_STATE_XATTR;
+       }
+       return 0;
+}
+
+/*
+ * ext4_xattr_set_handle()
+ *
+ * Create, replace or remove an extended attribute for this inode. Buffer
+ * is NULL to remove an existing extended attribute, and non-NULL to
+ * either replace an existing extended attribute, or create a new extended
+ * attribute. The flags XATTR_REPLACE and XATTR_CREATE
+ * specify that an extended attribute must exist and must not exist
+ * previous to the call, respectively.
+ *
+ * Returns 0, or a negative error number on failure.
+ */
+int
+ext4_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index,
+                     const char *name, const void *value, size_t value_len,
+                     int flags)
+{
+       struct ext4_xattr_info i = {
+               .name_index = name_index,
+               .name = name,
+               .value = value,
+               .value_len = value_len,
+
+       };
+       struct ext4_xattr_ibody_find is = {
+               .s = { .not_found = -ENODATA, },
+       };
+       struct ext4_xattr_block_find bs = {
+               .s = { .not_found = -ENODATA, },
+       };
+       int error;
+
+       if (!name)
+               return -EINVAL;
+       if (strlen(name) > 255)
+               return -ERANGE;
+       down_write(&EXT4_I(inode)->xattr_sem);
+       error = ext4_get_inode_loc(inode, &is.iloc);
+       if (error)
+               goto cleanup;
+
+       if (EXT4_I(inode)->i_state & EXT4_STATE_NEW) {
+               struct ext4_inode *raw_inode = ext4_raw_inode(&is.iloc);
+               memset(raw_inode, 0, EXT4_SB(inode->i_sb)->s_inode_size);
+               EXT4_I(inode)->i_state &= ~EXT4_STATE_NEW;
+       }
+
+       error = ext4_xattr_ibody_find(inode, &i, &is);
+       if (error)
+               goto cleanup;
+       if (is.s.not_found)
+               error = ext4_xattr_block_find(inode, &i, &bs);
+       if (error)
+               goto cleanup;
+       if (is.s.not_found && bs.s.not_found) {
+               error = -ENODATA;
+               if (flags & XATTR_REPLACE)
+                       goto cleanup;
+               error = 0;
+               if (!value)
+                       goto cleanup;
+       } else {
+               error = -EEXIST;
+               if (flags & XATTR_CREATE)
+                       goto cleanup;
+       }
+       error = ext4_journal_get_write_access(handle, is.iloc.bh);
+       if (error)
+               goto cleanup;
+       if (!value) {
+               if (!is.s.not_found)
+                       error = ext4_xattr_ibody_set(handle, inode, &i, &is);
+               else if (!bs.s.not_found)
+                       error = ext4_xattr_block_set(handle, inode, &i, &bs);
+       } else {
+               error = ext4_xattr_ibody_set(handle, inode, &i, &is);
+               if (!error && !bs.s.not_found) {
+                       i.value = NULL;
+                       error = ext4_xattr_block_set(handle, inode, &i, &bs);
+               } else if (error == -ENOSPC) {
+                       error = ext4_xattr_block_set(handle, inode, &i, &bs);
+                       if (error)
+                               goto cleanup;
+                       if (!is.s.not_found) {
+                               i.value = NULL;
+                               error = ext4_xattr_ibody_set(handle, inode, &i,
+                                                            &is);
+                       }
+               }
+       }
+       if (!error) {
+               ext4_xattr_update_super_block(handle, inode->i_sb);
+               inode->i_ctime = CURRENT_TIME_SEC;
+               error = ext4_mark_iloc_dirty(handle, inode, &is.iloc);
+               /*
+                * The bh is consumed by ext4_mark_iloc_dirty, even with
+                * error != 0.
+                */
+               is.iloc.bh = NULL;
+               if (IS_SYNC(inode))
+                       handle->h_sync = 1;
+       }
+
+cleanup:
+       brelse(is.iloc.bh);
+       brelse(bs.bh);
+       up_write(&EXT4_I(inode)->xattr_sem);
+       return error;
+}
+
+/*
+ * ext4_xattr_set()
+ *
+ * Like ext4_xattr_set_handle, but start from an inode. This extended
+ * attribute modification is a filesystem transaction by itself.
+ *
+ * Returns 0, or a negative error number on failure.
+ */
+int
+ext4_xattr_set(struct inode *inode, int name_index, const char *name,
+              const void *value, size_t value_len, int flags)
+{
+       handle_t *handle;
+       int error, retries = 0;
+
+retry:
+       handle = ext4_journal_start(inode, EXT4_DATA_TRANS_BLOCKS(inode->i_sb));
+       if (IS_ERR(handle)) {
+               error = PTR_ERR(handle);
+       } else {
+               int error2;
+
+               error = ext4_xattr_set_handle(handle, inode, name_index, name,
+                                             value, value_len, flags);
+               error2 = ext4_journal_stop(handle);
+               if (error == -ENOSPC &&
+                   ext4_should_retry_alloc(inode->i_sb, &retries))
+                       goto retry;
+               if (error == 0)
+                       error = error2;
+       }
+
+       return error;
+}
+
+/*
+ * ext4_xattr_delete_inode()
+ *
+ * Free extended attribute resources associated with this inode. This
+ * is called immediately before an inode is freed. We have exclusive
+ * access to the inode.
+ */
+void
+ext4_xattr_delete_inode(handle_t *handle, struct inode *inode)
+{
+       struct buffer_head *bh = NULL;
+
+       if (!EXT4_I(inode)->i_file_acl)
+               goto cleanup;
+       bh = sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl);
+       if (!bh) {
+               ext4_error(inode->i_sb, __FUNCTION__,
+                       "inode %lu: block %llu read error", inode->i_ino,
+                       EXT4_I(inode)->i_file_acl);
+               goto cleanup;
+       }
+       if (BHDR(bh)->h_magic != cpu_to_le32(EXT4_XATTR_MAGIC) ||
+           BHDR(bh)->h_blocks != cpu_to_le32(1)) {
+               ext4_error(inode->i_sb, __FUNCTION__,
+                       "inode %lu: bad block %llu", inode->i_ino,
+                       EXT4_I(inode)->i_file_acl);
+               goto cleanup;
+       }
+       ext4_xattr_release_block(handle, inode, bh);
+       EXT4_I(inode)->i_file_acl = 0;
+
+cleanup:
+       brelse(bh);
+}
+
+/*
+ * ext4_xattr_put_super()
+ *
+ * This is called when a file system is unmounted.
+ */
+void
+ext4_xattr_put_super(struct super_block *sb)
+{
+       mb_cache_shrink(sb->s_bdev);
+}
+
+/*
+ * ext4_xattr_cache_insert()
+ *
+ * Create a new entry in the extended attribute cache, and insert
+ * it unless such an entry is already in the cache.
+ *
+ * Returns 0, or a negative error number on failure.
+ */
+static void
+ext4_xattr_cache_insert(struct buffer_head *bh)
+{
+       __u32 hash = le32_to_cpu(BHDR(bh)->h_hash);
+       struct mb_cache_entry *ce;
+       int error;
+
+       ce = mb_cache_entry_alloc(ext4_xattr_cache);
+       if (!ce) {
+               ea_bdebug(bh, "out of memory");
+               return;
+       }
+       error = mb_cache_entry_insert(ce, bh->b_bdev, bh->b_blocknr, &hash);
+       if (error) {
+               mb_cache_entry_free(ce);
+               if (error == -EBUSY) {
+                       ea_bdebug(bh, "already in cache");
+                       error = 0;
+               }
+       } else {
+               ea_bdebug(bh, "inserting [%x]", (int)hash);
+               mb_cache_entry_release(ce);
+       }
+}
+
+/*
+ * ext4_xattr_cmp()
+ *
+ * Compare two extended attribute blocks for equality.
+ *
+ * Returns 0 if the blocks are equal, 1 if they differ, and
+ * a negative error number on errors.
+ */
+static int
+ext4_xattr_cmp(struct ext4_xattr_header *header1,
+              struct ext4_xattr_header *header2)
+{
+       struct ext4_xattr_entry *entry1, *entry2;
+
+       entry1 = ENTRY(header1+1);
+       entry2 = ENTRY(header2+1);
+       while (!IS_LAST_ENTRY(entry1)) {
+               if (IS_LAST_ENTRY(entry2))
+                       return 1;
+               if (entry1->e_hash != entry2->e_hash ||
+                   entry1->e_name_index != entry2->e_name_index ||
+                   entry1->e_name_len != entry2->e_name_len ||
+                   entry1->e_value_size != entry2->e_value_size ||
+                   memcmp(entry1->e_name, entry2->e_name, entry1->e_name_len))
+                       return 1;
+               if (entry1->e_value_block != 0 || entry2->e_value_block != 0)
+                       return -EIO;
+               if (memcmp((char *)header1 + le16_to_cpu(entry1->e_value_offs),
+                          (char *)header2 + le16_to_cpu(entry2->e_value_offs),
+                          le32_to_cpu(entry1->e_value_size)))
+                       return 1;
+
+               entry1 = EXT4_XATTR_NEXT(entry1);
+               entry2 = EXT4_XATTR_NEXT(entry2);
+       }
+       if (!IS_LAST_ENTRY(entry2))
+               return 1;
+       return 0;
+}
+
+/*
+ * ext4_xattr_cache_find()
+ *
+ * Find an identical extended attribute block.
+ *
+ * Returns a pointer to the block found, or NULL if such a block was
+ * not found or an error occurred.
+ */
+static struct buffer_head *
+ext4_xattr_cache_find(struct inode *inode, struct ext4_xattr_header *header,
+                     struct mb_cache_entry **pce)
+{
+       __u32 hash = le32_to_cpu(header->h_hash);
+       struct mb_cache_entry *ce;
+
+       if (!header->h_hash)
+               return NULL;  /* never share */
+       ea_idebug(inode, "looking for cached blocks [%x]", (int)hash);
+again:
+       ce = mb_cache_entry_find_first(ext4_xattr_cache, 0,
+                                      inode->i_sb->s_bdev, hash);
+       while (ce) {
+               struct buffer_head *bh;
+
+               if (IS_ERR(ce)) {
+                       if (PTR_ERR(ce) == -EAGAIN)
+                               goto again;
+                       break;
+               }
+               bh = sb_bread(inode->i_sb, ce->e_block);
+               if (!bh) {
+                       ext4_error(inode->i_sb, __FUNCTION__,
+                               "inode %lu: block %lu read error",
+                               inode->i_ino, (unsigned long) ce->e_block);
+               } else if (le32_to_cpu(BHDR(bh)->h_refcount) >=
+                               EXT4_XATTR_REFCOUNT_MAX) {
+                       ea_idebug(inode, "block %lu refcount %d>=%d",
+                                 (unsigned long) ce->e_block,
+                                 le32_to_cpu(BHDR(bh)->h_refcount),
+                                         EXT4_XATTR_REFCOUNT_MAX);
+               } else if (ext4_xattr_cmp(header, BHDR(bh)) == 0) {
+                       *pce = ce;
+                       return bh;
+               }
+               brelse(bh);
+               ce = mb_cache_entry_find_next(ce, 0, inode->i_sb->s_bdev, hash);
+       }
+       return NULL;
+}
+
+#define NAME_HASH_SHIFT 5
+#define VALUE_HASH_SHIFT 16
+
+/*
+ * ext4_xattr_hash_entry()
+ *
+ * Compute the hash of an extended attribute.
+ */
+static inline void ext4_xattr_hash_entry(struct ext4_xattr_header *header,
+                                        struct ext4_xattr_entry *entry)
+{
+       __u32 hash = 0;
+       char *name = entry->e_name;
+       int n;
+
+       for (n=0; n < entry->e_name_len; n++) {
+               hash = (hash << NAME_HASH_SHIFT) ^
+                      (hash >> (8*sizeof(hash) - NAME_HASH_SHIFT)) ^
+                      *name++;
+       }
+
+       if (entry->e_value_block == 0 && entry->e_value_size != 0) {
+               __le32 *value = (__le32 *)((char *)header +
+                       le16_to_cpu(entry->e_value_offs));
+               for (n = (le32_to_cpu(entry->e_value_size) +
+                    EXT4_XATTR_ROUND) >> EXT4_XATTR_PAD_BITS; n; n--) {
+                       hash = (hash << VALUE_HASH_SHIFT) ^
+                              (hash >> (8*sizeof(hash) - VALUE_HASH_SHIFT)) ^
+                              le32_to_cpu(*value++);
+               }
+       }
+       entry->e_hash = cpu_to_le32(hash);
+}
+
+#undef NAME_HASH_SHIFT
+#undef VALUE_HASH_SHIFT
+
+#define BLOCK_HASH_SHIFT 16
+
+/*
+ * ext4_xattr_rehash()
+ *
+ * Re-compute the extended attribute hash value after an entry has changed.
+ */
+static void ext4_xattr_rehash(struct ext4_xattr_header *header,
+                             struct ext4_xattr_entry *entry)
+{
+       struct ext4_xattr_entry *here;
+       __u32 hash = 0;
+
+       ext4_xattr_hash_entry(header, entry);
+       here = ENTRY(header+1);
+       while (!IS_LAST_ENTRY(here)) {
+               if (!here->e_hash) {
+                       /* Block is not shared if an entry's hash value == 0 */
+                       hash = 0;
+                       break;
+               }
+               hash = (hash << BLOCK_HASH_SHIFT) ^
+                      (hash >> (8*sizeof(hash) - BLOCK_HASH_SHIFT)) ^
+                      le32_to_cpu(here->e_hash);
+               here = EXT4_XATTR_NEXT(here);
+       }
+       header->h_hash = cpu_to_le32(hash);
+}
+
+#undef BLOCK_HASH_SHIFT
+
+int __init
+init_ext4_xattr(void)
+{
+       ext4_xattr_cache = mb_cache_create("ext4_xattr", NULL,
+               sizeof(struct mb_cache_entry) +
+               sizeof(((struct mb_cache_entry *) 0)->e_indexes[0]), 1, 6);
+       if (!ext4_xattr_cache)
+               return -ENOMEM;
+       return 0;
+}
+
+void
+exit_ext4_xattr(void)
+{
+       if (ext4_xattr_cache)
+               mb_cache_destroy(ext4_xattr_cache);
+       ext4_xattr_cache = NULL;
+}
diff --git a/fs/ext4/xattr.h b/fs/ext4/xattr.h
new file mode 100644 (file)
index 0000000..79432b3
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+  File: fs/ext4/xattr.h
+
+  On-disk format of extended attributes for the ext4 filesystem.
+
+  (C) 2001 Andreas Gruenbacher, <a.gruenbacher@computer.org>
+*/
+
+#include <linux/xattr.h>
+
+/* Magic value in attribute blocks */
+#define EXT4_XATTR_MAGIC               0xEA020000
+
+/* Maximum number of references to one attribute block */
+#define EXT4_XATTR_REFCOUNT_MAX                1024
+
+/* Name indexes */
+#define EXT4_XATTR_INDEX_USER                  1
+#define EXT4_XATTR_INDEX_POSIX_ACL_ACCESS      2
+#define EXT4_XATTR_INDEX_POSIX_ACL_DEFAULT     3
+#define EXT4_XATTR_INDEX_TRUSTED               4
+#define        EXT4_XATTR_INDEX_LUSTRE                 5
+#define EXT4_XATTR_INDEX_SECURITY              6
+
+struct ext4_xattr_header {
+       __le32  h_magic;        /* magic number for identification */
+       __le32  h_refcount;     /* reference count */
+       __le32  h_blocks;       /* number of disk blocks used */
+       __le32  h_hash;         /* hash value of all attributes */
+       __u32   h_reserved[4];  /* zero right now */
+};
+
+struct ext4_xattr_ibody_header {
+       __le32  h_magic;        /* magic number for identification */
+};
+
+struct ext4_xattr_entry {
+       __u8    e_name_len;     /* length of name */
+       __u8    e_name_index;   /* attribute name index */
+       __le16  e_value_offs;   /* offset in disk block of value */
+       __le32  e_value_block;  /* disk block attribute is stored on (n/i) */
+       __le32  e_value_size;   /* size of attribute value */
+       __le32  e_hash;         /* hash value of name and value */
+       char    e_name[0];      /* attribute name */
+};
+
+#define EXT4_XATTR_PAD_BITS            2
+#define EXT4_XATTR_PAD         (1<<EXT4_XATTR_PAD_BITS)
+#define EXT4_XATTR_ROUND               (EXT4_XATTR_PAD-1)
+#define EXT4_XATTR_LEN(name_len) \
+       (((name_len) + EXT4_XATTR_ROUND + \
+       sizeof(struct ext4_xattr_entry)) & ~EXT4_XATTR_ROUND)
+#define EXT4_XATTR_NEXT(entry) \
+       ( (struct ext4_xattr_entry *)( \
+         (char *)(entry) + EXT4_XATTR_LEN((entry)->e_name_len)) )
+#define EXT4_XATTR_SIZE(size) \
+       (((size) + EXT4_XATTR_ROUND) & ~EXT4_XATTR_ROUND)
+
+# ifdef CONFIG_EXT4DEV_FS_XATTR
+
+extern struct xattr_handler ext4_xattr_user_handler;
+extern struct xattr_handler ext4_xattr_trusted_handler;
+extern struct xattr_handler ext4_xattr_acl_access_handler;
+extern struct xattr_handler ext4_xattr_acl_default_handler;
+extern struct xattr_handler ext4_xattr_security_handler;
+
+extern ssize_t ext4_listxattr(struct dentry *, char *, size_t);
+
+extern int ext4_xattr_get(struct inode *, int, const char *, void *, size_t);
+extern int ext4_xattr_list(struct inode *, char *, size_t);
+extern int ext4_xattr_set(struct inode *, int, const char *, const void *, size_t, int);
+extern int ext4_xattr_set_handle(handle_t *, struct inode *, int, const char *, const void *, size_t, int);
+
+extern void ext4_xattr_delete_inode(handle_t *, struct inode *);
+extern void ext4_xattr_put_super(struct super_block *);
+
+extern int init_ext4_xattr(void);
+extern void exit_ext4_xattr(void);
+
+extern struct xattr_handler *ext4_xattr_handlers[];
+
+# else  /* CONFIG_EXT4DEV_FS_XATTR */
+
+static inline int
+ext4_xattr_get(struct inode *inode, int name_index, const char *name,
+              void *buffer, size_t size, int flags)
+{
+       return -EOPNOTSUPP;
+}
+
+static inline int
+ext4_xattr_list(struct inode *inode, void *buffer, size_t size)
+{
+       return -EOPNOTSUPP;
+}
+
+static inline int
+ext4_xattr_set(struct inode *inode, int name_index, const char *name,
+              const void *value, size_t size, int flags)
+{
+       return -EOPNOTSUPP;
+}
+
+static inline int
+ext4_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index,
+              const char *name, const void *value, size_t size, int flags)
+{
+       return -EOPNOTSUPP;
+}
+
+static inline void
+ext4_xattr_delete_inode(handle_t *handle, struct inode *inode)
+{
+}
+
+static inline void
+ext4_xattr_put_super(struct super_block *sb)
+{
+}
+
+static inline int
+init_ext4_xattr(void)
+{
+       return 0;
+}
+
+static inline void
+exit_ext4_xattr(void)
+{
+}
+
+#define ext4_xattr_handlers    NULL
+
+# endif  /* CONFIG_EXT4DEV_FS_XATTR */
+
+#ifdef CONFIG_EXT4DEV_FS_SECURITY
+extern int ext4_init_security(handle_t *handle, struct inode *inode,
+                               struct inode *dir);
+#else
+static inline int ext4_init_security(handle_t *handle, struct inode *inode,
+                               struct inode *dir)
+{
+       return 0;
+}
+#endif
diff --git a/fs/ext4/xattr_security.c b/fs/ext4/xattr_security.c
new file mode 100644 (file)
index 0000000..b6a6861
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * linux/fs/ext4/xattr_security.c
+ * Handler for storing security labels as extended attributes.
+ */
+
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/fs.h>
+#include <linux/smp_lock.h>
+#include <linux/ext4_jbd2.h>
+#include <linux/ext4_fs.h>
+#include <linux/security.h>
+#include "xattr.h"
+
+static size_t
+ext4_xattr_security_list(struct inode *inode, char *list, size_t list_size,
+                        const char *name, size_t name_len)
+{
+       const size_t prefix_len = sizeof(XATTR_SECURITY_PREFIX)-1;
+       const size_t total_len = prefix_len + name_len + 1;
+
+
+       if (list && total_len <= list_size) {
+               memcpy(list, XATTR_SECURITY_PREFIX, prefix_len);
+               memcpy(list+prefix_len, name, name_len);
+               list[prefix_len + name_len] = '\0';
+       }
+       return total_len;
+}
+
+static int
+ext4_xattr_security_get(struct inode *inode, const char *name,
+                      void *buffer, size_t size)
+{
+       if (strcmp(name, "") == 0)
+               return -EINVAL;
+       return ext4_xattr_get(inode, EXT4_XATTR_INDEX_SECURITY, name,
+                             buffer, size);
+}
+
+static int
+ext4_xattr_security_set(struct inode *inode, const char *name,
+                      const void *value, size_t size, int flags)
+{
+       if (strcmp(name, "") == 0)
+               return -EINVAL;
+       return ext4_xattr_set(inode, EXT4_XATTR_INDEX_SECURITY, name,
+                             value, size, flags);
+}
+
+int
+ext4_init_security(handle_t *handle, struct inode *inode, struct inode *dir)
+{
+       int err;
+       size_t len;
+       void *value;
+       char *name;
+
+       err = security_inode_init_security(inode, dir, &name, &value, &len);
+       if (err) {
+               if (err == -EOPNOTSUPP)
+                       return 0;
+               return err;
+       }
+       err = ext4_xattr_set_handle(handle, inode, EXT4_XATTR_INDEX_SECURITY,
+                                   name, value, len, 0);
+       kfree(name);
+       kfree(value);
+       return err;
+}
+
+struct xattr_handler ext4_xattr_security_handler = {
+       .prefix = XATTR_SECURITY_PREFIX,
+       .list   = ext4_xattr_security_list,
+       .get    = ext4_xattr_security_get,
+       .set    = ext4_xattr_security_set,
+};
diff --git a/fs/ext4/xattr_trusted.c b/fs/ext4/xattr_trusted.c
new file mode 100644 (file)
index 0000000..b76f2db
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * linux/fs/ext4/xattr_trusted.c
+ * Handler for trusted extended attributes.
+ *
+ * Copyright (C) 2003 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
+ */
+
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/capability.h>
+#include <linux/fs.h>
+#include <linux/smp_lock.h>
+#include <linux/ext4_jbd2.h>
+#include <linux/ext4_fs.h>
+#include "xattr.h"
+
+#define XATTR_TRUSTED_PREFIX "trusted."
+
+static size_t
+ext4_xattr_trusted_list(struct inode *inode, char *list, size_t list_size,
+                       const char *name, size_t name_len)
+{
+       const size_t prefix_len = sizeof(XATTR_TRUSTED_PREFIX)-1;
+       const size_t total_len = prefix_len + name_len + 1;
+
+       if (!capable(CAP_SYS_ADMIN))
+               return 0;
+
+       if (list && total_len <= list_size) {
+               memcpy(list, XATTR_TRUSTED_PREFIX, prefix_len);
+               memcpy(list+prefix_len, name, name_len);
+               list[prefix_len + name_len] = '\0';
+       }
+       return total_len;
+}
+
+static int
+ext4_xattr_trusted_get(struct inode *inode, const char *name,
+                      void *buffer, size_t size)
+{
+       if (strcmp(name, "") == 0)
+               return -EINVAL;
+       return ext4_xattr_get(inode, EXT4_XATTR_INDEX_TRUSTED, name,
+                             buffer, size);
+}
+
+static int
+ext4_xattr_trusted_set(struct inode *inode, const char *name,
+                      const void *value, size_t size, int flags)
+{
+       if (strcmp(name, "") == 0)
+               return -EINVAL;
+       return ext4_xattr_set(inode, EXT4_XATTR_INDEX_TRUSTED, name,
+                             value, size, flags);
+}
+
+struct xattr_handler ext4_xattr_trusted_handler = {
+       .prefix = XATTR_TRUSTED_PREFIX,
+       .list   = ext4_xattr_trusted_list,
+       .get    = ext4_xattr_trusted_get,
+       .set    = ext4_xattr_trusted_set,
+};
diff --git a/fs/ext4/xattr_user.c b/fs/ext4/xattr_user.c
new file mode 100644 (file)
index 0000000..c53cded
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * linux/fs/ext4/xattr_user.c
+ * Handler for extended user attributes.
+ *
+ * Copyright (C) 2001 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
+ */
+
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/fs.h>
+#include <linux/smp_lock.h>
+#include <linux/ext4_jbd2.h>
+#include <linux/ext4_fs.h>
+#include "xattr.h"
+
+#define XATTR_USER_PREFIX "user."
+
+static size_t
+ext4_xattr_user_list(struct inode *inode, char *list, size_t list_size,
+                    const char *name, size_t name_len)
+{
+       const size_t prefix_len = sizeof(XATTR_USER_PREFIX)-1;
+       const size_t total_len = prefix_len + name_len + 1;
+
+       if (!test_opt(inode->i_sb, XATTR_USER))
+               return 0;
+
+       if (list && total_len <= list_size) {
+               memcpy(list, XATTR_USER_PREFIX, prefix_len);
+               memcpy(list+prefix_len, name, name_len);
+               list[prefix_len + name_len] = '\0';
+       }
+       return total_len;
+}
+
+static int
+ext4_xattr_user_get(struct inode *inode, const char *name,
+                   void *buffer, size_t size)
+{
+       if (strcmp(name, "") == 0)
+               return -EINVAL;
+       if (!test_opt(inode->i_sb, XATTR_USER))
+               return -EOPNOTSUPP;
+       return ext4_xattr_get(inode, EXT4_XATTR_INDEX_USER, name, buffer, size);
+}
+
+static int
+ext4_xattr_user_set(struct inode *inode, const char *name,
+                   const void *value, size_t size, int flags)
+{
+       if (strcmp(name, "") == 0)
+               return -EINVAL;
+       if (!test_opt(inode->i_sb, XATTR_USER))
+               return -EOPNOTSUPP;
+       return ext4_xattr_set(inode, EXT4_XATTR_INDEX_USER, name,
+                             value, size, flags);
+}
+
+struct xattr_handler ext4_xattr_user_handler = {
+       .prefix = XATTR_USER_PREFIX,
+       .list   = ext4_xattr_user_list,
+       .get    = ext4_xattr_user_get,
+       .set    = ext4_xattr_user_set,
+};
index f4b8f8b3fbdd25ed95df235862171dcf2a905a2a..8337451e7897abc70d00752795fade9816aee985 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/smp_lock.h>
 #include <linux/buffer_head.h>
 #include <linux/writeback.h>
+#include <linux/backing-dev.h>
 #include <linux/blkdev.h>
 
 int fat_generic_ioctl(struct inode *inode, struct file *filp,
@@ -118,7 +119,7 @@ static int fat_file_release(struct inode *inode, struct file *filp)
        if ((filp->f_mode & FMODE_WRITE) &&
             MSDOS_SB(inode->i_sb)->options.flush) {
                fat_flush_inodes(inode->i_sb, inode, NULL);
-               blk_congestion_wait(WRITE, HZ/10);
+               congestion_wait(WRITE, HZ/10);
        }
        return 0;
 }
index 045738032a83d5f4579208881d17088a65326e5a..78945b53b0f827fed88da656666ec1dd6fa9aaa9 100644 (file)
@@ -384,7 +384,7 @@ static int fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de)
                                      le16_to_cpu(de->cdate)) + secs;
                inode->i_ctime.tv_nsec = csecs * 10000000;
                inode->i_atime.tv_sec =
-                       date_dos2unix(le16_to_cpu(0), le16_to_cpu(de->adate));
+                       date_dos2unix(0, le16_to_cpu(de->adate));
                inode->i_atime.tv_nsec = 0;
        } else
                inode->i_ctime = inode->i_atime = inode->i_mtime;
@@ -1472,7 +1472,7 @@ int fat_flush_inodes(struct super_block *sb, struct inode *i1, struct inode *i2)
                ret = writeback_inode(i1);
        if (!ret && i2)
                ret = writeback_inode(i2);
-       if (!ret && sb) {
+       if (!ret) {
                struct address_space *mapping = sb->s_bdev->bd_inode->i_mapping;
                ret = filemap_flush(mapping);
        }
index 8605155db171359398c952d8319c551a95fb305b..cfc8f81e60d0133a060a9d5374fc399820de9c9a 100644 (file)
@@ -138,6 +138,7 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd)
                struct fuse_entry_out outarg;
                struct fuse_conn *fc;
                struct fuse_req *req;
+               struct dentry *parent;
 
                /* Doesn't hurt to "reset" the validity timeout */
                fuse_invalidate_entry_cache(entry);
@@ -151,8 +152,10 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd)
                if (IS_ERR(req))
                        return 0;
 
-               fuse_lookup_init(req, entry->d_parent->d_inode, entry, &outarg);
+               parent = dget_parent(entry);
+               fuse_lookup_init(req, parent->d_inode, entry, &outarg);
                request_send(fc, req);
+               dput(parent);
                err = req->out.h.error;
                /* Zero nodeid is same as -ENOENT */
                if (!err && !outarg.nodeid)
@@ -163,7 +166,9 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd)
                                fuse_send_forget(fc, req, outarg.nodeid, 1);
                                return 0;
                        }
+                       spin_lock(&fc->lock);
                        fi->nlookup ++;
+                       spin_unlock(&fc->lock);
                }
                fuse_put_request(fc, req);
                if (err || (outarg.attr.mode ^ inode->i_mode) & S_IFMT)
@@ -175,22 +180,6 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd)
        return 1;
 }
 
-/*
- * Check if there's already a hashed alias of this directory inode.
- * If yes, then lookup and mkdir must not create a new alias.
- */
-static int dir_alias(struct inode *inode)
-{
-       if (S_ISDIR(inode->i_mode)) {
-               struct dentry *alias = d_find_alias(inode);
-               if (alias) {
-                       dput(alias);
-                       return 1;
-               }
-       }
-       return 0;
-}
-
 static int invalid_nodeid(u64 nodeid)
 {
        return !nodeid || nodeid == FUSE_ROOT_ID;
@@ -206,6 +195,24 @@ static int valid_mode(int m)
                S_ISBLK(m) || S_ISFIFO(m) || S_ISSOCK(m);
 }
 
+/*
+ * Add a directory inode to a dentry, ensuring that no other dentry
+ * refers to this inode.  Called with fc->inst_mutex.
+ */
+static int fuse_d_add_directory(struct dentry *entry, struct inode *inode)
+{
+       struct dentry *alias = d_find_alias(inode);
+       if (alias) {
+               /* This tries to shrink the subtree below alias */
+               fuse_invalidate_entry(alias);
+               dput(alias);
+               if (!list_empty(&inode->i_dentry))
+                       return -EBUSY;
+       }
+       d_add(entry, inode);
+       return 0;
+}
+
 static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
                                  struct nameidata *nd)
 {
@@ -241,11 +248,17 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
        if (err && err != -ENOENT)
                return ERR_PTR(err);
 
-       if (inode && dir_alias(inode)) {
-               iput(inode);
-               return ERR_PTR(-EIO);
-       }
-       d_add(entry, inode);
+       if (inode && S_ISDIR(inode->i_mode)) {
+               mutex_lock(&fc->inst_mutex);
+               err = fuse_d_add_directory(entry, inode);
+               mutex_unlock(&fc->inst_mutex);
+               if (err) {
+                       iput(inode);
+                       return ERR_PTR(err);
+               }
+       } else
+               d_add(entry, inode);
+
        entry->d_op = &fuse_dentry_operations;
        if (!err)
                fuse_change_timeout(entry, &outarg);
@@ -401,12 +414,22 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req,
        }
        fuse_put_request(fc, req);
 
-       if (dir_alias(inode)) {
-               iput(inode);
-               return -EIO;
-       }
+       if (S_ISDIR(inode->i_mode)) {
+               struct dentry *alias;
+               mutex_lock(&fc->inst_mutex);
+               alias = d_find_alias(inode);
+               if (alias) {
+                       /* New directory must have moved since mkdir */
+                       mutex_unlock(&fc->inst_mutex);
+                       dput(alias);
+                       iput(inode);
+                       return -EBUSY;
+               }
+               d_instantiate(entry, inode);
+               mutex_unlock(&fc->inst_mutex);
+       } else
+               d_instantiate(entry, inode);
 
-       d_instantiate(entry, inode);
        fuse_change_timeout(entry, &outarg);
        fuse_invalidate_attr(dir);
        return 0;
@@ -935,14 +958,30 @@ static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg)
        }
 }
 
+static void fuse_vmtruncate(struct inode *inode, loff_t offset)
+{
+       struct fuse_conn *fc = get_fuse_conn(inode);
+       int need_trunc;
+
+       spin_lock(&fc->lock);
+       need_trunc = inode->i_size > offset;
+       i_size_write(inode, offset);
+       spin_unlock(&fc->lock);
+
+       if (need_trunc) {
+               struct address_space *mapping = inode->i_mapping;
+               unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1);
+               truncate_inode_pages(mapping, offset);
+       }
+}
+
 /*
  * Set attributes, and at the same time refresh them.
  *
  * Truncation is slightly complicated, because the 'truncate' request
  * may fail, in which case we don't want to touch the mapping.
- * vmtruncate() doesn't allow for this case.  So do the rlimit
- * checking by hand and call vmtruncate() only after the file has
- * actually been truncated.
+ * vmtruncate() doesn't allow for this case, so do the rlimit checking
+ * and the actual truncation by hand.
  */
 static int fuse_setattr(struct dentry *entry, struct iattr *attr)
 {
@@ -993,12 +1032,8 @@ static int fuse_setattr(struct dentry *entry, struct iattr *attr)
                        make_bad_inode(inode);
                        err = -EIO;
                } else {
-                       if (is_truncate) {
-                               loff_t origsize = i_size_read(inode);
-                               i_size_write(inode, outarg.attr.size);
-                               if (origsize > outarg.attr.size)
-                                       vmtruncate(inode, outarg.attr.size);
-                       }
+                       if (is_truncate)
+                               fuse_vmtruncate(inode, outarg.attr.size);
                        fuse_change_attributes(inode, &outarg.attr);
                        fi->i_time = time_to_jiffies(outarg.attr_valid,
                                                     outarg.attr_valid_nsec);
index 183626868eea602d4658e5395ec31f46130c0afe..2bb5ace3882dd9e5bcdc6e92af17e5fce873365e 100644 (file)
@@ -481,8 +481,10 @@ static int fuse_commit_write(struct file *file, struct page *page,
                err = -EIO;
        if (!err) {
                pos += count;
-               if (pos > i_size_read(inode))
+               spin_lock(&fc->lock);
+               if (pos > inode->i_size)
                        i_size_write(inode, pos);
+               spin_unlock(&fc->lock);
 
                if (offset == 0 && to == PAGE_CACHE_SIZE) {
                        clear_page_dirty(page);
@@ -586,8 +588,12 @@ static ssize_t fuse_direct_io(struct file *file, const char __user *buf,
        }
        fuse_put_request(fc, req);
        if (res > 0) {
-               if (write && pos > i_size_read(inode))
-                       i_size_write(inode, pos);
+               if (write) {
+                       spin_lock(&fc->lock);
+                       if (pos > inode->i_size)
+                               i_size_write(inode, pos);
+                       spin_unlock(&fc->lock);
+               }
                *ppos = pos;
        }
        fuse_invalidate_attr(inode);
index 69c7750d55b8e59cfd95a0322f45557a74c0fdfe..91edb8932d905890a342c1f66cbfe5dbdd04f828 100644 (file)
@@ -239,6 +239,9 @@ struct fuse_conn {
        /** Lock protecting accessess to  members of this structure */
        spinlock_t lock;
 
+       /** Mutex protecting against directory alias creation */
+       struct mutex inst_mutex;
+
        /** Refcount */
        atomic_t count;
 
index 7d0a9aee01f248ef70bb1796a013fca8dda571af..fc42035703702813266c14c66d784ee1ec7e1c20 100644 (file)
@@ -109,6 +109,7 @@ static int fuse_remount_fs(struct super_block *sb, int *flags, char *data)
 
 void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr)
 {
+       struct fuse_conn *fc = get_fuse_conn(inode);
        if (S_ISREG(inode->i_mode) && i_size_read(inode) != attr->size)
                invalidate_inode_pages(inode->i_mapping);
 
@@ -117,7 +118,9 @@ void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr)
        inode->i_nlink   = attr->nlink;
        inode->i_uid     = attr->uid;
        inode->i_gid     = attr->gid;
+       spin_lock(&fc->lock);
        i_size_write(inode, attr->size);
+       spin_unlock(&fc->lock);
        inode->i_blocks  = attr->blocks;
        inode->i_atime.tv_sec   = attr->atime;
        inode->i_atime.tv_nsec  = attr->atimensec;
@@ -130,7 +133,7 @@ void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr)
 static void fuse_init_inode(struct inode *inode, struct fuse_attr *attr)
 {
        inode->i_mode = attr->mode & S_IFMT;
-       i_size_write(inode, attr->size);
+       inode->i_size = attr->size;
        if (S_ISREG(inode->i_mode)) {
                fuse_init_common(inode);
                fuse_init_file_inode(inode);
@@ -169,7 +172,6 @@ struct inode *fuse_iget(struct super_block *sb, unsigned long nodeid,
        struct inode *inode;
        struct fuse_inode *fi;
        struct fuse_conn *fc = get_fuse_conn_super(sb);
-       int retried = 0;
 
  retry:
        inode = iget5_locked(sb, nodeid, fuse_inode_eq, fuse_inode_set, &nodeid);
@@ -183,16 +185,16 @@ struct inode *fuse_iget(struct super_block *sb, unsigned long nodeid,
                fuse_init_inode(inode, attr);
                unlock_new_inode(inode);
        } else if ((inode->i_mode ^ attr->mode) & S_IFMT) {
-               BUG_ON(retried);
                /* Inode has changed type, any I/O on the old should fail */
                make_bad_inode(inode);
                iput(inode);
-               retried = 1;
                goto retry;
        }
 
        fi = get_fuse_inode(inode);
+       spin_lock(&fc->lock);
        fi->nlookup ++;
+       spin_unlock(&fc->lock);
        fuse_change_attributes(inode, attr);
        return inode;
 }
@@ -377,6 +379,7 @@ static struct fuse_conn *new_conn(void)
        fc = kzalloc(sizeof(*fc), GFP_KERNEL);
        if (fc) {
                spin_lock_init(&fc->lock);
+               mutex_init(&fc->inst_mutex);
                atomic_set(&fc->count, 1);
                init_waitqueue_head(&fc->waitq);
                init_waitqueue_head(&fc->blocked_waitq);
@@ -396,8 +399,10 @@ static struct fuse_conn *new_conn(void)
 
 void fuse_conn_put(struct fuse_conn *fc)
 {
-       if (atomic_dec_and_test(&fc->count))
+       if (atomic_dec_and_test(&fc->count)) {
+               mutex_destroy(&fc->inst_mutex);
                kfree(fc);
+       }
 }
 
 struct fuse_conn *fuse_conn_get(struct fuse_conn *fc)
index cc57f2ecd21974a7121ccaaf35b184c148711558..06e9a8cb45e959b89e744d64168da1dc4655f71b 100644 (file)
@@ -434,8 +434,7 @@ static int lookup_block(struct gfs2_inode *ip, struct buffer_head *bh,
  */
 
 static int gfs2_block_pointers(struct inode *inode, u64 lblock, int create,
-                              struct buffer_head *bh_map, struct metapath *mp,
-                              unsigned int maxlen)
+                              struct buffer_head *bh_map, struct metapath *mp)
 {
        struct gfs2_inode *ip = GFS2_I(inode);
        struct gfs2_sbd *sdp = GFS2_SB(inode);
@@ -448,6 +447,7 @@ static int gfs2_block_pointers(struct inode *inode, u64 lblock, int create,
        int new = 0;
        u64 dblock = 0;
        int boundary;
+       unsigned int maxlen = bh_map->b_size >> inode->i_blkbits;
 
        BUG_ON(maxlen == 0);
 
@@ -541,13 +541,13 @@ static inline void bmap_unlock(struct inode *inode, int create)
 }
 
 int gfs2_block_map(struct inode *inode, u64 lblock, int create,
-                  struct buffer_head *bh, unsigned int maxlen)
+                  struct buffer_head *bh)
 {
        struct metapath mp;
        int ret;
 
        bmap_lock(inode, create);
-       ret = gfs2_block_pointers(inode, lblock, create, bh, &mp, maxlen);
+       ret = gfs2_block_pointers(inode, lblock, create, bh, &mp);
        bmap_unlock(inode, create);
        return ret;
 }
@@ -555,7 +555,7 @@ int gfs2_block_map(struct inode *inode, u64 lblock, int create,
 int gfs2_extent_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, unsigned *extlen)
 {
        struct metapath mp;
-       struct buffer_head bh = { .b_state = 0, .b_blocknr = 0, .b_size = 0 };
+       struct buffer_head bh = { .b_state = 0, .b_blocknr = 0 };
        int ret;
        int create = *new;
 
@@ -563,8 +563,9 @@ int gfs2_extent_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, unsi
        BUG_ON(!dblock);
        BUG_ON(!new);
 
+       bh.b_size = 1 << (inode->i_blkbits + 5);
        bmap_lock(inode, create);
-       ret = gfs2_block_pointers(inode, lblock, create, &bh, &mp, 32);
+       ret = gfs2_block_pointers(inode, lblock, create, &bh, &mp);
        bmap_unlock(inode, create);
        *extlen = bh.b_size >> inode->i_blkbits;
        *dblock = bh.b_blocknr;
index 0fd379b4cd9e7460feddd916f9a67f1b6f2e79c2..ac2fd04370dc445d4c21925d6ee86ea7942fa8f6 100644 (file)
@@ -15,7 +15,7 @@ struct gfs2_inode;
 struct page;
 
 int gfs2_unstuff_dinode(struct gfs2_inode *ip, struct page *page);
-int gfs2_block_map(struct inode *inode, u64 lblock, int create, struct buffer_head *bh, unsigned int maxlen);
+int gfs2_block_map(struct inode *inode, u64 lblock, int create, struct buffer_head *bh);
 int gfs2_extent_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, unsigned *extlen);
 
 int gfs2_truncatei(struct gfs2_inode *ip, u64 size);
index 459498cac93bdbafc4ac4d9b40bf62f29e698071..e24af28b1a121e556ce19770682c4c9ae4df5fe1 100644 (file)
@@ -184,7 +184,7 @@ static int gfs2_dir_write_data(struct gfs2_inode *ip, const char *buf,
        while (copied < size) {
                unsigned int amount;
                struct buffer_head *bh;
-               int new;
+               int new = 0;
 
                amount = size - copied;
                if (amount > sdp->sd_sb.sb_bsize - o)
@@ -212,8 +212,6 @@ static int gfs2_dir_write_data(struct gfs2_inode *ip, const char *buf,
                gfs2_trans_add_bh(ip->i_gl, bh, 1);
                memcpy(bh->b_data + o, buf, amount);
                brelse(bh);
-               if (error)
-                       goto fail;
 
                buf += amount;
                copied += amount;
@@ -317,8 +315,7 @@ static int gfs2_dir_read_data(struct gfs2_inode *ip, char *buf, u64 offset,
                        if (!ra)
                                extlen = 1;
                        bh = gfs2_meta_ra(ip->i_gl, dblock, extlen);
-               }
-               if (!bh) {
+               } else {
                        error = gfs2_meta_read(ip->i_gl, dblock, DIO_WAIT, &bh);
                        if (error)
                                goto fail;
@@ -332,7 +329,6 @@ static int gfs2_dir_read_data(struct gfs2_inode *ip, char *buf, u64 offset,
                extlen--;
                memcpy(buf, bh->b_data + o, amount);
                brelse(bh);
-               bh = NULL;
                buf += amount;
                copied += amount;
                lblock++;
@@ -815,7 +811,7 @@ static struct gfs2_leaf *new_leaf(struct inode *inode, struct buffer_head **pbh,
        leaf = (struct gfs2_leaf *)bh->b_data;
        leaf->lf_depth = cpu_to_be16(depth);
        leaf->lf_entries = 0;
-       leaf->lf_dirent_format = cpu_to_be16(GFS2_FORMAT_DE);
+       leaf->lf_dirent_format = cpu_to_be32(GFS2_FORMAT_DE);
        leaf->lf_next = 0;
        memset(leaf->lf_reserved, 0, sizeof(leaf->lf_reserved));
        dent = (struct gfs2_dirent *)(leaf+1);
index 1f94dd35a9435562fa7e166320f58b4c005d1091..cdd1694e889bac2c866f3fdc328acc16b47d169f 100644 (file)
@@ -45,7 +45,7 @@ static struct gdlm_ls *init_gdlm(lm_callback_t cb, struct gfs2_sbd *sdp,
        strncpy(buf, table_name, 256);
        buf[255] = '\0';
 
-       p = strstr(buf, ":");
+       p = strchr(buf, ':');
        if (!p) {
                log_info("invalid table_name \"%s\"", table_name);
                kfree(ls);
index 554fe5bd1b728fcf402836570f6571e54c9dc501..0cace3da9dbb41795b6cacdbe97de52786d3678e 100644 (file)
@@ -312,10 +312,12 @@ void gfs2_log_release(struct gfs2_sbd *sdp, unsigned int blks)
 
 static u64 log_bmap(struct gfs2_sbd *sdp, unsigned int lbn)
 {
+       struct inode *inode = sdp->sd_jdesc->jd_inode;
        int error;
-       struct buffer_head bh_map;
+       struct buffer_head bh_map = { .b_state = 0, .b_blocknr = 0 };
 
-       error = gfs2_block_map(sdp->sd_jdesc->jd_inode, lbn, 0, &bh_map, 1);
+       bh_map.b_size = 1 << inode->i_blkbits;
+       error = gfs2_block_map(inode, lbn, 0, &bh_map);
        if (error || !bh_map.b_blocknr)
                printk(KERN_INFO "error=%d, dbn=%llu lbn=%u", error, bh_map.b_blocknr, lbn);
        gfs2_assert_withdraw(sdp, !error && bh_map.b_blocknr);
@@ -569,16 +571,15 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl)
        else if (sdp->sd_log_tail != current_tail(sdp) && !sdp->sd_log_idle)
                log_write_header(sdp, 0, PULL);
        lops_after_commit(sdp, ai);
-       sdp->sd_log_head = sdp->sd_log_flush_head;
 
+       gfs2_log_lock(sdp);
+       sdp->sd_log_head = sdp->sd_log_flush_head;
        sdp->sd_log_blks_free -= sdp->sd_log_num_hdrs;
-
        sdp->sd_log_blks_reserved = 0;
        sdp->sd_log_commited_buf = 0;
        sdp->sd_log_num_hdrs = 0;
        sdp->sd_log_commited_revoke = 0;
 
-       gfs2_log_lock(sdp);
        if (!list_empty(&ai->ai_ail1_list)) {
                list_add(&ai->ai_list, &sdp->sd_ail1_list);
                ai = NULL;
index 881e337b6a70ab8d7b9701d1d4b70380e2e79dba..ab6d1115f95d5fd2cfdb407a7338e0535fc9c487 100644 (file)
@@ -492,7 +492,7 @@ static int gfs2_check_magic(struct buffer_head *bh)
        ptr = kaddr + bh_offset(bh);
        if (*ptr == cpu_to_be32(GFS2_MAGIC))
                rv = 1;
-       kunmap_atomic(page, KM_USER0);
+       kunmap_atomic(kaddr, KM_USER0);
 
        return rv;
 }
@@ -626,7 +626,7 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp)
                                memcpy(bh->b_data,
                                       kaddr + bh_offset(bd2->bd_bh),
                                       sdp->sd_sb.sb_bsize);
-                               kunmap_atomic(page, KM_USER0);
+                               kunmap_atomic(kaddr, KM_USER0);
                                *(__be32 *)bh->b_data = 0;
                        } else {
                                bh = gfs2_log_fake_buf(sdp, bd2->bd_bh);
index 4fb743f4e4a42bae5cc2c585a3ae8122ed8ae983..8d5963c7e123bbcd1e85b59c1eee629634750ca6 100644 (file)
@@ -65,7 +65,7 @@ static void gfs2_page_add_databufs(struct gfs2_inode *ip, struct page *page,
 int gfs2_get_block(struct inode *inode, sector_t lblock,
                   struct buffer_head *bh_result, int create)
 {
-       return gfs2_block_map(inode, lblock, create, bh_result, 32);
+       return gfs2_block_map(inode, lblock, create, bh_result);
 }
 
 /**
@@ -83,7 +83,7 @@ static int gfs2_get_block_noalloc(struct inode *inode, sector_t lblock,
 {
        int error;
 
-       error = gfs2_block_map(inode, lblock, 0, bh_result, 1);
+       error = gfs2_block_map(inode, lblock, 0, bh_result);
        if (error)
                return error;
        if (bh_result->b_blocknr == 0)
@@ -94,7 +94,7 @@ static int gfs2_get_block_noalloc(struct inode *inode, sector_t lblock,
 static int gfs2_get_block_direct(struct inode *inode, sector_t lblock,
                                 struct buffer_head *bh_result, int create)
 {
-       return gfs2_block_map(inode, lblock, 0, bh_result, 32);
+       return gfs2_block_map(inode, lblock, 0, bh_result);
 }
 
 /**
@@ -162,7 +162,7 @@ static int zero_readpage(struct page *page)
 
        kaddr = kmap_atomic(page, KM_USER0);
        memset(kaddr, 0, PAGE_CACHE_SIZE);
-       kunmap_atomic(page, KM_USER0);
+       kunmap_atomic(kaddr, KM_USER0);
 
        SetPageUptodate(page);
 
@@ -195,7 +195,7 @@ static int stuffed_readpage(struct gfs2_inode *ip, struct page *page)
        memcpy(kaddr, dibh->b_data + sizeof(struct gfs2_dinode),
               ip->i_di.di_size);
        memset(kaddr + ip->i_di.di_size, 0, PAGE_CACHE_SIZE - ip->i_di.di_size);
-       kunmap_atomic(page, KM_USER0);
+       kunmap_atomic(kaddr, KM_USER0);
 
        brelse(dibh);
 
@@ -370,19 +370,22 @@ static int gfs2_prepare_write(struct file *file, struct page *page,
        loff_t pos = ((loff_t)page->index << PAGE_CACHE_SHIFT) + from;
        loff_t end = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
        struct gfs2_alloc *al;
+       unsigned int write_len = to - from;
+
 
        gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_ATIME|GL_AOP, &ip->i_gh);
        error = gfs2_glock_nq_m_atime(1, &ip->i_gh);
        if (error)
                goto out_uninit;
 
-       gfs2_write_calc_reserv(ip, to - from, &data_blocks, &ind_blocks);
+       gfs2_write_calc_reserv(ip, write_len, &data_blocks, &ind_blocks);
 
-       error = gfs2_write_alloc_required(ip, pos, from - to, &alloc_required);
+       error = gfs2_write_alloc_required(ip, pos, write_len, &alloc_required);
        if (error)
                goto out_unlock;
 
 
+       ip->i_alloc.al_requested = 0;
        if (alloc_required) {
                al = gfs2_alloc_get(ip);
 
@@ -482,7 +485,7 @@ static int gfs2_commit_write(struct file *file, struct page *page,
                kaddr = kmap_atomic(page, KM_USER0);
                memcpy(dibh->b_data + sizeof(struct gfs2_dinode) + from,
                       kaddr + from, to - from);
-               kunmap_atomic(page, KM_USER0);
+               kunmap_atomic(kaddr, KM_USER0);
 
                SetPageUptodate(page);
 
index 178b339118434004a25c383de97bd0b64eab3cf9..882873a6bd6909cf985c78ed859bbf54fb66c078 100644 (file)
@@ -794,8 +794,8 @@ static int fill_super_meta(struct super_block *sb, struct super_block *new,
                fs_err(sdp, "can't get root dentry\n");
                error = -ENOMEM;
                iput(inode);
-       }
-       new->s_root->d_op = &gfs2_dops;
+       } else
+               new->s_root->d_op = &gfs2_dops;
 
        return error;
 }
@@ -854,7 +854,6 @@ static int gfs2_get_sb_meta(struct file_system_type *fs_type, int flags,
        int error = 0;
        struct super_block *sb = NULL, *new;
        struct gfs2_sbd *sdp;
-       char *gfs2mnt = NULL;
 
        sb = get_gfs2_sb(dev_name);
        if (!sb) {
@@ -892,8 +891,6 @@ static int gfs2_get_sb_meta(struct file_system_type *fs_type, int flags,
        atomic_inc(&sdp->sd_gfs2mnt->mnt_count);
        return simple_set_mnt(mnt, new);
 error:
-       if (gfs2mnt)
-               kfree(gfs2mnt);
        return error;
 }
 
index c69b94a555880c9eb6006128468f58ad6e1cdf2f..a3deae7416c92d9ed8d78beae04dbea92165a73e 100644 (file)
@@ -251,7 +251,7 @@ static int bh_get(struct gfs2_quota_data *qd)
        unsigned int block, offset;
        struct buffer_head *bh;
        int error;
-       struct buffer_head bh_map;
+       struct buffer_head bh_map = { .b_state = 0, .b_blocknr = 0 };
 
        mutex_lock(&sdp->sd_quota_mutex);
 
@@ -263,7 +263,8 @@ static int bh_get(struct gfs2_quota_data *qd)
        block = qd->qd_slot / sdp->sd_qc_per_block;
        offset = qd->qd_slot % sdp->sd_qc_per_block;;
 
-       error = gfs2_block_map(&ip->i_inode, block, 0, &bh_map, 1);
+       bh_map.b_size = 1 << ip->i_inode.i_blkbits;
+       error = gfs2_block_map(&ip->i_inode, block, 0, &bh_map);
        if (error)
                goto fail;
        error = gfs2_meta_read(ip->i_gl, bh_map.b_blocknr, DIO_WAIT, &bh);
index 0a8a4b87dcc643038b36f3d56b2f6eb1f56d35f7..62cd223819b7aa4536335ef460ed9382ac90eb12 100644 (file)
@@ -372,11 +372,12 @@ static int clean_journal(struct gfs2_jdesc *jd, struct gfs2_log_header *head)
        u32 hash;
        struct buffer_head *bh;
        int error;
-       struct buffer_head bh_map;
+       struct buffer_head bh_map = { .b_state = 0, .b_blocknr = 0 };
 
        lblock = head->lh_blkno;
        gfs2_replay_incr_blk(sdp, &lblock);
-       error = gfs2_block_map(&ip->i_inode, lblock, 0, &bh_map, 1);
+       bh_map.b_size = 1 << ip->i_inode.i_blkbits;
+       error = gfs2_block_map(&ip->i_inode, lblock, 0, &bh_map);
        if (error)
                return error;
        if (!bh_map.b_blocknr) {
index 9eedfd12bfff5d60a610e98c50c5f05075d18504..b01e0cfc99b5fc8d38a3b04d059b66fa2c7c4542 100644 (file)
@@ -32,7 +32,7 @@ void gfs2_rgrp_repolish_clones(struct gfs2_rgrpd *rgd);
 struct gfs2_alloc *gfs2_alloc_get(struct gfs2_inode *ip);
 static inline void gfs2_alloc_put(struct gfs2_inode *ip)
 {
-       return; /* Se we can see where ip->i_alloc is used */
+       return; /* So we can see where ip->i_alloc is used */
 }
 
 int gfs2_inplace_reserve_i(struct gfs2_inode *ip,
index bcf6ee36e0656b258d050418de151e910c54ff2e..7faef8544f320bd67933fe560992800235c36728 100644 (file)
@@ -60,14 +60,14 @@ void hpfs_read_inode(struct inode *i)
        if (hpfs_sb(i->i_sb)->sb_eas) {
                if ((ea = hpfs_get_ea(i->i_sb, fnode, "UID", &ea_size))) {
                        if (ea_size == 2) {
-                               i->i_uid = le16_to_cpu(*(u16*)ea);
+                               i->i_uid = le16_to_cpu(*(__le16*)ea);
                                hpfs_inode->i_ea_uid = 1;
                        }
                        kfree(ea);
                }
                if ((ea = hpfs_get_ea(i->i_sb, fnode, "GID", &ea_size))) {
                        if (ea_size == 2) {
-                               i->i_gid = le16_to_cpu(*(u16*)ea);
+                               i->i_gid = le16_to_cpu(*(__le16*)ea);
                                hpfs_inode->i_ea_gid = 1;
                        }
                        kfree(ea);
@@ -87,7 +87,7 @@ void hpfs_read_inode(struct inode *i)
                        int rdev = 0;
                        umode_t mode = hpfs_sb(sb)->sb_mode;
                        if (ea_size == 2) {
-                               mode = le16_to_cpu(*(u16*)ea);
+                               mode = le16_to_cpu(*(__le16*)ea);
                                hpfs_inode->i_ea_mode = 1;
                        }
                        kfree(ea);
@@ -95,7 +95,7 @@ void hpfs_read_inode(struct inode *i)
                        if (S_ISBLK(mode) || S_ISCHR(mode)) {
                                if ((ea = hpfs_get_ea(i->i_sb, fnode, "DEV", &ea_size))) {
                                        if (ea_size == 4)
-                                               rdev = le32_to_cpu(*(u32*)ea);
+                                               rdev = le32_to_cpu(*(__le32*)ea);
                                        kfree(ea);
                                }
                        }
@@ -148,7 +148,7 @@ static void hpfs_write_inode_ea(struct inode *i, struct fnode *fnode)
                   we'd better not overwrite them
                hpfs_error(i->i_sb, "fnode %08x has some unknown HPFS386 stuctures", i->i_ino);
        } else*/ if (hpfs_sb(i->i_sb)->sb_eas >= 2) {
-               u32 ea;
+               __le32 ea;
                if ((i->i_uid != hpfs_sb(i->i_sb)->sb_uid) || hpfs_inode->i_ea_uid) {
                        ea = cpu_to_le32(i->i_uid);
                        hpfs_set_ea(i, fnode, "UID", (char*)&ea, 2);
@@ -165,6 +165,7 @@ static void hpfs_write_inode_ea(struct inode *i, struct fnode *fnode)
                          && i->i_mode != ((hpfs_sb(i->i_sb)->sb_mode & ~(S_ISDIR(i->i_mode) ? 0222 : 0333))
                          | (S_ISDIR(i->i_mode) ? S_IFDIR : S_IFREG))) || hpfs_inode->i_ea_mode) {
                                ea = cpu_to_le32(i->i_mode);
+                               /* sick, but legal */
                                hpfs_set_ea(i, fnode, "MODE", (char *)&ea, 2);
                                hpfs_inode->i_ea_mode = 1;
                        }
index dcb6d2e988b81a3bf86ecabc2a233979c2eff5bc..642675fc394a9e0a2771d4a106c91c2097d4fb23 100644 (file)
@@ -572,7 +572,7 @@ struct hppfs_dirent {
 };
 
 static int hppfs_filldir(void *d, const char *name, int size,
-                        loff_t offset, ino_t inode, unsigned int type)
+                        loff_t offset, u64 inode, unsigned int type)
 {
        struct hppfs_dirent *dirent = d;
 
index 5e03b2f67b932dcb37d61ed3dbbffb6576141cff..4ee3f006b861940f6d27c2b09711504498d59607 100644 (file)
@@ -293,7 +293,7 @@ hugetlb_vmtruncate_list(struct prio_tree_root *root, unsigned long h_pgoff)
                if (h_vm_pgoff >= h_pgoff)
                        v_offset = 0;
 
-               unmap_hugepage_range(vma,
+               __unmap_hugepage_range(vma,
                                vma->vm_start + v_offset, vma->vm_end);
        }
 }
index bf6bec4e54ff648b4696c04909dcf2a5000c8748..26cdb115ce67d5361222d39cf5e94039db654eec 100644 (file)
@@ -162,7 +162,7 @@ static struct inode *alloc_inode(struct super_block *sb)
                                bdi = sb->s_bdev->bd_inode->i_mapping->backing_dev_info;
                        mapping->backing_dev_info = bdi;
                }
-               inode->i_private = 0;
+               inode->i_private = NULL;
                inode->i_mapping = mapping;
        }
        return inode;
@@ -1306,6 +1306,42 @@ void wake_up_inode(struct inode *inode)
        wake_up_bit(&inode->i_state, __I_LOCK);
 }
 
+/*
+ * We rarely want to lock two inodes that do not have a parent/child
+ * relationship (such as directory, child inode) simultaneously. The
+ * vast majority of file systems should be able to get along fine
+ * without this. Do not use these functions except as a last resort.
+ */
+void inode_double_lock(struct inode *inode1, struct inode *inode2)
+{
+       if (inode1 == NULL || inode2 == NULL || inode1 == inode2) {
+               if (inode1)
+                       mutex_lock(&inode1->i_mutex);
+               else if (inode2)
+                       mutex_lock(&inode2->i_mutex);
+               return;
+       }
+
+       if (inode1 < inode2) {
+               mutex_lock_nested(&inode1->i_mutex, I_MUTEX_PARENT);
+               mutex_lock_nested(&inode2->i_mutex, I_MUTEX_CHILD);
+       } else {
+               mutex_lock_nested(&inode2->i_mutex, I_MUTEX_PARENT);
+               mutex_lock_nested(&inode1->i_mutex, I_MUTEX_CHILD);
+       }
+}
+EXPORT_SYMBOL(inode_double_lock);
+
+void inode_double_unlock(struct inode *inode1, struct inode *inode2)
+{
+       if (inode1)
+               mutex_unlock(&inode1->i_mutex);
+
+       if (inode2 && inode2 != inode1)
+               mutex_unlock(&inode2->i_mutex);
+}
+EXPORT_SYMBOL(inode_double_unlock);
+
 static __initdata unsigned long ihash_entries;
 static int __init set_ihash_entries(char *str)
 {
index 6dc6721d9e822d159fbb7e68cfc047aafe6c4e34..89e8da112a75e46cfa6aa6bef831266b07edf835 100644 (file)
@@ -150,11 +150,6 @@ int ioprio_best(unsigned short aprio, unsigned short bprio)
        unsigned short aclass = IOPRIO_PRIO_CLASS(aprio);
        unsigned short bclass = IOPRIO_PRIO_CLASS(bprio);
 
-       if (!ioprio_valid(aprio))
-               return bprio;
-       if (!ioprio_valid(bprio))
-               return aprio;
-
        if (aclass == IOPRIO_CLASS_NONE)
                aclass = IOPRIO_CLASS_BE;
        if (bclass == IOPRIO_CLASS_NONE)
index 81a90e170ac36a10a8fd56e4e3d2242dfab1885d..fb8fe7a9ddc6cf6aee6a8a80542505985c069a34 100644 (file)
@@ -14,9 +14,9 @@
  * Convert Unicode 16 to UTF-8 or ASCII.
  */
 static int
-uni16_to_x8(unsigned char *ascii, u16 *uni, int len, struct nls_table *nls)
+uni16_to_x8(unsigned char *ascii, __be16 *uni, int len, struct nls_table *nls)
 {
-       wchar_t *ip, ch;
+       __be16 *ip, ch;
        unsigned char *op;
 
        ip = uni;
@@ -24,8 +24,8 @@ uni16_to_x8(unsigned char *ascii, u16 *uni, int len, struct nls_table *nls)
 
        while ((ch = get_unaligned(ip)) && len) {
                int llen;
-               ch = be16_to_cpu(ch);
-               if ((llen = nls->uni2char(ch, op, NLS_MAX_CHARSET_SIZE)) > 0)
+               llen = nls->uni2char(be16_to_cpu(ch), op, NLS_MAX_CHARSET_SIZE);
+               if (llen > 0)
                        op += llen;
                else
                        *op++ = '?';
@@ -82,7 +82,7 @@ get_joliet_filename(struct iso_directory_record * de, unsigned char *outname, st
                len = wcsntombs_be(outname, de->name,
                                   de->name_len[0] >> 1, PAGE_SIZE);
        } else {
-               len = uni16_to_x8(outname, (u16 *) de->name,
+               len = uni16_to_x8(outname, (__be16 *) de->name,
                                  de->name_len[0] >> 1, nls);
        }
        if ((len > 2) && (outname[len-2] == ';') && (outname[len-1] == '1')) {
index c518dd8fe60a5c539055b33e7e6b33860daad361..b85c686b60dbc7f58c32e04740dcb7052056544e 100644 (file)
@@ -725,6 +725,7 @@ journal_t * journal_init_dev(struct block_device *bdev,
                        __FUNCTION__);
                kfree(journal);
                journal = NULL;
+               goto out;
        }
        journal->j_dev = bdev;
        journal->j_fs_dev = fs_dev;
@@ -735,7 +736,7 @@ journal_t * journal_init_dev(struct block_device *bdev,
        J_ASSERT(bh != NULL);
        journal->j_sb_buffer = bh;
        journal->j_superblock = (journal_superblock_t *)bh->b_data;
-
+out:
        return journal;
 }
 
index e1b3c8af4d1767cd8b530e90cb482655f891fa6f..d5c63047a8b3f89584963a31c85e22f08ee831c6 100644 (file)
@@ -1314,13 +1314,14 @@ int journal_stop(handle_t *handle)
        int old_handle_count, err;
        pid_t pid;
 
-       J_ASSERT(transaction->t_updates > 0);
        J_ASSERT(journal_current_handle() == handle);
 
        if (is_handle_aborted(handle))
                err = -EIO;
-       else
+       else {
+               J_ASSERT(transaction->t_updates > 0);
                err = 0;
+       }
 
        if (--handle->h_ref > 0) {
                jbd_debug(4, "h_ref %d -> %d\n", handle->h_ref + 1,
diff --git a/fs/jbd2/Makefile b/fs/jbd2/Makefile
new file mode 100644 (file)
index 0000000..802a341
--- /dev/null
@@ -0,0 +1,7 @@
+#
+# Makefile for the linux journaling routines.
+#
+
+obj-$(CONFIG_JBD2) += jbd2.o
+
+jbd2-objs := transaction.o commit.o recovery.o checkpoint.o revoke.o journal.o
diff --git a/fs/jbd2/checkpoint.c b/fs/jbd2/checkpoint.c
new file mode 100644 (file)
index 0000000..68039fa
--- /dev/null
@@ -0,0 +1,697 @@
+/*
+ * linux/fs/checkpoint.c
+ *
+ * Written by Stephen C. Tweedie <sct@redhat.com>, 1999
+ *
+ * Copyright 1999 Red Hat Software --- All Rights Reserved
+ *
+ * This file is part of the Linux kernel and is made available under
+ * the terms of the GNU General Public License, version 2, or at your
+ * option, any later version, incorporated herein by reference.
+ *
+ * Checkpoint routines for the generic filesystem journaling code.
+ * Part of the ext2fs journaling system.
+ *
+ * Checkpointing is the process of ensuring that a section of the log is
+ * committed fully to disk, so that that portion of the log can be
+ * reused.
+ */
+
+#include <linux/time.h>
+#include <linux/fs.h>
+#include <linux/jbd2.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+
+/*
+ * Unlink a buffer from a transaction checkpoint list.
+ *
+ * Called with j_list_lock held.
+ */
+static inline void __buffer_unlink_first(struct journal_head *jh)
+{
+       transaction_t *transaction = jh->b_cp_transaction;
+
+       jh->b_cpnext->b_cpprev = jh->b_cpprev;
+       jh->b_cpprev->b_cpnext = jh->b_cpnext;
+       if (transaction->t_checkpoint_list == jh) {
+               transaction->t_checkpoint_list = jh->b_cpnext;
+               if (transaction->t_checkpoint_list == jh)
+                       transaction->t_checkpoint_list = NULL;
+       }
+}
+
+/*
+ * Unlink a buffer from a transaction checkpoint(io) list.
+ *
+ * Called with j_list_lock held.
+ */
+static inline void __buffer_unlink(struct journal_head *jh)
+{
+       transaction_t *transaction = jh->b_cp_transaction;
+
+       __buffer_unlink_first(jh);
+       if (transaction->t_checkpoint_io_list == jh) {
+               transaction->t_checkpoint_io_list = jh->b_cpnext;
+               if (transaction->t_checkpoint_io_list == jh)
+                       transaction->t_checkpoint_io_list = NULL;
+       }
+}
+
+/*
+ * Move a buffer from the checkpoint list to the checkpoint io list
+ *
+ * Called with j_list_lock held
+ */
+static inline void __buffer_relink_io(struct journal_head *jh)
+{
+       transaction_t *transaction = jh->b_cp_transaction;
+
+       __buffer_unlink_first(jh);
+
+       if (!transaction->t_checkpoint_io_list) {
+               jh->b_cpnext = jh->b_cpprev = jh;
+       } else {
+               jh->b_cpnext = transaction->t_checkpoint_io_list;
+               jh->b_cpprev = transaction->t_checkpoint_io_list->b_cpprev;
+               jh->b_cpprev->b_cpnext = jh;
+               jh->b_cpnext->b_cpprev = jh;
+       }
+       transaction->t_checkpoint_io_list = jh;
+}
+
+/*
+ * Try to release a checkpointed buffer from its transaction.
+ * Returns 1 if we released it and 2 if we also released the
+ * whole transaction.
+ *
+ * Requires j_list_lock
+ * Called under jbd_lock_bh_state(jh2bh(jh)), and drops it
+ */
+static int __try_to_free_cp_buf(struct journal_head *jh)
+{
+       int ret = 0;
+       struct buffer_head *bh = jh2bh(jh);
+
+       if (jh->b_jlist == BJ_None && !buffer_locked(bh) && !buffer_dirty(bh)) {
+               JBUFFER_TRACE(jh, "remove from checkpoint list");
+               ret = __jbd2_journal_remove_checkpoint(jh) + 1;
+               jbd_unlock_bh_state(bh);
+               jbd2_journal_remove_journal_head(bh);
+               BUFFER_TRACE(bh, "release");
+               __brelse(bh);
+       } else {
+               jbd_unlock_bh_state(bh);
+       }
+       return ret;
+}
+
+/*
+ * __jbd2_log_wait_for_space: wait until there is space in the journal.
+ *
+ * Called under j-state_lock *only*.  It will be unlocked if we have to wait
+ * for a checkpoint to free up some space in the log.
+ */
+void __jbd2_log_wait_for_space(journal_t *journal)
+{
+       int nblocks;
+       assert_spin_locked(&journal->j_state_lock);
+
+       nblocks = jbd_space_needed(journal);
+       while (__jbd2_log_space_left(journal) < nblocks) {
+               if (journal->j_flags & JBD2_ABORT)
+                       return;
+               spin_unlock(&journal->j_state_lock);
+               mutex_lock(&journal->j_checkpoint_mutex);
+
+               /*
+                * Test again, another process may have checkpointed while we
+                * were waiting for the checkpoint lock
+                */
+               spin_lock(&journal->j_state_lock);
+               nblocks = jbd_space_needed(journal);
+               if (__jbd2_log_space_left(journal) < nblocks) {
+                       spin_unlock(&journal->j_state_lock);
+                       jbd2_log_do_checkpoint(journal);
+                       spin_lock(&journal->j_state_lock);
+               }
+               mutex_unlock(&journal->j_checkpoint_mutex);
+       }
+}
+
+/*
+ * We were unable to perform jbd_trylock_bh_state() inside j_list_lock.
+ * The caller must restart a list walk.  Wait for someone else to run
+ * jbd_unlock_bh_state().
+ */
+static void jbd_sync_bh(journal_t *journal, struct buffer_head *bh)
+       __releases(journal->j_list_lock)
+{
+       get_bh(bh);
+       spin_unlock(&journal->j_list_lock);
+       jbd_lock_bh_state(bh);
+       jbd_unlock_bh_state(bh);
+       put_bh(bh);
+}
+
+/*
+ * Clean up transaction's list of buffers submitted for io.
+ * We wait for any pending IO to complete and remove any clean
+ * buffers. Note that we take the buffers in the opposite ordering
+ * from the one in which they were submitted for IO.
+ *
+ * Called with j_list_lock held.
+ */
+static void __wait_cp_io(journal_t *journal, transaction_t *transaction)
+{
+       struct journal_head *jh;
+       struct buffer_head *bh;
+       tid_t this_tid;
+       int released = 0;
+
+       this_tid = transaction->t_tid;
+restart:
+       /* Did somebody clean up the transaction in the meanwhile? */
+       if (journal->j_checkpoint_transactions != transaction ||
+                       transaction->t_tid != this_tid)
+               return;
+       while (!released && transaction->t_checkpoint_io_list) {
+               jh = transaction->t_checkpoint_io_list;
+               bh = jh2bh(jh);
+               if (!jbd_trylock_bh_state(bh)) {
+                       jbd_sync_bh(journal, bh);
+                       spin_lock(&journal->j_list_lock);
+                       goto restart;
+               }
+               if (buffer_locked(bh)) {
+                       atomic_inc(&bh->b_count);
+                       spin_unlock(&journal->j_list_lock);
+                       jbd_unlock_bh_state(bh);
+                       wait_on_buffer(bh);
+                       /* the journal_head may have gone by now */
+                       BUFFER_TRACE(bh, "brelse");
+                       __brelse(bh);
+                       spin_lock(&journal->j_list_lock);
+                       goto restart;
+               }
+               /*
+                * Now in whatever state the buffer currently is, we know that
+                * it has been written out and so we can drop it from the list
+                */
+               released = __jbd2_journal_remove_checkpoint(jh);
+               jbd_unlock_bh_state(bh);
+               jbd2_journal_remove_journal_head(bh);
+               __brelse(bh);
+       }
+}
+
+#define NR_BATCH       64
+
+static void
+__flush_batch(journal_t *journal, struct buffer_head **bhs, int *batch_count)
+{
+       int i;
+
+       ll_rw_block(SWRITE, *batch_count, bhs);
+       for (i = 0; i < *batch_count; i++) {
+               struct buffer_head *bh = bhs[i];
+               clear_buffer_jwrite(bh);
+               BUFFER_TRACE(bh, "brelse");
+               __brelse(bh);
+       }
+       *batch_count = 0;
+}
+
+/*
+ * Try to flush one buffer from the checkpoint list to disk.
+ *
+ * Return 1 if something happened which requires us to abort the current
+ * scan of the checkpoint list.
+ *
+ * Called with j_list_lock held and drops it if 1 is returned
+ * Called under jbd_lock_bh_state(jh2bh(jh)), and drops it
+ */
+static int __process_buffer(journal_t *journal, struct journal_head *jh,
+                       struct buffer_head **bhs, int *batch_count)
+{
+       struct buffer_head *bh = jh2bh(jh);
+       int ret = 0;
+
+       if (buffer_locked(bh)) {
+               atomic_inc(&bh->b_count);
+               spin_unlock(&journal->j_list_lock);
+               jbd_unlock_bh_state(bh);
+               wait_on_buffer(bh);
+               /* the journal_head may have gone by now */
+               BUFFER_TRACE(bh, "brelse");
+               __brelse(bh);
+               ret = 1;
+       } else if (jh->b_transaction != NULL) {
+               transaction_t *t = jh->b_transaction;
+               tid_t tid = t->t_tid;
+
+               spin_unlock(&journal->j_list_lock);
+               jbd_unlock_bh_state(bh);
+               jbd2_log_start_commit(journal, tid);
+               jbd2_log_wait_commit(journal, tid);
+               ret = 1;
+       } else if (!buffer_dirty(bh)) {
+               J_ASSERT_JH(jh, !buffer_jbddirty(bh));
+               BUFFER_TRACE(bh, "remove from checkpoint");
+               __jbd2_journal_remove_checkpoint(jh);
+               spin_unlock(&journal->j_list_lock);
+               jbd_unlock_bh_state(bh);
+               jbd2_journal_remove_journal_head(bh);
+               __brelse(bh);
+               ret = 1;
+       } else {
+               /*
+                * Important: we are about to write the buffer, and
+                * possibly block, while still holding the journal lock.
+                * We cannot afford to let the transaction logic start
+                * messing around with this buffer before we write it to
+                * disk, as that would break recoverability.
+                */
+               BUFFER_TRACE(bh, "queue");
+               get_bh(bh);
+               J_ASSERT_BH(bh, !buffer_jwrite(bh));
+               set_buffer_jwrite(bh);
+               bhs[*batch_count] = bh;
+               __buffer_relink_io(jh);
+               jbd_unlock_bh_state(bh);
+               (*batch_count)++;
+               if (*batch_count == NR_BATCH) {
+                       spin_unlock(&journal->j_list_lock);
+                       __flush_batch(journal, bhs, batch_count);
+                       ret = 1;
+               }
+       }
+       return ret;
+}
+
+/*
+ * Perform an actual checkpoint. We take the first transaction on the
+ * list of transactions to be checkpointed and send all its buffers
+ * to disk. We submit larger chunks of data at once.
+ *
+ * The journal should be locked before calling this function.
+ */
+int jbd2_log_do_checkpoint(journal_t *journal)
+{
+       transaction_t *transaction;
+       tid_t this_tid;
+       int result;
+
+       jbd_debug(1, "Start checkpoint\n");
+
+       /*
+        * First thing: if there are any transactions in the log which
+        * don't need checkpointing, just eliminate them from the
+        * journal straight away.
+        */
+       result = jbd2_cleanup_journal_tail(journal);
+       jbd_debug(1, "cleanup_journal_tail returned %d\n", result);
+       if (result <= 0)
+               return result;
+
+       /*
+        * OK, we need to start writing disk blocks.  Take one transaction
+        * and write it.
+        */
+       spin_lock(&journal->j_list_lock);
+       if (!journal->j_checkpoint_transactions)
+               goto out;
+       transaction = journal->j_checkpoint_transactions;
+       this_tid = transaction->t_tid;
+restart:
+       /*
+        * If someone cleaned up this transaction while we slept, we're
+        * done (maybe it's a new transaction, but it fell at the same
+        * address).
+        */
+       if (journal->j_checkpoint_transactions == transaction &&
+                       transaction->t_tid == this_tid) {
+               int batch_count = 0;
+               struct buffer_head *bhs[NR_BATCH];
+               struct journal_head *jh;
+               int retry = 0;
+
+               while (!retry && transaction->t_checkpoint_list) {
+                       struct buffer_head *bh;
+
+                       jh = transaction->t_checkpoint_list;
+                       bh = jh2bh(jh);
+                       if (!jbd_trylock_bh_state(bh)) {
+                               jbd_sync_bh(journal, bh);
+                               retry = 1;
+                               break;
+                       }
+                       retry = __process_buffer(journal, jh, bhs,&batch_count);
+                       if (!retry && lock_need_resched(&journal->j_list_lock)){
+                               spin_unlock(&journal->j_list_lock);
+                               retry = 1;
+                               break;
+                       }
+               }
+
+               if (batch_count) {
+                       if (!retry) {
+                               spin_unlock(&journal->j_list_lock);
+                               retry = 1;
+                       }
+                       __flush_batch(journal, bhs, &batch_count);
+               }
+
+               if (retry) {
+                       spin_lock(&journal->j_list_lock);
+                       goto restart;
+               }
+               /*
+                * Now we have cleaned up the first transaction's checkpoint
+                * list. Let's clean up the second one
+                */
+               __wait_cp_io(journal, transaction);
+       }
+out:
+       spin_unlock(&journal->j_list_lock);
+       result = jbd2_cleanup_journal_tail(journal);
+       if (result < 0)
+               return result;
+       return 0;
+}
+
+/*
+ * Check the list of checkpoint transactions for the journal to see if
+ * we have already got rid of any since the last update of the log tail
+ * in the journal superblock.  If so, we can instantly roll the
+ * superblock forward to remove those transactions from the log.
+ *
+ * Return <0 on error, 0 on success, 1 if there was nothing to clean up.
+ *
+ * Called with the journal lock held.
+ *
+ * This is the only part of the journaling code which really needs to be
+ * aware of transaction aborts.  Checkpointing involves writing to the
+ * main filesystem area rather than to the journal, so it can proceed
+ * even in abort state, but we must not update the journal superblock if
+ * we have an abort error outstanding.
+ */
+
+int jbd2_cleanup_journal_tail(journal_t *journal)
+{
+       transaction_t * transaction;
+       tid_t           first_tid;
+       unsigned long   blocknr, freed;
+
+       /* OK, work out the oldest transaction remaining in the log, and
+        * the log block it starts at.
+        *
+        * If the log is now empty, we need to work out which is the
+        * next transaction ID we will write, and where it will
+        * start. */
+
+       spin_lock(&journal->j_state_lock);
+       spin_lock(&journal->j_list_lock);
+       transaction = journal->j_checkpoint_transactions;
+       if (transaction) {
+               first_tid = transaction->t_tid;
+               blocknr = transaction->t_log_start;
+       } else if ((transaction = journal->j_committing_transaction) != NULL) {
+               first_tid = transaction->t_tid;
+               blocknr = transaction->t_log_start;
+       } else if ((transaction = journal->j_running_transaction) != NULL) {
+               first_tid = transaction->t_tid;
+               blocknr = journal->j_head;
+       } else {
+               first_tid = journal->j_transaction_sequence;
+               blocknr = journal->j_head;
+       }
+       spin_unlock(&journal->j_list_lock);
+       J_ASSERT(blocknr != 0);
+
+       /* If the oldest pinned transaction is at the tail of the log
+           already then there's not much we can do right now. */
+       if (journal->j_tail_sequence == first_tid) {
+               spin_unlock(&journal->j_state_lock);
+               return 1;
+       }
+
+       /* OK, update the superblock to recover the freed space.
+        * Physical blocks come first: have we wrapped beyond the end of
+        * the log?  */
+       freed = blocknr - journal->j_tail;
+       if (blocknr < journal->j_tail)
+               freed = freed + journal->j_last - journal->j_first;
+
+       jbd_debug(1,
+                 "Cleaning journal tail from %d to %d (offset %lu), "
+                 "freeing %lu\n",
+                 journal->j_tail_sequence, first_tid, blocknr, freed);
+
+       journal->j_free += freed;
+       journal->j_tail_sequence = first_tid;
+       journal->j_tail = blocknr;
+       spin_unlock(&journal->j_state_lock);
+       if (!(journal->j_flags & JBD2_ABORT))
+               jbd2_journal_update_superblock(journal, 1);
+       return 0;
+}
+
+
+/* Checkpoint list management */
+
+/*
+ * journal_clean_one_cp_list
+ *
+ * Find all the written-back checkpoint buffers in the given list and release them.
+ *
+ * Called with the journal locked.
+ * Called with j_list_lock held.
+ * Returns number of bufers reaped (for debug)
+ */
+
+static int journal_clean_one_cp_list(struct journal_head *jh, int *released)
+{
+       struct journal_head *last_jh;
+       struct journal_head *next_jh = jh;
+       int ret, freed = 0;
+
+       *released = 0;
+       if (!jh)
+               return 0;
+
+       last_jh = jh->b_cpprev;
+       do {
+               jh = next_jh;
+               next_jh = jh->b_cpnext;
+               /* Use trylock because of the ranking */
+               if (jbd_trylock_bh_state(jh2bh(jh))) {
+                       ret = __try_to_free_cp_buf(jh);
+                       if (ret) {
+                               freed++;
+                               if (ret == 2) {
+                                       *released = 1;
+                                       return freed;
+                               }
+                       }
+               }
+               /*
+                * This function only frees up some memory
+                * if possible so we dont have an obligation
+                * to finish processing. Bail out if preemption
+                * requested:
+                */
+               if (need_resched())
+                       return freed;
+       } while (jh != last_jh);
+
+       return freed;
+}
+
+/*
+ * journal_clean_checkpoint_list
+ *
+ * Find all the written-back checkpoint buffers in the journal and release them.
+ *
+ * Called with the journal locked.
+ * Called with j_list_lock held.
+ * Returns number of buffers reaped (for debug)
+ */
+
+int __jbd2_journal_clean_checkpoint_list(journal_t *journal)
+{
+       transaction_t *transaction, *last_transaction, *next_transaction;
+       int ret = 0;
+       int released;
+
+       transaction = journal->j_checkpoint_transactions;
+       if (!transaction)
+               goto out;
+
+       last_transaction = transaction->t_cpprev;
+       next_transaction = transaction;
+       do {
+               transaction = next_transaction;
+               next_transaction = transaction->t_cpnext;
+               ret += journal_clean_one_cp_list(transaction->
+                               t_checkpoint_list, &released);
+               /*
+                * This function only frees up some memory if possible so we
+                * dont have an obligation to finish processing. Bail out if
+                * preemption requested:
+                */
+               if (need_resched())
+                       goto out;
+               if (released)
+                       continue;
+               /*
+                * It is essential that we are as careful as in the case of
+                * t_checkpoint_list with removing the buffer from the list as
+                * we can possibly see not yet submitted buffers on io_list
+                */
+               ret += journal_clean_one_cp_list(transaction->
+                               t_checkpoint_io_list, &released);
+               if (need_resched())
+                       goto out;
+       } while (transaction != last_transaction);
+out:
+       return ret;
+}
+
+/*
+ * journal_remove_checkpoint: called after a buffer has been committed
+ * to disk (either by being write-back flushed to disk, or being
+ * committed to the log).
+ *
+ * We cannot safely clean a transaction out of the log until all of the
+ * buffer updates committed in that transaction have safely been stored
+ * elsewhere on disk.  To achieve this, all of the buffers in a
+ * transaction need to be maintained on the transaction's checkpoint
+ * lists until they have been rewritten, at which point this function is
+ * called to remove the buffer from the existing transaction's
+ * checkpoint lists.
+ *
+ * The function returns 1 if it frees the transaction, 0 otherwise.
+ *
+ * This function is called with the journal locked.
+ * This function is called with j_list_lock held.
+ * This function is called with jbd_lock_bh_state(jh2bh(jh))
+ */
+
+int __jbd2_journal_remove_checkpoint(struct journal_head *jh)
+{
+       transaction_t *transaction;
+       journal_t *journal;
+       int ret = 0;
+
+       JBUFFER_TRACE(jh, "entry");
+
+       if ((transaction = jh->b_cp_transaction) == NULL) {
+               JBUFFER_TRACE(jh, "not on transaction");
+               goto out;
+       }
+       journal = transaction->t_journal;
+
+       __buffer_unlink(jh);
+       jh->b_cp_transaction = NULL;
+
+       if (transaction->t_checkpoint_list != NULL ||
+           transaction->t_checkpoint_io_list != NULL)
+               goto out;
+       JBUFFER_TRACE(jh, "transaction has no more buffers");
+
+       /*
+        * There is one special case to worry about: if we have just pulled the
+        * buffer off a committing transaction's forget list, then even if the
+        * checkpoint list is empty, the transaction obviously cannot be
+        * dropped!
+        *
+        * The locking here around j_committing_transaction is a bit sleazy.
+        * See the comment at the end of jbd2_journal_commit_transaction().
+        */
+       if (transaction == journal->j_committing_transaction) {
+               JBUFFER_TRACE(jh, "belongs to committing transaction");
+               goto out;
+       }
+
+       /* OK, that was the last buffer for the transaction: we can now
+          safely remove this transaction from the log */
+
+       __jbd2_journal_drop_transaction(journal, transaction);
+
+       /* Just in case anybody was waiting for more transactions to be
+           checkpointed... */
+       wake_up(&journal->j_wait_logspace);
+       ret = 1;
+out:
+       JBUFFER_TRACE(jh, "exit");
+       return ret;
+}
+
+/*
+ * journal_insert_checkpoint: put a committed buffer onto a checkpoint
+ * list so that we know when it is safe to clean the transaction out of
+ * the log.
+ *
+ * Called with the journal locked.
+ * Called with j_list_lock held.
+ */
+void __jbd2_journal_insert_checkpoint(struct journal_head *jh,
+                              transaction_t *transaction)
+{
+       JBUFFER_TRACE(jh, "entry");
+       J_ASSERT_JH(jh, buffer_dirty(jh2bh(jh)) || buffer_jbddirty(jh2bh(jh)));
+       J_ASSERT_JH(jh, jh->b_cp_transaction == NULL);
+
+       jh->b_cp_transaction = transaction;
+
+       if (!transaction->t_checkpoint_list) {
+               jh->b_cpnext = jh->b_cpprev = jh;
+       } else {
+               jh->b_cpnext = transaction->t_checkpoint_list;
+               jh->b_cpprev = transaction->t_checkpoint_list->b_cpprev;
+               jh->b_cpprev->b_cpnext = jh;
+               jh->b_cpnext->b_cpprev = jh;
+       }
+       transaction->t_checkpoint_list = jh;
+}
+
+/*
+ * We've finished with this transaction structure: adios...
+ *
+ * The transaction must have no links except for the checkpoint by this
+ * point.
+ *
+ * Called with the journal locked.
+ * Called with j_list_lock held.
+ */
+
+void __jbd2_journal_drop_transaction(journal_t *journal, transaction_t *transaction)
+{
+       assert_spin_locked(&journal->j_list_lock);
+       if (transaction->t_cpnext) {
+               transaction->t_cpnext->t_cpprev = transaction->t_cpprev;
+               transaction->t_cpprev->t_cpnext = transaction->t_cpnext;
+               if (journal->j_checkpoint_transactions == transaction)
+                       journal->j_checkpoint_transactions =
+                               transaction->t_cpnext;
+               if (journal->j_checkpoint_transactions == transaction)
+                       journal->j_checkpoint_transactions = NULL;
+       }
+
+       J_ASSERT(transaction->t_state == T_FINISHED);
+       J_ASSERT(transaction->t_buffers == NULL);
+       J_ASSERT(transaction->t_sync_datalist == NULL);
+       J_ASSERT(transaction->t_forget == NULL);
+       J_ASSERT(transaction->t_iobuf_list == NULL);
+       J_ASSERT(transaction->t_shadow_list == NULL);
+       J_ASSERT(transaction->t_log_list == NULL);
+       J_ASSERT(transaction->t_checkpoint_list == NULL);
+       J_ASSERT(transaction->t_checkpoint_io_list == NULL);
+       J_ASSERT(transaction->t_updates == 0);
+       J_ASSERT(journal->j_committing_transaction != transaction);
+       J_ASSERT(journal->j_running_transaction != transaction);
+
+       jbd_debug(1, "Dropping transaction %d, all done\n", transaction->t_tid);
+       kfree(transaction);
+}
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c
new file mode 100644 (file)
index 0000000..70b2ae1
--- /dev/null
@@ -0,0 +1,920 @@
+/*
+ * linux/fs/jbd2/commit.c
+ *
+ * Written by Stephen C. Tweedie <sct@redhat.com>, 1998
+ *
+ * Copyright 1998 Red Hat corp --- All Rights Reserved
+ *
+ * This file is part of the Linux kernel and is made available under
+ * the terms of the GNU General Public License, version 2, or at your
+ * option, any later version, incorporated herein by reference.
+ *
+ * Journal commit routines for the generic filesystem journaling code;
+ * part of the ext2fs journaling system.
+ */
+
+#include <linux/time.h>
+#include <linux/fs.h>
+#include <linux/jbd2.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/pagemap.h>
+#include <linux/smp_lock.h>
+
+/*
+ * Default IO end handler for temporary BJ_IO buffer_heads.
+ */
+static void journal_end_buffer_io_sync(struct buffer_head *bh, int uptodate)
+{
+       BUFFER_TRACE(bh, "");
+       if (uptodate)
+               set_buffer_uptodate(bh);
+       else
+               clear_buffer_uptodate(bh);
+       unlock_buffer(bh);
+}
+
+/*
+ * When an ext3-ordered file is truncated, it is possible that many pages are
+ * not sucessfully freed, because they are attached to a committing transaction.
+ * After the transaction commits, these pages are left on the LRU, with no
+ * ->mapping, and with attached buffers.  These pages are trivially reclaimable
+ * by the VM, but their apparent absence upsets the VM accounting, and it makes
+ * the numbers in /proc/meminfo look odd.
+ *
+ * So here, we have a buffer which has just come off the forget list.  Look to
+ * see if we can strip all buffers from the backing page.
+ *
+ * Called under lock_journal(), and possibly under journal_datalist_lock.  The
+ * caller provided us with a ref against the buffer, and we drop that here.
+ */
+static void release_buffer_page(struct buffer_head *bh)
+{
+       struct page *page;
+
+       if (buffer_dirty(bh))
+               goto nope;
+       if (atomic_read(&bh->b_count) != 1)
+               goto nope;
+       page = bh->b_page;
+       if (!page)
+               goto nope;
+       if (page->mapping)
+               goto nope;
+
+       /* OK, it's a truncated page */
+       if (TestSetPageLocked(page))
+               goto nope;
+
+       page_cache_get(page);
+       __brelse(bh);
+       try_to_free_buffers(page);
+       unlock_page(page);
+       page_cache_release(page);
+       return;
+
+nope:
+       __brelse(bh);
+}
+
+/*
+ * Try to acquire jbd_lock_bh_state() against the buffer, when j_list_lock is
+ * held.  For ranking reasons we must trylock.  If we lose, schedule away and
+ * return 0.  j_list_lock is dropped in this case.
+ */
+static int inverted_lock(journal_t *journal, struct buffer_head *bh)
+{
+       if (!jbd_trylock_bh_state(bh)) {
+               spin_unlock(&journal->j_list_lock);
+               schedule();
+               return 0;
+       }
+       return 1;
+}
+
+/* Done it all: now write the commit record.  We should have
+ * cleaned up our previous buffers by now, so if we are in abort
+ * mode we can now just skip the rest of the journal write
+ * entirely.
+ *
+ * Returns 1 if the journal needs to be aborted or 0 on success
+ */
+static int journal_write_commit_record(journal_t *journal,
+                                       transaction_t *commit_transaction)
+{
+       struct journal_head *descriptor;
+       struct buffer_head *bh;
+       int i, ret;
+       int barrier_done = 0;
+
+       if (is_journal_aborted(journal))
+               return 0;
+
+       descriptor = jbd2_journal_get_descriptor_buffer(journal);
+       if (!descriptor)
+               return 1;
+
+       bh = jh2bh(descriptor);
+
+       /* AKPM: buglet - add `i' to tmp! */
+       for (i = 0; i < bh->b_size; i += 512) {
+               journal_header_t *tmp = (journal_header_t*)bh->b_data;
+               tmp->h_magic = cpu_to_be32(JBD2_MAGIC_NUMBER);
+               tmp->h_blocktype = cpu_to_be32(JBD2_COMMIT_BLOCK);
+               tmp->h_sequence = cpu_to_be32(commit_transaction->t_tid);
+       }
+
+       JBUFFER_TRACE(descriptor, "write commit block");
+       set_buffer_dirty(bh);
+       if (journal->j_flags & JBD2_BARRIER) {
+               set_buffer_ordered(bh);
+               barrier_done = 1;
+       }
+       ret = sync_dirty_buffer(bh);
+       /* is it possible for another commit to fail at roughly
+        * the same time as this one?  If so, we don't want to
+        * trust the barrier flag in the super, but instead want
+        * to remember if we sent a barrier request
+        */
+       if (ret == -EOPNOTSUPP && barrier_done) {
+               char b[BDEVNAME_SIZE];
+
+               printk(KERN_WARNING
+                       "JBD: barrier-based sync failed on %s - "
+                       "disabling barriers\n",
+                       bdevname(journal->j_dev, b));
+               spin_lock(&journal->j_state_lock);
+               journal->j_flags &= ~JBD2_BARRIER;
+               spin_unlock(&journal->j_state_lock);
+
+               /* And try again, without the barrier */
+               clear_buffer_ordered(bh);
+               set_buffer_uptodate(bh);
+               set_buffer_dirty(bh);
+               ret = sync_dirty_buffer(bh);
+       }
+       put_bh(bh);             /* One for getblk() */
+       jbd2_journal_put_journal_head(descriptor);
+
+       return (ret == -EIO);
+}
+
+static void journal_do_submit_data(struct buffer_head **wbuf, int bufs)
+{
+       int i;
+
+       for (i = 0; i < bufs; i++) {
+               wbuf[i]->b_end_io = end_buffer_write_sync;
+               /* We use-up our safety reference in submit_bh() */
+               submit_bh(WRITE, wbuf[i]);
+       }
+}
+
+/*
+ *  Submit all the data buffers to disk
+ */
+static void journal_submit_data_buffers(journal_t *journal,
+                               transaction_t *commit_transaction)
+{
+       struct journal_head *jh;
+       struct buffer_head *bh;
+       int locked;
+       int bufs = 0;
+       struct buffer_head **wbuf = journal->j_wbuf;
+
+       /*
+        * Whenever we unlock the journal and sleep, things can get added
+        * onto ->t_sync_datalist, so we have to keep looping back to
+        * write_out_data until we *know* that the list is empty.
+        *
+        * Cleanup any flushed data buffers from the data list.  Even in
+        * abort mode, we want to flush this out as soon as possible.
+        */
+write_out_data:
+       cond_resched();
+       spin_lock(&journal->j_list_lock);
+
+       while (commit_transaction->t_sync_datalist) {
+               jh = commit_transaction->t_sync_datalist;
+               bh = jh2bh(jh);
+               locked = 0;
+
+               /* Get reference just to make sure buffer does not disappear
+                * when we are forced to drop various locks */
+               get_bh(bh);
+               /* If the buffer is dirty, we need to submit IO and hence
+                * we need the buffer lock. We try to lock the buffer without
+                * blocking. If we fail, we need to drop j_list_lock and do
+                * blocking lock_buffer().
+                */
+               if (buffer_dirty(bh)) {
+                       if (test_set_buffer_locked(bh)) {
+                               BUFFER_TRACE(bh, "needs blocking lock");
+                               spin_unlock(&journal->j_list_lock);
+                               /* Write out all data to prevent deadlocks */
+                               journal_do_submit_data(wbuf, bufs);
+                               bufs = 0;
+                               lock_buffer(bh);
+                               spin_lock(&journal->j_list_lock);
+                       }
+                       locked = 1;
+               }
+               /* We have to get bh_state lock. Again out of order, sigh. */
+               if (!inverted_lock(journal, bh)) {
+                       jbd_lock_bh_state(bh);
+                       spin_lock(&journal->j_list_lock);
+               }
+               /* Someone already cleaned up the buffer? */
+               if (!buffer_jbd(bh)
+                       || jh->b_transaction != commit_transaction
+                       || jh->b_jlist != BJ_SyncData) {
+                       jbd_unlock_bh_state(bh);
+                       if (locked)
+                               unlock_buffer(bh);
+                       BUFFER_TRACE(bh, "already cleaned up");
+                       put_bh(bh);
+                       continue;
+               }
+               if (locked && test_clear_buffer_dirty(bh)) {
+                       BUFFER_TRACE(bh, "needs writeout, adding to array");
+                       wbuf[bufs++] = bh;
+                       __jbd2_journal_file_buffer(jh, commit_transaction,
+                                               BJ_Locked);
+                       jbd_unlock_bh_state(bh);
+                       if (bufs == journal->j_wbufsize) {
+                               spin_unlock(&journal->j_list_lock);
+                               journal_do_submit_data(wbuf, bufs);
+                               bufs = 0;
+                               goto write_out_data;
+                       }
+               }
+               else {
+                       BUFFER_TRACE(bh, "writeout complete: unfile");
+                       __jbd2_journal_unfile_buffer(jh);
+                       jbd_unlock_bh_state(bh);
+                       if (locked)
+                               unlock_buffer(bh);
+                       jbd2_journal_remove_journal_head(bh);
+                       /* Once for our safety reference, once for
+                        * jbd2_journal_remove_journal_head() */
+                       put_bh(bh);
+                       put_bh(bh);
+               }
+
+               if (lock_need_resched(&journal->j_list_lock)) {
+                       spin_unlock(&journal->j_list_lock);
+                       goto write_out_data;
+               }
+       }
+       spin_unlock(&journal->j_list_lock);
+       journal_do_submit_data(wbuf, bufs);
+}
+
+static inline void write_tag_block(int tag_bytes, journal_block_tag_t *tag,
+                                  unsigned long long block)
+{
+       tag->t_blocknr = cpu_to_be32(block & (u32)~0);
+       if (tag_bytes > JBD_TAG_SIZE32)
+               tag->t_blocknr_high = cpu_to_be32((block >> 31) >> 1);
+}
+
+/*
+ * jbd2_journal_commit_transaction
+ *
+ * The primary function for committing a transaction to the log.  This
+ * function is called by the journal thread to begin a complete commit.
+ */
+void jbd2_journal_commit_transaction(journal_t *journal)
+{
+       transaction_t *commit_transaction;
+       struct journal_head *jh, *new_jh, *descriptor;
+       struct buffer_head **wbuf = journal->j_wbuf;
+       int bufs;
+       int flags;
+       int err;
+       unsigned long long blocknr;
+       char *tagp = NULL;
+       journal_header_t *header;
+       journal_block_tag_t *tag = NULL;
+       int space_left = 0;
+       int first_tag = 0;
+       int tag_flag;
+       int i;
+       int tag_bytes = journal_tag_bytes(journal);
+
+       /*
+        * First job: lock down the current transaction and wait for
+        * all outstanding updates to complete.
+        */
+
+#ifdef COMMIT_STATS
+       spin_lock(&journal->j_list_lock);
+       summarise_journal_usage(journal);
+       spin_unlock(&journal->j_list_lock);
+#endif
+
+       /* Do we need to erase the effects of a prior jbd2_journal_flush? */
+       if (journal->j_flags & JBD2_FLUSHED) {
+               jbd_debug(3, "super block updated\n");
+               jbd2_journal_update_superblock(journal, 1);
+       } else {
+               jbd_debug(3, "superblock not updated\n");
+       }
+
+       J_ASSERT(journal->j_running_transaction != NULL);
+       J_ASSERT(journal->j_committing_transaction == NULL);
+
+       commit_transaction = journal->j_running_transaction;
+       J_ASSERT(commit_transaction->t_state == T_RUNNING);
+
+       jbd_debug(1, "JBD: starting commit of transaction %d\n",
+                       commit_transaction->t_tid);
+
+       spin_lock(&journal->j_state_lock);
+       commit_transaction->t_state = T_LOCKED;
+
+       spin_lock(&commit_transaction->t_handle_lock);
+       while (commit_transaction->t_updates) {
+               DEFINE_WAIT(wait);
+
+               prepare_to_wait(&journal->j_wait_updates, &wait,
+                                       TASK_UNINTERRUPTIBLE);
+               if (commit_transaction->t_updates) {
+                       spin_unlock(&commit_transaction->t_handle_lock);
+                       spin_unlock(&journal->j_state_lock);
+                       schedule();
+                       spin_lock(&journal->j_state_lock);
+                       spin_lock(&commit_transaction->t_handle_lock);
+               }
+               finish_wait(&journal->j_wait_updates, &wait);
+       }
+       spin_unlock(&commit_transaction->t_handle_lock);
+
+       J_ASSERT (commit_transaction->t_outstanding_credits <=
+                       journal->j_max_transaction_buffers);
+
+       /*
+        * First thing we are allowed to do is to discard any remaining
+        * BJ_Reserved buffers.  Note, it is _not_ permissible to assume
+        * that there are no such buffers: if a large filesystem
+        * operation like a truncate needs to split itself over multiple
+        * transactions, then it may try to do a jbd2_journal_restart() while
+        * there are still BJ_Reserved buffers outstanding.  These must
+        * be released cleanly from the current transaction.
+        *
+        * In this case, the filesystem must still reserve write access
+        * again before modifying the buffer in the new transaction, but
+        * we do not require it to remember exactly which old buffers it
+        * has reserved.  This is consistent with the existing behaviour
+        * that multiple jbd2_journal_get_write_access() calls to the same
+        * buffer are perfectly permissable.
+        */
+       while (commit_transaction->t_reserved_list) {
+               jh = commit_transaction->t_reserved_list;
+               JBUFFER_TRACE(jh, "reserved, unused: refile");
+               /*
+                * A jbd2_journal_get_undo_access()+jbd2_journal_release_buffer() may
+                * leave undo-committed data.
+                */
+               if (jh->b_committed_data) {
+                       struct buffer_head *bh = jh2bh(jh);
+
+                       jbd_lock_bh_state(bh);
+                       jbd2_slab_free(jh->b_committed_data, bh->b_size);
+                       jh->b_committed_data = NULL;
+                       jbd_unlock_bh_state(bh);
+               }
+               jbd2_journal_refile_buffer(journal, jh);
+       }
+
+       /*
+        * Now try to drop any written-back buffers from the journal's
+        * checkpoint lists.  We do this *before* commit because it potentially
+        * frees some memory
+        */
+       spin_lock(&journal->j_list_lock);
+       __jbd2_journal_clean_checkpoint_list(journal);
+       spin_unlock(&journal->j_list_lock);
+
+       jbd_debug (3, "JBD: commit phase 1\n");
+
+       /*
+        * Switch to a new revoke table.
+        */
+       jbd2_journal_switch_revoke_table(journal);
+
+       commit_transaction->t_state = T_FLUSH;
+       journal->j_committing_transaction = commit_transaction;
+       journal->j_running_transaction = NULL;
+       commit_transaction->t_log_start = journal->j_head;
+       wake_up(&journal->j_wait_transaction_locked);
+       spin_unlock(&journal->j_state_lock);
+
+       jbd_debug (3, "JBD: commit phase 2\n");
+
+       /*
+        * First, drop modified flag: all accesses to the buffers
+        * will be tracked for a new trasaction only -bzzz
+        */
+       spin_lock(&journal->j_list_lock);
+       if (commit_transaction->t_buffers) {
+               new_jh = jh = commit_transaction->t_buffers->b_tnext;
+               do {
+                       J_ASSERT_JH(new_jh, new_jh->b_modified == 1 ||
+                                       new_jh->b_modified == 0);
+                       new_jh->b_modified = 0;
+                       new_jh = new_jh->b_tnext;
+               } while (new_jh != jh);
+       }
+       spin_unlock(&journal->j_list_lock);
+
+       /*
+        * Now start flushing things to disk, in the order they appear
+        * on the transaction lists.  Data blocks go first.
+        */
+       err = 0;
+       journal_submit_data_buffers(journal, commit_transaction);
+
+       /*
+        * Wait for all previously submitted IO to complete.
+        */
+       spin_lock(&journal->j_list_lock);
+       while (commit_transaction->t_locked_list) {
+               struct buffer_head *bh;
+
+               jh = commit_transaction->t_locked_list->b_tprev;
+               bh = jh2bh(jh);
+               get_bh(bh);
+               if (buffer_locked(bh)) {
+                       spin_unlock(&journal->j_list_lock);
+                       wait_on_buffer(bh);
+                       if (unlikely(!buffer_uptodate(bh)))
+                               err = -EIO;
+                       spin_lock(&journal->j_list_lock);
+               }
+               if (!inverted_lock(journal, bh)) {
+                       put_bh(bh);
+                       spin_lock(&journal->j_list_lock);
+                       continue;
+               }
+               if (buffer_jbd(bh) && jh->b_jlist == BJ_Locked) {
+                       __jbd2_journal_unfile_buffer(jh);
+                       jbd_unlock_bh_state(bh);
+                       jbd2_journal_remove_journal_head(bh);
+                       put_bh(bh);
+               } else {
+                       jbd_unlock_bh_state(bh);
+               }
+               put_bh(bh);
+               cond_resched_lock(&journal->j_list_lock);
+       }
+       spin_unlock(&journal->j_list_lock);
+
+       if (err)
+               __jbd2_journal_abort_hard(journal);
+
+       jbd2_journal_write_revoke_records(journal, commit_transaction);
+
+       jbd_debug(3, "JBD: commit phase 2\n");
+
+       /*
+        * If we found any dirty or locked buffers, then we should have
+        * looped back up to the write_out_data label.  If there weren't
+        * any then journal_clean_data_list should have wiped the list
+        * clean by now, so check that it is in fact empty.
+        */
+       J_ASSERT (commit_transaction->t_sync_datalist == NULL);
+
+       jbd_debug (3, "JBD: commit phase 3\n");
+
+       /*
+        * Way to go: we have now written out all of the data for a
+        * transaction!  Now comes the tricky part: we need to write out
+        * metadata.  Loop over the transaction's entire buffer list:
+        */
+       commit_transaction->t_state = T_COMMIT;
+
+       descriptor = NULL;
+       bufs = 0;
+       while (commit_transaction->t_buffers) {
+
+               /* Find the next buffer to be journaled... */
+
+               jh = commit_transaction->t_buffers;
+
+               /* If we're in abort mode, we just un-journal the buffer and
+                  release it for background writing. */
+
+               if (is_journal_aborted(journal)) {
+                       JBUFFER_TRACE(jh, "journal is aborting: refile");
+                       jbd2_journal_refile_buffer(journal, jh);
+                       /* If that was the last one, we need to clean up
+                        * any descriptor buffers which may have been
+                        * already allocated, even if we are now
+                        * aborting. */
+                       if (!commit_transaction->t_buffers)
+                               goto start_journal_io;
+                       continue;
+               }
+
+               /* Make sure we have a descriptor block in which to
+                  record the metadata buffer. */
+
+               if (!descriptor) {
+                       struct buffer_head *bh;
+
+                       J_ASSERT (bufs == 0);
+
+                       jbd_debug(4, "JBD: get descriptor\n");
+
+                       descriptor = jbd2_journal_get_descriptor_buffer(journal);
+                       if (!descriptor) {
+                               __jbd2_journal_abort_hard(journal);
+                               continue;
+                       }
+
+                       bh = jh2bh(descriptor);
+                       jbd_debug(4, "JBD: got buffer %llu (%p)\n",
+                               (unsigned long long)bh->b_blocknr, bh->b_data);
+                       header = (journal_header_t *)&bh->b_data[0];
+                       header->h_magic     = cpu_to_be32(JBD2_MAGIC_NUMBER);
+                       header->h_blocktype = cpu_to_be32(JBD2_DESCRIPTOR_BLOCK);
+                       header->h_sequence  = cpu_to_be32(commit_transaction->t_tid);
+
+                       tagp = &bh->b_data[sizeof(journal_header_t)];
+                       space_left = bh->b_size - sizeof(journal_header_t);
+                       first_tag = 1;
+                       set_buffer_jwrite(bh);
+                       set_buffer_dirty(bh);
+                       wbuf[bufs++] = bh;
+
+                       /* Record it so that we can wait for IO
+                           completion later */
+                       BUFFER_TRACE(bh, "ph3: file as descriptor");
+                       jbd2_journal_file_buffer(descriptor, commit_transaction,
+                                       BJ_LogCtl);
+               }
+
+               /* Where is the buffer to be written? */
+
+               err = jbd2_journal_next_log_block(journal, &blocknr);
+               /* If the block mapping failed, just abandon the buffer
+                  and repeat this loop: we'll fall into the
+                  refile-on-abort condition above. */
+               if (err) {
+                       __jbd2_journal_abort_hard(journal);
+                       continue;
+               }
+
+               /*
+                * start_this_handle() uses t_outstanding_credits to determine
+                * the free space in the log, but this counter is changed
+                * by jbd2_journal_next_log_block() also.
+                */
+               commit_transaction->t_outstanding_credits--;
+
+               /* Bump b_count to prevent truncate from stumbling over
+                   the shadowed buffer!  @@@ This can go if we ever get
+                   rid of the BJ_IO/BJ_Shadow pairing of buffers. */
+               atomic_inc(&jh2bh(jh)->b_count);
+
+               /* Make a temporary IO buffer with which to write it out
+                   (this will requeue both the metadata buffer and the
+                   temporary IO buffer). new_bh goes on BJ_IO*/
+
+               set_bit(BH_JWrite, &jh2bh(jh)->b_state);
+               /*
+                * akpm: jbd2_journal_write_metadata_buffer() sets
+                * new_bh->b_transaction to commit_transaction.
+                * We need to clean this up before we release new_bh
+                * (which is of type BJ_IO)
+                */
+               JBUFFER_TRACE(jh, "ph3: write metadata");
+               flags = jbd2_journal_write_metadata_buffer(commit_transaction,
+                                                     jh, &new_jh, blocknr);
+               set_bit(BH_JWrite, &jh2bh(new_jh)->b_state);
+               wbuf[bufs++] = jh2bh(new_jh);
+
+               /* Record the new block's tag in the current descriptor
+                   buffer */
+
+               tag_flag = 0;
+               if (flags & 1)
+                       tag_flag |= JBD2_FLAG_ESCAPE;
+               if (!first_tag)
+                       tag_flag |= JBD2_FLAG_SAME_UUID;
+
+               tag = (journal_block_tag_t *) tagp;
+               write_tag_block(tag_bytes, tag, jh2bh(jh)->b_blocknr);
+               tag->t_flags = cpu_to_be32(tag_flag);
+               tagp += tag_bytes;
+               space_left -= tag_bytes;
+
+               if (first_tag) {
+                       memcpy (tagp, journal->j_uuid, 16);
+                       tagp += 16;
+                       space_left -= 16;
+                       first_tag = 0;
+               }
+
+               /* If there's no more to do, or if the descriptor is full,
+                  let the IO rip! */
+
+               if (bufs == journal->j_wbufsize ||
+                   commit_transaction->t_buffers == NULL ||
+                   space_left < tag_bytes + 16) {
+
+                       jbd_debug(4, "JBD: Submit %d IOs\n", bufs);
+
+                       /* Write an end-of-descriptor marker before
+                           submitting the IOs.  "tag" still points to
+                           the last tag we set up. */
+
+                       tag->t_flags |= cpu_to_be32(JBD2_FLAG_LAST_TAG);
+
+start_journal_io:
+                       for (i = 0; i < bufs; i++) {
+                               struct buffer_head *bh = wbuf[i];
+                               lock_buffer(bh);
+                               clear_buffer_dirty(bh);
+                               set_buffer_uptodate(bh);
+                               bh->b_end_io = journal_end_buffer_io_sync;
+                               submit_bh(WRITE, bh);
+                       }
+                       cond_resched();
+
+                       /* Force a new descriptor to be generated next
+                           time round the loop. */
+                       descriptor = NULL;
+                       bufs = 0;
+               }
+       }
+
+       /* Lo and behold: we have just managed to send a transaction to
+           the log.  Before we can commit it, wait for the IO so far to
+           complete.  Control buffers being written are on the
+           transaction's t_log_list queue, and metadata buffers are on
+           the t_iobuf_list queue.
+
+          Wait for the buffers in reverse order.  That way we are
+          less likely to be woken up until all IOs have completed, and
+          so we incur less scheduling load.
+       */
+
+       jbd_debug(3, "JBD: commit phase 4\n");
+
+       /*
+        * akpm: these are BJ_IO, and j_list_lock is not needed.
+        * See __journal_try_to_free_buffer.
+        */
+wait_for_iobuf:
+       while (commit_transaction->t_iobuf_list != NULL) {
+               struct buffer_head *bh;
+
+               jh = commit_transaction->t_iobuf_list->b_tprev;
+               bh = jh2bh(jh);
+               if (buffer_locked(bh)) {
+                       wait_on_buffer(bh);
+                       goto wait_for_iobuf;
+               }
+               if (cond_resched())
+                       goto wait_for_iobuf;
+
+               if (unlikely(!buffer_uptodate(bh)))
+                       err = -EIO;
+
+               clear_buffer_jwrite(bh);
+
+               JBUFFER_TRACE(jh, "ph4: unfile after journal write");
+               jbd2_journal_unfile_buffer(journal, jh);
+
+               /*
+                * ->t_iobuf_list should contain only dummy buffer_heads
+                * which were created by jbd2_journal_write_metadata_buffer().
+                */
+               BUFFER_TRACE(bh, "dumping temporary bh");
+               jbd2_journal_put_journal_head(jh);
+               __brelse(bh);
+               J_ASSERT_BH(bh, atomic_read(&bh->b_count) == 0);
+               free_buffer_head(bh);
+
+               /* We also have to unlock and free the corresponding
+                   shadowed buffer */
+               jh = commit_transaction->t_shadow_list->b_tprev;
+               bh = jh2bh(jh);
+               clear_bit(BH_JWrite, &bh->b_state);
+               J_ASSERT_BH(bh, buffer_jbddirty(bh));
+
+               /* The metadata is now released for reuse, but we need
+                   to remember it against this transaction so that when
+                   we finally commit, we can do any checkpointing
+                   required. */
+               JBUFFER_TRACE(jh, "file as BJ_Forget");
+               jbd2_journal_file_buffer(jh, commit_transaction, BJ_Forget);
+               /* Wake up any transactions which were waiting for this
+                  IO to complete */
+               wake_up_bit(&bh->b_state, BH_Unshadow);
+               JBUFFER_TRACE(jh, "brelse shadowed buffer");
+               __brelse(bh);
+       }
+
+       J_ASSERT (commit_transaction->t_shadow_list == NULL);
+
+       jbd_debug(3, "JBD: commit phase 5\n");
+
+       /* Here we wait for the revoke record and descriptor record buffers */
+ wait_for_ctlbuf:
+       while (commit_transaction->t_log_list != NULL) {
+               struct buffer_head *bh;
+
+               jh = commit_transaction->t_log_list->b_tprev;
+               bh = jh2bh(jh);
+               if (buffer_locked(bh)) {
+                       wait_on_buffer(bh);
+                       goto wait_for_ctlbuf;
+               }
+               if (cond_resched())
+                       goto wait_for_ctlbuf;
+
+               if (unlikely(!buffer_uptodate(bh)))
+                       err = -EIO;
+
+               BUFFER_TRACE(bh, "ph5: control buffer writeout done: unfile");
+               clear_buffer_jwrite(bh);
+               jbd2_journal_unfile_buffer(journal, jh);
+               jbd2_journal_put_journal_head(jh);
+               __brelse(bh);           /* One for getblk */
+               /* AKPM: bforget here */
+       }
+
+       jbd_debug(3, "JBD: commit phase 6\n");
+
+       if (journal_write_commit_record(journal, commit_transaction))
+               err = -EIO;
+
+       if (err)
+               __jbd2_journal_abort_hard(journal);
+
+       /* End of a transaction!  Finally, we can do checkpoint
+           processing: any buffers committed as a result of this
+           transaction can be removed from any checkpoint list it was on
+           before. */
+
+       jbd_debug(3, "JBD: commit phase 7\n");
+
+       J_ASSERT(commit_transaction->t_sync_datalist == NULL);
+       J_ASSERT(commit_transaction->t_buffers == NULL);
+       J_ASSERT(commit_transaction->t_checkpoint_list == NULL);
+       J_ASSERT(commit_transaction->t_iobuf_list == NULL);
+       J_ASSERT(commit_transaction->t_shadow_list == NULL);
+       J_ASSERT(commit_transaction->t_log_list == NULL);
+
+restart_loop:
+       /*
+        * As there are other places (journal_unmap_buffer()) adding buffers
+        * to this list we have to be careful and hold the j_list_lock.
+        */
+       spin_lock(&journal->j_list_lock);
+       while (commit_transaction->t_forget) {
+               transaction_t *cp_transaction;
+               struct buffer_head *bh;
+
+               jh = commit_transaction->t_forget;
+               spin_unlock(&journal->j_list_lock);
+               bh = jh2bh(jh);
+               jbd_lock_bh_state(bh);
+               J_ASSERT_JH(jh, jh->b_transaction == commit_transaction ||
+                       jh->b_transaction == journal->j_running_transaction);
+
+               /*
+                * If there is undo-protected committed data against
+                * this buffer, then we can remove it now.  If it is a
+                * buffer needing such protection, the old frozen_data
+                * field now points to a committed version of the
+                * buffer, so rotate that field to the new committed
+                * data.
+                *
+                * Otherwise, we can just throw away the frozen data now.
+                */
+               if (jh->b_committed_data) {
+                       jbd2_slab_free(jh->b_committed_data, bh->b_size);
+                       jh->b_committed_data = NULL;
+                       if (jh->b_frozen_data) {
+                               jh->b_committed_data = jh->b_frozen_data;
+                               jh->b_frozen_data = NULL;
+                       }
+               } else if (jh->b_frozen_data) {
+                       jbd2_slab_free(jh->b_frozen_data, bh->b_size);
+                       jh->b_frozen_data = NULL;
+               }
+
+               spin_lock(&journal->j_list_lock);
+               cp_transaction = jh->b_cp_transaction;
+               if (cp_transaction) {
+                       JBUFFER_TRACE(jh, "remove from old cp transaction");
+                       __jbd2_journal_remove_checkpoint(jh);
+               }
+
+               /* Only re-checkpoint the buffer_head if it is marked
+                * dirty.  If the buffer was added to the BJ_Forget list
+                * by jbd2_journal_forget, it may no longer be dirty and
+                * there's no point in keeping a checkpoint record for
+                * it. */
+
+               /* A buffer which has been freed while still being
+                * journaled by a previous transaction may end up still
+                * being dirty here, but we want to avoid writing back
+                * that buffer in the future now that the last use has
+                * been committed.  That's not only a performance gain,
+                * it also stops aliasing problems if the buffer is left
+                * behind for writeback and gets reallocated for another
+                * use in a different page. */
+               if (buffer_freed(bh)) {
+                       clear_buffer_freed(bh);
+                       clear_buffer_jbddirty(bh);
+               }
+
+               if (buffer_jbddirty(bh)) {
+                       JBUFFER_TRACE(jh, "add to new checkpointing trans");
+                       __jbd2_journal_insert_checkpoint(jh, commit_transaction);
+                       JBUFFER_TRACE(jh, "refile for checkpoint writeback");
+                       __jbd2_journal_refile_buffer(jh);
+                       jbd_unlock_bh_state(bh);
+               } else {
+                       J_ASSERT_BH(bh, !buffer_dirty(bh));
+                       /* The buffer on BJ_Forget list and not jbddirty means
+                        * it has been freed by this transaction and hence it
+                        * could not have been reallocated until this
+                        * transaction has committed. *BUT* it could be
+                        * reallocated once we have written all the data to
+                        * disk and before we process the buffer on BJ_Forget
+                        * list. */
+                       JBUFFER_TRACE(jh, "refile or unfile freed buffer");
+                       __jbd2_journal_refile_buffer(jh);
+                       if (!jh->b_transaction) {
+                               jbd_unlock_bh_state(bh);
+                                /* needs a brelse */
+                               jbd2_journal_remove_journal_head(bh);
+                               release_buffer_page(bh);
+                       } else
+                               jbd_unlock_bh_state(bh);
+               }
+               cond_resched_lock(&journal->j_list_lock);
+       }
+       spin_unlock(&journal->j_list_lock);
+       /*
+        * This is a bit sleazy.  We borrow j_list_lock to protect
+        * journal->j_committing_transaction in __jbd2_journal_remove_checkpoint.
+        * Really, __jbd2_journal_remove_checkpoint should be using j_state_lock but
+        * it's a bit hassle to hold that across __jbd2_journal_remove_checkpoint
+        */
+       spin_lock(&journal->j_state_lock);
+       spin_lock(&journal->j_list_lock);
+       /*
+        * Now recheck if some buffers did not get attached to the transaction
+        * while the lock was dropped...
+        */
+       if (commit_transaction->t_forget) {
+               spin_unlock(&journal->j_list_lock);
+               spin_unlock(&journal->j_state_lock);
+               goto restart_loop;
+       }
+
+       /* Done with this transaction! */
+
+       jbd_debug(3, "JBD: commit phase 8\n");
+
+       J_ASSERT(commit_transaction->t_state == T_COMMIT);
+
+       commit_transaction->t_state = T_FINISHED;
+       J_ASSERT(commit_transaction == journal->j_committing_transaction);
+       journal->j_commit_sequence = commit_transaction->t_tid;
+       journal->j_committing_transaction = NULL;
+       spin_unlock(&journal->j_state_lock);
+
+       if (commit_transaction->t_checkpoint_list == NULL) {
+               __jbd2_journal_drop_transaction(journal, commit_transaction);
+       } else {
+               if (journal->j_checkpoint_transactions == NULL) {
+                       journal->j_checkpoint_transactions = commit_transaction;
+                       commit_transaction->t_cpnext = commit_transaction;
+                       commit_transaction->t_cpprev = commit_transaction;
+               } else {
+                       commit_transaction->t_cpnext =
+                               journal->j_checkpoint_transactions;
+                       commit_transaction->t_cpprev =
+                               commit_transaction->t_cpnext->t_cpprev;
+                       commit_transaction->t_cpnext->t_cpprev =
+                               commit_transaction;
+                       commit_transaction->t_cpprev->t_cpnext =
+                               commit_transaction;
+               }
+       }
+       spin_unlock(&journal->j_list_lock);
+
+       jbd_debug(1, "JBD: commit %d complete, head %d\n",
+                 journal->j_commit_sequence, journal->j_tail_sequence);
+
+       wake_up(&journal->j_wait_done_commit);
+}
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
new file mode 100644 (file)
index 0000000..c60f378
--- /dev/null
@@ -0,0 +1,2084 @@
+/*
+ * linux/fs/jbd2/journal.c
+ *
+ * Written by Stephen C. Tweedie <sct@redhat.com>, 1998
+ *
+ * Copyright 1998 Red Hat corp --- All Rights Reserved
+ *
+ * This file is part of the Linux kernel and is made available under
+ * the terms of the GNU General Public License, version 2, or at your
+ * option, any later version, incorporated herein by reference.
+ *
+ * Generic filesystem journal-writing code; part of the ext2fs
+ * journaling system.
+ *
+ * This file manages journals: areas of disk reserved for logging
+ * transactional updates.  This includes the kernel journaling thread
+ * which is responsible for scheduling updates to the log.
+ *
+ * We do not actually manage the physical storage of the journal in this
+ * file: that is left to a per-journal policy function, which allows us
+ * to store the journal within a filesystem-specified area for ext2
+ * journaling (ext2 can use a reserved inode for storing the log).
+ */
+
+#include <linux/module.h>
+#include <linux/time.h>
+#include <linux/fs.h>
+#include <linux/jbd2.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/smp_lock.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/suspend.h>
+#include <linux/pagemap.h>
+#include <linux/kthread.h>
+#include <linux/poison.h>
+#include <linux/proc_fs.h>
+
+#include <asm/uaccess.h>
+#include <asm/page.h>
+
+EXPORT_SYMBOL(jbd2_journal_start);
+EXPORT_SYMBOL(jbd2_journal_restart);
+EXPORT_SYMBOL(jbd2_journal_extend);
+EXPORT_SYMBOL(jbd2_journal_stop);
+EXPORT_SYMBOL(jbd2_journal_lock_updates);
+EXPORT_SYMBOL(jbd2_journal_unlock_updates);
+EXPORT_SYMBOL(jbd2_journal_get_write_access);
+EXPORT_SYMBOL(jbd2_journal_get_create_access);
+EXPORT_SYMBOL(jbd2_journal_get_undo_access);
+EXPORT_SYMBOL(jbd2_journal_dirty_data);
+EXPORT_SYMBOL(jbd2_journal_dirty_metadata);
+EXPORT_SYMBOL(jbd2_journal_release_buffer);
+EXPORT_SYMBOL(jbd2_journal_forget);
+#if 0
+EXPORT_SYMBOL(journal_sync_buffer);
+#endif
+EXPORT_SYMBOL(jbd2_journal_flush);
+EXPORT_SYMBOL(jbd2_journal_revoke);
+
+EXPORT_SYMBOL(jbd2_journal_init_dev);
+EXPORT_SYMBOL(jbd2_journal_init_inode);
+EXPORT_SYMBOL(jbd2_journal_update_format);
+EXPORT_SYMBOL(jbd2_journal_check_used_features);
+EXPORT_SYMBOL(jbd2_journal_check_available_features);
+EXPORT_SYMBOL(jbd2_journal_set_features);
+EXPORT_SYMBOL(jbd2_journal_create);
+EXPORT_SYMBOL(jbd2_journal_load);
+EXPORT_SYMBOL(jbd2_journal_destroy);
+EXPORT_SYMBOL(jbd2_journal_update_superblock);
+EXPORT_SYMBOL(jbd2_journal_abort);
+EXPORT_SYMBOL(jbd2_journal_errno);
+EXPORT_SYMBOL(jbd2_journal_ack_err);
+EXPORT_SYMBOL(jbd2_journal_clear_err);
+EXPORT_SYMBOL(jbd2_log_wait_commit);
+EXPORT_SYMBOL(jbd2_journal_start_commit);
+EXPORT_SYMBOL(jbd2_journal_force_commit_nested);
+EXPORT_SYMBOL(jbd2_journal_wipe);
+EXPORT_SYMBOL(jbd2_journal_blocks_per_page);
+EXPORT_SYMBOL(jbd2_journal_invalidatepage);
+EXPORT_SYMBOL(jbd2_journal_try_to_free_buffers);
+EXPORT_SYMBOL(jbd2_journal_force_commit);
+
+static int journal_convert_superblock_v1(journal_t *, journal_superblock_t *);
+static void __journal_abort_soft (journal_t *journal, int errno);
+static int jbd2_journal_create_jbd_slab(size_t slab_size);
+
+/*
+ * Helper function used to manage commit timeouts
+ */
+
+static void commit_timeout(unsigned long __data)
+{
+       struct task_struct * p = (struct task_struct *) __data;
+
+       wake_up_process(p);
+}
+
+/*
+ * kjournald2: The main thread function used to manage a logging device
+ * journal.
+ *
+ * This kernel thread is responsible for two things:
+ *
+ * 1) COMMIT:  Every so often we need to commit the current state of the
+ *    filesystem to disk.  The journal thread is responsible for writing
+ *    all of the metadata buffers to disk.
+ *
+ * 2) CHECKPOINT: We cannot reuse a used section of the log file until all
+ *    of the data in that part of the log has been rewritten elsewhere on
+ *    the disk.  Flushing these old buffers to reclaim space in the log is
+ *    known as checkpointing, and this thread is responsible for that job.
+ */
+
+static int kjournald2(void *arg)
+{
+       journal_t *journal = arg;
+       transaction_t *transaction;
+
+       /*
+        * Set up an interval timer which can be used to trigger a commit wakeup
+        * after the commit interval expires
+        */
+       setup_timer(&journal->j_commit_timer, commit_timeout,
+                       (unsigned long)current);
+
+       /* Record that the journal thread is running */
+       journal->j_task = current;
+       wake_up(&journal->j_wait_done_commit);
+
+       printk(KERN_INFO "kjournald2 starting.  Commit interval %ld seconds\n",
+                       journal->j_commit_interval / HZ);
+
+       /*
+        * And now, wait forever for commit wakeup events.
+        */
+       spin_lock(&journal->j_state_lock);
+
+loop:
+       if (journal->j_flags & JBD2_UNMOUNT)
+               goto end_loop;
+
+       jbd_debug(1, "commit_sequence=%d, commit_request=%d\n",
+               journal->j_commit_sequence, journal->j_commit_request);
+
+       if (journal->j_commit_sequence != journal->j_commit_request) {
+               jbd_debug(1, "OK, requests differ\n");
+               spin_unlock(&journal->j_state_lock);
+               del_timer_sync(&journal->j_commit_timer);
+               jbd2_journal_commit_transaction(journal);
+               spin_lock(&journal->j_state_lock);
+               goto loop;
+       }
+
+       wake_up(&journal->j_wait_done_commit);
+       if (freezing(current)) {
+               /*
+                * The simpler the better. Flushing journal isn't a
+                * good idea, because that depends on threads that may
+                * be already stopped.
+                */
+               jbd_debug(1, "Now suspending kjournald2\n");
+               spin_unlock(&journal->j_state_lock);
+               refrigerator();
+               spin_lock(&journal->j_state_lock);
+       } else {
+               /*
+                * We assume on resume that commits are already there,
+                * so we don't sleep
+                */
+               DEFINE_WAIT(wait);
+               int should_sleep = 1;
+
+               prepare_to_wait(&journal->j_wait_commit, &wait,
+                               TASK_INTERRUPTIBLE);
+               if (journal->j_commit_sequence != journal->j_commit_request)
+                       should_sleep = 0;
+               transaction = journal->j_running_transaction;
+               if (transaction && time_after_eq(jiffies,
+                                               transaction->t_expires))
+                       should_sleep = 0;
+               if (journal->j_flags & JBD2_UNMOUNT)
+                       should_sleep = 0;
+               if (should_sleep) {
+                       spin_unlock(&journal->j_state_lock);
+                       schedule();
+                       spin_lock(&journal->j_state_lock);
+               }
+               finish_wait(&journal->j_wait_commit, &wait);
+       }
+
+       jbd_debug(1, "kjournald2 wakes\n");
+
+       /*
+        * Were we woken up by a commit wakeup event?
+        */
+       transaction = journal->j_running_transaction;
+       if (transaction && time_after_eq(jiffies, transaction->t_expires)) {
+               journal->j_commit_request = transaction->t_tid;
+               jbd_debug(1, "woke because of timeout\n");
+       }
+       goto loop;
+
+end_loop:
+       spin_unlock(&journal->j_state_lock);
+       del_timer_sync(&journal->j_commit_timer);
+       journal->j_task = NULL;
+       wake_up(&journal->j_wait_done_commit);
+       jbd_debug(1, "Journal thread exiting.\n");
+       return 0;
+}
+
+static void jbd2_journal_start_thread(journal_t *journal)
+{
+       kthread_run(kjournald2, journal, "kjournald2");
+       wait_event(journal->j_wait_done_commit, journal->j_task != 0);
+}
+
+static void journal_kill_thread(journal_t *journal)
+{
+       spin_lock(&journal->j_state_lock);
+       journal->j_flags |= JBD2_UNMOUNT;
+
+       while (journal->j_task) {
+               wake_up(&journal->j_wait_commit);
+               spin_unlock(&journal->j_state_lock);
+               wait_event(journal->j_wait_done_commit, journal->j_task == 0);
+               spin_lock(&journal->j_state_lock);
+       }
+       spin_unlock(&journal->j_state_lock);
+}
+
+/*
+ * jbd2_journal_write_metadata_buffer: write a metadata buffer to the journal.
+ *
+ * Writes a metadata buffer to a given disk block.  The actual IO is not
+ * performed but a new buffer_head is constructed which labels the data
+ * to be written with the correct destination disk block.
+ *
+ * Any magic-number escaping which needs to be done will cause a
+ * copy-out here.  If the buffer happens to start with the
+ * JBD2_MAGIC_NUMBER, then we can't write it to the log directly: the
+ * magic number is only written to the log for descripter blocks.  In
+ * this case, we copy the data and replace the first word with 0, and we
+ * return a result code which indicates that this buffer needs to be
+ * marked as an escaped buffer in the corresponding log descriptor
+ * block.  The missing word can then be restored when the block is read
+ * during recovery.
+ *
+ * If the source buffer has already been modified by a new transaction
+ * since we took the last commit snapshot, we use the frozen copy of
+ * that data for IO.  If we end up using the existing buffer_head's data
+ * for the write, then we *have* to lock the buffer to prevent anyone
+ * else from using and possibly modifying it while the IO is in
+ * progress.
+ *
+ * The function returns a pointer to the buffer_heads to be used for IO.
+ *
+ * We assume that the journal has already been locked in this function.
+ *
+ * Return value:
+ *  <0: Error
+ * >=0: Finished OK
+ *
+ * On success:
+ * Bit 0 set == escape performed on the data
+ * Bit 1 set == buffer copy-out performed (kfree the data after IO)
+ */
+
+int jbd2_journal_write_metadata_buffer(transaction_t *transaction,
+                                 struct journal_head  *jh_in,
+                                 struct journal_head **jh_out,
+                                 unsigned long long blocknr)
+{
+       int need_copy_out = 0;
+       int done_copy_out = 0;
+       int do_escape = 0;
+       char *mapped_data;
+       struct buffer_head *new_bh;
+       struct journal_head *new_jh;
+       struct page *new_page;
+       unsigned int new_offset;
+       struct buffer_head *bh_in = jh2bh(jh_in);
+
+       /*
+        * The buffer really shouldn't be locked: only the current committing
+        * transaction is allowed to write it, so nobody else is allowed
+        * to do any IO.
+        *
+        * akpm: except if we're journalling data, and write() output is
+        * also part of a shared mapping, and another thread has
+        * decided to launch a writepage() against this buffer.
+        */
+       J_ASSERT_BH(bh_in, buffer_jbddirty(bh_in));
+
+       new_bh = alloc_buffer_head(GFP_NOFS|__GFP_NOFAIL);
+
+       /*
+        * If a new transaction has already done a buffer copy-out, then
+        * we use that version of the data for the commit.
+        */
+       jbd_lock_bh_state(bh_in);
+repeat:
+       if (jh_in->b_frozen_data) {
+               done_copy_out = 1;
+               new_page = virt_to_page(jh_in->b_frozen_data);
+               new_offset = offset_in_page(jh_in->b_frozen_data);
+       } else {
+               new_page = jh2bh(jh_in)->b_page;
+               new_offset = offset_in_page(jh2bh(jh_in)->b_data);
+       }
+
+       mapped_data = kmap_atomic(new_page, KM_USER0);
+       /*
+        * Check for escaping
+        */
+       if (*((__be32 *)(mapped_data + new_offset)) ==
+                               cpu_to_be32(JBD2_MAGIC_NUMBER)) {
+               need_copy_out = 1;
+               do_escape = 1;
+       }
+       kunmap_atomic(mapped_data, KM_USER0);
+
+       /*
+        * Do we need to do a data copy?
+        */
+       if (need_copy_out && !done_copy_out) {
+               char *tmp;
+
+               jbd_unlock_bh_state(bh_in);
+               tmp = jbd2_slab_alloc(bh_in->b_size, GFP_NOFS);
+               jbd_lock_bh_state(bh_in);
+               if (jh_in->b_frozen_data) {
+                       jbd2_slab_free(tmp, bh_in->b_size);
+                       goto repeat;
+               }
+
+               jh_in->b_frozen_data = tmp;
+               mapped_data = kmap_atomic(new_page, KM_USER0);
+               memcpy(tmp, mapped_data + new_offset, jh2bh(jh_in)->b_size);
+               kunmap_atomic(mapped_data, KM_USER0);
+
+               new_page = virt_to_page(tmp);
+               new_offset = offset_in_page(tmp);
+               done_copy_out = 1;
+       }
+
+       /*
+        * Did we need to do an escaping?  Now we've done all the
+        * copying, we can finally do so.
+        */
+       if (do_escape) {
+               mapped_data = kmap_atomic(new_page, KM_USER0);
+               *((unsigned int *)(mapped_data + new_offset)) = 0;
+               kunmap_atomic(mapped_data, KM_USER0);
+       }
+
+       /* keep subsequent assertions sane */
+       new_bh->b_state = 0;
+       init_buffer(new_bh, NULL, NULL);
+       atomic_set(&new_bh->b_count, 1);
+       jbd_unlock_bh_state(bh_in);
+
+       new_jh = jbd2_journal_add_journal_head(new_bh); /* This sleeps */
+
+       set_bh_page(new_bh, new_page, new_offset);
+       new_jh->b_transaction = NULL;
+       new_bh->b_size = jh2bh(jh_in)->b_size;
+       new_bh->b_bdev = transaction->t_journal->j_dev;
+       new_bh->b_blocknr = blocknr;
+       set_buffer_mapped(new_bh);
+       set_buffer_dirty(new_bh);
+
+       *jh_out = new_jh;
+
+       /*
+        * The to-be-written buffer needs to get moved to the io queue,
+        * and the original buffer whose contents we are shadowing or
+        * copying is moved to the transaction's shadow queue.
+        */
+       JBUFFER_TRACE(jh_in, "file as BJ_Shadow");
+       jbd2_journal_file_buffer(jh_in, transaction, BJ_Shadow);
+       JBUFFER_TRACE(new_jh, "file as BJ_IO");
+       jbd2_journal_file_buffer(new_jh, transaction, BJ_IO);
+
+       return do_escape | (done_copy_out << 1);
+}
+
+/*
+ * Allocation code for the journal file.  Manage the space left in the
+ * journal, so that we can begin checkpointing when appropriate.
+ */
+
+/*
+ * __jbd2_log_space_left: Return the number of free blocks left in the journal.
+ *
+ * Called with the journal already locked.
+ *
+ * Called under j_state_lock
+ */
+
+int __jbd2_log_space_left(journal_t *journal)
+{
+       int left = journal->j_free;
+
+       assert_spin_locked(&journal->j_state_lock);
+
+       /*
+        * Be pessimistic here about the number of those free blocks which
+        * might be required for log descriptor control blocks.
+        */
+
+#define MIN_LOG_RESERVED_BLOCKS 32 /* Allow for rounding errors */
+
+       left -= MIN_LOG_RESERVED_BLOCKS;
+
+       if (left <= 0)
+               return 0;
+       left -= (left >> 3);
+       return left;
+}
+
+/*
+ * Called under j_state_lock.  Returns true if a transaction was started.
+ */
+int __jbd2_log_start_commit(journal_t *journal, tid_t target)
+{
+       /*
+        * Are we already doing a recent enough commit?
+        */
+       if (!tid_geq(journal->j_commit_request, target)) {
+               /*
+                * We want a new commit: OK, mark the request and wakup the
+                * commit thread.  We do _not_ do the commit ourselves.
+                */
+
+               journal->j_commit_request = target;
+               jbd_debug(1, "JBD: requesting commit %d/%d\n",
+                         journal->j_commit_request,
+                         journal->j_commit_sequence);
+               wake_up(&journal->j_wait_commit);
+               return 1;
+       }
+       return 0;
+}
+
+int jbd2_log_start_commit(journal_t *journal, tid_t tid)
+{
+       int ret;
+
+       spin_lock(&journal->j_state_lock);
+       ret = __jbd2_log_start_commit(journal, tid);
+       spin_unlock(&journal->j_state_lock);
+       return ret;
+}
+
+/*
+ * Force and wait upon a commit if the calling process is not within
+ * transaction.  This is used for forcing out undo-protected data which contains
+ * bitmaps, when the fs is running out of space.
+ *
+ * We can only force the running transaction if we don't have an active handle;
+ * otherwise, we will deadlock.
+ *
+ * Returns true if a transaction was started.
+ */
+int jbd2_journal_force_commit_nested(journal_t *journal)
+{
+       transaction_t *transaction = NULL;
+       tid_t tid;
+
+       spin_lock(&journal->j_state_lock);
+       if (journal->j_running_transaction && !current->journal_info) {
+               transaction = journal->j_running_transaction;
+               __jbd2_log_start_commit(journal, transaction->t_tid);
+       } else if (journal->j_committing_transaction)
+               transaction = journal->j_committing_transaction;
+
+       if (!transaction) {
+               spin_unlock(&journal->j_state_lock);
+               return 0;       /* Nothing to retry */
+       }
+
+       tid = transaction->t_tid;
+       spin_unlock(&journal->j_state_lock);
+       jbd2_log_wait_commit(journal, tid);
+       return 1;
+}
+
+/*
+ * Start a commit of the current running transaction (if any).  Returns true
+ * if a transaction was started, and fills its tid in at *ptid
+ */
+int jbd2_journal_start_commit(journal_t *journal, tid_t *ptid)
+{
+       int ret = 0;
+
+       spin_lock(&journal->j_state_lock);
+       if (journal->j_running_transaction) {
+               tid_t tid = journal->j_running_transaction->t_tid;
+
+               ret = __jbd2_log_start_commit(journal, tid);
+               if (ret && ptid)
+                       *ptid = tid;
+       } else if (journal->j_committing_transaction && ptid) {
+               /*
+                * If ext3_write_super() recently started a commit, then we
+                * have to wait for completion of that transaction
+                */
+               *ptid = journal->j_committing_transaction->t_tid;
+               ret = 1;
+       }
+       spin_unlock(&journal->j_state_lock);
+       return ret;
+}
+
+/*
+ * Wait for a specified commit to complete.
+ * The caller may not hold the journal lock.
+ */
+int jbd2_log_wait_commit(journal_t *journal, tid_t tid)
+{
+       int err = 0;
+
+#ifdef CONFIG_JBD_DEBUG
+       spin_lock(&journal->j_state_lock);
+       if (!tid_geq(journal->j_commit_request, tid)) {
+               printk(KERN_EMERG
+                      "%s: error: j_commit_request=%d, tid=%d\n",
+                      __FUNCTION__, journal->j_commit_request, tid);
+       }
+       spin_unlock(&journal->j_state_lock);
+#endif
+       spin_lock(&journal->j_state_lock);
+       while (tid_gt(tid, journal->j_commit_sequence)) {
+               jbd_debug(1, "JBD: want %d, j_commit_sequence=%d\n",
+                                 tid, journal->j_commit_sequence);
+               wake_up(&journal->j_wait_commit);
+               spin_unlock(&journal->j_state_lock);
+               wait_event(journal->j_wait_done_commit,
+                               !tid_gt(tid, journal->j_commit_sequence));
+               spin_lock(&journal->j_state_lock);
+       }
+       spin_unlock(&journal->j_state_lock);
+
+       if (unlikely(is_journal_aborted(journal))) {
+               printk(KERN_EMERG "journal commit I/O error\n");
+               err = -EIO;
+       }
+       return err;
+}
+
+/*
+ * Log buffer allocation routines:
+ */
+
+int jbd2_journal_next_log_block(journal_t *journal, unsigned long long *retp)
+{
+       unsigned long blocknr;
+
+       spin_lock(&journal->j_state_lock);
+       J_ASSERT(journal->j_free > 1);
+
+       blocknr = journal->j_head;
+       journal->j_head++;
+       journal->j_free--;
+       if (journal->j_head == journal->j_last)
+               journal->j_head = journal->j_first;
+       spin_unlock(&journal->j_state_lock);
+       return jbd2_journal_bmap(journal, blocknr, retp);
+}
+
+/*
+ * Conversion of logical to physical block numbers for the journal
+ *
+ * On external journals the journal blocks are identity-mapped, so
+ * this is a no-op.  If needed, we can use j_blk_offset - everything is
+ * ready.
+ */
+int jbd2_journal_bmap(journal_t *journal, unsigned long blocknr,
+                unsigned long long *retp)
+{
+       int err = 0;
+       unsigned long long ret;
+
+       if (journal->j_inode) {
+               ret = bmap(journal->j_inode, blocknr);
+               if (ret)
+                       *retp = ret;
+               else {
+                       char b[BDEVNAME_SIZE];
+
+                       printk(KERN_ALERT "%s: journal block not found "
+                                       "at offset %lu on %s\n",
+                               __FUNCTION__,
+                               blocknr,
+                               bdevname(journal->j_dev, b));
+                       err = -EIO;
+                       __journal_abort_soft(journal, err);
+               }
+       } else {
+               *retp = blocknr; /* +journal->j_blk_offset */
+       }
+       return err;
+}
+
+/*
+ * We play buffer_head aliasing tricks to write data/metadata blocks to
+ * the journal without copying their contents, but for journal
+ * descriptor blocks we do need to generate bona fide buffers.
+ *
+ * After the caller of jbd2_journal_get_descriptor_buffer() has finished modifying
+ * the buffer's contents they really should run flush_dcache_page(bh->b_page).
+ * But we don't bother doing that, so there will be coherency problems with
+ * mmaps of blockdevs which hold live JBD-controlled filesystems.
+ */
+struct journal_head *jbd2_journal_get_descriptor_buffer(journal_t *journal)
+{
+       struct buffer_head *bh;
+       unsigned long long blocknr;
+       int err;
+
+       err = jbd2_journal_next_log_block(journal, &blocknr);
+
+       if (err)
+               return NULL;
+
+       bh = __getblk(journal->j_dev, blocknr, journal->j_blocksize);
+       lock_buffer(bh);
+       memset(bh->b_data, 0, journal->j_blocksize);
+       set_buffer_uptodate(bh);
+       unlock_buffer(bh);
+       BUFFER_TRACE(bh, "return this buffer");
+       return jbd2_journal_add_journal_head(bh);
+}
+
+/*
+ * Management for journal control blocks: functions to create and
+ * destroy journal_t structures, and to initialise and read existing
+ * journal blocks from disk.  */
+
+/* First: create and setup a journal_t object in memory.  We initialise
+ * very few fields yet: that has to wait until we have created the
+ * journal structures from from scratch, or loaded them from disk. */
+
+static journal_t * journal_init_common (void)
+{
+       journal_t *journal;
+       int err;
+
+       journal = jbd_kmalloc(sizeof(*journal), GFP_KERNEL);
+       if (!journal)
+               goto fail;
+       memset(journal, 0, sizeof(*journal));
+
+       init_waitqueue_head(&journal->j_wait_transaction_locked);
+       init_waitqueue_head(&journal->j_wait_logspace);
+       init_waitqueue_head(&journal->j_wait_done_commit);
+       init_waitqueue_head(&journal->j_wait_checkpoint);
+       init_waitqueue_head(&journal->j_wait_commit);
+       init_waitqueue_head(&journal->j_wait_updates);
+       mutex_init(&journal->j_barrier);
+       mutex_init(&journal->j_checkpoint_mutex);
+       spin_lock_init(&journal->j_revoke_lock);
+       spin_lock_init(&journal->j_list_lock);
+       spin_lock_init(&journal->j_state_lock);
+
+       journal->j_commit_interval = (HZ * JBD_DEFAULT_MAX_COMMIT_AGE);
+
+       /* The journal is marked for error until we succeed with recovery! */
+       journal->j_flags = JBD2_ABORT;
+
+       /* Set up a default-sized revoke table for the new mount. */
+       err = jbd2_journal_init_revoke(journal, JOURNAL_REVOKE_DEFAULT_HASH);
+       if (err) {
+               kfree(journal);
+               goto fail;
+       }
+       return journal;
+fail:
+       return NULL;
+}
+
+/* jbd2_journal_init_dev and jbd2_journal_init_inode:
+ *
+ * Create a journal structure assigned some fixed set of disk blocks to
+ * the journal.  We don't actually touch those disk blocks yet, but we
+ * need to set up all of the mapping information to tell the journaling
+ * system where the journal blocks are.
+ *
+ */
+
+/**
+ *  journal_t * jbd2_journal_init_dev() - creates an initialises a journal structure
+ *  @bdev: Block device on which to create the journal
+ *  @fs_dev: Device which hold journalled filesystem for this journal.
+ *  @start: Block nr Start of journal.
+ *  @len:  Length of the journal in blocks.
+ *  @blocksize: blocksize of journalling device
+ *  @returns: a newly created journal_t *
+ *
+ *  jbd2_journal_init_dev creates a journal which maps a fixed contiguous
+ *  range of blocks on an arbitrary block device.
+ *
+ */
+journal_t * jbd2_journal_init_dev(struct block_device *bdev,
+                       struct block_device *fs_dev,
+                       unsigned long long start, int len, int blocksize)
+{
+       journal_t *journal = journal_init_common();
+       struct buffer_head *bh;
+       int n;
+
+       if (!journal)
+               return NULL;
+
+       /* journal descriptor can store up to n blocks -bzzz */
+       journal->j_blocksize = blocksize;
+       n = journal->j_blocksize / sizeof(journal_block_tag_t);
+       journal->j_wbufsize = n;
+       journal->j_wbuf = kmalloc(n * sizeof(struct buffer_head*), GFP_KERNEL);
+       if (!journal->j_wbuf) {
+               printk(KERN_ERR "%s: Cant allocate bhs for commit thread\n",
+                       __FUNCTION__);
+               kfree(journal);
+               journal = NULL;
+               goto out;
+       }
+       journal->j_dev = bdev;
+       journal->j_fs_dev = fs_dev;
+       journal->j_blk_offset = start;
+       journal->j_maxlen = len;
+
+       bh = __getblk(journal->j_dev, start, journal->j_blocksize);
+       J_ASSERT(bh != NULL);
+       journal->j_sb_buffer = bh;
+       journal->j_superblock = (journal_superblock_t *)bh->b_data;
+out:
+       return journal;
+}
+
+/**
+ *  journal_t * jbd2_journal_init_inode () - creates a journal which maps to a inode.
+ *  @inode: An inode to create the journal in
+ *
+ * jbd2_journal_init_inode creates a journal which maps an on-disk inode as
+ * the journal.  The inode must exist already, must support bmap() and
+ * must have all data blocks preallocated.
+ */
+journal_t * jbd2_journal_init_inode (struct inode *inode)
+{
+       struct buffer_head *bh;
+       journal_t *journal = journal_init_common();
+       int err;
+       int n;
+       unsigned long long blocknr;
+
+       if (!journal)
+               return NULL;
+
+       journal->j_dev = journal->j_fs_dev = inode->i_sb->s_bdev;
+       journal->j_inode = inode;
+       jbd_debug(1,
+                 "journal %p: inode %s/%ld, size %Ld, bits %d, blksize %ld\n",
+                 journal, inode->i_sb->s_id, inode->i_ino,
+                 (long long) inode->i_size,
+                 inode->i_sb->s_blocksize_bits, inode->i_sb->s_blocksize);
+
+       journal->j_maxlen = inode->i_size >> inode->i_sb->s_blocksize_bits;
+       journal->j_blocksize = inode->i_sb->s_blocksize;
+
+       /* journal descriptor can store up to n blocks -bzzz */
+       n = journal->j_blocksize / sizeof(journal_block_tag_t);
+       journal->j_wbufsize = n;
+       journal->j_wbuf = kmalloc(n * sizeof(struct buffer_head*), GFP_KERNEL);
+       if (!journal->j_wbuf) {
+               printk(KERN_ERR "%s: Cant allocate bhs for commit thread\n",
+                       __FUNCTION__);
+               kfree(journal);
+               return NULL;
+       }
+
+       err = jbd2_journal_bmap(journal, 0, &blocknr);
+       /* If that failed, give up */
+       if (err) {
+               printk(KERN_ERR "%s: Cannnot locate journal superblock\n",
+                      __FUNCTION__);
+               kfree(journal);
+               return NULL;
+       }
+
+       bh = __getblk(journal->j_dev, blocknr, journal->j_blocksize);
+       J_ASSERT(bh != NULL);
+       journal->j_sb_buffer = bh;
+       journal->j_superblock = (journal_superblock_t *)bh->b_data;
+
+       return journal;
+}
+
+/*
+ * If the journal init or create aborts, we need to mark the journal
+ * superblock as being NULL to prevent the journal destroy from writing
+ * back a bogus superblock.
+ */
+static void journal_fail_superblock (journal_t *journal)
+{
+       struct buffer_head *bh = journal->j_sb_buffer;
+       brelse(bh);
+       journal->j_sb_buffer = NULL;
+}
+
+/*
+ * Given a journal_t structure, initialise the various fields for
+ * startup of a new journaling session.  We use this both when creating
+ * a journal, and after recovering an old journal to reset it for
+ * subsequent use.
+ */
+
+static int journal_reset(journal_t *journal)
+{
+       journal_superblock_t *sb = journal->j_superblock;
+       unsigned long long first, last;
+
+       first = be32_to_cpu(sb->s_first);
+       last = be32_to_cpu(sb->s_maxlen);
+
+       journal->j_first = first;
+       journal->j_last = last;
+
+       journal->j_head = first;
+       journal->j_tail = first;
+       journal->j_free = last - first;
+
+       journal->j_tail_sequence = journal->j_transaction_sequence;
+       journal->j_commit_sequence = journal->j_transaction_sequence - 1;
+       journal->j_commit_request = journal->j_commit_sequence;
+
+       journal->j_max_transaction_buffers = journal->j_maxlen / 4;
+
+       /* Add the dynamic fields and write it to disk. */
+       jbd2_journal_update_superblock(journal, 1);
+       jbd2_journal_start_thread(journal);
+       return 0;
+}
+
+/**
+ * int jbd2_journal_create() - Initialise the new journal file
+ * @journal: Journal to create. This structure must have been initialised
+ *
+ * Given a journal_t structure which tells us which disk blocks we can
+ * use, create a new journal superblock and initialise all of the
+ * journal fields from scratch.
+ **/
+int jbd2_journal_create(journal_t *journal)
+{
+       unsigned long long blocknr;
+       struct buffer_head *bh;
+       journal_superblock_t *sb;
+       int i, err;
+
+       if (journal->j_maxlen < JBD2_MIN_JOURNAL_BLOCKS) {
+               printk (KERN_ERR "Journal length (%d blocks) too short.\n",
+                       journal->j_maxlen);
+               journal_fail_superblock(journal);
+               return -EINVAL;
+       }
+
+       if (journal->j_inode == NULL) {
+               /*
+                * We don't know what block to start at!
+                */
+               printk(KERN_EMERG
+                      "%s: creation of journal on external device!\n",
+                      __FUNCTION__);
+               BUG();
+       }
+
+       /* Zero out the entire journal on disk.  We cannot afford to
+          have any blocks on disk beginning with JBD2_MAGIC_NUMBER. */
+       jbd_debug(1, "JBD: Zeroing out journal blocks...\n");
+       for (i = 0; i < journal->j_maxlen; i++) {
+               err = jbd2_journal_bmap(journal, i, &blocknr);
+               if (err)
+                       return err;
+               bh = __getblk(journal->j_dev, blocknr, journal->j_blocksize);
+               lock_buffer(bh);
+               memset (bh->b_data, 0, journal->j_blocksize);
+               BUFFER_TRACE(bh, "marking dirty");
+               mark_buffer_dirty(bh);
+               BUFFER_TRACE(bh, "marking uptodate");
+               set_buffer_uptodate(bh);
+               unlock_buffer(bh);
+               __brelse(bh);
+       }
+
+       sync_blockdev(journal->j_dev);
+       jbd_debug(1, "JBD: journal cleared.\n");
+
+       /* OK, fill in the initial static fields in the new superblock */
+       sb = journal->j_superblock;
+
+       sb->s_header.h_magic     = cpu_to_be32(JBD2_MAGIC_NUMBER);
+       sb->s_header.h_blocktype = cpu_to_be32(JBD2_SUPERBLOCK_V2);
+
+       sb->s_blocksize = cpu_to_be32(journal->j_blocksize);
+       sb->s_maxlen    = cpu_to_be32(journal->j_maxlen);
+       sb->s_first     = cpu_to_be32(1);
+
+       journal->j_transaction_sequence = 1;
+
+       journal->j_flags &= ~JBD2_ABORT;
+       journal->j_format_version = 2;
+
+       return journal_reset(journal);
+}
+
+/**
+ * void jbd2_journal_update_superblock() - Update journal sb on disk.
+ * @journal: The journal to update.
+ * @wait: Set to '0' if you don't want to wait for IO completion.
+ *
+ * Update a journal's dynamic superblock fields and write it to disk,
+ * optionally waiting for the IO to complete.
+ */
+void jbd2_journal_update_superblock(journal_t *journal, int wait)
+{
+       journal_superblock_t *sb = journal->j_superblock;
+       struct buffer_head *bh = journal->j_sb_buffer;
+
+       /*
+        * As a special case, if the on-disk copy is already marked as needing
+        * no recovery (s_start == 0) and there are no outstanding transactions
+        * in the filesystem, then we can safely defer the superblock update
+        * until the next commit by setting JBD2_FLUSHED.  This avoids
+        * attempting a write to a potential-readonly device.
+        */
+       if (sb->s_start == 0 && journal->j_tail_sequence ==
+                               journal->j_transaction_sequence) {
+               jbd_debug(1,"JBD: Skipping superblock update on recovered sb "
+                       "(start %ld, seq %d, errno %d)\n",
+                       journal->j_tail, journal->j_tail_sequence,
+                       journal->j_errno);
+               goto out;
+       }
+
+       spin_lock(&journal->j_state_lock);
+       jbd_debug(1,"JBD: updating superblock (start %ld, seq %d, errno %d)\n",
+                 journal->j_tail, journal->j_tail_sequence, journal->j_errno);
+
+       sb->s_sequence = cpu_to_be32(journal->j_tail_sequence);
+       sb->s_start    = cpu_to_be32(journal->j_tail);
+       sb->s_errno    = cpu_to_be32(journal->j_errno);
+       spin_unlock(&journal->j_state_lock);
+
+       BUFFER_TRACE(bh, "marking dirty");
+       mark_buffer_dirty(bh);
+       if (wait)
+               sync_dirty_buffer(bh);
+       else
+               ll_rw_block(SWRITE, 1, &bh);
+
+out:
+       /* If we have just flushed the log (by marking s_start==0), then
+        * any future commit will have to be careful to update the
+        * superblock again to re-record the true start of the log. */
+
+       spin_lock(&journal->j_state_lock);
+       if (sb->s_start)
+               journal->j_flags &= ~JBD2_FLUSHED;
+       else
+               journal->j_flags |= JBD2_FLUSHED;
+       spin_unlock(&journal->j_state_lock);
+}
+
+/*
+ * Read the superblock for a given journal, performing initial
+ * validation of the format.
+ */
+
+static int journal_get_superblock(journal_t *journal)
+{
+       struct buffer_head *bh;
+       journal_superblock_t *sb;
+       int err = -EIO;
+
+       bh = journal->j_sb_buffer;
+
+       J_ASSERT(bh != NULL);
+       if (!buffer_uptodate(bh)) {
+               ll_rw_block(READ, 1, &bh);
+               wait_on_buffer(bh);
+               if (!buffer_uptodate(bh)) {
+                       printk (KERN_ERR
+                               "JBD: IO error reading journal superblock\n");
+                       goto out;
+               }
+       }
+
+       sb = journal->j_superblock;
+
+       err = -EINVAL;
+
+       if (sb->s_header.h_magic != cpu_to_be32(JBD2_MAGIC_NUMBER) ||
+           sb->s_blocksize != cpu_to_be32(journal->j_blocksize)) {
+               printk(KERN_WARNING "JBD: no valid journal superblock found\n");
+               goto out;
+       }
+
+       switch(be32_to_cpu(sb->s_header.h_blocktype)) {
+       case JBD2_SUPERBLOCK_V1:
+               journal->j_format_version = 1;
+               break;
+       case JBD2_SUPERBLOCK_V2:
+               journal->j_format_version = 2;
+               break;
+       default:
+               printk(KERN_WARNING "JBD: unrecognised superblock format ID\n");
+               goto out;
+       }
+
+       if (be32_to_cpu(sb->s_maxlen) < journal->j_maxlen)
+               journal->j_maxlen = be32_to_cpu(sb->s_maxlen);
+       else if (be32_to_cpu(sb->s_maxlen) > journal->j_maxlen) {
+               printk (KERN_WARNING "JBD: journal file too short\n");
+               goto out;
+       }
+
+       return 0;
+
+out:
+       journal_fail_superblock(journal);
+       return err;
+}
+
+/*
+ * Load the on-disk journal superblock and read the key fields into the
+ * journal_t.
+ */
+
+static int load_superblock(journal_t *journal)
+{
+       int err;
+       journal_superblock_t *sb;
+
+       err = journal_get_superblock(journal);
+       if (err)
+               return err;
+
+       sb = journal->j_superblock;
+
+       journal->j_tail_sequence = be32_to_cpu(sb->s_sequence);
+       journal->j_tail = be32_to_cpu(sb->s_start);
+       journal->j_first = be32_to_cpu(sb->s_first);
+       journal->j_last = be32_to_cpu(sb->s_maxlen);
+       journal->j_errno = be32_to_cpu(sb->s_errno);
+
+       return 0;
+}
+
+
+/**
+ * int jbd2_journal_load() - Read journal from disk.
+ * @journal: Journal to act on.
+ *
+ * Given a journal_t structure which tells us which disk blocks contain
+ * a journal, read the journal from disk to initialise the in-memory
+ * structures.
+ */
+int jbd2_journal_load(journal_t *journal)
+{
+       int err;
+       journal_superblock_t *sb;
+
+       err = load_superblock(journal);
+       if (err)
+               return err;
+
+       sb = journal->j_superblock;
+       /* If this is a V2 superblock, then we have to check the
+        * features flags on it. */
+
+       if (journal->j_format_version >= 2) {
+               if ((sb->s_feature_ro_compat &
+                    ~cpu_to_be32(JBD2_KNOWN_ROCOMPAT_FEATURES)) ||
+                   (sb->s_feature_incompat &
+                    ~cpu_to_be32(JBD2_KNOWN_INCOMPAT_FEATURES))) {
+                       printk (KERN_WARNING
+                               "JBD: Unrecognised features on journal\n");
+                       return -EINVAL;
+               }
+       }
+
+       /*
+        * Create a slab for this blocksize
+        */
+       err = jbd2_journal_create_jbd_slab(be32_to_cpu(sb->s_blocksize));
+       if (err)
+               return err;
+
+       /* Let the recovery code check whether it needs to recover any
+        * data from the journal. */
+       if (jbd2_journal_recover(journal))
+               goto recovery_error;
+
+       /* OK, we've finished with the dynamic journal bits:
+        * reinitialise the dynamic contents of the superblock in memory
+        * and reset them on disk. */
+       if (journal_reset(journal))
+               goto recovery_error;
+
+       journal->j_flags &= ~JBD2_ABORT;
+       journal->j_flags |= JBD2_LOADED;
+       return 0;
+
+recovery_error:
+       printk (KERN_WARNING "JBD: recovery failed\n");
+       return -EIO;
+}
+
+/**
+ * void jbd2_journal_destroy() - Release a journal_t structure.
+ * @journal: Journal to act on.
+ *
+ * Release a journal_t structure once it is no longer in use by the
+ * journaled object.
+ */
+void jbd2_journal_destroy(journal_t *journal)
+{
+       /* Wait for the commit thread to wake up and die. */
+       journal_kill_thread(journal);
+
+       /* Force a final log commit */
+       if (journal->j_running_transaction)
+               jbd2_journal_commit_transaction(journal);
+
+       /* Force any old transactions to disk */
+
+       /* Totally anal locking here... */
+       spin_lock(&journal->j_list_lock);
+       while (journal->j_checkpoint_transactions != NULL) {
+               spin_unlock(&journal->j_list_lock);
+               jbd2_log_do_checkpoint(journal);
+               spin_lock(&journal->j_list_lock);
+       }
+
+       J_ASSERT(journal->j_running_transaction == NULL);
+       J_ASSERT(journal->j_committing_transaction == NULL);
+       J_ASSERT(journal->j_checkpoint_transactions == NULL);
+       spin_unlock(&journal->j_list_lock);
+
+       /* We can now mark the journal as empty. */
+       journal->j_tail = 0;
+       journal->j_tail_sequence = ++journal->j_transaction_sequence;
+       if (journal->j_sb_buffer) {
+               jbd2_journal_update_superblock(journal, 1);
+               brelse(journal->j_sb_buffer);
+       }
+
+       if (journal->j_inode)
+               iput(journal->j_inode);
+       if (journal->j_revoke)
+               jbd2_journal_destroy_revoke(journal);
+       kfree(journal->j_wbuf);
+       kfree(journal);
+}
+
+
+/**
+ *int jbd2_journal_check_used_features () - Check if features specified are used.
+ * @journal: Journal to check.
+ * @compat: bitmask of compatible features
+ * @ro: bitmask of features that force read-only mount
+ * @incompat: bitmask of incompatible features
+ *
+ * Check whether the journal uses all of a given set of
+ * features.  Return true (non-zero) if it does.
+ **/
+
+int jbd2_journal_check_used_features (journal_t *journal, unsigned long compat,
+                                unsigned long ro, unsigned long incompat)
+{
+       journal_superblock_t *sb;
+
+       if (!compat && !ro && !incompat)
+               return 1;
+       if (journal->j_format_version == 1)
+               return 0;
+
+       sb = journal->j_superblock;
+
+       if (((be32_to_cpu(sb->s_feature_compat) & compat) == compat) &&
+           ((be32_to_cpu(sb->s_feature_ro_compat) & ro) == ro) &&
+           ((be32_to_cpu(sb->s_feature_incompat) & incompat) == incompat))
+               return 1;
+
+       return 0;
+}
+
+/**
+ * int jbd2_journal_check_available_features() - Check feature set in journalling layer
+ * @journal: Journal to check.
+ * @compat: bitmask of compatible features
+ * @ro: bitmask of features that force read-only mount
+ * @incompat: bitmask of incompatible features
+ *
+ * Check whether the journaling code supports the use of
+ * all of a given set of features on this journal.  Return true
+ * (non-zero) if it can. */
+
+int jbd2_journal_check_available_features (journal_t *journal, unsigned long compat,
+                                     unsigned long ro, unsigned long incompat)
+{
+       journal_superblock_t *sb;
+
+       if (!compat && !ro && !incompat)
+               return 1;
+
+       sb = journal->j_superblock;
+
+       /* We can support any known requested features iff the
+        * superblock is in version 2.  Otherwise we fail to support any
+        * extended sb features. */
+
+       if (journal->j_format_version != 2)
+               return 0;
+
+       if ((compat   & JBD2_KNOWN_COMPAT_FEATURES) == compat &&
+           (ro       & JBD2_KNOWN_ROCOMPAT_FEATURES) == ro &&
+           (incompat & JBD2_KNOWN_INCOMPAT_FEATURES) == incompat)
+               return 1;
+
+       return 0;
+}
+
+/**
+ * int jbd2_journal_set_features () - Mark a given journal feature in the superblock
+ * @journal: Journal to act on.
+ * @compat: bitmask of compatible features
+ * @ro: bitmask of features that force read-only mount
+ * @incompat: bitmask of incompatible features
+ *
+ * Mark a given journal feature as present on the
+ * superblock.  Returns true if the requested features could be set.
+ *
+ */
+
+int jbd2_journal_set_features (journal_t *journal, unsigned long compat,
+                         unsigned long ro, unsigned long incompat)
+{
+       journal_superblock_t *sb;
+
+       if (jbd2_journal_check_used_features(journal, compat, ro, incompat))
+               return 1;
+
+       if (!jbd2_journal_check_available_features(journal, compat, ro, incompat))
+               return 0;
+
+       jbd_debug(1, "Setting new features 0x%lx/0x%lx/0x%lx\n",
+                 compat, ro, incompat);
+
+       sb = journal->j_superblock;
+
+       sb->s_feature_compat    |= cpu_to_be32(compat);
+       sb->s_feature_ro_compat |= cpu_to_be32(ro);
+       sb->s_feature_incompat  |= cpu_to_be32(incompat);
+
+       return 1;
+}
+
+
+/**
+ * int jbd2_journal_update_format () - Update on-disk journal structure.
+ * @journal: Journal to act on.
+ *
+ * Given an initialised but unloaded journal struct, poke about in the
+ * on-disk structure to update it to the most recent supported version.
+ */
+int jbd2_journal_update_format (journal_t *journal)
+{
+       journal_superblock_t *sb;
+       int err;
+
+       err = journal_get_superblock(journal);
+       if (err)
+               return err;
+
+       sb = journal->j_superblock;
+
+       switch (be32_to_cpu(sb->s_header.h_blocktype)) {
+       case JBD2_SUPERBLOCK_V2:
+               return 0;
+       case JBD2_SUPERBLOCK_V1:
+               return journal_convert_superblock_v1(journal, sb);
+       default:
+               break;
+       }
+       return -EINVAL;
+}
+
+static int journal_convert_superblock_v1(journal_t *journal,
+                                        journal_superblock_t *sb)
+{
+       int offset, blocksize;
+       struct buffer_head *bh;
+
+       printk(KERN_WARNING
+               "JBD: Converting superblock from version 1 to 2.\n");
+
+       /* Pre-initialise new fields to zero */
+       offset = ((char *) &(sb->s_feature_compat)) - ((char *) sb);
+       blocksize = be32_to_cpu(sb->s_blocksize);
+       memset(&sb->s_feature_compat, 0, blocksize-offset);
+
+       sb->s_nr_users = cpu_to_be32(1);
+       sb->s_header.h_blocktype = cpu_to_be32(JBD2_SUPERBLOCK_V2);
+       journal->j_format_version = 2;
+
+       bh = journal->j_sb_buffer;
+       BUFFER_TRACE(bh, "marking dirty");
+       mark_buffer_dirty(bh);
+       sync_dirty_buffer(bh);
+       return 0;
+}
+
+
+/**
+ * int jbd2_journal_flush () - Flush journal
+ * @journal: Journal to act on.
+ *
+ * Flush all data for a given journal to disk and empty the journal.
+ * Filesystems can use this when remounting readonly to ensure that
+ * recovery does not need to happen on remount.
+ */
+
+int jbd2_journal_flush(journal_t *journal)
+{
+       int err = 0;
+       transaction_t *transaction = NULL;
+       unsigned long old_tail;
+
+       spin_lock(&journal->j_state_lock);
+
+       /* Force everything buffered to the log... */
+       if (journal->j_running_transaction) {
+               transaction = journal->j_running_transaction;
+               __jbd2_log_start_commit(journal, transaction->t_tid);
+       } else if (journal->j_committing_transaction)
+               transaction = journal->j_committing_transaction;
+
+       /* Wait for the log commit to complete... */
+       if (transaction) {
+               tid_t tid = transaction->t_tid;
+
+               spin_unlock(&journal->j_state_lock);
+               jbd2_log_wait_commit(journal, tid);
+       } else {
+               spin_unlock(&journal->j_state_lock);
+       }
+
+       /* ...and flush everything in the log out to disk. */
+       spin_lock(&journal->j_list_lock);
+       while (!err && journal->j_checkpoint_transactions != NULL) {
+               spin_unlock(&journal->j_list_lock);
+               err = jbd2_log_do_checkpoint(journal);
+               spin_lock(&journal->j_list_lock);
+       }
+       spin_unlock(&journal->j_list_lock);
+       jbd2_cleanup_journal_tail(journal);
+
+       /* Finally, mark the journal as really needing no recovery.
+        * This sets s_start==0 in the underlying superblock, which is
+        * the magic code for a fully-recovered superblock.  Any future
+        * commits of data to the journal will restore the current
+        * s_start value. */
+       spin_lock(&journal->j_state_lock);
+       old_tail = journal->j_tail;
+       journal->j_tail = 0;
+       spin_unlock(&journal->j_state_lock);
+       jbd2_journal_update_superblock(journal, 1);
+       spin_lock(&journal->j_state_lock);
+       journal->j_tail = old_tail;
+
+       J_ASSERT(!journal->j_running_transaction);
+       J_ASSERT(!journal->j_committing_transaction);
+       J_ASSERT(!journal->j_checkpoint_transactions);
+       J_ASSERT(journal->j_head == journal->j_tail);
+       J_ASSERT(journal->j_tail_sequence == journal->j_transaction_sequence);
+       spin_unlock(&journal->j_state_lock);
+       return err;
+}
+
+/**
+ * int jbd2_journal_wipe() - Wipe journal contents
+ * @journal: Journal to act on.
+ * @write: flag (see below)
+ *
+ * Wipe out all of the contents of a journal, safely.  This will produce
+ * a warning if the journal contains any valid recovery information.
+ * Must be called between journal_init_*() and jbd2_journal_load().
+ *
+ * If 'write' is non-zero, then we wipe out the journal on disk; otherwise
+ * we merely suppress recovery.
+ */
+
+int jbd2_journal_wipe(journal_t *journal, int write)
+{
+       journal_superblock_t *sb;
+       int err = 0;
+
+       J_ASSERT (!(journal->j_flags & JBD2_LOADED));
+
+       err = load_superblock(journal);
+       if (err)
+               return err;
+
+       sb = journal->j_superblock;
+
+       if (!journal->j_tail)
+               goto no_recovery;
+
+       printk (KERN_WARNING "JBD: %s recovery information on journal\n",
+               write ? "Clearing" : "Ignoring");
+
+       err = jbd2_journal_skip_recovery(journal);
+       if (write)
+               jbd2_journal_update_superblock(journal, 1);
+
+ no_recovery:
+       return err;
+}
+
+/*
+ * journal_dev_name: format a character string to describe on what
+ * device this journal is present.
+ */
+
+static const char *journal_dev_name(journal_t *journal, char *buffer)
+{
+       struct block_device *bdev;
+
+       if (journal->j_inode)
+               bdev = journal->j_inode->i_sb->s_bdev;
+       else
+               bdev = journal->j_dev;
+
+       return bdevname(bdev, buffer);
+}
+
+/*
+ * Journal abort has very specific semantics, which we describe
+ * for journal abort.
+ *
+ * Two internal function, which provide abort to te jbd layer
+ * itself are here.
+ */
+
+/*
+ * Quick version for internal journal use (doesn't lock the journal).
+ * Aborts hard --- we mark the abort as occurred, but do _nothing_ else,
+ * and don't attempt to make any other journal updates.
+ */
+void __jbd2_journal_abort_hard(journal_t *journal)
+{
+       transaction_t *transaction;
+       char b[BDEVNAME_SIZE];
+
+       if (journal->j_flags & JBD2_ABORT)
+               return;
+
+       printk(KERN_ERR "Aborting journal on device %s.\n",
+               journal_dev_name(journal, b));
+
+       spin_lock(&journal->j_state_lock);
+       journal->j_flags |= JBD2_ABORT;
+       transaction = journal->j_running_transaction;
+       if (transaction)
+               __jbd2_log_start_commit(journal, transaction->t_tid);
+       spin_unlock(&journal->j_state_lock);
+}
+
+/* Soft abort: record the abort error status in the journal superblock,
+ * but don't do any other IO. */
+static void __journal_abort_soft (journal_t *journal, int errno)
+{
+       if (journal->j_flags & JBD2_ABORT)
+               return;
+
+       if (!journal->j_errno)
+               journal->j_errno = errno;
+
+       __jbd2_journal_abort_hard(journal);
+
+       if (errno)
+               jbd2_journal_update_superblock(journal, 1);
+}
+
+/**
+ * void jbd2_journal_abort () - Shutdown the journal immediately.
+ * @journal: the journal to shutdown.
+ * @errno:   an error number to record in the journal indicating
+ *           the reason for the shutdown.
+ *
+ * Perform a complete, immediate shutdown of the ENTIRE
+ * journal (not of a single transaction).  This operation cannot be
+ * undone without closing and reopening the journal.
+ *
+ * The jbd2_journal_abort function is intended to support higher level error
+ * recovery mechanisms such as the ext2/ext3 remount-readonly error
+ * mode.
+ *
+ * Journal abort has very specific semantics.  Any existing dirty,
+ * unjournaled buffers in the main filesystem will still be written to
+ * disk by bdflush, but the journaling mechanism will be suspended
+ * immediately and no further transaction commits will be honoured.
+ *
+ * Any dirty, journaled buffers will be written back to disk without
+ * hitting the journal.  Atomicity cannot be guaranteed on an aborted
+ * filesystem, but we _do_ attempt to leave as much data as possible
+ * behind for fsck to use for cleanup.
+ *
+ * Any attempt to get a new transaction handle on a journal which is in
+ * ABORT state will just result in an -EROFS error return.  A
+ * jbd2_journal_stop on an existing handle will return -EIO if we have
+ * entered abort state during the update.
+ *
+ * Recursive transactions are not disturbed by journal abort until the
+ * final jbd2_journal_stop, which will receive the -EIO error.
+ *
+ * Finally, the jbd2_journal_abort call allows the caller to supply an errno
+ * which will be recorded (if possible) in the journal superblock.  This
+ * allows a client to record failure conditions in the middle of a
+ * transaction without having to complete the transaction to record the
+ * failure to disk.  ext3_error, for example, now uses this
+ * functionality.
+ *
+ * Errors which originate from within the journaling layer will NOT
+ * supply an errno; a null errno implies that absolutely no further
+ * writes are done to the journal (unless there are any already in
+ * progress).
+ *
+ */
+
+void jbd2_journal_abort(journal_t *journal, int errno)
+{
+       __journal_abort_soft(journal, errno);
+}
+
+/**
+ * int jbd2_journal_errno () - returns the journal's error state.
+ * @journal: journal to examine.
+ *
+ * This is the errno numbet set with jbd2_journal_abort(), the last
+ * time the journal was mounted - if the journal was stopped
+ * without calling abort this will be 0.
+ *
+ * If the journal has been aborted on this mount time -EROFS will
+ * be returned.
+ */
+int jbd2_journal_errno(journal_t *journal)
+{
+       int err;
+
+       spin_lock(&journal->j_state_lock);
+       if (journal->j_flags & JBD2_ABORT)
+               err = -EROFS;
+       else
+               err = journal->j_errno;
+       spin_unlock(&journal->j_state_lock);
+       return err;
+}
+
+/**
+ * int jbd2_journal_clear_err () - clears the journal's error state
+ * @journal: journal to act on.
+ *
+ * An error must be cleared or Acked to take a FS out of readonly
+ * mode.
+ */
+int jbd2_journal_clear_err(journal_t *journal)
+{
+       int err = 0;
+
+       spin_lock(&journal->j_state_lock);
+       if (journal->j_flags & JBD2_ABORT)
+               err = -EROFS;
+       else
+               journal->j_errno = 0;
+       spin_unlock(&journal->j_state_lock);
+       return err;
+}
+
+/**
+ * void jbd2_journal_ack_err() - Ack journal err.
+ * @journal: journal to act on.
+ *
+ * An error must be cleared or Acked to take a FS out of readonly
+ * mode.
+ */
+void jbd2_journal_ack_err(journal_t *journal)
+{
+       spin_lock(&journal->j_state_lock);
+       if (journal->j_errno)
+               journal->j_flags |= JBD2_ACK_ERR;
+       spin_unlock(&journal->j_state_lock);
+}
+
+int jbd2_journal_blocks_per_page(struct inode *inode)
+{
+       return 1 << (PAGE_CACHE_SHIFT - inode->i_sb->s_blocksize_bits);
+}
+
+/*
+ * helper functions to deal with 32 or 64bit block numbers.
+ */
+size_t journal_tag_bytes(journal_t *journal)
+{
+       if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_64BIT))
+               return JBD_TAG_SIZE64;
+       else
+               return JBD_TAG_SIZE32;
+}
+
+/*
+ * Simple support for retrying memory allocations.  Introduced to help to
+ * debug different VM deadlock avoidance strategies.
+ */
+void * __jbd2_kmalloc (const char *where, size_t size, gfp_t flags, int retry)
+{
+       return kmalloc(size, flags | (retry ? __GFP_NOFAIL : 0));
+}
+
+/*
+ * jbd slab management: create 1k, 2k, 4k, 8k slabs as needed
+ * and allocate frozen and commit buffers from these slabs.
+ *
+ * Reason for doing this is to avoid, SLAB_DEBUG - since it could
+ * cause bh to cross page boundary.
+ */
+
+#define JBD_MAX_SLABS 5
+#define JBD_SLAB_INDEX(size)  (size >> 11)
+
+static kmem_cache_t *jbd_slab[JBD_MAX_SLABS];
+static const char *jbd_slab_names[JBD_MAX_SLABS] = {
+       "jbd2_1k", "jbd2_2k", "jbd2_4k", NULL, "jbd2_8k"
+};
+
+static void jbd2_journal_destroy_jbd_slabs(void)
+{
+       int i;
+
+       for (i = 0; i < JBD_MAX_SLABS; i++) {
+               if (jbd_slab[i])
+                       kmem_cache_destroy(jbd_slab[i]);
+               jbd_slab[i] = NULL;
+       }
+}
+
+static int jbd2_journal_create_jbd_slab(size_t slab_size)
+{
+       int i = JBD_SLAB_INDEX(slab_size);
+
+       BUG_ON(i >= JBD_MAX_SLABS);
+
+       /*
+        * Check if we already have a slab created for this size
+        */
+       if (jbd_slab[i])
+               return 0;
+
+       /*
+        * Create a slab and force alignment to be same as slabsize -
+        * this will make sure that allocations won't cross the page
+        * boundary.
+        */
+       jbd_slab[i] = kmem_cache_create(jbd_slab_names[i],
+                               slab_size, slab_size, 0, NULL, NULL);
+       if (!jbd_slab[i]) {
+               printk(KERN_EMERG "JBD: no memory for jbd_slab cache\n");
+               return -ENOMEM;
+       }
+       return 0;
+}
+
+void * jbd2_slab_alloc(size_t size, gfp_t flags)
+{
+       int idx;
+
+       idx = JBD_SLAB_INDEX(size);
+       BUG_ON(jbd_slab[idx] == NULL);
+       return kmem_cache_alloc(jbd_slab[idx], flags | __GFP_NOFAIL);
+}
+
+void jbd2_slab_free(void *ptr,  size_t size)
+{
+       int idx;
+
+       idx = JBD_SLAB_INDEX(size);
+       BUG_ON(jbd_slab[idx] == NULL);
+       kmem_cache_free(jbd_slab[idx], ptr);
+}
+
+/*
+ * Journal_head storage management
+ */
+static kmem_cache_t *jbd2_journal_head_cache;
+#ifdef CONFIG_JBD_DEBUG
+static atomic_t nr_journal_heads = ATOMIC_INIT(0);
+#endif
+
+static int journal_init_jbd2_journal_head_cache(void)
+{
+       int retval;
+
+       J_ASSERT(jbd2_journal_head_cache == 0);
+       jbd2_journal_head_cache = kmem_cache_create("jbd2_journal_head",
+                               sizeof(struct journal_head),
+                               0,              /* offset */
+                               0,              /* flags */
+                               NULL,           /* ctor */
+                               NULL);          /* dtor */
+       retval = 0;
+       if (jbd2_journal_head_cache == 0) {
+               retval = -ENOMEM;
+               printk(KERN_EMERG "JBD: no memory for journal_head cache\n");
+       }
+       return retval;
+}
+
+static void jbd2_journal_destroy_jbd2_journal_head_cache(void)
+{
+       J_ASSERT(jbd2_journal_head_cache != NULL);
+       kmem_cache_destroy(jbd2_journal_head_cache);
+       jbd2_journal_head_cache = NULL;
+}
+
+/*
+ * journal_head splicing and dicing
+ */
+static struct journal_head *journal_alloc_journal_head(void)
+{
+       struct journal_head *ret;
+       static unsigned long last_warning;
+
+#ifdef CONFIG_JBD_DEBUG
+       atomic_inc(&nr_journal_heads);
+#endif
+       ret = kmem_cache_alloc(jbd2_journal_head_cache, GFP_NOFS);
+       if (ret == 0) {
+               jbd_debug(1, "out of memory for journal_head\n");
+               if (time_after(jiffies, last_warning + 5*HZ)) {
+                       printk(KERN_NOTICE "ENOMEM in %s, retrying.\n",
+                              __FUNCTION__);
+                       last_warning = jiffies;
+               }
+               while (ret == 0) {
+                       yield();
+                       ret = kmem_cache_alloc(jbd2_journal_head_cache, GFP_NOFS);
+               }
+       }
+       return ret;
+}
+
+static void journal_free_journal_head(struct journal_head *jh)
+{
+#ifdef CONFIG_JBD_DEBUG
+       atomic_dec(&nr_journal_heads);
+       memset(jh, JBD_POISON_FREE, sizeof(*jh));
+#endif
+       kmem_cache_free(jbd2_journal_head_cache, jh);
+}
+
+/*
+ * A journal_head is attached to a buffer_head whenever JBD has an
+ * interest in the buffer.
+ *
+ * Whenever a buffer has an attached journal_head, its ->b_state:BH_JBD bit
+ * is set.  This bit is tested in core kernel code where we need to take
+ * JBD-specific actions.  Testing the zeroness of ->b_private is not reliable
+ * there.
+ *
+ * When a buffer has its BH_JBD bit set, its ->b_count is elevated by one.
+ *
+ * When a buffer has its BH_JBD bit set it is immune from being released by
+ * core kernel code, mainly via ->b_count.
+ *
+ * A journal_head may be detached from its buffer_head when the journal_head's
+ * b_transaction, b_cp_transaction and b_next_transaction pointers are NULL.
+ * Various places in JBD call jbd2_journal_remove_journal_head() to indicate that the
+ * journal_head can be dropped if needed.
+ *
+ * Various places in the kernel want to attach a journal_head to a buffer_head
+ * _before_ attaching the journal_head to a transaction.  To protect the
+ * journal_head in this situation, jbd2_journal_add_journal_head elevates the
+ * journal_head's b_jcount refcount by one.  The caller must call
+ * jbd2_journal_put_journal_head() to undo this.
+ *
+ * So the typical usage would be:
+ *
+ *     (Attach a journal_head if needed.  Increments b_jcount)
+ *     struct journal_head *jh = jbd2_journal_add_journal_head(bh);
+ *     ...
+ *     jh->b_transaction = xxx;
+ *     jbd2_journal_put_journal_head(jh);
+ *
+ * Now, the journal_head's b_jcount is zero, but it is safe from being released
+ * because it has a non-zero b_transaction.
+ */
+
+/*
+ * Give a buffer_head a journal_head.
+ *
+ * Doesn't need the journal lock.
+ * May sleep.
+ */
+struct journal_head *jbd2_journal_add_journal_head(struct buffer_head *bh)
+{
+       struct journal_head *jh;
+       struct journal_head *new_jh = NULL;
+
+repeat:
+       if (!buffer_jbd(bh)) {
+               new_jh = journal_alloc_journal_head();
+               memset(new_jh, 0, sizeof(*new_jh));
+       }
+
+       jbd_lock_bh_journal_head(bh);
+       if (buffer_jbd(bh)) {
+               jh = bh2jh(bh);
+       } else {
+               J_ASSERT_BH(bh,
+                       (atomic_read(&bh->b_count) > 0) ||
+                       (bh->b_page && bh->b_page->mapping));
+
+               if (!new_jh) {
+                       jbd_unlock_bh_journal_head(bh);
+                       goto repeat;
+               }
+
+               jh = new_jh;
+               new_jh = NULL;          /* We consumed it */
+               set_buffer_jbd(bh);
+               bh->b_private = jh;
+               jh->b_bh = bh;
+               get_bh(bh);
+               BUFFER_TRACE(bh, "added journal_head");
+       }
+       jh->b_jcount++;
+       jbd_unlock_bh_journal_head(bh);
+       if (new_jh)
+               journal_free_journal_head(new_jh);
+       return bh->b_private;
+}
+
+/*
+ * Grab a ref against this buffer_head's journal_head.  If it ended up not
+ * having a journal_head, return NULL
+ */
+struct journal_head *jbd2_journal_grab_journal_head(struct buffer_head *bh)
+{
+       struct journal_head *jh = NULL;
+
+       jbd_lock_bh_journal_head(bh);
+       if (buffer_jbd(bh)) {
+               jh = bh2jh(bh);
+               jh->b_jcount++;
+       }
+       jbd_unlock_bh_journal_head(bh);
+       return jh;
+}
+
+static void __journal_remove_journal_head(struct buffer_head *bh)
+{
+       struct journal_head *jh = bh2jh(bh);
+
+       J_ASSERT_JH(jh, jh->b_jcount >= 0);
+
+       get_bh(bh);
+       if (jh->b_jcount == 0) {
+               if (jh->b_transaction == NULL &&
+                               jh->b_next_transaction == NULL &&
+                               jh->b_cp_transaction == NULL) {
+                       J_ASSERT_JH(jh, jh->b_jlist == BJ_None);
+                       J_ASSERT_BH(bh, buffer_jbd(bh));
+                       J_ASSERT_BH(bh, jh2bh(jh) == bh);
+                       BUFFER_TRACE(bh, "remove journal_head");
+                       if (jh->b_frozen_data) {
+                               printk(KERN_WARNING "%s: freeing "
+                                               "b_frozen_data\n",
+                                               __FUNCTION__);
+                               jbd2_slab_free(jh->b_frozen_data, bh->b_size);
+                       }
+                       if (jh->b_committed_data) {
+                               printk(KERN_WARNING "%s: freeing "
+                                               "b_committed_data\n",
+                                               __FUNCTION__);
+                               jbd2_slab_free(jh->b_committed_data, bh->b_size);
+                       }
+                       bh->b_private = NULL;
+                       jh->b_bh = NULL;        /* debug, really */
+                       clear_buffer_jbd(bh);
+                       __brelse(bh);
+                       journal_free_journal_head(jh);
+               } else {
+                       BUFFER_TRACE(bh, "journal_head was locked");
+               }
+       }
+}
+
+/*
+ * jbd2_journal_remove_journal_head(): if the buffer isn't attached to a transaction
+ * and has a zero b_jcount then remove and release its journal_head.   If we did
+ * see that the buffer is not used by any transaction we also "logically"
+ * decrement ->b_count.
+ *
+ * We in fact take an additional increment on ->b_count as a convenience,
+ * because the caller usually wants to do additional things with the bh
+ * after calling here.
+ * The caller of jbd2_journal_remove_journal_head() *must* run __brelse(bh) at some
+ * time.  Once the caller has run __brelse(), the buffer is eligible for
+ * reaping by try_to_free_buffers().
+ */
+void jbd2_journal_remove_journal_head(struct buffer_head *bh)
+{
+       jbd_lock_bh_journal_head(bh);
+       __journal_remove_journal_head(bh);
+       jbd_unlock_bh_journal_head(bh);
+}
+
+/*
+ * Drop a reference on the passed journal_head.  If it fell to zero then try to
+ * release the journal_head from the buffer_head.
+ */
+void jbd2_journal_put_journal_head(struct journal_head *jh)
+{
+       struct buffer_head *bh = jh2bh(jh);
+
+       jbd_lock_bh_journal_head(bh);
+       J_ASSERT_JH(jh, jh->b_jcount > 0);
+       --jh->b_jcount;
+       if (!jh->b_jcount && !jh->b_transaction) {
+               __journal_remove_journal_head(bh);
+               __brelse(bh);
+       }
+       jbd_unlock_bh_journal_head(bh);
+}
+
+/*
+ * /proc tunables
+ */
+#if defined(CONFIG_JBD_DEBUG)
+int jbd2_journal_enable_debug;
+EXPORT_SYMBOL(jbd2_journal_enable_debug);
+#endif
+
+#if defined(CONFIG_JBD_DEBUG) && defined(CONFIG_PROC_FS)
+
+static struct proc_dir_entry *proc_jbd_debug;
+
+static int read_jbd_debug(char *page, char **start, off_t off,
+                         int count, int *eof, void *data)
+{
+       int ret;
+
+       ret = sprintf(page + off, "%d\n", jbd2_journal_enable_debug);
+       *eof = 1;
+       return ret;
+}
+
+static int write_jbd_debug(struct file *file, const char __user *buffer,
+                          unsigned long count, void *data)
+{
+       char buf[32];
+
+       if (count > ARRAY_SIZE(buf) - 1)
+               count = ARRAY_SIZE(buf) - 1;
+       if (copy_from_user(buf, buffer, count))
+               return -EFAULT;
+       buf[ARRAY_SIZE(buf) - 1] = '\0';
+       jbd2_journal_enable_debug = simple_strtoul(buf, NULL, 10);
+       return count;
+}
+
+#define JBD_PROC_NAME "sys/fs/jbd2-debug"
+
+static void __init create_jbd_proc_entry(void)
+{
+       proc_jbd_debug = create_proc_entry(JBD_PROC_NAME, 0644, NULL);
+       if (proc_jbd_debug) {
+               /* Why is this so hard? */
+               proc_jbd_debug->read_proc = read_jbd_debug;
+               proc_jbd_debug->write_proc = write_jbd_debug;
+       }
+}
+
+static void __exit jbd2_remove_jbd_proc_entry(void)
+{
+       if (proc_jbd_debug)
+               remove_proc_entry(JBD_PROC_NAME, NULL);
+}
+
+#else
+
+#define create_jbd_proc_entry() do {} while (0)
+#define jbd2_remove_jbd_proc_entry() do {} while (0)
+
+#endif
+
+kmem_cache_t *jbd2_handle_cache;
+
+static int __init journal_init_handle_cache(void)
+{
+       jbd2_handle_cache = kmem_cache_create("jbd2_journal_handle",
+                               sizeof(handle_t),
+                               0,              /* offset */
+                               0,              /* flags */
+                               NULL,           /* ctor */
+                               NULL);          /* dtor */
+       if (jbd2_handle_cache == NULL) {
+               printk(KERN_EMERG "JBD: failed to create handle cache\n");
+               return -ENOMEM;
+       }
+       return 0;
+}
+
+static void jbd2_journal_destroy_handle_cache(void)
+{
+       if (jbd2_handle_cache)
+               kmem_cache_destroy(jbd2_handle_cache);
+}
+
+/*
+ * Module startup and shutdown
+ */
+
+static int __init journal_init_caches(void)
+{
+       int ret;
+
+       ret = jbd2_journal_init_revoke_caches();
+       if (ret == 0)
+               ret = journal_init_jbd2_journal_head_cache();
+       if (ret == 0)
+               ret = journal_init_handle_cache();
+       return ret;
+}
+
+static void jbd2_journal_destroy_caches(void)
+{
+       jbd2_journal_destroy_revoke_caches();
+       jbd2_journal_destroy_jbd2_journal_head_cache();
+       jbd2_journal_destroy_handle_cache();
+       jbd2_journal_destroy_jbd_slabs();
+}
+
+static int __init journal_init(void)
+{
+       int ret;
+
+       BUILD_BUG_ON(sizeof(struct journal_superblock_s) != 1024);
+
+       ret = journal_init_caches();
+       if (ret != 0)
+               jbd2_journal_destroy_caches();
+       create_jbd_proc_entry();
+       return ret;
+}
+
+static void __exit journal_exit(void)
+{
+#ifdef CONFIG_JBD_DEBUG
+       int n = atomic_read(&nr_journal_heads);
+       if (n)
+               printk(KERN_EMERG "JBD: leaked %d journal_heads!\n", n);
+#endif
+       jbd2_remove_jbd_proc_entry();
+       jbd2_journal_destroy_caches();
+}
+
+MODULE_LICENSE("GPL");
+module_init(journal_init);
+module_exit(journal_exit);
+
diff --git a/fs/jbd2/recovery.c b/fs/jbd2/recovery.c
new file mode 100644 (file)
index 0000000..9f10aca
--- /dev/null
@@ -0,0 +1,609 @@
+/*
+ * linux/fs/recovery.c
+ *
+ * Written by Stephen C. Tweedie <sct@redhat.com>, 1999
+ *
+ * Copyright 1999-2000 Red Hat Software --- All Rights Reserved
+ *
+ * This file is part of the Linux kernel and is made available under
+ * the terms of the GNU General Public License, version 2, or at your
+ * option, any later version, incorporated herein by reference.
+ *
+ * Journal recovery routines for the generic filesystem journaling code;
+ * part of the ext2fs journaling system.
+ */
+
+#ifndef __KERNEL__
+#include "jfs_user.h"
+#else
+#include <linux/time.h>
+#include <linux/fs.h>
+#include <linux/jbd2.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#endif
+
+/*
+ * Maintain information about the progress of the recovery job, so that
+ * the different passes can carry information between them.
+ */
+struct recovery_info
+{
+       tid_t           start_transaction;
+       tid_t           end_transaction;
+
+       int             nr_replays;
+       int             nr_revokes;
+       int             nr_revoke_hits;
+};
+
+enum passtype {PASS_SCAN, PASS_REVOKE, PASS_REPLAY};
+static int do_one_pass(journal_t *journal,
+                               struct recovery_info *info, enum passtype pass);
+static int scan_revoke_records(journal_t *, struct buffer_head *,
+                               tid_t, struct recovery_info *);
+
+#ifdef __KERNEL__
+
+/* Release readahead buffers after use */
+static void journal_brelse_array(struct buffer_head *b[], int n)
+{
+       while (--n >= 0)
+               brelse (b[n]);
+}
+
+
+/*
+ * When reading from the journal, we are going through the block device
+ * layer directly and so there is no readahead being done for us.  We
+ * need to implement any readahead ourselves if we want it to happen at
+ * all.  Recovery is basically one long sequential read, so make sure we
+ * do the IO in reasonably large chunks.
+ *
+ * This is not so critical that we need to be enormously clever about
+ * the readahead size, though.  128K is a purely arbitrary, good-enough
+ * fixed value.
+ */
+
+#define MAXBUF 8
+static int do_readahead(journal_t *journal, unsigned int start)
+{
+       int err;
+       unsigned int max, nbufs, next;
+       unsigned long long blocknr;
+       struct buffer_head *bh;
+
+       struct buffer_head * bufs[MAXBUF];
+
+       /* Do up to 128K of readahead */
+       max = start + (128 * 1024 / journal->j_blocksize);
+       if (max > journal->j_maxlen)
+               max = journal->j_maxlen;
+
+       /* Do the readahead itself.  We'll submit MAXBUF buffer_heads at
+        * a time to the block device IO layer. */
+
+       nbufs = 0;
+
+       for (next = start; next < max; next++) {
+               err = jbd2_journal_bmap(journal, next, &blocknr);
+
+               if (err) {
+                       printk (KERN_ERR "JBD: bad block at offset %u\n",
+                               next);
+                       goto failed;
+               }
+
+               bh = __getblk(journal->j_dev, blocknr, journal->j_blocksize);
+               if (!bh) {
+                       err = -ENOMEM;
+                       goto failed;
+               }
+
+               if (!buffer_uptodate(bh) && !buffer_locked(bh)) {
+                       bufs[nbufs++] = bh;
+                       if (nbufs == MAXBUF) {
+                               ll_rw_block(READ, nbufs, bufs);
+                               journal_brelse_array(bufs, nbufs);
+                               nbufs = 0;
+                       }
+               } else
+                       brelse(bh);
+       }
+
+       if (nbufs)
+               ll_rw_block(READ, nbufs, bufs);
+       err = 0;
+
+failed:
+       if (nbufs)
+               journal_brelse_array(bufs, nbufs);
+       return err;
+}
+
+#endif /* __KERNEL__ */
+
+
+/*
+ * Read a block from the journal
+ */
+
+static int jread(struct buffer_head **bhp, journal_t *journal,
+                unsigned int offset)
+{
+       int err;
+       unsigned long long blocknr;
+       struct buffer_head *bh;
+
+       *bhp = NULL;
+
+       if (offset >= journal->j_maxlen) {
+               printk(KERN_ERR "JBD: corrupted journal superblock\n");
+               return -EIO;
+       }
+
+       err = jbd2_journal_bmap(journal, offset, &blocknr);
+
+       if (err) {
+               printk (KERN_ERR "JBD: bad block at offset %u\n",
+                       offset);
+               return err;
+       }
+
+       bh = __getblk(journal->j_dev, blocknr, journal->j_blocksize);
+       if (!bh)
+               return -ENOMEM;
+
+       if (!buffer_uptodate(bh)) {
+               /* If this is a brand new buffer, start readahead.
+                   Otherwise, we assume we are already reading it.  */
+               if (!buffer_req(bh))
+                       do_readahead(journal, offset);
+               wait_on_buffer(bh);
+       }
+
+       if (!buffer_uptodate(bh)) {
+               printk (KERN_ERR "JBD: Failed to read block at offset %u\n",
+                       offset);
+               brelse(bh);
+               return -EIO;
+       }
+
+       *bhp = bh;
+       return 0;
+}
+
+
+/*
+ * Count the number of in-use tags in a journal descriptor block.
+ */
+
+static int count_tags(journal_t *journal, struct buffer_head *bh)
+{
+       char *                  tagp;
+       journal_block_tag_t *   tag;
+       int                     nr = 0, size = journal->j_blocksize;
+       int                     tag_bytes = journal_tag_bytes(journal);
+
+       tagp = &bh->b_data[sizeof(journal_header_t)];
+
+       while ((tagp - bh->b_data + tag_bytes) <= size) {
+               tag = (journal_block_tag_t *) tagp;
+
+               nr++;
+               tagp += tag_bytes;
+               if (!(tag->t_flags & cpu_to_be32(JBD2_FLAG_SAME_UUID)))
+                       tagp += 16;
+
+               if (tag->t_flags & cpu_to_be32(JBD2_FLAG_LAST_TAG))
+                       break;
+       }
+
+       return nr;
+}
+
+
+/* Make sure we wrap around the log correctly! */
+#define wrap(journal, var)                                             \
+do {                                                                   \
+       if (var >= (journal)->j_last)                                   \
+               var -= ((journal)->j_last - (journal)->j_first);        \
+} while (0)
+
+/**
+ * jbd2_journal_recover - recovers a on-disk journal
+ * @journal: the journal to recover
+ *
+ * The primary function for recovering the log contents when mounting a
+ * journaled device.
+ *
+ * Recovery is done in three passes.  In the first pass, we look for the
+ * end of the log.  In the second, we assemble the list of revoke
+ * blocks.  In the third and final pass, we replay any un-revoked blocks
+ * in the log.
+ */
+int jbd2_journal_recover(journal_t *journal)
+{
+       int                     err;
+       journal_superblock_t *  sb;
+
+       struct recovery_info    info;
+
+       memset(&info, 0, sizeof(info));
+       sb = journal->j_superblock;
+
+       /*
+        * The journal superblock's s_start field (the current log head)
+        * is always zero if, and only if, the journal was cleanly
+        * unmounted.
+        */
+
+       if (!sb->s_start) {
+               jbd_debug(1, "No recovery required, last transaction %d\n",
+                         be32_to_cpu(sb->s_sequence));
+               journal->j_transaction_sequence = be32_to_cpu(sb->s_sequence) + 1;
+               return 0;
+       }
+
+       err = do_one_pass(journal, &info, PASS_SCAN);
+       if (!err)
+               err = do_one_pass(journal, &info, PASS_REVOKE);
+       if (!err)
+               err = do_one_pass(journal, &info, PASS_REPLAY);
+
+       jbd_debug(0, "JBD: recovery, exit status %d, "
+                 "recovered transactions %u to %u\n",
+                 err, info.start_transaction, info.end_transaction);
+       jbd_debug(0, "JBD: Replayed %d and revoked %d/%d blocks\n",
+                 info.nr_replays, info.nr_revoke_hits, info.nr_revokes);
+
+       /* Restart the log at the next transaction ID, thus invalidating
+        * any existing commit records in the log. */
+       journal->j_transaction_sequence = ++info.end_transaction;
+
+       jbd2_journal_clear_revoke(journal);
+       sync_blockdev(journal->j_fs_dev);
+       return err;
+}
+
+/**
+ * jbd2_journal_skip_recovery - Start journal and wipe exiting records
+ * @journal: journal to startup
+ *
+ * Locate any valid recovery information from the journal and set up the
+ * journal structures in memory to ignore it (presumably because the
+ * caller has evidence that it is out of date).
+ * This function does'nt appear to be exorted..
+ *
+ * We perform one pass over the journal to allow us to tell the user how
+ * much recovery information is being erased, and to let us initialise
+ * the journal transaction sequence numbers to the next unused ID.
+ */
+int jbd2_journal_skip_recovery(journal_t *journal)
+{
+       int                     err;
+       journal_superblock_t *  sb;
+
+       struct recovery_info    info;
+
+       memset (&info, 0, sizeof(info));
+       sb = journal->j_superblock;
+
+       err = do_one_pass(journal, &info, PASS_SCAN);
+
+       if (err) {
+               printk(KERN_ERR "JBD: error %d scanning journal\n", err);
+               ++journal->j_transaction_sequence;
+       } else {
+#ifdef CONFIG_JBD_DEBUG
+               int dropped = info.end_transaction - be32_to_cpu(sb->s_sequence);
+#endif
+               jbd_debug(0,
+                         "JBD: ignoring %d transaction%s from the journal.\n",
+                         dropped, (dropped == 1) ? "" : "s");
+               journal->j_transaction_sequence = ++info.end_transaction;
+       }
+
+       journal->j_tail = 0;
+       return err;
+}
+
+static inline unsigned long long read_tag_block(int tag_bytes, journal_block_tag_t *tag)
+{
+       unsigned long long block = be32_to_cpu(tag->t_blocknr);
+       if (tag_bytes > JBD_TAG_SIZE32)
+               block |= (u64)be32_to_cpu(tag->t_blocknr_high) << 32;
+       return block;
+}
+
+static int do_one_pass(journal_t *journal,
+                       struct recovery_info *info, enum passtype pass)
+{
+       unsigned int            first_commit_ID, next_commit_ID;
+       unsigned long           next_log_block;
+       int                     err, success = 0;
+       journal_superblock_t *  sb;
+       journal_header_t *      tmp;
+       struct buffer_head *    bh;
+       unsigned int            sequence;
+       int                     blocktype;
+       int                     tag_bytes = journal_tag_bytes(journal);
+
+       /* Precompute the maximum metadata descriptors in a descriptor block */
+       int                     MAX_BLOCKS_PER_DESC;
+       MAX_BLOCKS_PER_DESC = ((journal->j_blocksize-sizeof(journal_header_t))
+                              / tag_bytes);
+
+       /*
+        * First thing is to establish what we expect to find in the log
+        * (in terms of transaction IDs), and where (in terms of log
+        * block offsets): query the superblock.
+        */
+
+       sb = journal->j_superblock;
+       next_commit_ID = be32_to_cpu(sb->s_sequence);
+       next_log_block = be32_to_cpu(sb->s_start);
+
+       first_commit_ID = next_commit_ID;
+       if (pass == PASS_SCAN)
+               info->start_transaction = first_commit_ID;
+
+       jbd_debug(1, "Starting recovery pass %d\n", pass);
+
+       /*
+        * Now we walk through the log, transaction by transaction,
+        * making sure that each transaction has a commit block in the
+        * expected place.  Each complete transaction gets replayed back
+        * into the main filesystem.
+        */
+
+       while (1) {
+               int                     flags;
+               char *                  tagp;
+               journal_block_tag_t *   tag;
+               struct buffer_head *    obh;
+               struct buffer_head *    nbh;
+
+               cond_resched();         /* We're under lock_kernel() */
+
+               /* If we already know where to stop the log traversal,
+                * check right now that we haven't gone past the end of
+                * the log. */
+
+               if (pass != PASS_SCAN)
+                       if (tid_geq(next_commit_ID, info->end_transaction))
+                               break;
+
+               jbd_debug(2, "Scanning for sequence ID %u at %lu/%lu\n",
+                         next_commit_ID, next_log_block, journal->j_last);
+
+               /* Skip over each chunk of the transaction looking
+                * either the next descriptor block or the final commit
+                * record. */
+
+               jbd_debug(3, "JBD: checking block %ld\n", next_log_block);
+               err = jread(&bh, journal, next_log_block);
+               if (err)
+                       goto failed;
+
+               next_log_block++;
+               wrap(journal, next_log_block);
+
+               /* What kind of buffer is it?
+                *
+                * If it is a descriptor block, check that it has the
+                * expected sequence number.  Otherwise, we're all done
+                * here. */
+
+               tmp = (journal_header_t *)bh->b_data;
+
+               if (tmp->h_magic != cpu_to_be32(JBD2_MAGIC_NUMBER)) {
+                       brelse(bh);
+                       break;
+               }
+
+               blocktype = be32_to_cpu(tmp->h_blocktype);
+               sequence = be32_to_cpu(tmp->h_sequence);
+               jbd_debug(3, "Found magic %d, sequence %d\n",
+                         blocktype, sequence);
+
+               if (sequence != next_commit_ID) {
+                       brelse(bh);
+                       break;
+               }
+
+               /* OK, we have a valid descriptor block which matches
+                * all of the sequence number checks.  What are we going
+                * to do with it?  That depends on the pass... */
+
+               switch(blocktype) {
+               case JBD2_DESCRIPTOR_BLOCK:
+                       /* If it is a valid descriptor block, replay it
+                        * in pass REPLAY; otherwise, just skip over the
+                        * blocks it describes. */
+                       if (pass != PASS_REPLAY) {
+                               next_log_block += count_tags(journal, bh);
+                               wrap(journal, next_log_block);
+                               brelse(bh);
+                               continue;
+                       }
+
+                       /* A descriptor block: we can now write all of
+                        * the data blocks.  Yay, useful work is finally
+                        * getting done here! */
+
+                       tagp = &bh->b_data[sizeof(journal_header_t)];
+                       while ((tagp - bh->b_data + tag_bytes)
+                              <= journal->j_blocksize) {
+                               unsigned long io_block;
+
+                               tag = (journal_block_tag_t *) tagp;
+                               flags = be32_to_cpu(tag->t_flags);
+
+                               io_block = next_log_block++;
+                               wrap(journal, next_log_block);
+                               err = jread(&obh, journal, io_block);
+                               if (err) {
+                                       /* Recover what we can, but
+                                        * report failure at the end. */
+                                       success = err;
+                                       printk (KERN_ERR
+                                               "JBD: IO error %d recovering "
+                                               "block %ld in log\n",
+                                               err, io_block);
+                               } else {
+                                       unsigned long long blocknr;
+
+                                       J_ASSERT(obh != NULL);
+                                       blocknr = read_tag_block(tag_bytes,
+                                                                tag);
+
+                                       /* If the block has been
+                                        * revoked, then we're all done
+                                        * here. */
+                                       if (jbd2_journal_test_revoke
+                                           (journal, blocknr,
+                                            next_commit_ID)) {
+                                               brelse(obh);
+                                               ++info->nr_revoke_hits;
+                                               goto skip_write;
+                                       }
+
+                                       /* Find a buffer for the new
+                                        * data being restored */
+                                       nbh = __getblk(journal->j_fs_dev,
+                                                       blocknr,
+                                                       journal->j_blocksize);
+                                       if (nbh == NULL) {
+                                               printk(KERN_ERR
+                                                      "JBD: Out of memory "
+                                                      "during recovery.\n");
+                                               err = -ENOMEM;
+                                               brelse(bh);
+                                               brelse(obh);
+                                               goto failed;
+                                       }
+
+                                       lock_buffer(nbh);
+                                       memcpy(nbh->b_data, obh->b_data,
+                                                       journal->j_blocksize);
+                                       if (flags & JBD2_FLAG_ESCAPE) {
+                                               *((__be32 *)bh->b_data) =
+                                               cpu_to_be32(JBD2_MAGIC_NUMBER);
+                                       }
+
+                                       BUFFER_TRACE(nbh, "marking dirty");
+                                       set_buffer_uptodate(nbh);
+                                       mark_buffer_dirty(nbh);
+                                       BUFFER_TRACE(nbh, "marking uptodate");
+                                       ++info->nr_replays;
+                                       /* ll_rw_block(WRITE, 1, &nbh); */
+                                       unlock_buffer(nbh);
+                                       brelse(obh);
+                                       brelse(nbh);
+                               }
+
+                       skip_write:
+                               tagp += tag_bytes;
+                               if (!(flags & JBD2_FLAG_SAME_UUID))
+                                       tagp += 16;
+
+                               if (flags & JBD2_FLAG_LAST_TAG)
+                                       break;
+                       }
+
+                       brelse(bh);
+                       continue;
+
+               case JBD2_COMMIT_BLOCK:
+                       /* Found an expected commit block: not much to
+                        * do other than move on to the next sequence
+                        * number. */
+                       brelse(bh);
+                       next_commit_ID++;
+                       continue;
+
+               case JBD2_REVOKE_BLOCK:
+                       /* If we aren't in the REVOKE pass, then we can
+                        * just skip over this block. */
+                       if (pass != PASS_REVOKE) {
+                               brelse(bh);
+                               continue;
+                       }
+
+                       err = scan_revoke_records(journal, bh,
+                                                 next_commit_ID, info);
+                       brelse(bh);
+                       if (err)
+                               goto failed;
+                       continue;
+
+               default:
+                       jbd_debug(3, "Unrecognised magic %d, end of scan.\n",
+                                 blocktype);
+                       brelse(bh);
+                       goto done;
+               }
+       }
+
+ done:
+       /*
+        * We broke out of the log scan loop: either we came to the
+        * known end of the log or we found an unexpected block in the
+        * log.  If the latter happened, then we know that the "current"
+        * transaction marks the end of the valid log.
+        */
+
+       if (pass == PASS_SCAN)
+               info->end_transaction = next_commit_ID;
+       else {
+               /* It's really bad news if different passes end up at
+                * different places (but possible due to IO errors). */
+               if (info->end_transaction != next_commit_ID) {
+                       printk (KERN_ERR "JBD: recovery pass %d ended at "
+                               "transaction %u, expected %u\n",
+                               pass, next_commit_ID, info->end_transaction);
+                       if (!success)
+                               success = -EIO;
+               }
+       }
+
+       return success;
+
+ failed:
+       return err;
+}
+
+
+/* Scan a revoke record, marking all blocks mentioned as revoked. */
+
+static int scan_revoke_records(journal_t *journal, struct buffer_head *bh,
+                              tid_t sequence, struct recovery_info *info)
+{
+       jbd2_journal_revoke_header_t *header;
+       int offset, max;
+       int record_len = 4;
+
+       header = (jbd2_journal_revoke_header_t *) bh->b_data;
+       offset = sizeof(jbd2_journal_revoke_header_t);
+       max = be32_to_cpu(header->r_count);
+
+       if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_64BIT))
+               record_len = 8;
+
+       while (offset + record_len <= max) {
+               unsigned long long blocknr;
+               int err;
+
+               if (record_len == 4)
+                       blocknr = be32_to_cpu(* ((__be32 *) (bh->b_data+offset)));
+               else
+                       blocknr = be64_to_cpu(* ((__be64 *) (bh->b_data+offset)));
+               offset += record_len;
+               err = jbd2_journal_set_revoke(journal, blocknr, sequence);
+               if (err)
+                       return err;
+               ++info->nr_revokes;
+       }
+       return 0;
+}
diff --git a/fs/jbd2/revoke.c b/fs/jbd2/revoke.c
new file mode 100644 (file)
index 0000000..380d199
--- /dev/null
@@ -0,0 +1,712 @@
+/*
+ * linux/fs/revoke.c
+ *
+ * Written by Stephen C. Tweedie <sct@redhat.com>, 2000
+ *
+ * Copyright 2000 Red Hat corp --- All Rights Reserved
+ *
+ * This file is part of the Linux kernel and is made available under
+ * the terms of the GNU General Public License, version 2, or at your
+ * option, any later version, incorporated herein by reference.
+ *
+ * Journal revoke routines for the generic filesystem journaling code;
+ * part of the ext2fs journaling system.
+ *
+ * Revoke is the mechanism used to prevent old log records for deleted
+ * metadata from being replayed on top of newer data using the same
+ * blocks.  The revoke mechanism is used in two separate places:
+ *
+ * + Commit: during commit we write the entire list of the current
+ *   transaction's revoked blocks to the journal
+ *
+ * + Recovery: during recovery we record the transaction ID of all
+ *   revoked blocks.  If there are multiple revoke records in the log
+ *   for a single block, only the last one counts, and if there is a log
+ *   entry for a block beyond the last revoke, then that log entry still
+ *   gets replayed.
+ *
+ * We can get interactions between revokes and new log data within a
+ * single transaction:
+ *
+ * Block is revoked and then journaled:
+ *   The desired end result is the journaling of the new block, so we
+ *   cancel the revoke before the transaction commits.
+ *
+ * Block is journaled and then revoked:
+ *   The revoke must take precedence over the write of the block, so we
+ *   need either to cancel the journal entry or to write the revoke
+ *   later in the log than the log block.  In this case, we choose the
+ *   latter: journaling a block cancels any revoke record for that block
+ *   in the current transaction, so any revoke for that block in the
+ *   transaction must have happened after the block was journaled and so
+ *   the revoke must take precedence.
+ *
+ * Block is revoked and then written as data:
+ *   The data write is allowed to succeed, but the revoke is _not_
+ *   cancelled.  We still need to prevent old log records from
+ *   overwriting the new data.  We don't even need to clear the revoke
+ *   bit here.
+ *
+ * Revoke information on buffers is a tri-state value:
+ *
+ * RevokeValid clear:  no cached revoke status, need to look it up
+ * RevokeValid set, Revoked clear:
+ *                     buffer has not been revoked, and cancel_revoke
+ *                     need do nothing.
+ * RevokeValid set, Revoked set:
+ *                     buffer has been revoked.
+ */
+
+#ifndef __KERNEL__
+#include "jfs_user.h"
+#else
+#include <linux/time.h>
+#include <linux/fs.h>
+#include <linux/jbd2.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/list.h>
+#include <linux/smp_lock.h>
+#include <linux/init.h>
+#endif
+
+static kmem_cache_t *jbd2_revoke_record_cache;
+static kmem_cache_t *jbd2_revoke_table_cache;
+
+/* Each revoke record represents one single revoked block.  During
+   journal replay, this involves recording the transaction ID of the
+   last transaction to revoke this block. */
+
+struct jbd2_revoke_record_s
+{
+       struct list_head  hash;
+       tid_t             sequence;     /* Used for recovery only */
+       unsigned long long        blocknr;
+};
+
+
+/* The revoke table is just a simple hash table of revoke records. */
+struct jbd2_revoke_table_s
+{
+       /* It is conceivable that we might want a larger hash table
+        * for recovery.  Must be a power of two. */
+       int               hash_size;
+       int               hash_shift;
+       struct list_head *hash_table;
+};
+
+
+#ifdef __KERNEL__
+static void write_one_revoke_record(journal_t *, transaction_t *,
+                                   struct journal_head **, int *,
+                                   struct jbd2_revoke_record_s *);
+static void flush_descriptor(journal_t *, struct journal_head *, int);
+#endif
+
+/* Utility functions to maintain the revoke table */
+
+/* Borrowed from buffer.c: this is a tried and tested block hash function */
+static inline int hash(journal_t *journal, unsigned long long block)
+{
+       struct jbd2_revoke_table_s *table = journal->j_revoke;
+       int hash_shift = table->hash_shift;
+       int hash = (int)block ^ (int)((block >> 31) >> 1);
+
+       return ((hash << (hash_shift - 6)) ^
+               (hash >> 13) ^
+               (hash << (hash_shift - 12))) & (table->hash_size - 1);
+}
+
+static int insert_revoke_hash(journal_t *journal, unsigned long long blocknr,
+                             tid_t seq)
+{
+       struct list_head *hash_list;
+       struct jbd2_revoke_record_s *record;
+
+repeat:
+       record = kmem_cache_alloc(jbd2_revoke_record_cache, GFP_NOFS);
+       if (!record)
+               goto oom;
+
+       record->sequence = seq;
+       record->blocknr = blocknr;
+       hash_list = &journal->j_revoke->hash_table[hash(journal, blocknr)];
+       spin_lock(&journal->j_revoke_lock);
+       list_add(&record->hash, hash_list);
+       spin_unlock(&journal->j_revoke_lock);
+       return 0;
+
+oom:
+       if (!journal_oom_retry)
+               return -ENOMEM;
+       jbd_debug(1, "ENOMEM in %s, retrying\n", __FUNCTION__);
+       yield();
+       goto repeat;
+}
+
+/* Find a revoke record in the journal's hash table. */
+
+static struct jbd2_revoke_record_s *find_revoke_record(journal_t *journal,
+                                                     unsigned long long blocknr)
+{
+       struct list_head *hash_list;
+       struct jbd2_revoke_record_s *record;
+
+       hash_list = &journal->j_revoke->hash_table[hash(journal, blocknr)];
+
+       spin_lock(&journal->j_revoke_lock);
+       record = (struct jbd2_revoke_record_s *) hash_list->next;
+       while (&(record->hash) != hash_list) {
+               if (record->blocknr == blocknr) {
+                       spin_unlock(&journal->j_revoke_lock);
+                       return record;
+               }
+               record = (struct jbd2_revoke_record_s *) record->hash.next;
+       }
+       spin_unlock(&journal->j_revoke_lock);
+       return NULL;
+}
+
+int __init jbd2_journal_init_revoke_caches(void)
+{
+       jbd2_revoke_record_cache = kmem_cache_create("jbd2_revoke_record",
+                                          sizeof(struct jbd2_revoke_record_s),
+                                          0, SLAB_HWCACHE_ALIGN, NULL, NULL);
+       if (jbd2_revoke_record_cache == 0)
+               return -ENOMEM;
+
+       jbd2_revoke_table_cache = kmem_cache_create("jbd2_revoke_table",
+                                          sizeof(struct jbd2_revoke_table_s),
+                                          0, 0, NULL, NULL);
+       if (jbd2_revoke_table_cache == 0) {
+               kmem_cache_destroy(jbd2_revoke_record_cache);
+               jbd2_revoke_record_cache = NULL;
+               return -ENOMEM;
+       }
+       return 0;
+}
+
+void jbd2_journal_destroy_revoke_caches(void)
+{
+       kmem_cache_destroy(jbd2_revoke_record_cache);
+       jbd2_revoke_record_cache = NULL;
+       kmem_cache_destroy(jbd2_revoke_table_cache);
+       jbd2_revoke_table_cache = NULL;
+}
+
+/* Initialise the revoke table for a given journal to a given size. */
+
+int jbd2_journal_init_revoke(journal_t *journal, int hash_size)
+{
+       int shift, tmp;
+
+       J_ASSERT (journal->j_revoke_table[0] == NULL);
+
+       shift = 0;
+       tmp = hash_size;
+       while((tmp >>= 1UL) != 0UL)
+               shift++;
+
+       journal->j_revoke_table[0] = kmem_cache_alloc(jbd2_revoke_table_cache, GFP_KERNEL);
+       if (!journal->j_revoke_table[0])
+               return -ENOMEM;
+       journal->j_revoke = journal->j_revoke_table[0];
+
+       /* Check that the hash_size is a power of two */
+       J_ASSERT ((hash_size & (hash_size-1)) == 0);
+
+       journal->j_revoke->hash_size = hash_size;
+
+       journal->j_revoke->hash_shift = shift;
+
+       journal->j_revoke->hash_table =
+               kmalloc(hash_size * sizeof(struct list_head), GFP_KERNEL);
+       if (!journal->j_revoke->hash_table) {
+               kmem_cache_free(jbd2_revoke_table_cache, journal->j_revoke_table[0]);
+               journal->j_revoke = NULL;
+               return -ENOMEM;
+       }
+
+       for (tmp = 0; tmp < hash_size; tmp++)
+               INIT_LIST_HEAD(&journal->j_revoke->hash_table[tmp]);
+
+       journal->j_revoke_table[1] = kmem_cache_alloc(jbd2_revoke_table_cache, GFP_KERNEL);
+       if (!journal->j_revoke_table[1]) {
+               kfree(journal->j_revoke_table[0]->hash_table);
+               kmem_cache_free(jbd2_revoke_table_cache, journal->j_revoke_table[0]);
+               return -ENOMEM;
+       }
+
+       journal->j_revoke = journal->j_revoke_table[1];
+
+       /* Check that the hash_size is a power of two */
+       J_ASSERT ((hash_size & (hash_size-1)) == 0);
+
+       journal->j_revoke->hash_size = hash_size;
+
+       journal->j_revoke->hash_shift = shift;
+
+       journal->j_revoke->hash_table =
+               kmalloc(hash_size * sizeof(struct list_head), GFP_KERNEL);
+       if (!journal->j_revoke->hash_table) {
+               kfree(journal->j_revoke_table[0]->hash_table);
+               kmem_cache_free(jbd2_revoke_table_cache, journal->j_revoke_table[0]);
+               kmem_cache_free(jbd2_revoke_table_cache, journal->j_revoke_table[1]);
+               journal->j_revoke = NULL;
+               return -ENOMEM;
+       }
+
+       for (tmp = 0; tmp < hash_size; tmp++)
+               INIT_LIST_HEAD(&journal->j_revoke->hash_table[tmp]);
+
+       spin_lock_init(&journal->j_revoke_lock);
+
+       return 0;
+}
+
+/* Destoy a journal's revoke table.  The table must already be empty! */
+
+void jbd2_journal_destroy_revoke(journal_t *journal)
+{
+       struct jbd2_revoke_table_s *table;
+       struct list_head *hash_list;
+       int i;
+
+       table = journal->j_revoke_table[0];
+       if (!table)
+               return;
+
+       for (i=0; i<table->hash_size; i++) {
+               hash_list = &table->hash_table[i];
+               J_ASSERT (list_empty(hash_list));
+       }
+
+       kfree(table->hash_table);
+       kmem_cache_free(jbd2_revoke_table_cache, table);
+       journal->j_revoke = NULL;
+
+       table = journal->j_revoke_table[1];
+       if (!table)
+               return;
+
+       for (i=0; i<table->hash_size; i++) {
+               hash_list = &table->hash_table[i];
+               J_ASSERT (list_empty(hash_list));
+       }
+
+       kfree(table->hash_table);
+       kmem_cache_free(jbd2_revoke_table_cache, table);
+       journal->j_revoke = NULL;
+}
+
+
+#ifdef __KERNEL__
+
+/*
+ * jbd2_journal_revoke: revoke a given buffer_head from the journal.  This
+ * prevents the block from being replayed during recovery if we take a
+ * crash after this current transaction commits.  Any subsequent
+ * metadata writes of the buffer in this transaction cancel the
+ * revoke.
+ *
+ * Note that this call may block --- it is up to the caller to make
+ * sure that there are no further calls to journal_write_metadata
+ * before the revoke is complete.  In ext3, this implies calling the
+ * revoke before clearing the block bitmap when we are deleting
+ * metadata.
+ *
+ * Revoke performs a jbd2_journal_forget on any buffer_head passed in as a
+ * parameter, but does _not_ forget the buffer_head if the bh was only
+ * found implicitly.
+ *
+ * bh_in may not be a journalled buffer - it may have come off
+ * the hash tables without an attached journal_head.
+ *
+ * If bh_in is non-zero, jbd2_journal_revoke() will decrement its b_count
+ * by one.
+ */
+
+int jbd2_journal_revoke(handle_t *handle, unsigned long long blocknr,
+                  struct buffer_head *bh_in)
+{
+       struct buffer_head *bh = NULL;
+       journal_t *journal;
+       struct block_device *bdev;
+       int err;
+
+       might_sleep();
+       if (bh_in)
+               BUFFER_TRACE(bh_in, "enter");
+
+       journal = handle->h_transaction->t_journal;
+       if (!jbd2_journal_set_features(journal, 0, 0, JBD2_FEATURE_INCOMPAT_REVOKE)){
+               J_ASSERT (!"Cannot set revoke feature!");
+               return -EINVAL;
+       }
+
+       bdev = journal->j_fs_dev;
+       bh = bh_in;
+
+       if (!bh) {
+               bh = __find_get_block(bdev, blocknr, journal->j_blocksize);
+               if (bh)
+                       BUFFER_TRACE(bh, "found on hash");
+       }
+#ifdef JBD_EXPENSIVE_CHECKING
+       else {
+               struct buffer_head *bh2;
+
+               /* If there is a different buffer_head lying around in
+                * memory anywhere... */
+               bh2 = __find_get_block(bdev, blocknr, journal->j_blocksize);
+               if (bh2) {
+                       /* ... and it has RevokeValid status... */
+                       if (bh2 != bh && buffer_revokevalid(bh2))
+                               /* ...then it better be revoked too,
+                                * since it's illegal to create a revoke
+                                * record against a buffer_head which is
+                                * not marked revoked --- that would
+                                * risk missing a subsequent revoke
+                                * cancel. */
+                               J_ASSERT_BH(bh2, buffer_revoked(bh2));
+                       put_bh(bh2);
+               }
+       }
+#endif
+
+       /* We really ought not ever to revoke twice in a row without
+           first having the revoke cancelled: it's illegal to free a
+           block twice without allocating it in between! */
+       if (bh) {
+               if (!J_EXPECT_BH(bh, !buffer_revoked(bh),
+                                "inconsistent data on disk")) {
+                       if (!bh_in)
+                               brelse(bh);
+                       return -EIO;
+               }
+               set_buffer_revoked(bh);
+               set_buffer_revokevalid(bh);
+               if (bh_in) {
+                       BUFFER_TRACE(bh_in, "call jbd2_journal_forget");
+                       jbd2_journal_forget(handle, bh_in);
+               } else {
+                       BUFFER_TRACE(bh, "call brelse");
+                       __brelse(bh);
+               }
+       }
+
+       jbd_debug(2, "insert revoke for block %llu, bh_in=%p\n",blocknr, bh_in);
+       err = insert_revoke_hash(journal, blocknr,
+                               handle->h_transaction->t_tid);
+       BUFFER_TRACE(bh_in, "exit");
+       return err;
+}
+
+/*
+ * Cancel an outstanding revoke.  For use only internally by the
+ * journaling code (called from jbd2_journal_get_write_access).
+ *
+ * We trust buffer_revoked() on the buffer if the buffer is already
+ * being journaled: if there is no revoke pending on the buffer, then we
+ * don't do anything here.
+ *
+ * This would break if it were possible for a buffer to be revoked and
+ * discarded, and then reallocated within the same transaction.  In such
+ * a case we would have lost the revoked bit, but when we arrived here
+ * the second time we would still have a pending revoke to cancel.  So,
+ * do not trust the Revoked bit on buffers unless RevokeValid is also
+ * set.
+ *
+ * The caller must have the journal locked.
+ */
+int jbd2_journal_cancel_revoke(handle_t *handle, struct journal_head *jh)
+{
+       struct jbd2_revoke_record_s *record;
+       journal_t *journal = handle->h_transaction->t_journal;
+       int need_cancel;
+       int did_revoke = 0;     /* akpm: debug */
+       struct buffer_head *bh = jh2bh(jh);
+
+       jbd_debug(4, "journal_head %p, cancelling revoke\n", jh);
+
+       /* Is the existing Revoke bit valid?  If so, we trust it, and
+        * only perform the full cancel if the revoke bit is set.  If
+        * not, we can't trust the revoke bit, and we need to do the
+        * full search for a revoke record. */
+       if (test_set_buffer_revokevalid(bh)) {
+               need_cancel = test_clear_buffer_revoked(bh);
+       } else {
+               need_cancel = 1;
+               clear_buffer_revoked(bh);
+       }
+
+       if (need_cancel) {
+               record = find_revoke_record(journal, bh->b_blocknr);
+               if (record) {
+                       jbd_debug(4, "cancelled existing revoke on "
+                                 "blocknr %llu\n", (unsigned long long)bh->b_blocknr);
+                       spin_lock(&journal->j_revoke_lock);
+                       list_del(&record->hash);
+                       spin_unlock(&journal->j_revoke_lock);
+                       kmem_cache_free(jbd2_revoke_record_cache, record);
+                       did_revoke = 1;
+               }
+       }
+
+#ifdef JBD_EXPENSIVE_CHECKING
+       /* There better not be one left behind by now! */
+       record = find_revoke_record(journal, bh->b_blocknr);
+       J_ASSERT_JH(jh, record == NULL);
+#endif
+
+       /* Finally, have we just cleared revoke on an unhashed
+        * buffer_head?  If so, we'd better make sure we clear the
+        * revoked status on any hashed alias too, otherwise the revoke
+        * state machine will get very upset later on. */
+       if (need_cancel) {
+               struct buffer_head *bh2;
+               bh2 = __find_get_block(bh->b_bdev, bh->b_blocknr, bh->b_size);
+               if (bh2) {
+                       if (bh2 != bh)
+                               clear_buffer_revoked(bh2);
+                       __brelse(bh2);
+               }
+       }
+       return did_revoke;
+}
+
+/* journal_switch_revoke table select j_revoke for next transaction
+ * we do not want to suspend any processing until all revokes are
+ * written -bzzz
+ */
+void jbd2_journal_switch_revoke_table(journal_t *journal)
+{
+       int i;
+
+       if (journal->j_revoke == journal->j_revoke_table[0])
+               journal->j_revoke = journal->j_revoke_table[1];
+       else
+               journal->j_revoke = journal->j_revoke_table[0];
+
+       for (i = 0; i < journal->j_revoke->hash_size; i++)
+               INIT_LIST_HEAD(&journal->j_revoke->hash_table[i]);
+}
+
+/*
+ * Write revoke records to the journal for all entries in the current
+ * revoke hash, deleting the entries as we go.
+ *
+ * Called with the journal lock held.
+ */
+
+void jbd2_journal_write_revoke_records(journal_t *journal,
+                                 transaction_t *transaction)
+{
+       struct journal_head *descriptor;
+       struct jbd2_revoke_record_s *record;
+       struct jbd2_revoke_table_s *revoke;
+       struct list_head *hash_list;
+       int i, offset, count;
+
+       descriptor = NULL;
+       offset = 0;
+       count = 0;
+
+       /* select revoke table for committing transaction */
+       revoke = journal->j_revoke == journal->j_revoke_table[0] ?
+               journal->j_revoke_table[1] : journal->j_revoke_table[0];
+
+       for (i = 0; i < revoke->hash_size; i++) {
+               hash_list = &revoke->hash_table[i];
+
+               while (!list_empty(hash_list)) {
+                       record = (struct jbd2_revoke_record_s *)
+                               hash_list->next;
+                       write_one_revoke_record(journal, transaction,
+                                               &descriptor, &offset,
+                                               record);
+                       count++;
+                       list_del(&record->hash);
+                       kmem_cache_free(jbd2_revoke_record_cache, record);
+               }
+       }
+       if (descriptor)
+               flush_descriptor(journal, descriptor, offset);
+       jbd_debug(1, "Wrote %d revoke records\n", count);
+}
+
+/*
+ * Write out one revoke record.  We need to create a new descriptor
+ * block if the old one is full or if we have not already created one.
+ */
+
+static void write_one_revoke_record(journal_t *journal,
+                                   transaction_t *transaction,
+                                   struct journal_head **descriptorp,
+                                   int *offsetp,
+                                   struct jbd2_revoke_record_s *record)
+{
+       struct journal_head *descriptor;
+       int offset;
+       journal_header_t *header;
+
+       /* If we are already aborting, this all becomes a noop.  We
+           still need to go round the loop in
+           jbd2_journal_write_revoke_records in order to free all of the
+           revoke records: only the IO to the journal is omitted. */
+       if (is_journal_aborted(journal))
+               return;
+
+       descriptor = *descriptorp;
+       offset = *offsetp;
+
+       /* Make sure we have a descriptor with space left for the record */
+       if (descriptor) {
+               if (offset == journal->j_blocksize) {
+                       flush_descriptor(journal, descriptor, offset);
+                       descriptor = NULL;
+               }
+       }
+
+       if (!descriptor) {
+               descriptor = jbd2_journal_get_descriptor_buffer(journal);
+               if (!descriptor)
+                       return;
+               header = (journal_header_t *) &jh2bh(descriptor)->b_data[0];
+               header->h_magic     = cpu_to_be32(JBD2_MAGIC_NUMBER);
+               header->h_blocktype = cpu_to_be32(JBD2_REVOKE_BLOCK);
+               header->h_sequence  = cpu_to_be32(transaction->t_tid);
+
+               /* Record it so that we can wait for IO completion later */
+               JBUFFER_TRACE(descriptor, "file as BJ_LogCtl");
+               jbd2_journal_file_buffer(descriptor, transaction, BJ_LogCtl);
+
+               offset = sizeof(jbd2_journal_revoke_header_t);
+               *descriptorp = descriptor;
+       }
+
+       if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_64BIT)) {
+               * ((__be64 *)(&jh2bh(descriptor)->b_data[offset])) =
+                       cpu_to_be64(record->blocknr);
+               offset += 8;
+
+       } else {
+               * ((__be32 *)(&jh2bh(descriptor)->b_data[offset])) =
+                       cpu_to_be32(record->blocknr);
+               offset += 4;
+       }
+
+       *offsetp = offset;
+}
+
+/*
+ * Flush a revoke descriptor out to the journal.  If we are aborting,
+ * this is a noop; otherwise we are generating a buffer which needs to
+ * be waited for during commit, so it has to go onto the appropriate
+ * journal buffer list.
+ */
+
+static void flush_descriptor(journal_t *journal,
+                            struct journal_head *descriptor,
+                            int offset)
+{
+       jbd2_journal_revoke_header_t *header;
+       struct buffer_head *bh = jh2bh(descriptor);
+
+       if (is_journal_aborted(journal)) {
+               put_bh(bh);
+               return;
+       }
+
+       header = (jbd2_journal_revoke_header_t *) jh2bh(descriptor)->b_data;
+       header->r_count = cpu_to_be32(offset);
+       set_buffer_jwrite(bh);
+       BUFFER_TRACE(bh, "write");
+       set_buffer_dirty(bh);
+       ll_rw_block(SWRITE, 1, &bh);
+}
+#endif
+
+/*
+ * Revoke support for recovery.
+ *
+ * Recovery needs to be able to:
+ *
+ *  record all revoke records, including the tid of the latest instance
+ *  of each revoke in the journal
+ *
+ *  check whether a given block in a given transaction should be replayed
+ *  (ie. has not been revoked by a revoke record in that or a subsequent
+ *  transaction)
+ *
+ *  empty the revoke table after recovery.
+ */
+
+/*
+ * First, setting revoke records.  We create a new revoke record for
+ * every block ever revoked in the log as we scan it for recovery, and
+ * we update the existing records if we find multiple revokes for a
+ * single block.
+ */
+
+int jbd2_journal_set_revoke(journal_t *journal,
+                      unsigned long long blocknr,
+                      tid_t sequence)
+{
+       struct jbd2_revoke_record_s *record;
+
+       record = find_revoke_record(journal, blocknr);
+       if (record) {
+               /* If we have multiple occurrences, only record the
+                * latest sequence number in the hashed record */
+               if (tid_gt(sequence, record->sequence))
+                       record->sequence = sequence;
+               return 0;
+       }
+       return insert_revoke_hash(journal, blocknr, sequence);
+}
+
+/*
+ * Test revoke records.  For a given block referenced in the log, has
+ * that block been revoked?  A revoke record with a given transaction
+ * sequence number revokes all blocks in that transaction and earlier
+ * ones, but later transactions still need replayed.
+ */
+
+int jbd2_journal_test_revoke(journal_t *journal,
+                       unsigned long long blocknr,
+                       tid_t sequence)
+{
+       struct jbd2_revoke_record_s *record;
+
+       record = find_revoke_record(journal, blocknr);
+       if (!record)
+               return 0;
+       if (tid_gt(sequence, record->sequence))
+               return 0;
+       return 1;
+}
+
+/*
+ * Finally, once recovery is over, we need to clear the revoke table so
+ * that it can be reused by the running filesystem.
+ */
+
+void jbd2_journal_clear_revoke(journal_t *journal)
+{
+       int i;
+       struct list_head *hash_list;
+       struct jbd2_revoke_record_s *record;
+       struct jbd2_revoke_table_s *revoke;
+
+       revoke = journal->j_revoke;
+
+       for (i = 0; i < revoke->hash_size; i++) {
+               hash_list = &revoke->hash_table[i];
+               while (!list_empty(hash_list)) {
+                       record = (struct jbd2_revoke_record_s*) hash_list->next;
+                       list_del(&record->hash);
+                       kmem_cache_free(jbd2_revoke_record_cache, record);
+               }
+       }
+}
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
new file mode 100644 (file)
index 0000000..b6cf2be
--- /dev/null
@@ -0,0 +1,2081 @@
+/*
+ * linux/fs/transaction.c
+ *
+ * Written by Stephen C. Tweedie <sct@redhat.com>, 1998
+ *
+ * Copyright 1998 Red Hat corp --- All Rights Reserved
+ *
+ * This file is part of the Linux kernel and is made available under
+ * the terms of the GNU General Public License, version 2, or at your
+ * option, any later version, incorporated herein by reference.
+ *
+ * Generic filesystem transaction handling code; part of the ext2fs
+ * journaling system.
+ *
+ * This file manages transactions (compound commits managed by the
+ * journaling code) and handles (individual atomic operations by the
+ * filesystem).
+ */
+
+#include <linux/time.h>
+#include <linux/fs.h>
+#include <linux/jbd2.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/timer.h>
+#include <linux/smp_lock.h>
+#include <linux/mm.h>
+#include <linux/highmem.h>
+
+/*
+ * jbd2_get_transaction: obtain a new transaction_t object.
+ *
+ * Simply allocate and initialise a new transaction.  Create it in
+ * RUNNING state and add it to the current journal (which should not
+ * have an existing running transaction: we only make a new transaction
+ * once we have started to commit the old one).
+ *
+ * Preconditions:
+ *     The journal MUST be locked.  We don't perform atomic mallocs on the
+ *     new transaction and we can't block without protecting against other
+ *     processes trying to touch the journal while it is in transition.
+ *
+ * Called under j_state_lock
+ */
+
+static transaction_t *
+jbd2_get_transaction(journal_t *journal, transaction_t *transaction)
+{
+       transaction->t_journal = journal;
+       transaction->t_state = T_RUNNING;
+       transaction->t_tid = journal->j_transaction_sequence++;
+       transaction->t_expires = jiffies + journal->j_commit_interval;
+       spin_lock_init(&transaction->t_handle_lock);
+
+       /* Set up the commit timer for the new transaction. */
+       journal->j_commit_timer.expires = transaction->t_expires;
+       add_timer(&journal->j_commit_timer);
+
+       J_ASSERT(journal->j_running_transaction == NULL);
+       journal->j_running_transaction = transaction;
+
+       return transaction;
+}
+
+/*
+ * Handle management.
+ *
+ * A handle_t is an object which represents a single atomic update to a
+ * filesystem, and which tracks all of the modifications which form part
+ * of that one update.
+ */
+
+/*
+ * start_this_handle: Given a handle, deal with any locking or stalling
+ * needed to make sure that there is enough journal space for the handle
+ * to begin.  Attach the handle to a transaction and set up the
+ * transaction's buffer credits.
+ */
+
+static int start_this_handle(journal_t *journal, handle_t *handle)
+{
+       transaction_t *transaction;
+       int needed;
+       int nblocks = handle->h_buffer_credits;
+       transaction_t *new_transaction = NULL;
+       int ret = 0;
+
+       if (nblocks > journal->j_max_transaction_buffers) {
+               printk(KERN_ERR "JBD: %s wants too many credits (%d > %d)\n",
+                      current->comm, nblocks,
+                      journal->j_max_transaction_buffers);
+               ret = -ENOSPC;
+               goto out;
+       }
+
+alloc_transaction:
+       if (!journal->j_running_transaction) {
+               new_transaction = jbd_kmalloc(sizeof(*new_transaction),
+                                               GFP_NOFS);
+               if (!new_transaction) {
+                       ret = -ENOMEM;
+                       goto out;
+               }
+               memset(new_transaction, 0, sizeof(*new_transaction));
+       }
+
+       jbd_debug(3, "New handle %p going live.\n", handle);
+
+repeat:
+
+       /*
+        * We need to hold j_state_lock until t_updates has been incremented,
+        * for proper journal barrier handling
+        */
+       spin_lock(&journal->j_state_lock);
+repeat_locked:
+       if (is_journal_aborted(journal) ||
+           (journal->j_errno != 0 && !(journal->j_flags & JBD2_ACK_ERR))) {
+               spin_unlock(&journal->j_state_lock);
+               ret = -EROFS;
+               goto out;
+       }
+
+       /* Wait on the journal's transaction barrier if necessary */
+       if (journal->j_barrier_count) {
+               spin_unlock(&journal->j_state_lock);
+               wait_event(journal->j_wait_transaction_locked,
+                               journal->j_barrier_count == 0);
+               goto repeat;
+       }
+
+       if (!journal->j_running_transaction) {
+               if (!new_transaction) {
+                       spin_unlock(&journal->j_state_lock);
+                       goto alloc_transaction;
+               }
+               jbd2_get_transaction(journal, new_transaction);
+               new_transaction = NULL;
+       }
+
+       transaction = journal->j_running_transaction;
+
+       /*
+        * If the current transaction is locked down for commit, wait for the
+        * lock to be released.
+        */
+       if (transaction->t_state == T_LOCKED) {
+               DEFINE_WAIT(wait);
+
+               prepare_to_wait(&journal->j_wait_transaction_locked,
+                                       &wait, TASK_UNINTERRUPTIBLE);
+               spin_unlock(&journal->j_state_lock);
+               schedule();
+               finish_wait(&journal->j_wait_transaction_locked, &wait);
+               goto repeat;
+       }
+
+       /*
+        * If there is not enough space left in the log to write all potential
+        * buffers requested by this operation, we need to stall pending a log
+        * checkpoint to free some more log space.
+        */
+       spin_lock(&transaction->t_handle_lock);
+       needed = transaction->t_outstanding_credits + nblocks;
+
+       if (needed > journal->j_max_transaction_buffers) {
+               /*
+                * If the current transaction is already too large, then start
+                * to commit it: we can then go back and attach this handle to
+                * a new transaction.
+                */
+               DEFINE_WAIT(wait);
+
+               jbd_debug(2, "Handle %p starting new commit...\n", handle);
+               spin_unlock(&transaction->t_handle_lock);
+               prepare_to_wait(&journal->j_wait_transaction_locked, &wait,
+                               TASK_UNINTERRUPTIBLE);
+               __jbd2_log_start_commit(journal, transaction->t_tid);
+               spin_unlock(&journal->j_state_lock);
+               schedule();
+               finish_wait(&journal->j_wait_transaction_locked, &wait);
+               goto repeat;
+       }
+
+       /*
+        * The commit code assumes that it can get enough log space
+        * without forcing a checkpoint.  This is *critical* for
+        * correctness: a checkpoint of a buffer which is also
+        * associated with a committing transaction creates a deadlock,
+        * so commit simply cannot force through checkpoints.
+        *
+        * We must therefore ensure the necessary space in the journal
+        * *before* starting to dirty potentially checkpointed buffers
+        * in the new transaction.
+        *
+        * The worst part is, any transaction currently committing can
+        * reduce the free space arbitrarily.  Be careful to account for
+        * those buffers when checkpointing.
+        */
+
+       /*
+        * @@@ AKPM: This seems rather over-defensive.  We're giving commit
+        * a _lot_ of headroom: 1/4 of the journal plus the size of
+        * the committing transaction.  Really, we only need to give it
+        * committing_transaction->t_outstanding_credits plus "enough" for
+        * the log control blocks.
+        * Also, this test is inconsitent with the matching one in
+        * jbd2_journal_extend().
+        */
+       if (__jbd2_log_space_left(journal) < jbd_space_needed(journal)) {
+               jbd_debug(2, "Handle %p waiting for checkpoint...\n", handle);
+               spin_unlock(&transaction->t_handle_lock);
+               __jbd2_log_wait_for_space(journal);
+               goto repeat_locked;
+       }
+
+       /* OK, account for the buffers that this operation expects to
+        * use and add the handle to the running transaction. */
+
+       handle->h_transaction = transaction;
+       transaction->t_outstanding_credits += nblocks;
+       transaction->t_updates++;
+       transaction->t_handle_count++;
+       jbd_debug(4, "Handle %p given %d credits (total %d, free %d)\n",
+                 handle, nblocks, transaction->t_outstanding_credits,
+                 __jbd2_log_space_left(journal));
+       spin_unlock(&transaction->t_handle_lock);
+       spin_unlock(&journal->j_state_lock);
+out:
+       if (unlikely(new_transaction))          /* It's usually NULL */
+               kfree(new_transaction);
+       return ret;
+}
+
+/* Allocate a new handle.  This should probably be in a slab... */
+static handle_t *new_handle(int nblocks)
+{
+       handle_t *handle = jbd_alloc_handle(GFP_NOFS);
+       if (!handle)
+               return NULL;
+       memset(handle, 0, sizeof(*handle));
+       handle->h_buffer_credits = nblocks;
+       handle->h_ref = 1;
+
+       return handle;
+}
+
+/**
+ * handle_t *jbd2_journal_start() - Obtain a new handle.
+ * @journal: Journal to start transaction on.
+ * @nblocks: number of block buffer we might modify
+ *
+ * We make sure that the transaction can guarantee at least nblocks of
+ * modified buffers in the log.  We block until the log can guarantee
+ * that much space.
+ *
+ * This function is visible to journal users (like ext3fs), so is not
+ * called with the journal already locked.
+ *
+ * Return a pointer to a newly allocated handle, or NULL on failure
+ */
+handle_t *jbd2_journal_start(journal_t *journal, int nblocks)
+{
+       handle_t *handle = journal_current_handle();
+       int err;
+
+       if (!journal)
+               return ERR_PTR(-EROFS);
+
+       if (handle) {
+               J_ASSERT(handle->h_transaction->t_journal == journal);
+               handle->h_ref++;
+               return handle;
+       }
+
+       handle = new_handle(nblocks);
+       if (!handle)
+               return ERR_PTR(-ENOMEM);
+
+       current->journal_info = handle;
+
+       err = start_this_handle(journal, handle);
+       if (err < 0) {
+               jbd_free_handle(handle);
+               current->journal_info = NULL;
+               handle = ERR_PTR(err);
+       }
+       return handle;
+}
+
+/**
+ * int jbd2_journal_extend() - extend buffer credits.
+ * @handle:  handle to 'extend'
+ * @nblocks: nr blocks to try to extend by.
+ *
+ * Some transactions, such as large extends and truncates, can be done
+ * atomically all at once or in several stages.  The operation requests
+ * a credit for a number of buffer modications in advance, but can
+ * extend its credit if it needs more.
+ *
+ * jbd2_journal_extend tries to give the running handle more buffer credits.
+ * It does not guarantee that allocation - this is a best-effort only.
+ * The calling process MUST be able to deal cleanly with a failure to
+ * extend here.
+ *
+ * Return 0 on success, non-zero on failure.
+ *
+ * return code < 0 implies an error
+ * return code > 0 implies normal transaction-full status.
+ */
+int jbd2_journal_extend(handle_t *handle, int nblocks)
+{
+       transaction_t *transaction = handle->h_transaction;
+       journal_t *journal = transaction->t_journal;
+       int result;
+       int wanted;
+
+       result = -EIO;
+       if (is_handle_aborted(handle))
+               goto out;
+
+       result = 1;
+
+       spin_lock(&journal->j_state_lock);
+
+       /* Don't extend a locked-down transaction! */
+       if (handle->h_transaction->t_state != T_RUNNING) {
+               jbd_debug(3, "denied handle %p %d blocks: "
+                         "transaction not running\n", handle, nblocks);
+               goto error_out;
+       }
+
+       spin_lock(&transaction->t_handle_lock);
+       wanted = transaction->t_outstanding_credits + nblocks;
+
+       if (wanted > journal->j_max_transaction_buffers) {
+               jbd_debug(3, "denied handle %p %d blocks: "
+                         "transaction too large\n", handle, nblocks);
+               goto unlock;
+       }
+
+       if (wanted > __jbd2_log_space_left(journal)) {
+               jbd_debug(3, "denied handle %p %d blocks: "
+                         "insufficient log space\n", handle, nblocks);
+               goto unlock;
+       }
+
+       handle->h_buffer_credits += nblocks;
+       transaction->t_outstanding_credits += nblocks;
+       result = 0;
+
+       jbd_debug(3, "extended handle %p by %d\n", handle, nblocks);
+unlock:
+       spin_unlock(&transaction->t_handle_lock);
+error_out:
+       spin_unlock(&journal->j_state_lock);
+out:
+       return result;
+}
+
+
+/**
+ * int jbd2_journal_restart() - restart a handle .
+ * @handle:  handle to restart
+ * @nblocks: nr credits requested
+ *
+ * Restart a handle for a multi-transaction filesystem
+ * operation.
+ *
+ * If the jbd2_journal_extend() call above fails to grant new buffer credits
+ * to a running handle, a call to jbd2_journal_restart will commit the
+ * handle's transaction so far and reattach the handle to a new
+ * transaction capabable of guaranteeing the requested number of
+ * credits.
+ */
+
+int jbd2_journal_restart(handle_t *handle, int nblocks)
+{
+       transaction_t *transaction = handle->h_transaction;
+       journal_t *journal = transaction->t_journal;
+       int ret;
+
+       /* If we've had an abort of any type, don't even think about
+        * actually doing the restart! */
+       if (is_handle_aborted(handle))
+               return 0;
+
+       /*
+        * First unlink the handle from its current transaction, and start the
+        * commit on that.
+        */
+       J_ASSERT(transaction->t_updates > 0);
+       J_ASSERT(journal_current_handle() == handle);
+
+       spin_lock(&journal->j_state_lock);
+       spin_lock(&transaction->t_handle_lock);
+       transaction->t_outstanding_credits -= handle->h_buffer_credits;
+       transaction->t_updates--;
+
+       if (!transaction->t_updates)
+               wake_up(&journal->j_wait_updates);
+       spin_unlock(&transaction->t_handle_lock);
+
+       jbd_debug(2, "restarting handle %p\n", handle);
+       __jbd2_log_start_commit(journal, transaction->t_tid);
+       spin_unlock(&journal->j_state_lock);
+
+       handle->h_buffer_credits = nblocks;
+       ret = start_this_handle(journal, handle);
+       return ret;
+}
+
+
+/**
+ * void jbd2_journal_lock_updates () - establish a transaction barrier.
+ * @journal:  Journal to establish a barrier on.
+ *
+ * This locks out any further updates from being started, and blocks
+ * until all existing updates have completed, returning only once the
+ * journal is in a quiescent state with no updates running.
+ *
+ * The journal lock should not be held on entry.
+ */
+void jbd2_journal_lock_updates(journal_t *journal)
+{
+       DEFINE_WAIT(wait);
+
+       spin_lock(&journal->j_state_lock);
+       ++journal->j_barrier_count;
+
+       /* Wait until there are no running updates */
+       while (1) {
+               transaction_t *transaction = journal->j_running_transaction;
+
+               if (!transaction)
+                       break;
+
+               spin_lock(&transaction->t_handle_lock);
+               if (!transaction->t_updates) {
+                       spin_unlock(&transaction->t_handle_lock);
+                       break;
+               }
+               prepare_to_wait(&journal->j_wait_updates, &wait,
+                               TASK_UNINTERRUPTIBLE);
+               spin_unlock(&transaction->t_handle_lock);
+               spin_unlock(&journal->j_state_lock);
+               schedule();
+               finish_wait(&journal->j_wait_updates, &wait);
+               spin_lock(&journal->j_state_lock);
+       }
+       spin_unlock(&journal->j_state_lock);
+
+       /*
+        * We have now established a barrier against other normal updates, but
+        * we also need to barrier against other jbd2_journal_lock_updates() calls
+        * to make sure that we serialise special journal-locked operations
+        * too.
+        */
+       mutex_lock(&journal->j_barrier);
+}
+
+/**
+ * void jbd2_journal_unlock_updates (journal_t* journal) - release barrier
+ * @journal:  Journal to release the barrier on.
+ *
+ * Release a transaction barrier obtained with jbd2_journal_lock_updates().
+ *
+ * Should be called without the journal lock held.
+ */
+void jbd2_journal_unlock_updates (journal_t *journal)
+{
+       J_ASSERT(journal->j_barrier_count != 0);
+
+       mutex_unlock(&journal->j_barrier);
+       spin_lock(&journal->j_state_lock);
+       --journal->j_barrier_count;
+       spin_unlock(&journal->j_state_lock);
+       wake_up(&journal->j_wait_transaction_locked);
+}
+
+/*
+ * Report any unexpected dirty buffers which turn up.  Normally those
+ * indicate an error, but they can occur if the user is running (say)
+ * tune2fs to modify the live filesystem, so we need the option of
+ * continuing as gracefully as possible.  #
+ *
+ * The caller should already hold the journal lock and
+ * j_list_lock spinlock: most callers will need those anyway
+ * in order to probe the buffer's journaling state safely.
+ */
+static void jbd_unexpected_dirty_buffer(struct journal_head *jh)
+{
+       int jlist;
+
+       /* If this buffer is one which might reasonably be dirty
+        * --- ie. data, or not part of this journal --- then
+        * we're OK to leave it alone, but otherwise we need to
+        * move the dirty bit to the journal's own internal
+        * JBDDirty bit. */
+       jlist = jh->b_jlist;
+
+       if (jlist == BJ_Metadata || jlist == BJ_Reserved ||
+           jlist == BJ_Shadow || jlist == BJ_Forget) {
+               struct buffer_head *bh = jh2bh(jh);
+
+               if (test_clear_buffer_dirty(bh))
+                       set_buffer_jbddirty(bh);
+       }
+}
+
+/*
+ * If the buffer is already part of the current transaction, then there
+ * is nothing we need to do.  If it is already part of a prior
+ * transaction which we are still committing to disk, then we need to
+ * make sure that we do not overwrite the old copy: we do copy-out to
+ * preserve the copy going to disk.  We also account the buffer against
+ * the handle's metadata buffer credits (unless the buffer is already
+ * part of the transaction, that is).
+ *
+ */
+static int
+do_get_write_access(handle_t *handle, struct journal_head *jh,
+                       int force_copy)
+{
+       struct buffer_head *bh;
+       transaction_t *transaction;
+       journal_t *journal;
+       int error;
+       char *frozen_buffer = NULL;
+       int need_copy = 0;
+
+       if (is_handle_aborted(handle))
+               return -EROFS;
+
+       transaction = handle->h_transaction;
+       journal = transaction->t_journal;
+
+       jbd_debug(5, "buffer_head %p, force_copy %d\n", jh, force_copy);
+
+       JBUFFER_TRACE(jh, "entry");
+repeat:
+       bh = jh2bh(jh);
+
+       /* @@@ Need to check for errors here at some point. */
+
+       lock_buffer(bh);
+       jbd_lock_bh_state(bh);
+
+       /* We now hold the buffer lock so it is safe to query the buffer
+        * state.  Is the buffer dirty?
+        *
+        * If so, there are two possibilities.  The buffer may be
+        * non-journaled, and undergoing a quite legitimate writeback.
+        * Otherwise, it is journaled, and we don't expect dirty buffers
+        * in that state (the buffers should be marked JBD_Dirty
+        * instead.)  So either the IO is being done under our own
+        * control and this is a bug, or it's a third party IO such as
+        * dump(8) (which may leave the buffer scheduled for read ---
+        * ie. locked but not dirty) or tune2fs (which may actually have
+        * the buffer dirtied, ugh.)  */
+
+       if (buffer_dirty(bh)) {
+               /*
+                * First question: is this buffer already part of the current
+                * transaction or the existing committing transaction?
+                */
+               if (jh->b_transaction) {
+                       J_ASSERT_JH(jh,
+                               jh->b_transaction == transaction ||
+                               jh->b_transaction ==
+                                       journal->j_committing_transaction);
+                       if (jh->b_next_transaction)
+                               J_ASSERT_JH(jh, jh->b_next_transaction ==
+                                                       transaction);
+               }
+               /*
+                * In any case we need to clean the dirty flag and we must
+                * do it under the buffer lock to be sure we don't race
+                * with running write-out.
+                */
+               JBUFFER_TRACE(jh, "Unexpected dirty buffer");
+               jbd_unexpected_dirty_buffer(jh);
+       }
+
+       unlock_buffer(bh);
+
+       error = -EROFS;
+       if (is_handle_aborted(handle)) {
+               jbd_unlock_bh_state(bh);
+               goto out;
+       }
+       error = 0;
+
+       /*
+        * The buffer is already part of this transaction if b_transaction or
+        * b_next_transaction points to it
+        */
+       if (jh->b_transaction == transaction ||
+           jh->b_next_transaction == transaction)
+               goto done;
+
+       /*
+        * If there is already a copy-out version of this buffer, then we don't
+        * need to make another one
+        */
+       if (jh->b_frozen_data) {
+               JBUFFER_TRACE(jh, "has frozen data");
+               J_ASSERT_JH(jh, jh->b_next_transaction == NULL);
+               jh->b_next_transaction = transaction;
+               goto done;
+       }
+
+       /* Is there data here we need to preserve? */
+
+       if (jh->b_transaction && jh->b_transaction != transaction) {
+               JBUFFER_TRACE(jh, "owned by older transaction");
+               J_ASSERT_JH(jh, jh->b_next_transaction == NULL);
+               J_ASSERT_JH(jh, jh->b_transaction ==
+                                       journal->j_committing_transaction);
+
+               /* There is one case we have to be very careful about.
+                * If the committing transaction is currently writing
+                * this buffer out to disk and has NOT made a copy-out,
+                * then we cannot modify the buffer contents at all
+                * right now.  The essence of copy-out is that it is the
+                * extra copy, not the primary copy, which gets
+                * journaled.  If the primary copy is already going to
+                * disk then we cannot do copy-out here. */
+
+               if (jh->b_jlist == BJ_Shadow) {
+                       DEFINE_WAIT_BIT(wait, &bh->b_state, BH_Unshadow);
+                       wait_queue_head_t *wqh;
+
+                       wqh = bit_waitqueue(&bh->b_state, BH_Unshadow);
+
+                       JBUFFER_TRACE(jh, "on shadow: sleep");
+                       jbd_unlock_bh_state(bh);
+                       /* commit wakes up all shadow buffers after IO */
+                       for ( ; ; ) {
+                               prepare_to_wait(wqh, &wait.wait,
+                                               TASK_UNINTERRUPTIBLE);
+                               if (jh->b_jlist != BJ_Shadow)
+                                       break;
+                               schedule();
+                       }
+                       finish_wait(wqh, &wait.wait);
+                       goto repeat;
+               }
+
+               /* Only do the copy if the currently-owning transaction
+                * still needs it.  If it is on the Forget list, the
+                * committing transaction is past that stage.  The
+                * buffer had better remain locked during the kmalloc,
+                * but that should be true --- we hold the journal lock
+                * still and the buffer is already on the BUF_JOURNAL
+                * list so won't be flushed.
+                *
+                * Subtle point, though: if this is a get_undo_access,
+                * then we will be relying on the frozen_data to contain
+                * the new value of the committed_data record after the
+                * transaction, so we HAVE to force the frozen_data copy
+                * in that case. */
+
+               if (jh->b_jlist != BJ_Forget || force_copy) {
+                       JBUFFER_TRACE(jh, "generate frozen data");
+                       if (!frozen_buffer) {
+                               JBUFFER_TRACE(jh, "allocate memory for buffer");
+                               jbd_unlock_bh_state(bh);
+                               frozen_buffer =
+                                       jbd2_slab_alloc(jh2bh(jh)->b_size,
+                                                        GFP_NOFS);
+                               if (!frozen_buffer) {
+                                       printk(KERN_EMERG
+                                              "%s: OOM for frozen_buffer\n",
+                                              __FUNCTION__);
+                                       JBUFFER_TRACE(jh, "oom!");
+                                       error = -ENOMEM;
+                                       jbd_lock_bh_state(bh);
+                                       goto done;
+                               }
+                               goto repeat;
+                       }
+                       jh->b_frozen_data = frozen_buffer;
+                       frozen_buffer = NULL;
+                       need_copy = 1;
+               }
+               jh->b_next_transaction = transaction;
+       }
+
+
+       /*
+        * Finally, if the buffer is not journaled right now, we need to make
+        * sure it doesn't get written to disk before the caller actually
+        * commits the new data
+        */
+       if (!jh->b_transaction) {
+               JBUFFER_TRACE(jh, "no transaction");
+               J_ASSERT_JH(jh, !jh->b_next_transaction);
+               jh->b_transaction = transaction;
+               JBUFFER_TRACE(jh, "file as BJ_Reserved");
+               spin_lock(&journal->j_list_lock);
+               __jbd2_journal_file_buffer(jh, transaction, BJ_Reserved);
+               spin_unlock(&journal->j_list_lock);
+       }
+
+done:
+       if (need_copy) {
+               struct page *page;
+               int offset;
+               char *source;
+
+               J_EXPECT_JH(jh, buffer_uptodate(jh2bh(jh)),
+                           "Possible IO failure.\n");
+               page = jh2bh(jh)->b_page;
+               offset = ((unsigned long) jh2bh(jh)->b_data) & ~PAGE_MASK;
+               source = kmap_atomic(page, KM_USER0);
+               memcpy(jh->b_frozen_data, source+offset, jh2bh(jh)->b_size);
+               kunmap_atomic(source, KM_USER0);
+       }
+       jbd_unlock_bh_state(bh);
+
+       /*
+        * If we are about to journal a buffer, then any revoke pending on it is
+        * no longer valid
+        */
+       jbd2_journal_cancel_revoke(handle, jh);
+
+out:
+       if (unlikely(frozen_buffer))    /* It's usually NULL */
+               jbd2_slab_free(frozen_buffer, bh->b_size);
+
+       JBUFFER_TRACE(jh, "exit");
+       return error;
+}
+
+/**
+ * int jbd2_journal_get_write_access() - notify intent to modify a buffer for metadata (not data) update.
+ * @handle: transaction to add buffer modifications to
+ * @bh:     bh to be used for metadata writes
+ * @credits: variable that will receive credits for the buffer
+ *
+ * Returns an error code or 0 on success.
+ *
+ * In full data journalling mode the buffer may be of type BJ_AsyncData,
+ * because we're write()ing a buffer which is also part of a shared mapping.
+ */
+
+int jbd2_journal_get_write_access(handle_t *handle, struct buffer_head *bh)
+{
+       struct journal_head *jh = jbd2_journal_add_journal_head(bh);
+       int rc;
+
+       /* We do not want to get caught playing with fields which the
+        * log thread also manipulates.  Make sure that the buffer
+        * completes any outstanding IO before proceeding. */
+       rc = do_get_write_access(handle, jh, 0);
+       jbd2_journal_put_journal_head(jh);
+       return rc;
+}
+
+
+/*
+ * When the user wants to journal a newly created buffer_head
+ * (ie. getblk() returned a new buffer and we are going to populate it
+ * manually rather than reading off disk), then we need to keep the
+ * buffer_head locked until it has been completely filled with new
+ * data.  In this case, we should be able to make the assertion that
+ * the bh is not already part of an existing transaction.
+ *
+ * The buffer should already be locked by the caller by this point.
+ * There is no lock ranking violation: it was a newly created,
+ * unlocked buffer beforehand. */
+
+/**
+ * int jbd2_journal_get_create_access () - notify intent to use newly created bh
+ * @handle: transaction to new buffer to
+ * @bh: new buffer.
+ *
+ * Call this if you create a new bh.
+ */
+int jbd2_journal_get_create_access(handle_t *handle, struct buffer_head *bh)
+{
+       transaction_t *transaction = handle->h_transaction;
+       journal_t *journal = transaction->t_journal;
+       struct journal_head *jh = jbd2_journal_add_journal_head(bh);
+       int err;
+
+       jbd_debug(5, "journal_head %p\n", jh);
+       err = -EROFS;
+       if (is_handle_aborted(handle))
+               goto out;
+       err = 0;
+
+       JBUFFER_TRACE(jh, "entry");
+       /*
+        * The buffer may already belong to this transaction due to pre-zeroing
+        * in the filesystem's new_block code.  It may also be on the previous,
+        * committing transaction's lists, but it HAS to be in Forget state in
+        * that case: the transaction must have deleted the buffer for it to be
+        * reused here.
+        */
+       jbd_lock_bh_state(bh);
+       spin_lock(&journal->j_list_lock);
+       J_ASSERT_JH(jh, (jh->b_transaction == transaction ||
+               jh->b_transaction == NULL ||
+               (jh->b_transaction == journal->j_committing_transaction &&
+                         jh->b_jlist == BJ_Forget)));
+
+       J_ASSERT_JH(jh, jh->b_next_transaction == NULL);
+       J_ASSERT_JH(jh, buffer_locked(jh2bh(jh)));
+
+       if (jh->b_transaction == NULL) {
+               jh->b_transaction = transaction;
+               JBUFFER_TRACE(jh, "file as BJ_Reserved");
+               __jbd2_journal_file_buffer(jh, transaction, BJ_Reserved);
+       } else if (jh->b_transaction == journal->j_committing_transaction) {
+               JBUFFER_TRACE(jh, "set next transaction");
+               jh->b_next_transaction = transaction;
+       }
+       spin_unlock(&journal->j_list_lock);
+       jbd_unlock_bh_state(bh);
+
+       /*
+        * akpm: I added this.  ext3_alloc_branch can pick up new indirect
+        * blocks which contain freed but then revoked metadata.  We need
+        * to cancel the revoke in case we end up freeing it yet again
+        * and the reallocating as data - this would cause a second revoke,
+        * which hits an assertion error.
+        */
+       JBUFFER_TRACE(jh, "cancelling revoke");
+       jbd2_journal_cancel_revoke(handle, jh);
+       jbd2_journal_put_journal_head(jh);
+out:
+       return err;
+}
+
+/**
+ * int jbd2_journal_get_undo_access() -  Notify intent to modify metadata with
+ *     non-rewindable consequences
+ * @handle: transaction
+ * @bh: buffer to undo
+ * @credits: store the number of taken credits here (if not NULL)
+ *
+ * Sometimes there is a need to distinguish between metadata which has
+ * been committed to disk and that which has not.  The ext3fs code uses
+ * this for freeing and allocating space, we have to make sure that we
+ * do not reuse freed space until the deallocation has been committed,
+ * since if we overwrote that space we would make the delete
+ * un-rewindable in case of a crash.
+ *
+ * To deal with that, jbd2_journal_get_undo_access requests write access to a
+ * buffer for parts of non-rewindable operations such as delete
+ * operations on the bitmaps.  The journaling code must keep a copy of
+ * the buffer's contents prior to the undo_access call until such time
+ * as we know that the buffer has definitely been committed to disk.
+ *
+ * We never need to know which transaction the committed data is part
+ * of, buffers touched here are guaranteed to be dirtied later and so
+ * will be committed to a new transaction in due course, at which point
+ * we can discard the old committed data pointer.
+ *
+ * Returns error number or 0 on success.
+ */
+int jbd2_journal_get_undo_access(handle_t *handle, struct buffer_head *bh)
+{
+       int err;
+       struct journal_head *jh = jbd2_journal_add_journal_head(bh);
+       char *committed_data = NULL;
+
+       JBUFFER_TRACE(jh, "entry");
+
+       /*
+        * Do this first --- it can drop the journal lock, so we want to
+        * make sure that obtaining the committed_data is done
+        * atomically wrt. completion of any outstanding commits.
+        */
+       err = do_get_write_access(handle, jh, 1);
+       if (err)
+               goto out;
+
+repeat:
+       if (!jh->b_committed_data) {
+               committed_data = jbd2_slab_alloc(jh2bh(jh)->b_size, GFP_NOFS);
+               if (!committed_data) {
+                       printk(KERN_EMERG "%s: No memory for committed data\n",
+                               __FUNCTION__);
+                       err = -ENOMEM;
+                       goto out;
+               }
+       }
+
+       jbd_lock_bh_state(bh);
+       if (!jh->b_committed_data) {
+               /* Copy out the current buffer contents into the
+                * preserved, committed copy. */
+               JBUFFER_TRACE(jh, "generate b_committed data");
+               if (!committed_data) {
+                       jbd_unlock_bh_state(bh);
+                       goto repeat;
+               }
+
+               jh->b_committed_data = committed_data;
+               committed_data = NULL;
+               memcpy(jh->b_committed_data, bh->b_data, bh->b_size);
+       }
+       jbd_unlock_bh_state(bh);
+out:
+       jbd2_journal_put_journal_head(jh);
+       if (unlikely(committed_data))
+               jbd2_slab_free(committed_data, bh->b_size);
+       return err;
+}
+
+/**
+ * int jbd2_journal_dirty_data() -  mark a buffer as containing dirty data which
+ *                             needs to be flushed before we can commit the
+ *                             current transaction.
+ * @handle: transaction
+ * @bh: bufferhead to mark
+ *
+ * The buffer is placed on the transaction's data list and is marked as
+ * belonging to the transaction.
+ *
+ * Returns error number or 0 on success.
+ *
+ * jbd2_journal_dirty_data() can be called via page_launder->ext3_writepage
+ * by kswapd.
+ */
+int jbd2_journal_dirty_data(handle_t *handle, struct buffer_head *bh)
+{
+       journal_t *journal = handle->h_transaction->t_journal;
+       int need_brelse = 0;
+       struct journal_head *jh;
+
+       if (is_handle_aborted(handle))
+               return 0;
+
+       jh = jbd2_journal_add_journal_head(bh);
+       JBUFFER_TRACE(jh, "entry");
+
+       /*
+        * The buffer could *already* be dirty.  Writeout can start
+        * at any time.
+        */
+       jbd_debug(4, "jh: %p, tid:%d\n", jh, handle->h_transaction->t_tid);
+
+       /*
+        * What if the buffer is already part of a running transaction?
+        *
+        * There are two cases:
+        * 1) It is part of the current running transaction.  Refile it,
+        *    just in case we have allocated it as metadata, deallocated
+        *    it, then reallocated it as data.
+        * 2) It is part of the previous, still-committing transaction.
+        *    If all we want to do is to guarantee that the buffer will be
+        *    written to disk before this new transaction commits, then
+        *    being sure that the *previous* transaction has this same
+        *    property is sufficient for us!  Just leave it on its old
+        *    transaction.
+        *
+        * In case (2), the buffer must not already exist as metadata
+        * --- that would violate write ordering (a transaction is free
+        * to write its data at any point, even before the previous
+        * committing transaction has committed).  The caller must
+        * never, ever allow this to happen: there's nothing we can do
+        * about it in this layer.
+        */
+       jbd_lock_bh_state(bh);
+       spin_lock(&journal->j_list_lock);
+       if (jh->b_transaction) {
+               JBUFFER_TRACE(jh, "has transaction");
+               if (jh->b_transaction != handle->h_transaction) {
+                       JBUFFER_TRACE(jh, "belongs to older transaction");
+                       J_ASSERT_JH(jh, jh->b_transaction ==
+                                       journal->j_committing_transaction);
+
+                       /* @@@ IS THIS TRUE  ? */
+                       /*
+                        * Not any more.  Scenario: someone does a write()
+                        * in data=journal mode.  The buffer's transaction has
+                        * moved into commit.  Then someone does another
+                        * write() to the file.  We do the frozen data copyout
+                        * and set b_next_transaction to point to j_running_t.
+                        * And while we're in that state, someone does a
+                        * writepage() in an attempt to pageout the same area
+                        * of the file via a shared mapping.  At present that
+                        * calls jbd2_journal_dirty_data(), and we get right here.
+                        * It may be too late to journal the data.  Simply
+                        * falling through to the next test will suffice: the
+                        * data will be dirty and wil be checkpointed.  The
+                        * ordering comments in the next comment block still
+                        * apply.
+                        */
+                       //J_ASSERT_JH(jh, jh->b_next_transaction == NULL);
+
+                       /*
+                        * If we're journalling data, and this buffer was
+                        * subject to a write(), it could be metadata, forget
+                        * or shadow against the committing transaction.  Now,
+                        * someone has dirtied the same darn page via a mapping
+                        * and it is being writepage()'d.
+                        * We *could* just steal the page from commit, with some
+                        * fancy locking there.  Instead, we just skip it -
+                        * don't tie the page's buffers to the new transaction
+                        * at all.
+                        * Implication: if we crash before the writepage() data
+                        * is written into the filesystem, recovery will replay
+                        * the write() data.
+                        */
+                       if (jh->b_jlist != BJ_None &&
+                                       jh->b_jlist != BJ_SyncData &&
+                                       jh->b_jlist != BJ_Locked) {
+                               JBUFFER_TRACE(jh, "Not stealing");
+                               goto no_journal;
+                       }
+
+                       /*
+                        * This buffer may be undergoing writeout in commit.  We
+                        * can't return from here and let the caller dirty it
+                        * again because that can cause the write-out loop in
+                        * commit to never terminate.
+                        */
+                       if (buffer_dirty(bh)) {
+                               get_bh(bh);
+                               spin_unlock(&journal->j_list_lock);
+                               jbd_unlock_bh_state(bh);
+                               need_brelse = 1;
+                               sync_dirty_buffer(bh);
+                               jbd_lock_bh_state(bh);
+                               spin_lock(&journal->j_list_lock);
+                               /* The buffer may become locked again at any
+                                  time if it is redirtied */
+                       }
+
+                       /* journal_clean_data_list() may have got there first */
+                       if (jh->b_transaction != NULL) {
+                               JBUFFER_TRACE(jh, "unfile from commit");
+                               __jbd2_journal_temp_unlink_buffer(jh);
+                               /* It still points to the committing
+                                * transaction; move it to this one so
+                                * that the refile assert checks are
+                                * happy. */
+                               jh->b_transaction = handle->h_transaction;
+                       }
+                       /* The buffer will be refiled below */
+
+               }
+               /*
+                * Special case --- the buffer might actually have been
+                * allocated and then immediately deallocated in the previous,
+                * committing transaction, so might still be left on that
+                * transaction's metadata lists.
+                */
+               if (jh->b_jlist != BJ_SyncData && jh->b_jlist != BJ_Locked) {
+                       JBUFFER_TRACE(jh, "not on correct data list: unfile");
+                       J_ASSERT_JH(jh, jh->b_jlist != BJ_Shadow);
+                       __jbd2_journal_temp_unlink_buffer(jh);
+                       jh->b_transaction = handle->h_transaction;
+                       JBUFFER_TRACE(jh, "file as data");
+                       __jbd2_journal_file_buffer(jh, handle->h_transaction,
+                                               BJ_SyncData);
+               }
+       } else {
+               JBUFFER_TRACE(jh, "not on a transaction");
+               __jbd2_journal_file_buffer(jh, handle->h_transaction, BJ_SyncData);
+       }
+no_journal:
+       spin_unlock(&journal->j_list_lock);
+       jbd_unlock_bh_state(bh);
+       if (need_brelse) {
+               BUFFER_TRACE(bh, "brelse");
+               __brelse(bh);
+       }
+       JBUFFER_TRACE(jh, "exit");
+       jbd2_journal_put_journal_head(jh);
+       return 0;
+}
+
+/**
+ * int jbd2_journal_dirty_metadata() -  mark a buffer as containing dirty metadata
+ * @handle: transaction to add buffer to.
+ * @bh: buffer to mark
+ *
+ * mark dirty metadata which needs to be journaled as part of the current
+ * transaction.
+ *
+ * The buffer is placed on the transaction's metadata list and is marked
+ * as belonging to the transaction.
+ *
+ * Returns error number or 0 on success.
+ *
+ * Special care needs to be taken if the buffer already belongs to the
+ * current committing transaction (in which case we should have frozen
+ * data present for that commit).  In that case, we don't relink the
+ * buffer: that only gets done when the old transaction finally
+ * completes its commit.
+ */
+int jbd2_journal_dirty_metadata(handle_t *handle, struct buffer_head *bh)
+{
+       transaction_t *transaction = handle->h_transaction;
+       journal_t *journal = transaction->t_journal;
+       struct journal_head *jh = bh2jh(bh);
+
+       jbd_debug(5, "journal_head %p\n", jh);
+       JBUFFER_TRACE(jh, "entry");
+       if (is_handle_aborted(handle))
+               goto out;
+
+       jbd_lock_bh_state(bh);
+
+       if (jh->b_modified == 0) {
+               /*
+                * This buffer's got modified and becoming part
+                * of the transaction. This needs to be done
+                * once a transaction -bzzz
+                */
+               jh->b_modified = 1;
+               J_ASSERT_JH(jh, handle->h_buffer_credits > 0);
+               handle->h_buffer_credits--;
+       }
+
+       /*
+        * fastpath, to avoid expensive locking.  If this buffer is already
+        * on the running transaction's metadata list there is nothing to do.
+        * Nobody can take it off again because there is a handle open.
+        * I _think_ we're OK here with SMP barriers - a mistaken decision will
+        * result in this test being false, so we go in and take the locks.
+        */
+       if (jh->b_transaction == transaction && jh->b_jlist == BJ_Metadata) {
+               JBUFFER_TRACE(jh, "fastpath");
+               J_ASSERT_JH(jh, jh->b_transaction ==
+                                       journal->j_running_transaction);
+               goto out_unlock_bh;
+       }
+
+       set_buffer_jbddirty(bh);
+
+       /*
+        * Metadata already on the current transaction list doesn't
+        * need to be filed.  Metadata on another transaction's list must
+        * be committing, and will be refiled once the commit completes:
+        * leave it alone for now.
+        */
+       if (jh->b_transaction != transaction) {
+               JBUFFER_TRACE(jh, "already on other transaction");
+               J_ASSERT_JH(jh, jh->b_transaction ==
+                                       journal->j_committing_transaction);
+               J_ASSERT_JH(jh, jh->b_next_transaction == transaction);
+               /* And this case is illegal: we can't reuse another
+                * transaction's data buffer, ever. */
+               goto out_unlock_bh;
+       }
+
+       /* That test should have eliminated the following case: */
+       J_ASSERT_JH(jh, jh->b_frozen_data == 0);
+
+       JBUFFER_TRACE(jh, "file as BJ_Metadata");
+       spin_lock(&journal->j_list_lock);
+       __jbd2_journal_file_buffer(jh, handle->h_transaction, BJ_Metadata);
+       spin_unlock(&journal->j_list_lock);
+out_unlock_bh:
+       jbd_unlock_bh_state(bh);
+out:
+       JBUFFER_TRACE(jh, "exit");
+       return 0;
+}
+
+/*
+ * jbd2_journal_release_buffer: undo a get_write_access without any buffer
+ * updates, if the update decided in the end that it didn't need access.
+ *
+ */
+void
+jbd2_journal_release_buffer(handle_t *handle, struct buffer_head *bh)
+{
+       BUFFER_TRACE(bh, "entry");
+}
+
+/**
+ * void jbd2_journal_forget() - bforget() for potentially-journaled buffers.
+ * @handle: transaction handle
+ * @bh:     bh to 'forget'
+ *
+ * We can only do the bforget if there are no commits pending against the
+ * buffer.  If the buffer is dirty in the current running transaction we
+ * can safely unlink it.
+ *
+ * bh may not be a journalled buffer at all - it may be a non-JBD
+ * buffer which came off the hashtable.  Check for this.
+ *
+ * Decrements bh->b_count by one.
+ *
+ * Allow this call even if the handle has aborted --- it may be part of
+ * the caller's cleanup after an abort.
+ */
+int jbd2_journal_forget (handle_t *handle, struct buffer_head *bh)
+{
+       transaction_t *transaction = handle->h_transaction;
+       journal_t *journal = transaction->t_journal;
+       struct journal_head *jh;
+       int drop_reserve = 0;
+       int err = 0;
+
+       BUFFER_TRACE(bh, "entry");
+
+       jbd_lock_bh_state(bh);
+       spin_lock(&journal->j_list_lock);
+
+       if (!buffer_jbd(bh))
+               goto not_jbd;
+       jh = bh2jh(bh);
+
+       /* Critical error: attempting to delete a bitmap buffer, maybe?
+        * Don't do any jbd operations, and return an error. */
+       if (!J_EXPECT_JH(jh, !jh->b_committed_data,
+                        "inconsistent data on disk")) {
+               err = -EIO;
+               goto not_jbd;
+       }
+
+       /*
+        * The buffer's going from the transaction, we must drop
+        * all references -bzzz
+        */
+       jh->b_modified = 0;
+
+       if (jh->b_transaction == handle->h_transaction) {
+               J_ASSERT_JH(jh, !jh->b_frozen_data);
+
+               /* If we are forgetting a buffer which is already part
+                * of this transaction, then we can just drop it from
+                * the transaction immediately. */
+               clear_buffer_dirty(bh);
+               clear_buffer_jbddirty(bh);
+
+               JBUFFER_TRACE(jh, "belongs to current transaction: unfile");
+
+               drop_reserve = 1;
+
+               /*
+                * We are no longer going to journal this buffer.
+                * However, the commit of this transaction is still
+                * important to the buffer: the delete that we are now
+                * processing might obsolete an old log entry, so by
+                * committing, we can satisfy the buffer's checkpoint.
+                *
+                * So, if we have a checkpoint on the buffer, we should
+                * now refile the buffer on our BJ_Forget list so that
+                * we know to remove the checkpoint after we commit.
+                */
+
+               if (jh->b_cp_transaction) {
+                       __jbd2_journal_temp_unlink_buffer(jh);
+                       __jbd2_journal_file_buffer(jh, transaction, BJ_Forget);
+               } else {
+                       __jbd2_journal_unfile_buffer(jh);
+                       jbd2_journal_remove_journal_head(bh);
+                       __brelse(bh);
+                       if (!buffer_jbd(bh)) {
+                               spin_unlock(&journal->j_list_lock);
+                               jbd_unlock_bh_state(bh);
+                               __bforget(bh);
+                               goto drop;
+                       }
+               }
+       } else if (jh->b_transaction) {
+               J_ASSERT_JH(jh, (jh->b_transaction ==
+                                journal->j_committing_transaction));
+               /* However, if the buffer is still owned by a prior
+                * (committing) transaction, we can't drop it yet... */
+               JBUFFER_TRACE(jh, "belongs to older transaction");
+               /* ... but we CAN drop it from the new transaction if we
+                * have also modified it since the original commit. */
+
+               if (jh->b_next_transaction) {
+                       J_ASSERT(jh->b_next_transaction == transaction);
+                       jh->b_next_transaction = NULL;
+                       drop_reserve = 1;
+               }
+       }
+
+not_jbd:
+       spin_unlock(&journal->j_list_lock);
+       jbd_unlock_bh_state(bh);
+       __brelse(bh);
+drop:
+       if (drop_reserve) {
+               /* no need to reserve log space for this block -bzzz */
+               handle->h_buffer_credits++;
+       }
+       return err;
+}
+
+/**
+ * int jbd2_journal_stop() - complete a transaction
+ * @handle: tranaction to complete.
+ *
+ * All done for a particular handle.
+ *
+ * There is not much action needed here.  We just return any remaining
+ * buffer credits to the transaction and remove the handle.  The only
+ * complication is that we need to start a commit operation if the
+ * filesystem is marked for synchronous update.
+ *
+ * jbd2_journal_stop itself will not usually return an error, but it may
+ * do so in unusual circumstances.  In particular, expect it to
+ * return -EIO if a jbd2_journal_abort has been executed since the
+ * transaction began.
+ */
+int jbd2_journal_stop(handle_t *handle)
+{
+       transaction_t *transaction = handle->h_transaction;
+       journal_t *journal = transaction->t_journal;
+       int old_handle_count, err;
+       pid_t pid;
+
+       J_ASSERT(journal_current_handle() == handle);
+
+       if (is_handle_aborted(handle))
+               err = -EIO;
+       else {
+               J_ASSERT(transaction->t_updates > 0);
+               err = 0;
+       }
+
+       if (--handle->h_ref > 0) {
+               jbd_debug(4, "h_ref %d -> %d\n", handle->h_ref + 1,
+                         handle->h_ref);
+               return err;
+       }
+
+       jbd_debug(4, "Handle %p going down\n", handle);
+
+       /*
+        * Implement synchronous transaction batching.  If the handle
+        * was synchronous, don't force a commit immediately.  Let's
+        * yield and let another thread piggyback onto this transaction.
+        * Keep doing that while new threads continue to arrive.
+        * It doesn't cost much - we're about to run a commit and sleep
+        * on IO anyway.  Speeds up many-threaded, many-dir operations
+        * by 30x or more...
+        *
+        * But don't do this if this process was the most recent one to
+        * perform a synchronous write.  We do this to detect the case where a
+        * single process is doing a stream of sync writes.  No point in waiting
+        * for joiners in that case.
+        */
+       pid = current->pid;
+       if (handle->h_sync && journal->j_last_sync_writer != pid) {
+               journal->j_last_sync_writer = pid;
+               do {
+                       old_handle_count = transaction->t_handle_count;
+                       schedule_timeout_uninterruptible(1);
+               } while (old_handle_count != transaction->t_handle_count);
+       }
+
+       current->journal_info = NULL;
+       spin_lock(&journal->j_state_lock);
+       spin_lock(&transaction->t_handle_lock);
+       transaction->t_outstanding_credits -= handle->h_buffer_credits;
+       transaction->t_updates--;
+       if (!transaction->t_updates) {
+               wake_up(&journal->j_wait_updates);
+               if (journal->j_barrier_count)
+                       wake_up(&journal->j_wait_transaction_locked);
+       }
+
+       /*
+        * If the handle is marked SYNC, we need to set another commit
+        * going!  We also want to force a commit if the current
+        * transaction is occupying too much of the log, or if the
+        * transaction is too old now.
+        */
+       if (handle->h_sync ||
+                       transaction->t_outstanding_credits >
+                               journal->j_max_transaction_buffers ||
+                       time_after_eq(jiffies, transaction->t_expires)) {
+               /* Do this even for aborted journals: an abort still
+                * completes the commit thread, it just doesn't write
+                * anything to disk. */
+               tid_t tid = transaction->t_tid;
+
+               spin_unlock(&transaction->t_handle_lock);
+               jbd_debug(2, "transaction too old, requesting commit for "
+                                       "handle %p\n", handle);
+               /* This is non-blocking */
+               __jbd2_log_start_commit(journal, transaction->t_tid);
+               spin_unlock(&journal->j_state_lock);
+
+               /*
+                * Special case: JBD2_SYNC synchronous updates require us
+                * to wait for the commit to complete.
+                */
+               if (handle->h_sync && !(current->flags & PF_MEMALLOC))
+                       err = jbd2_log_wait_commit(journal, tid);
+       } else {
+               spin_unlock(&transaction->t_handle_lock);
+               spin_unlock(&journal->j_state_lock);
+       }
+
+       jbd_free_handle(handle);
+       return err;
+}
+
+/**int jbd2_journal_force_commit() - force any uncommitted transactions
+ * @journal: journal to force
+ *
+ * For synchronous operations: force any uncommitted transactions
+ * to disk.  May seem kludgy, but it reuses all the handle batching
+ * code in a very simple manner.
+ */
+int jbd2_journal_force_commit(journal_t *journal)
+{
+       handle_t *handle;
+       int ret;
+
+       handle = jbd2_journal_start(journal, 1);
+       if (IS_ERR(handle)) {
+               ret = PTR_ERR(handle);
+       } else {
+               handle->h_sync = 1;
+               ret = jbd2_journal_stop(handle);
+       }
+       return ret;
+}
+
+/*
+ *
+ * List management code snippets: various functions for manipulating the
+ * transaction buffer lists.
+ *
+ */
+
+/*
+ * Append a buffer to a transaction list, given the transaction's list head
+ * pointer.
+ *
+ * j_list_lock is held.
+ *
+ * jbd_lock_bh_state(jh2bh(jh)) is held.
+ */
+
+static inline void
+__blist_add_buffer(struct journal_head **list, struct journal_head *jh)
+{
+       if (!*list) {
+               jh->b_tnext = jh->b_tprev = jh;
+               *list = jh;
+       } else {
+               /* Insert at the tail of the list to preserve order */
+               struct journal_head *first = *list, *last = first->b_tprev;
+               jh->b_tprev = last;
+               jh->b_tnext = first;
+               last->b_tnext = first->b_tprev = jh;
+       }
+}
+
+/*
+ * Remove a buffer from a transaction list, given the transaction's list
+ * head pointer.
+ *
+ * Called with j_list_lock held, and the journal may not be locked.
+ *
+ * jbd_lock_bh_state(jh2bh(jh)) is held.
+ */
+
+static inline void
+__blist_del_buffer(struct journal_head **list, struct journal_head *jh)
+{
+       if (*list == jh) {
+               *list = jh->b_tnext;
+               if (*list == jh)
+                       *list = NULL;
+       }
+       jh->b_tprev->b_tnext = jh->b_tnext;
+       jh->b_tnext->b_tprev = jh->b_tprev;
+}
+
+/*
+ * Remove a buffer from the appropriate transaction list.
+ *
+ * Note that this function can *change* the value of
+ * bh->b_transaction->t_sync_datalist, t_buffers, t_forget,
+ * t_iobuf_list, t_shadow_list, t_log_list or t_reserved_list.  If the caller
+ * is holding onto a copy of one of thee pointers, it could go bad.
+ * Generally the caller needs to re-read the pointer from the transaction_t.
+ *
+ * Called under j_list_lock.  The journal may not be locked.
+ */
+void __jbd2_journal_temp_unlink_buffer(struct journal_head *jh)
+{
+       struct journal_head **list = NULL;
+       transaction_t *transaction;
+       struct buffer_head *bh = jh2bh(jh);
+
+       J_ASSERT_JH(jh, jbd_is_locked_bh_state(bh));
+       transaction = jh->b_transaction;
+       if (transaction)
+               assert_spin_locked(&transaction->t_journal->j_list_lock);
+
+       J_ASSERT_JH(jh, jh->b_jlist < BJ_Types);
+       if (jh->b_jlist != BJ_None)
+               J_ASSERT_JH(jh, transaction != 0);
+
+       switch (jh->b_jlist) {
+       case BJ_None:
+               return;
+       case BJ_SyncData:
+               list = &transaction->t_sync_datalist;
+               break;
+       case BJ_Metadata:
+               transaction->t_nr_buffers--;
+               J_ASSERT_JH(jh, transaction->t_nr_buffers >= 0);
+               list = &transaction->t_buffers;
+               break;
+       case BJ_Forget:
+               list = &transaction->t_forget;
+               break;
+       case BJ_IO:
+               list = &transaction->t_iobuf_list;
+               break;
+       case BJ_Shadow:
+               list = &transaction->t_shadow_list;
+               break;
+       case BJ_LogCtl:
+               list = &transaction->t_log_list;
+               break;
+       case BJ_Reserved:
+               list = &transaction->t_reserved_list;
+               break;
+       case BJ_Locked:
+               list = &transaction->t_locked_list;
+               break;
+       }
+
+       __blist_del_buffer(list, jh);
+       jh->b_jlist = BJ_None;
+       if (test_clear_buffer_jbddirty(bh))
+               mark_buffer_dirty(bh);  /* Expose it to the VM */
+}
+
+void __jbd2_journal_unfile_buffer(struct journal_head *jh)
+{
+       __jbd2_journal_temp_unlink_buffer(jh);
+       jh->b_transaction = NULL;
+}
+
+void jbd2_journal_unfile_buffer(journal_t *journal, struct journal_head *jh)
+{
+       jbd_lock_bh_state(jh2bh(jh));
+       spin_lock(&journal->j_list_lock);
+       __jbd2_journal_unfile_buffer(jh);
+       spin_unlock(&journal->j_list_lock);
+       jbd_unlock_bh_state(jh2bh(jh));
+}
+
+/*
+ * Called from jbd2_journal_try_to_free_buffers().
+ *
+ * Called under jbd_lock_bh_state(bh)
+ */
+static void
+__journal_try_to_free_buffer(journal_t *journal, struct buffer_head *bh)
+{
+       struct journal_head *jh;
+
+       jh = bh2jh(bh);
+
+       if (buffer_locked(bh) || buffer_dirty(bh))
+               goto out;
+
+       if (jh->b_next_transaction != 0)
+               goto out;
+
+       spin_lock(&journal->j_list_lock);
+       if (jh->b_transaction != 0 && jh->b_cp_transaction == 0) {
+               if (jh->b_jlist == BJ_SyncData || jh->b_jlist == BJ_Locked) {
+                       /* A written-back ordered data buffer */
+                       JBUFFER_TRACE(jh, "release data");
+                       __jbd2_journal_unfile_buffer(jh);
+                       jbd2_journal_remove_journal_head(bh);
+                       __brelse(bh);
+               }
+       } else if (jh->b_cp_transaction != 0 && jh->b_transaction == 0) {
+               /* written-back checkpointed metadata buffer */
+               if (jh->b_jlist == BJ_None) {
+                       JBUFFER_TRACE(jh, "remove from checkpoint list");
+                       __jbd2_journal_remove_checkpoint(jh);
+                       jbd2_journal_remove_journal_head(bh);
+                       __brelse(bh);
+               }
+       }
+       spin_unlock(&journal->j_list_lock);
+out:
+       return;
+}
+
+
+/**
+ * int jbd2_journal_try_to_free_buffers() - try to free page buffers.
+ * @journal: journal for operation
+ * @page: to try and free
+ * @unused_gfp_mask: unused
+ *
+ *
+ * For all the buffers on this page,
+ * if they are fully written out ordered data, move them onto BUF_CLEAN
+ * so try_to_free_buffers() can reap them.
+ *
+ * This function returns non-zero if we wish try_to_free_buffers()
+ * to be called. We do this if the page is releasable by try_to_free_buffers().
+ * We also do it if the page has locked or dirty buffers and the caller wants
+ * us to perform sync or async writeout.
+ *
+ * This complicates JBD locking somewhat.  We aren't protected by the
+ * BKL here.  We wish to remove the buffer from its committing or
+ * running transaction's ->t_datalist via __jbd2_journal_unfile_buffer.
+ *
+ * This may *change* the value of transaction_t->t_datalist, so anyone
+ * who looks at t_datalist needs to lock against this function.
+ *
+ * Even worse, someone may be doing a jbd2_journal_dirty_data on this
+ * buffer.  So we need to lock against that.  jbd2_journal_dirty_data()
+ * will come out of the lock with the buffer dirty, which makes it
+ * ineligible for release here.
+ *
+ * Who else is affected by this?  hmm...  Really the only contender
+ * is do_get_write_access() - it could be looking at the buffer while
+ * journal_try_to_free_buffer() is changing its state.  But that
+ * cannot happen because we never reallocate freed data as metadata
+ * while the data is part of a transaction.  Yes?
+ */
+int jbd2_journal_try_to_free_buffers(journal_t *journal,
+                               struct page *page, gfp_t unused_gfp_mask)
+{
+       struct buffer_head *head;
+       struct buffer_head *bh;
+       int ret = 0;
+
+       J_ASSERT(PageLocked(page));
+
+       head = page_buffers(page);
+       bh = head;
+       do {
+               struct journal_head *jh;
+
+               /*
+                * We take our own ref against the journal_head here to avoid
+                * having to add tons of locking around each instance of
+                * jbd2_journal_remove_journal_head() and jbd2_journal_put_journal_head().
+                */
+               jh = jbd2_journal_grab_journal_head(bh);
+               if (!jh)
+                       continue;
+
+               jbd_lock_bh_state(bh);
+               __journal_try_to_free_buffer(journal, bh);
+               jbd2_journal_put_journal_head(jh);
+               jbd_unlock_bh_state(bh);
+               if (buffer_jbd(bh))
+                       goto busy;
+       } while ((bh = bh->b_this_page) != head);
+       ret = try_to_free_buffers(page);
+busy:
+       return ret;
+}
+
+/*
+ * This buffer is no longer needed.  If it is on an older transaction's
+ * checkpoint list we need to record it on this transaction's forget list
+ * to pin this buffer (and hence its checkpointing transaction) down until
+ * this transaction commits.  If the buffer isn't on a checkpoint list, we
+ * release it.
+ * Returns non-zero if JBD no longer has an interest in the buffer.
+ *
+ * Called under j_list_lock.
+ *
+ * Called under jbd_lock_bh_state(bh).
+ */
+static int __dispose_buffer(struct journal_head *jh, transaction_t *transaction)
+{
+       int may_free = 1;
+       struct buffer_head *bh = jh2bh(jh);
+
+       __jbd2_journal_unfile_buffer(jh);
+
+       if (jh->b_cp_transaction) {
+               JBUFFER_TRACE(jh, "on running+cp transaction");
+               __jbd2_journal_file_buffer(jh, transaction, BJ_Forget);
+               clear_buffer_jbddirty(bh);
+               may_free = 0;
+       } else {
+               JBUFFER_TRACE(jh, "on running transaction");
+               jbd2_journal_remove_journal_head(bh);
+               __brelse(bh);
+       }
+       return may_free;
+}
+
+/*
+ * jbd2_journal_invalidatepage
+ *
+ * This code is tricky.  It has a number of cases to deal with.
+ *
+ * There are two invariants which this code relies on:
+ *
+ * i_size must be updated on disk before we start calling invalidatepage on the
+ * data.
+ *
+ *  This is done in ext3 by defining an ext3_setattr method which
+ *  updates i_size before truncate gets going.  By maintaining this
+ *  invariant, we can be sure that it is safe to throw away any buffers
+ *  attached to the current transaction: once the transaction commits,
+ *  we know that the data will not be needed.
+ *
+ *  Note however that we can *not* throw away data belonging to the
+ *  previous, committing transaction!
+ *
+ * Any disk blocks which *are* part of the previous, committing
+ * transaction (and which therefore cannot be discarded immediately) are
+ * not going to be reused in the new running transaction
+ *
+ *  The bitmap committed_data images guarantee this: any block which is
+ *  allocated in one transaction and removed in the next will be marked
+ *  as in-use in the committed_data bitmap, so cannot be reused until
+ *  the next transaction to delete the block commits.  This means that
+ *  leaving committing buffers dirty is quite safe: the disk blocks
+ *  cannot be reallocated to a different file and so buffer aliasing is
+ *  not possible.
+ *
+ *
+ * The above applies mainly to ordered data mode.  In writeback mode we
+ * don't make guarantees about the order in which data hits disk --- in
+ * particular we don't guarantee that new dirty data is flushed before
+ * transaction commit --- so it is always safe just to discard data
+ * immediately in that mode.  --sct
+ */
+
+/*
+ * The journal_unmap_buffer helper function returns zero if the buffer
+ * concerned remains pinned as an anonymous buffer belonging to an older
+ * transaction.
+ *
+ * We're outside-transaction here.  Either or both of j_running_transaction
+ * and j_committing_transaction may be NULL.
+ */
+static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh)
+{
+       transaction_t *transaction;
+       struct journal_head *jh;
+       int may_free = 1;
+       int ret;
+
+       BUFFER_TRACE(bh, "entry");
+
+       /*
+        * It is safe to proceed here without the j_list_lock because the
+        * buffers cannot be stolen by try_to_free_buffers as long as we are
+        * holding the page lock. --sct
+        */
+
+       if (!buffer_jbd(bh))
+               goto zap_buffer_unlocked;
+
+       spin_lock(&journal->j_state_lock);
+       jbd_lock_bh_state(bh);
+       spin_lock(&journal->j_list_lock);
+
+       jh = jbd2_journal_grab_journal_head(bh);
+       if (!jh)
+               goto zap_buffer_no_jh;
+
+       transaction = jh->b_transaction;
+       if (transaction == NULL) {
+               /* First case: not on any transaction.  If it
+                * has no checkpoint link, then we can zap it:
+                * it's a writeback-mode buffer so we don't care
+                * if it hits disk safely. */
+               if (!jh->b_cp_transaction) {
+                       JBUFFER_TRACE(jh, "not on any transaction: zap");
+                       goto zap_buffer;
+               }
+
+               if (!buffer_dirty(bh)) {
+                       /* bdflush has written it.  We can drop it now */
+                       goto zap_buffer;
+               }
+
+               /* OK, it must be in the journal but still not
+                * written fully to disk: it's metadata or
+                * journaled data... */
+
+               if (journal->j_running_transaction) {
+                       /* ... and once the current transaction has
+                        * committed, the buffer won't be needed any
+                        * longer. */
+                       JBUFFER_TRACE(jh, "checkpointed: add to BJ_Forget");
+                       ret = __dispose_buffer(jh,
+                                       journal->j_running_transaction);
+                       jbd2_journal_put_journal_head(jh);
+                       spin_unlock(&journal->j_list_lock);
+                       jbd_unlock_bh_state(bh);
+                       spin_unlock(&journal->j_state_lock);
+                       return ret;
+               } else {
+                       /* There is no currently-running transaction. So the
+                        * orphan record which we wrote for this file must have
+                        * passed into commit.  We must attach this buffer to
+                        * the committing transaction, if it exists. */
+                       if (journal->j_committing_transaction) {
+                               JBUFFER_TRACE(jh, "give to committing trans");
+                               ret = __dispose_buffer(jh,
+                                       journal->j_committing_transaction);
+                               jbd2_journal_put_journal_head(jh);
+                               spin_unlock(&journal->j_list_lock);
+                               jbd_unlock_bh_state(bh);
+                               spin_unlock(&journal->j_state_lock);
+                               return ret;
+                       } else {
+                               /* The orphan record's transaction has
+                                * committed.  We can cleanse this buffer */
+                               clear_buffer_jbddirty(bh);
+                               goto zap_buffer;
+                       }
+               }
+       } else if (transaction == journal->j_committing_transaction) {
+               if (jh->b_jlist == BJ_Locked) {
+                       /*
+                        * The buffer is on the committing transaction's locked
+                        * list.  We have the buffer locked, so I/O has
+                        * completed.  So we can nail the buffer now.
+                        */
+                       may_free = __dispose_buffer(jh, transaction);
+                       goto zap_buffer;
+               }
+               /*
+                * If it is committing, we simply cannot touch it.  We
+                * can remove it's next_transaction pointer from the
+                * running transaction if that is set, but nothing
+                * else. */
+               JBUFFER_TRACE(jh, "on committing transaction");
+               set_buffer_freed(bh);
+               if (jh->b_next_transaction) {
+                       J_ASSERT(jh->b_next_transaction ==
+                                       journal->j_running_transaction);
+                       jh->b_next_transaction = NULL;
+               }
+               jbd2_journal_put_journal_head(jh);
+               spin_unlock(&journal->j_list_lock);
+               jbd_unlock_bh_state(bh);
+               spin_unlock(&journal->j_state_lock);
+               return 0;
+       } else {
+               /* Good, the buffer belongs to the running transaction.
+                * We are writing our own transaction's data, not any
+                * previous one's, so it is safe to throw it away
+                * (remember that we expect the filesystem to have set
+                * i_size already for this truncate so recovery will not
+                * expose the disk blocks we are discarding here.) */
+               J_ASSERT_JH(jh, transaction == journal->j_running_transaction);
+               may_free = __dispose_buffer(jh, transaction);
+       }
+
+zap_buffer:
+       jbd2_journal_put_journal_head(jh);
+zap_buffer_no_jh:
+       spin_unlock(&journal->j_list_lock);
+       jbd_unlock_bh_state(bh);
+       spin_unlock(&journal->j_state_lock);
+zap_buffer_unlocked:
+       clear_buffer_dirty(bh);
+       J_ASSERT_BH(bh, !buffer_jbddirty(bh));
+       clear_buffer_mapped(bh);
+       clear_buffer_req(bh);
+       clear_buffer_new(bh);
+       bh->b_bdev = NULL;
+       return may_free;
+}
+
+/**
+ * void jbd2_journal_invalidatepage()
+ * @journal: journal to use for flush...
+ * @page:    page to flush
+ * @offset:  length of page to invalidate.
+ *
+ * Reap page buffers containing data after offset in page.
+ *
+ */
+void jbd2_journal_invalidatepage(journal_t *journal,
+                     struct page *page,
+                     unsigned long offset)
+{
+       struct buffer_head *head, *bh, *next;
+       unsigned int curr_off = 0;
+       int may_free = 1;
+
+       if (!PageLocked(page))
+               BUG();
+       if (!page_has_buffers(page))
+               return;
+
+       /* We will potentially be playing with lists other than just the
+        * data lists (especially for journaled data mode), so be
+        * cautious in our locking. */
+
+       head = bh = page_buffers(page);
+       do {
+               unsigned int next_off = curr_off + bh->b_size;
+               next = bh->b_this_page;
+
+               if (offset <= curr_off) {
+                       /* This block is wholly outside the truncation point */
+                       lock_buffer(bh);
+                       may_free &= journal_unmap_buffer(journal, bh);
+                       unlock_buffer(bh);
+               }
+               curr_off = next_off;
+               bh = next;
+
+       } while (bh != head);
+
+       if (!offset) {
+               if (may_free && try_to_free_buffers(page))
+                       J_ASSERT(!page_has_buffers(page));
+       }
+}
+
+/*
+ * File a buffer on the given transaction list.
+ */
+void __jbd2_journal_file_buffer(struct journal_head *jh,
+                       transaction_t *transaction, int jlist)
+{
+       struct journal_head **list = NULL;
+       int was_dirty = 0;
+       struct buffer_head *bh = jh2bh(jh);
+
+       J_ASSERT_JH(jh, jbd_is_locked_bh_state(bh));
+       assert_spin_locked(&transaction->t_journal->j_list_lock);
+
+       J_ASSERT_JH(jh, jh->b_jlist < BJ_Types);
+       J_ASSERT_JH(jh, jh->b_transaction == transaction ||
+                               jh->b_transaction == 0);
+
+       if (jh->b_transaction && jh->b_jlist == jlist)
+               return;
+
+       /* The following list of buffer states needs to be consistent
+        * with __jbd_unexpected_dirty_buffer()'s handling of dirty
+        * state. */
+
+       if (jlist == BJ_Metadata || jlist == BJ_Reserved ||
+           jlist == BJ_Shadow || jlist == BJ_Forget) {
+               if (test_clear_buffer_dirty(bh) ||
+                   test_clear_buffer_jbddirty(bh))
+                       was_dirty = 1;
+       }
+
+       if (jh->b_transaction)
+               __jbd2_journal_temp_unlink_buffer(jh);
+       jh->b_transaction = transaction;
+
+       switch (jlist) {
+       case BJ_None:
+               J_ASSERT_JH(jh, !jh->b_committed_data);
+               J_ASSERT_JH(jh, !jh->b_frozen_data);
+               return;
+       case BJ_SyncData:
+               list = &transaction->t_sync_datalist;
+               break;
+       case BJ_Metadata:
+               transaction->t_nr_buffers++;
+               list = &transaction->t_buffers;
+               break;
+       case BJ_Forget:
+               list = &transaction->t_forget;
+               break;
+       case BJ_IO:
+               list = &transaction->t_iobuf_list;
+               break;
+       case BJ_Shadow:
+               list = &transaction->t_shadow_list;
+               break;
+       case BJ_LogCtl:
+               list = &transaction->t_log_list;
+               break;
+       case BJ_Reserved:
+               list = &transaction->t_reserved_list;
+               break;
+       case BJ_Locked:
+               list =  &transaction->t_locked_list;
+               break;
+       }
+
+       __blist_add_buffer(list, jh);
+       jh->b_jlist = jlist;
+
+       if (was_dirty)
+               set_buffer_jbddirty(bh);
+}
+
+void jbd2_journal_file_buffer(struct journal_head *jh,
+                               transaction_t *transaction, int jlist)
+{
+       jbd_lock_bh_state(jh2bh(jh));
+       spin_lock(&transaction->t_journal->j_list_lock);
+       __jbd2_journal_file_buffer(jh, transaction, jlist);
+       spin_unlock(&transaction->t_journal->j_list_lock);
+       jbd_unlock_bh_state(jh2bh(jh));
+}
+
+/*
+ * Remove a buffer from its current buffer list in preparation for
+ * dropping it from its current transaction entirely.  If the buffer has
+ * already started to be used by a subsequent transaction, refile the
+ * buffer on that transaction's metadata list.
+ *
+ * Called under journal->j_list_lock
+ *
+ * Called under jbd_lock_bh_state(jh2bh(jh))
+ */
+void __jbd2_journal_refile_buffer(struct journal_head *jh)
+{
+       int was_dirty;
+       struct buffer_head *bh = jh2bh(jh);
+
+       J_ASSERT_JH(jh, jbd_is_locked_bh_state(bh));
+       if (jh->b_transaction)
+               assert_spin_locked(&jh->b_transaction->t_journal->j_list_lock);
+
+       /* If the buffer is now unused, just drop it. */
+       if (jh->b_next_transaction == NULL) {
+               __jbd2_journal_unfile_buffer(jh);
+               return;
+       }
+
+       /*
+        * It has been modified by a later transaction: add it to the new
+        * transaction's metadata list.
+        */
+
+       was_dirty = test_clear_buffer_jbddirty(bh);
+       __jbd2_journal_temp_unlink_buffer(jh);
+       jh->b_transaction = jh->b_next_transaction;
+       jh->b_next_transaction = NULL;
+       __jbd2_journal_file_buffer(jh, jh->b_transaction,
+                               was_dirty ? BJ_Metadata : BJ_Reserved);
+       J_ASSERT_JH(jh, jh->b_transaction->t_state == T_RUNNING);
+
+       if (was_dirty)
+               set_buffer_jbddirty(bh);
+}
+
+/*
+ * For the unlocked version of this call, also make sure that any
+ * hanging journal_head is cleaned up if necessary.
+ *
+ * __jbd2_journal_refile_buffer is usually called as part of a single locked
+ * operation on a buffer_head, in which the caller is probably going to
+ * be hooking the journal_head onto other lists.  In that case it is up
+ * to the caller to remove the journal_head if necessary.  For the
+ * unlocked jbd2_journal_refile_buffer call, the caller isn't going to be
+ * doing anything else to the buffer so we need to do the cleanup
+ * ourselves to avoid a jh leak.
+ *
+ * *** The journal_head may be freed by this call! ***
+ */
+void jbd2_journal_refile_buffer(journal_t *journal, struct journal_head *jh)
+{
+       struct buffer_head *bh = jh2bh(jh);
+
+       jbd_lock_bh_state(bh);
+       spin_lock(&journal->j_list_lock);
+
+       __jbd2_journal_refile_buffer(jh);
+       jbd_unlock_bh_state(bh);
+       jbd2_journal_remove_journal_head(bh);
+
+       spin_unlock(&journal->j_list_lock);
+       __brelse(bh);
+}
index 6de374513c010790ab15e40f4103781f669d93c8..bc4b8106a49010bf8144bfbe3a0e6532860eacb4 100644 (file)
@@ -334,10 +334,10 @@ static int __init init_jffs2_fs(void)
           which means just 'no padding', without the alignment
           thing. But GCC doesn't have that -- we have to just
           hope the structs are the right sizes, instead. */
-       BUG_ON(sizeof(struct jffs2_unknown_node) != 12);
-       BUG_ON(sizeof(struct jffs2_raw_dirent) != 40);
-       BUG_ON(sizeof(struct jffs2_raw_inode) != 68);
-       BUG_ON(sizeof(struct jffs2_raw_summary) != 32);
+       BUILD_BUG_ON(sizeof(struct jffs2_unknown_node) != 12);
+       BUILD_BUG_ON(sizeof(struct jffs2_raw_dirent) != 40);
+       BUILD_BUG_ON(sizeof(struct jffs2_raw_inode) != 68);
+       BUILD_BUG_ON(sizeof(struct jffs2_raw_summary) != 32);
 
        printk(KERN_INFO "JFFS2 version 2.2."
 #ifdef CONFIG_JFFS2_FS_WRITEBUFFER
index 489a3d63002db2db9d5dec4a3c3f1899a154a4e7..ee9b473b7b808d7866dfd95db09d775576977943 100644 (file)
@@ -318,7 +318,7 @@ int diRead(struct inode *ip)
        struct inomap *imap;
        int block_offset;
        int inodes_left;
-       uint pageno;
+       unsigned long pageno;
        int rel_inode;
 
        jfs_info("diRead: ino = %ld", ip->i_ino);
@@ -606,7 +606,7 @@ int diWrite(tid_t tid, struct inode *ip)
        int block_offset;
        int inodes_left;
        struct metapage *mp;
-       uint pageno;
+       unsigned long pageno;
        int rel_inode;
        int dioffset;
        struct inode *ipimap;
index e8c7765419e8c8e55e0f8a9d3a6706c149fcabba..b85a0ad2cfb622fee0986450f530b44d3f987b16 100644 (file)
@@ -100,12 +100,12 @@ int nlmclnt_block(struct nlm_wait *block, struct nlm_rqst *req, long timeout)
 /*
  * The server lockd has called us back to tell us the lock was granted
  */
-u32 nlmclnt_grant(const struct sockaddr_in *addr, const struct nlm_lock *lock)
+__be32 nlmclnt_grant(const struct sockaddr_in *addr, const struct nlm_lock *lock)
 {
        const struct file_lock *fl = &lock->fl;
        const struct nfs_fh *fh = &lock->fh;
        struct nlm_wait *block;
-       u32 res = nlm_lck_denied;
+       __be32 res = nlm_lck_denied;
 
        /*
         * Look up blocked request based on arguments. 
index e0179f8c327f65657ffb6b83e03fa88265dce0c5..eb243edf8932b36e58c26f72c24efeb46f1040b3 100644 (file)
@@ -148,8 +148,8 @@ nsm_create(void)
  * XDR functions for NSM.
  */
 
-static u32 *
-xdr_encode_common(struct rpc_rqst *rqstp, u32 *p, struct nsm_args *argp)
+static __be32 *
+xdr_encode_common(struct rpc_rqst *rqstp, __be32 *p, struct nsm_args *argp)
 {
        char    buffer[20], *name;
 
@@ -176,7 +176,7 @@ xdr_encode_common(struct rpc_rqst *rqstp, u32 *p, struct nsm_args *argp)
 }
 
 static int
-xdr_encode_mon(struct rpc_rqst *rqstp, u32 *p, struct nsm_args *argp)
+xdr_encode_mon(struct rpc_rqst *rqstp, __be32 *p, struct nsm_args *argp)
 {
        p = xdr_encode_common(rqstp, p, argp);
        if (IS_ERR(p))
@@ -192,7 +192,7 @@ xdr_encode_mon(struct rpc_rqst *rqstp, u32 *p, struct nsm_args *argp)
 }
 
 static int
-xdr_encode_unmon(struct rpc_rqst *rqstp, u32 *p, struct nsm_args *argp)
+xdr_encode_unmon(struct rpc_rqst *rqstp, __be32 *p, struct nsm_args *argp)
 {
        p = xdr_encode_common(rqstp, p, argp);
        if (IS_ERR(p))
@@ -202,7 +202,7 @@ xdr_encode_unmon(struct rpc_rqst *rqstp, u32 *p, struct nsm_args *argp)
 }
 
 static int
-xdr_decode_stat_res(struct rpc_rqst *rqstp, u32 *p, struct nsm_res *resp)
+xdr_decode_stat_res(struct rpc_rqst *rqstp, __be32 *p, struct nsm_res *resp)
 {
        resp->status = ntohl(*p++);
        resp->state = ntohl(*p++);
@@ -212,7 +212,7 @@ xdr_decode_stat_res(struct rpc_rqst *rqstp, u32 *p, struct nsm_res *resp)
 }
 
 static int
-xdr_decode_stat(struct rpc_rqst *rqstp, u32 *p, struct nsm_res *resp)
+xdr_decode_stat(struct rpc_rqst *rqstp, __be32 *p, struct nsm_res *resp)
 {
        resp->state = ntohl(*p++);
        return 0;
index fa370f6eb07b27ddf2b1dc2b984ed5633b3d7c82..0ce5c81ff5078076e3fd43f659fa0de561370917 100644 (file)
 /*
  * Obtain client and file from arguments
  */
-static u32
+static __be32
 nlm4svc_retrieve_args(struct svc_rqst *rqstp, struct nlm_args *argp,
                        struct nlm_host **hostp, struct nlm_file **filp)
 {
        struct nlm_host         *host = NULL;
        struct nlm_file         *file = NULL;
        struct nlm_lock         *lock = &argp->lock;
-       u32                     error = 0;
+       __be32                  error = 0;
 
        /* nfsd callbacks must have been installed for this procedure */
        if (!nlmsvc_ops)
@@ -68,7 +68,7 @@ no_locks:
 /*
  * NULL: Test for presence of service
  */
-static int
+static __be32
 nlm4svc_proc_null(struct svc_rqst *rqstp, void *argp, void *resp)
 {
        dprintk("lockd: NULL          called\n");
@@ -78,7 +78,7 @@ nlm4svc_proc_null(struct svc_rqst *rqstp, void *argp, void *resp)
 /*
  * TEST: Check for conflicting lock
  */
-static int
+static __be32
 nlm4svc_proc_test(struct svc_rqst *rqstp, struct nlm_args *argp,
                                         struct nlm_res  *resp)
 {
@@ -96,7 +96,7 @@ nlm4svc_proc_test(struct svc_rqst *rqstp, struct nlm_args *argp,
 
        /* Obtain client and file */
        if ((resp->status = nlm4svc_retrieve_args(rqstp, argp, &host, &file)))
-               return rpc_success;
+               return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success;
 
        /* Now check for conflicting locks */
        resp->status = nlmsvc_testlock(file, &argp->lock, &resp->lock);
@@ -107,7 +107,7 @@ nlm4svc_proc_test(struct svc_rqst *rqstp, struct nlm_args *argp,
        return rpc_success;
 }
 
-static int
+static __be32
 nlm4svc_proc_lock(struct svc_rqst *rqstp, struct nlm_args *argp,
                                         struct nlm_res  *resp)
 {
@@ -126,7 +126,7 @@ nlm4svc_proc_lock(struct svc_rqst *rqstp, struct nlm_args *argp,
 
        /* Obtain client and file */
        if ((resp->status = nlm4svc_retrieve_args(rqstp, argp, &host, &file)))
-               return rpc_success;
+               return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success;
 
 #if 0
        /* If supplied state doesn't match current state, we assume it's
@@ -150,7 +150,7 @@ nlm4svc_proc_lock(struct svc_rqst *rqstp, struct nlm_args *argp,
        return rpc_success;
 }
 
-static int
+static __be32
 nlm4svc_proc_cancel(struct svc_rqst *rqstp, struct nlm_args *argp,
                                           struct nlm_res  *resp)
 {
@@ -169,7 +169,7 @@ nlm4svc_proc_cancel(struct svc_rqst *rqstp, struct nlm_args *argp,
 
        /* Obtain client and file */
        if ((resp->status = nlm4svc_retrieve_args(rqstp, argp, &host, &file)))
-               return rpc_success;
+               return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success;
 
        /* Try to cancel request. */
        resp->status = nlmsvc_cancel_blocked(file, &argp->lock);
@@ -183,7 +183,7 @@ nlm4svc_proc_cancel(struct svc_rqst *rqstp, struct nlm_args *argp,
 /*
  * UNLOCK: release a lock
  */
-static int
+static __be32
 nlm4svc_proc_unlock(struct svc_rqst *rqstp, struct nlm_args *argp,
                                           struct nlm_res  *resp)
 {
@@ -202,7 +202,7 @@ nlm4svc_proc_unlock(struct svc_rqst *rqstp, struct nlm_args *argp,
 
        /* Obtain client and file */
        if ((resp->status = nlm4svc_retrieve_args(rqstp, argp, &host, &file)))
-               return rpc_success;
+               return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success;
 
        /* Now try to remove the lock */
        resp->status = nlmsvc_unlock(file, &argp->lock);
@@ -217,7 +217,7 @@ nlm4svc_proc_unlock(struct svc_rqst *rqstp, struct nlm_args *argp,
  * GRANTED: A server calls us to tell that a process' lock request
  * was granted
  */
-static int
+static __be32
 nlm4svc_proc_granted(struct svc_rqst *rqstp, struct nlm_args *argp,
                                            struct nlm_res  *resp)
 {
@@ -253,12 +253,12 @@ static const struct rpc_call_ops nlm4svc_callback_ops = {
  * because we send the callback before the reply proper. I hope this
  * doesn't break any clients.
  */
-static int nlm4svc_callback(struct svc_rqst *rqstp, u32 proc, struct nlm_args *argp,
-               int (*func)(struct svc_rqst *, struct nlm_args *, struct nlm_res  *))
+static __be32 nlm4svc_callback(struct svc_rqst *rqstp, u32 proc, struct nlm_args *argp,
+               __be32 (*func)(struct svc_rqst *, struct nlm_args *, struct nlm_res  *))
 {
        struct nlm_host *host;
        struct nlm_rqst *call;
-       int stat;
+       __be32 stat;
 
        host = nlmsvc_lookup_host(rqstp,
                                  argp->lock.caller,
@@ -282,35 +282,35 @@ static int nlm4svc_callback(struct svc_rqst *rqstp, u32 proc, struct nlm_args *a
        return rpc_success;
 }
 
-static int nlm4svc_proc_test_msg(struct svc_rqst *rqstp, struct nlm_args *argp,
+static __be32 nlm4svc_proc_test_msg(struct svc_rqst *rqstp, struct nlm_args *argp,
                                             void            *resp)
 {
        dprintk("lockd: TEST_MSG      called\n");
        return nlm4svc_callback(rqstp, NLMPROC_TEST_RES, argp, nlm4svc_proc_test);
 }
 
-static int nlm4svc_proc_lock_msg(struct svc_rqst *rqstp, struct nlm_args *argp,
+static __be32 nlm4svc_proc_lock_msg(struct svc_rqst *rqstp, struct nlm_args *argp,
                                             void            *resp)
 {
        dprintk("lockd: LOCK_MSG      called\n");
        return nlm4svc_callback(rqstp, NLMPROC_LOCK_RES, argp, nlm4svc_proc_lock);
 }
 
-static int nlm4svc_proc_cancel_msg(struct svc_rqst *rqstp, struct nlm_args *argp,
+static __be32 nlm4svc_proc_cancel_msg(struct svc_rqst *rqstp, struct nlm_args *argp,
                                               void            *resp)
 {
        dprintk("lockd: CANCEL_MSG    called\n");
        return nlm4svc_callback(rqstp, NLMPROC_CANCEL_RES, argp, nlm4svc_proc_cancel);
 }
 
-static int nlm4svc_proc_unlock_msg(struct svc_rqst *rqstp, struct nlm_args *argp,
+static __be32 nlm4svc_proc_unlock_msg(struct svc_rqst *rqstp, struct nlm_args *argp,
                                                void            *resp)
 {
        dprintk("lockd: UNLOCK_MSG    called\n");
        return nlm4svc_callback(rqstp, NLMPROC_UNLOCK_RES, argp, nlm4svc_proc_unlock);
 }
 
-static int nlm4svc_proc_granted_msg(struct svc_rqst *rqstp, struct nlm_args *argp,
+static __be32 nlm4svc_proc_granted_msg(struct svc_rqst *rqstp, struct nlm_args *argp,
                                                 void            *resp)
 {
        dprintk("lockd: GRANTED_MSG   called\n");
@@ -320,7 +320,7 @@ static int nlm4svc_proc_granted_msg(struct svc_rqst *rqstp, struct nlm_args *arg
 /*
  * SHARE: create a DOS share or alter existing share.
  */
-static int
+static __be32
 nlm4svc_proc_share(struct svc_rqst *rqstp, struct nlm_args *argp,
                                          struct nlm_res  *resp)
 {
@@ -339,7 +339,7 @@ nlm4svc_proc_share(struct svc_rqst *rqstp, struct nlm_args *argp,
 
        /* Obtain client and file */
        if ((resp->status = nlm4svc_retrieve_args(rqstp, argp, &host, &file)))
-               return rpc_success;
+               return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success;
 
        /* Now try to create the share */
        resp->status = nlmsvc_share_file(host, file, argp);
@@ -353,7 +353,7 @@ nlm4svc_proc_share(struct svc_rqst *rqstp, struct nlm_args *argp,
 /*
  * UNSHARE: Release a DOS share.
  */
-static int
+static __be32
 nlm4svc_proc_unshare(struct svc_rqst *rqstp, struct nlm_args *argp,
                                            struct nlm_res  *resp)
 {
@@ -372,7 +372,7 @@ nlm4svc_proc_unshare(struct svc_rqst *rqstp, struct nlm_args *argp,
 
        /* Obtain client and file */
        if ((resp->status = nlm4svc_retrieve_args(rqstp, argp, &host, &file)))
-               return rpc_success;
+               return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success;
 
        /* Now try to lock the file */
        resp->status = nlmsvc_unshare_file(host, file, argp);
@@ -386,7 +386,7 @@ nlm4svc_proc_unshare(struct svc_rqst *rqstp, struct nlm_args *argp,
 /*
  * NM_LOCK: Create an unmonitored lock
  */
-static int
+static __be32
 nlm4svc_proc_nm_lock(struct svc_rqst *rqstp, struct nlm_args *argp,
                                            struct nlm_res  *resp)
 {
@@ -399,7 +399,7 @@ nlm4svc_proc_nm_lock(struct svc_rqst *rqstp, struct nlm_args *argp,
 /*
  * FREE_ALL: Release all locks and shares held by client
  */
-static int
+static __be32
 nlm4svc_proc_free_all(struct svc_rqst *rqstp, struct nlm_args *argp,
                                             void            *resp)
 {
@@ -417,7 +417,7 @@ nlm4svc_proc_free_all(struct svc_rqst *rqstp, struct nlm_args *argp,
 /*
  * SM_NOTIFY: private callback from statd (not part of official NLM proto)
  */
-static int
+static __be32
 nlm4svc_proc_sm_notify(struct svc_rqst *rqstp, struct nlm_reboot *argp,
                                              void              *resp)
 {
@@ -446,7 +446,7 @@ nlm4svc_proc_sm_notify(struct svc_rqst *rqstp, struct nlm_reboot *argp,
 /*
  * client sent a GRANTED_RES, let's remove the associated block
  */
-static int
+static __be32
 nlm4svc_proc_granted_res(struct svc_rqst *rqstp, struct nlm_res  *argp,
                                                 void            *resp)
 {
index 814c6064c9e0514fef4a712a2f1be156afb7fb25..7e219b93855274dd053551b6c2c09b6f747b464d 100644 (file)
@@ -334,13 +334,13 @@ static void nlmsvc_freegrantargs(struct nlm_rqst *call)
  * Attempt to establish a lock, and if it can't be granted, block it
  * if required.
  */
-u32
+__be32
 nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file,
                        struct nlm_lock *lock, int wait, struct nlm_cookie *cookie)
 {
        struct nlm_block        *block, *newblock = NULL;
        int                     error;
-       u32                     ret;
+       __be32                  ret;
 
        dprintk("lockd: nlmsvc_lock(%s/%ld, ty=%d, pi=%d, %Ld-%Ld, bl=%d)\n",
                                file->f_file->f_dentry->d_inode->i_sb->s_id,
@@ -415,7 +415,7 @@ out:
 /*
  * Test for presence of a conflicting lock.
  */
-u32
+__be32
 nlmsvc_testlock(struct nlm_file *file, struct nlm_lock *lock,
                                       struct nlm_lock *conflock)
 {
@@ -448,7 +448,7 @@ nlmsvc_testlock(struct nlm_file *file, struct nlm_lock *lock,
  * afterwards. In this case the block will still be there, and hence
  * must be removed.
  */
-u32
+__be32
 nlmsvc_unlock(struct nlm_file *file, struct nlm_lock *lock)
 {
        int     error;
@@ -476,7 +476,7 @@ nlmsvc_unlock(struct nlm_file *file, struct nlm_lock *lock)
  * be in progress.
  * The calling procedure must check whether the file can be closed.
  */
-u32
+__be32
 nlmsvc_cancel_blocked(struct nlm_file *file, struct nlm_lock *lock)
 {
        struct nlm_block        *block;
index 75b2c81bcb93c01782710b7a36fc501aea42ca9a..32e99a6e8dcad6c20964d63d3dcb5d460423b495 100644 (file)
@@ -22,8 +22,8 @@
 #define NLMDBG_FACILITY                NLMDBG_CLIENT
 
 #ifdef CONFIG_LOCKD_V4
-static u32
-cast_to_nlm(u32 status, u32 vers)
+static __be32
+cast_to_nlm(__be32 status, u32 vers)
 {
        /* Note: status is assumed to be in network byte order !!! */
        if (vers != 4){
@@ -52,14 +52,14 @@ cast_to_nlm(u32 status, u32 vers)
 /*
  * Obtain client and file from arguments
  */
-static u32
+static __be32
 nlmsvc_retrieve_args(struct svc_rqst *rqstp, struct nlm_args *argp,
                        struct nlm_host **hostp, struct nlm_file **filp)
 {
        struct nlm_host         *host = NULL;
        struct nlm_file         *file = NULL;
        struct nlm_lock         *lock = &argp->lock;
-       u32                     error;
+       __be32                  error = 0;
 
        /* nfsd callbacks must have been installed for this procedure */
        if (!nlmsvc_ops)
@@ -88,13 +88,15 @@ nlmsvc_retrieve_args(struct svc_rqst *rqstp, struct nlm_args *argp,
 no_locks:
        if (host)
                nlm_release_host(host);
+       if (error)
+               return error;
        return nlm_lck_denied_nolocks;
 }
 
 /*
  * NULL: Test for presence of service
  */
-static int
+static __be32
 nlmsvc_proc_null(struct svc_rqst *rqstp, void *argp, void *resp)
 {
        dprintk("lockd: NULL          called\n");
@@ -104,7 +106,7 @@ nlmsvc_proc_null(struct svc_rqst *rqstp, void *argp, void *resp)
 /*
  * TEST: Check for conflicting lock
  */
-static int
+static __be32
 nlmsvc_proc_test(struct svc_rqst *rqstp, struct nlm_args *argp,
                                         struct nlm_res  *resp)
 {
@@ -122,7 +124,7 @@ nlmsvc_proc_test(struct svc_rqst *rqstp, struct nlm_args *argp,
 
        /* Obtain client and file */
        if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file)))
-               return rpc_success;
+               return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success;
 
        /* Now check for conflicting locks */
        resp->status = cast_status(nlmsvc_testlock(file, &argp->lock, &resp->lock));
@@ -134,7 +136,7 @@ nlmsvc_proc_test(struct svc_rqst *rqstp, struct nlm_args *argp,
        return rpc_success;
 }
 
-static int
+static __be32
 nlmsvc_proc_lock(struct svc_rqst *rqstp, struct nlm_args *argp,
                                         struct nlm_res  *resp)
 {
@@ -153,7 +155,7 @@ nlmsvc_proc_lock(struct svc_rqst *rqstp, struct nlm_args *argp,
 
        /* Obtain client and file */
        if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file)))
-               return rpc_success;
+               return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success;
 
 #if 0
        /* If supplied state doesn't match current state, we assume it's
@@ -177,7 +179,7 @@ nlmsvc_proc_lock(struct svc_rqst *rqstp, struct nlm_args *argp,
        return rpc_success;
 }
 
-static int
+static __be32
 nlmsvc_proc_cancel(struct svc_rqst *rqstp, struct nlm_args *argp,
                                           struct nlm_res  *resp)
 {
@@ -196,7 +198,7 @@ nlmsvc_proc_cancel(struct svc_rqst *rqstp, struct nlm_args *argp,
 
        /* Obtain client and file */
        if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file)))
-               return rpc_success;
+               return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success;
 
        /* Try to cancel request. */
        resp->status = cast_status(nlmsvc_cancel_blocked(file, &argp->lock));
@@ -210,7 +212,7 @@ nlmsvc_proc_cancel(struct svc_rqst *rqstp, struct nlm_args *argp,
 /*
  * UNLOCK: release a lock
  */
-static int
+static __be32
 nlmsvc_proc_unlock(struct svc_rqst *rqstp, struct nlm_args *argp,
                                           struct nlm_res  *resp)
 {
@@ -229,7 +231,7 @@ nlmsvc_proc_unlock(struct svc_rqst *rqstp, struct nlm_args *argp,
 
        /* Obtain client and file */
        if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file)))
-               return rpc_success;
+               return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success;
 
        /* Now try to remove the lock */
        resp->status = cast_status(nlmsvc_unlock(file, &argp->lock));
@@ -244,7 +246,7 @@ nlmsvc_proc_unlock(struct svc_rqst *rqstp, struct nlm_args *argp,
  * GRANTED: A server calls us to tell that a process' lock request
  * was granted
  */
-static int
+static __be32
 nlmsvc_proc_granted(struct svc_rqst *rqstp, struct nlm_args *argp,
                                            struct nlm_res  *resp)
 {
@@ -280,12 +282,12 @@ static const struct rpc_call_ops nlmsvc_callback_ops = {
  * because we send the callback before the reply proper. I hope this
  * doesn't break any clients.
  */
-static int nlmsvc_callback(struct svc_rqst *rqstp, u32 proc, struct nlm_args *argp,
-               int (*func)(struct svc_rqst *, struct nlm_args *, struct nlm_res  *))
+static __be32 nlmsvc_callback(struct svc_rqst *rqstp, u32 proc, struct nlm_args *argp,
+               __be32 (*func)(struct svc_rqst *, struct nlm_args *, struct nlm_res  *))
 {
        struct nlm_host *host;
        struct nlm_rqst *call;
-       int stat;
+       __be32 stat;
 
        host = nlmsvc_lookup_host(rqstp,
                                  argp->lock.caller,
@@ -309,28 +311,28 @@ static int nlmsvc_callback(struct svc_rqst *rqstp, u32 proc, struct nlm_args *ar
        return rpc_success;
 }
 
-static int nlmsvc_proc_test_msg(struct svc_rqst *rqstp, struct nlm_args *argp,
+static __be32 nlmsvc_proc_test_msg(struct svc_rqst *rqstp, struct nlm_args *argp,
                                             void            *resp)
 {
        dprintk("lockd: TEST_MSG      called\n");
        return nlmsvc_callback(rqstp, NLMPROC_TEST_RES, argp, nlmsvc_proc_test);
 }
 
-static int nlmsvc_proc_lock_msg(struct svc_rqst *rqstp, struct nlm_args *argp,
+static __be32 nlmsvc_proc_lock_msg(struct svc_rqst *rqstp, struct nlm_args *argp,
                                             void            *resp)
 {
        dprintk("lockd: LOCK_MSG      called\n");
        return nlmsvc_callback(rqstp, NLMPROC_LOCK_RES, argp, nlmsvc_proc_lock);
 }
 
-static int nlmsvc_proc_cancel_msg(struct svc_rqst *rqstp, struct nlm_args *argp,
+static __be32 nlmsvc_proc_cancel_msg(struct svc_rqst *rqstp, struct nlm_args *argp,
                                               void            *resp)
 {
        dprintk("lockd: CANCEL_MSG    called\n");
        return nlmsvc_callback(rqstp, NLMPROC_CANCEL_RES, argp, nlmsvc_proc_cancel);
 }
 
-static int
+static __be32
 nlmsvc_proc_unlock_msg(struct svc_rqst *rqstp, struct nlm_args *argp,
                                                void            *resp)
 {
@@ -338,7 +340,7 @@ nlmsvc_proc_unlock_msg(struct svc_rqst *rqstp, struct nlm_args *argp,
        return nlmsvc_callback(rqstp, NLMPROC_UNLOCK_RES, argp, nlmsvc_proc_unlock);
 }
 
-static int
+static __be32
 nlmsvc_proc_granted_msg(struct svc_rqst *rqstp, struct nlm_args *argp,
                                                 void            *resp)
 {
@@ -349,7 +351,7 @@ nlmsvc_proc_granted_msg(struct svc_rqst *rqstp, struct nlm_args *argp,
 /*
  * SHARE: create a DOS share or alter existing share.
  */
-static int
+static __be32
 nlmsvc_proc_share(struct svc_rqst *rqstp, struct nlm_args *argp,
                                          struct nlm_res  *resp)
 {
@@ -368,7 +370,7 @@ nlmsvc_proc_share(struct svc_rqst *rqstp, struct nlm_args *argp,
 
        /* Obtain client and file */
        if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file)))
-               return rpc_success;
+               return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success;
 
        /* Now try to create the share */
        resp->status = cast_status(nlmsvc_share_file(host, file, argp));
@@ -382,7 +384,7 @@ nlmsvc_proc_share(struct svc_rqst *rqstp, struct nlm_args *argp,
 /*
  * UNSHARE: Release a DOS share.
  */
-static int
+static __be32
 nlmsvc_proc_unshare(struct svc_rqst *rqstp, struct nlm_args *argp,
                                            struct nlm_res  *resp)
 {
@@ -401,7 +403,7 @@ nlmsvc_proc_unshare(struct svc_rqst *rqstp, struct nlm_args *argp,
 
        /* Obtain client and file */
        if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file)))
-               return rpc_success;
+               return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success;
 
        /* Now try to unshare the file */
        resp->status = cast_status(nlmsvc_unshare_file(host, file, argp));
@@ -415,7 +417,7 @@ nlmsvc_proc_unshare(struct svc_rqst *rqstp, struct nlm_args *argp,
 /*
  * NM_LOCK: Create an unmonitored lock
  */
-static int
+static __be32
 nlmsvc_proc_nm_lock(struct svc_rqst *rqstp, struct nlm_args *argp,
                                            struct nlm_res  *resp)
 {
@@ -428,7 +430,7 @@ nlmsvc_proc_nm_lock(struct svc_rqst *rqstp, struct nlm_args *argp,
 /*
  * FREE_ALL: Release all locks and shares held by client
  */
-static int
+static __be32
 nlmsvc_proc_free_all(struct svc_rqst *rqstp, struct nlm_args *argp,
                                             void            *resp)
 {
@@ -446,7 +448,7 @@ nlmsvc_proc_free_all(struct svc_rqst *rqstp, struct nlm_args *argp,
 /*
  * SM_NOTIFY: private callback from statd (not part of official NLM proto)
  */
-static int
+static __be32
 nlmsvc_proc_sm_notify(struct svc_rqst *rqstp, struct nlm_reboot *argp,
                                              void              *resp)
 {
@@ -475,7 +477,7 @@ nlmsvc_proc_sm_notify(struct svc_rqst *rqstp, struct nlm_reboot *argp,
 /*
  * client sent a GRANTED_RES, let's remove the associated block
  */
-static int
+static __be32
 nlmsvc_proc_granted_res(struct svc_rqst *rqstp, struct nlm_res  *argp,
                                                 void            *resp)
 {
index b9926ce8782e86b7782ab752e61474af35806cca..6220dc2a3f2c246e31817902a674648321fd6873 100644 (file)
@@ -23,7 +23,7 @@ nlm_cmp_owner(struct nlm_share *share, struct xdr_netobj *oh)
            && !memcmp(share->s_owner.data, oh->data, oh->len);
 }
 
-u32
+__be32
 nlmsvc_share_file(struct nlm_host *host, struct nlm_file *file,
                        struct nlm_args *argp)
 {
@@ -64,7 +64,7 @@ update:
 /*
  * Delete a share.
  */
-u32
+__be32
 nlmsvc_unshare_file(struct nlm_host *host, struct nlm_file *file,
                        struct nlm_args *argp)
 {
index 514f5f20701ea3d3cc8ba0410dd8fd3098e71c87..e83024e16042b57c9c13fc8d64f15573b7168416 100644 (file)
@@ -78,14 +78,14 @@ static inline unsigned int file_hash(struct nfs_fh *f)
  * This is not quite right, but for now, we assume the client performs
  * the proper R/W checking.
  */
-u32
+__be32
 nlm_lookup_file(struct svc_rqst *rqstp, struct nlm_file **result,
                                        struct nfs_fh *f)
 {
        struct hlist_node *pos;
        struct nlm_file *file;
        unsigned int    hash;
-       u32             nfserr;
+       __be32          nfserr;
 
        nlm_debug_print_fh("nlm_file_lookup", f);
 
@@ -135,12 +135,6 @@ out_unlock:
 
 out_free:
        kfree(file);
-#ifdef CONFIG_LOCKD_V4
-       if (nfserr == 1)
-               nfserr = nlm4_stale_fh;
-       else
-#endif
-       nfserr = nlm_lck_denied;
        goto out_unlock;
 }
 
@@ -324,7 +318,16 @@ nlmsvc_same_host(struct nlm_host *host, struct nlm_host *other)
 static int
 nlmsvc_is_client(struct nlm_host *host, struct nlm_host *dummy)
 {
-       return host->h_server;
+       if (host->h_server) {
+               /* we are destroying locks even though the client
+                * hasn't asked us too, so don't unmonitor the
+                * client
+                */
+               if (host->h_nsmhandle)
+                       host->h_nsmhandle->sm_sticky = 1;
+               return 1;
+       } else
+               return 0;
 }
 
 /*
index 61c46facf257413f21ca462a9466e402265df906..b7c949256e5a3c2b88d7cc74f673462b4ec9be70 100644 (file)
@@ -43,7 +43,7 @@ loff_t_to_s32(loff_t offset)
 /*
  * XDR functions for basic NLM types
  */
-static u32 *nlm_decode_cookie(u32 *p, struct nlm_cookie *c)
+static __be32 *nlm_decode_cookie(__be32 *p, struct nlm_cookie *c)
 {
        unsigned int    len;
 
@@ -69,8 +69,8 @@ static u32 *nlm_decode_cookie(u32 *p, struct nlm_cookie *c)
        return p;
 }
 
-static inline u32 *
-nlm_encode_cookie(u32 *p, struct nlm_cookie *c)
+static inline __be32 *
+nlm_encode_cookie(__be32 *p, struct nlm_cookie *c)
 {
        *p++ = htonl(c->len);
        memcpy(p, c->data, c->len);
@@ -78,8 +78,8 @@ nlm_encode_cookie(u32 *p, struct nlm_cookie *c)
        return p;
 }
 
-static u32 *
-nlm_decode_fh(u32 *p, struct nfs_fh *f)
+static __be32 *
+nlm_decode_fh(__be32 *p, struct nfs_fh *f)
 {
        unsigned int    len;
 
@@ -95,8 +95,8 @@ nlm_decode_fh(u32 *p, struct nfs_fh *f)
        return p + XDR_QUADLEN(NFS2_FHSIZE);
 }
 
-static inline u32 *
-nlm_encode_fh(u32 *p, struct nfs_fh *f)
+static inline __be32 *
+nlm_encode_fh(__be32 *p, struct nfs_fh *f)
 {
        *p++ = htonl(NFS2_FHSIZE);
        memcpy(p, f->data, NFS2_FHSIZE);
@@ -106,20 +106,20 @@ nlm_encode_fh(u32 *p, struct nfs_fh *f)
 /*
  * Encode and decode owner handle
  */
-static inline u32 *
-nlm_decode_oh(u32 *p, struct xdr_netobj *oh)
+static inline __be32 *
+nlm_decode_oh(__be32 *p, struct xdr_netobj *oh)
 {
        return xdr_decode_netobj(p, oh);
 }
 
-static inline u32 *
-nlm_encode_oh(u32 *p, struct xdr_netobj *oh)
+static inline __be32 *
+nlm_encode_oh(__be32 *p, struct xdr_netobj *oh)
 {
        return xdr_encode_netobj(p, oh);
 }
 
-static u32 *
-nlm_decode_lock(u32 *p, struct nlm_lock *lock)
+static __be32 *
+nlm_decode_lock(__be32 *p, struct nlm_lock *lock)
 {
        struct file_lock        *fl = &lock->fl;
        s32                     start, len, end;
@@ -153,8 +153,8 @@ nlm_decode_lock(u32 *p, struct nlm_lock *lock)
 /*
  * Encode a lock as part of an NLM call
  */
-static u32 *
-nlm_encode_lock(u32 *p, struct nlm_lock *lock)
+static __be32 *
+nlm_encode_lock(__be32 *p, struct nlm_lock *lock)
 {
        struct file_lock        *fl = &lock->fl;
        __s32                   start, len;
@@ -184,8 +184,8 @@ nlm_encode_lock(u32 *p, struct nlm_lock *lock)
 /*
  * Encode result of a TEST/TEST_MSG call
  */
-static u32 *
-nlm_encode_testres(u32 *p, struct nlm_res *resp)
+static __be32 *
+nlm_encode_testres(__be32 *p, struct nlm_res *resp)
 {
        s32             start, len;
 
@@ -221,7 +221,7 @@ nlm_encode_testres(u32 *p, struct nlm_res *resp)
  * First, the server side XDR functions
  */
 int
-nlmsvc_decode_testargs(struct svc_rqst *rqstp, u32 *p, nlm_args *argp)
+nlmsvc_decode_testargs(struct svc_rqst *rqstp, __be32 *p, nlm_args *argp)
 {
        u32     exclusive;
 
@@ -238,7 +238,7 @@ nlmsvc_decode_testargs(struct svc_rqst *rqstp, u32 *p, nlm_args *argp)
 }
 
 int
-nlmsvc_encode_testres(struct svc_rqst *rqstp, u32 *p, struct nlm_res *resp)
+nlmsvc_encode_testres(struct svc_rqst *rqstp, __be32 *p, struct nlm_res *resp)
 {
        if (!(p = nlm_encode_testres(p, resp)))
                return 0;
@@ -246,7 +246,7 @@ nlmsvc_encode_testres(struct svc_rqst *rqstp, u32 *p, struct nlm_res *resp)
 }
 
 int
-nlmsvc_decode_lockargs(struct svc_rqst *rqstp, u32 *p, nlm_args *argp)
+nlmsvc_decode_lockargs(struct svc_rqst *rqstp, __be32 *p, nlm_args *argp)
 {
        u32     exclusive;
 
@@ -266,7 +266,7 @@ nlmsvc_decode_lockargs(struct svc_rqst *rqstp, u32 *p, nlm_args *argp)
 }
 
 int
-nlmsvc_decode_cancargs(struct svc_rqst *rqstp, u32 *p, nlm_args *argp)
+nlmsvc_decode_cancargs(struct svc_rqst *rqstp, __be32 *p, nlm_args *argp)
 {
        u32     exclusive;
 
@@ -282,7 +282,7 @@ nlmsvc_decode_cancargs(struct svc_rqst *rqstp, u32 *p, nlm_args *argp)
 }
 
 int
-nlmsvc_decode_unlockargs(struct svc_rqst *rqstp, u32 *p, nlm_args *argp)
+nlmsvc_decode_unlockargs(struct svc_rqst *rqstp, __be32 *p, nlm_args *argp)
 {
        if (!(p = nlm_decode_cookie(p, &argp->cookie))
         || !(p = nlm_decode_lock(p, &argp->lock)))
@@ -292,7 +292,7 @@ nlmsvc_decode_unlockargs(struct svc_rqst *rqstp, u32 *p, nlm_args *argp)
 }
 
 int
-nlmsvc_decode_shareargs(struct svc_rqst *rqstp, u32 *p, nlm_args *argp)
+nlmsvc_decode_shareargs(struct svc_rqst *rqstp, __be32 *p, nlm_args *argp)
 {
        struct nlm_lock *lock = &argp->lock;
 
@@ -313,7 +313,7 @@ nlmsvc_decode_shareargs(struct svc_rqst *rqstp, u32 *p, nlm_args *argp)
 }
 
 int
-nlmsvc_encode_shareres(struct svc_rqst *rqstp, u32 *p, struct nlm_res *resp)
+nlmsvc_encode_shareres(struct svc_rqst *rqstp, __be32 *p, struct nlm_res *resp)
 {
        if (!(p = nlm_encode_cookie(p, &resp->cookie)))
                return 0;
@@ -323,7 +323,7 @@ nlmsvc_encode_shareres(struct svc_rqst *rqstp, u32 *p, struct nlm_res *resp)
 }
 
 int
-nlmsvc_encode_res(struct svc_rqst *rqstp, u32 *p, struct nlm_res *resp)
+nlmsvc_encode_res(struct svc_rqst *rqstp, __be32 *p, struct nlm_res *resp)
 {
        if (!(p = nlm_encode_cookie(p, &resp->cookie)))
                return 0;
@@ -332,7 +332,7 @@ nlmsvc_encode_res(struct svc_rqst *rqstp, u32 *p, struct nlm_res *resp)
 }
 
 int
-nlmsvc_decode_notify(struct svc_rqst *rqstp, u32 *p, struct nlm_args *argp)
+nlmsvc_decode_notify(struct svc_rqst *rqstp, __be32 *p, struct nlm_args *argp)
 {
        struct nlm_lock *lock = &argp->lock;
 
@@ -344,7 +344,7 @@ nlmsvc_decode_notify(struct svc_rqst *rqstp, u32 *p, struct nlm_args *argp)
 }
 
 int
-nlmsvc_decode_reboot(struct svc_rqst *rqstp, u32 *p, struct nlm_reboot *argp)
+nlmsvc_decode_reboot(struct svc_rqst *rqstp, __be32 *p, struct nlm_reboot *argp)
 {
        if (!(p = xdr_decode_string_inplace(p, &argp->mon, &argp->len, SM_MAXSTRLEN)))
                return 0;
@@ -357,7 +357,7 @@ nlmsvc_decode_reboot(struct svc_rqst *rqstp, u32 *p, struct nlm_reboot *argp)
 }
 
 int
-nlmsvc_decode_res(struct svc_rqst *rqstp, u32 *p, struct nlm_res *resp)
+nlmsvc_decode_res(struct svc_rqst *rqstp, __be32 *p, struct nlm_res *resp)
 {
        if (!(p = nlm_decode_cookie(p, &resp->cookie)))
                return 0;
@@ -366,13 +366,13 @@ nlmsvc_decode_res(struct svc_rqst *rqstp, u32 *p, struct nlm_res *resp)
 }
 
 int
-nlmsvc_decode_void(struct svc_rqst *rqstp, u32 *p, void *dummy)
+nlmsvc_decode_void(struct svc_rqst *rqstp, __be32 *p, void *dummy)
 {
        return xdr_argsize_check(rqstp, p);
 }
 
 int
-nlmsvc_encode_void(struct svc_rqst *rqstp, u32 *p, void *dummy)
+nlmsvc_encode_void(struct svc_rqst *rqstp, __be32 *p, void *dummy)
 {
        return xdr_ressize_check(rqstp, p);
 }
@@ -389,7 +389,7 @@ nlmclt_decode_void(struct rpc_rqst *req, u32 *p, void *ptr)
 #endif
 
 static int
-nlmclt_encode_testargs(struct rpc_rqst *req, u32 *p, nlm_args *argp)
+nlmclt_encode_testargs(struct rpc_rqst *req, __be32 *p, nlm_args *argp)
 {
        struct nlm_lock *lock = &argp->lock;
 
@@ -403,7 +403,7 @@ nlmclt_encode_testargs(struct rpc_rqst *req, u32 *p, nlm_args *argp)
 }
 
 static int
-nlmclt_decode_testres(struct rpc_rqst *req, u32 *p, struct nlm_res *resp)
+nlmclt_decode_testres(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp)
 {
        if (!(p = nlm_decode_cookie(p, &resp->cookie)))
                return -EIO;
@@ -438,7 +438,7 @@ nlmclt_decode_testres(struct rpc_rqst *req, u32 *p, struct nlm_res *resp)
 
 
 static int
-nlmclt_encode_lockargs(struct rpc_rqst *req, u32 *p, nlm_args *argp)
+nlmclt_encode_lockargs(struct rpc_rqst *req, __be32 *p, nlm_args *argp)
 {
        struct nlm_lock *lock = &argp->lock;
 
@@ -455,7 +455,7 @@ nlmclt_encode_lockargs(struct rpc_rqst *req, u32 *p, nlm_args *argp)
 }
 
 static int
-nlmclt_encode_cancargs(struct rpc_rqst *req, u32 *p, nlm_args *argp)
+nlmclt_encode_cancargs(struct rpc_rqst *req, __be32 *p, nlm_args *argp)
 {
        struct nlm_lock *lock = &argp->lock;
 
@@ -470,7 +470,7 @@ nlmclt_encode_cancargs(struct rpc_rqst *req, u32 *p, nlm_args *argp)
 }
 
 static int
-nlmclt_encode_unlockargs(struct rpc_rqst *req, u32 *p, nlm_args *argp)
+nlmclt_encode_unlockargs(struct rpc_rqst *req, __be32 *p, nlm_args *argp)
 {
        struct nlm_lock *lock = &argp->lock;
 
@@ -483,7 +483,7 @@ nlmclt_encode_unlockargs(struct rpc_rqst *req, u32 *p, nlm_args *argp)
 }
 
 static int
-nlmclt_encode_res(struct rpc_rqst *req, u32 *p, struct nlm_res *resp)
+nlmclt_encode_res(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp)
 {
        if (!(p = nlm_encode_cookie(p, &resp->cookie)))
                return -EIO;
@@ -493,7 +493,7 @@ nlmclt_encode_res(struct rpc_rqst *req, u32 *p, struct nlm_res *resp)
 }
 
 static int
-nlmclt_encode_testres(struct rpc_rqst *req, u32 *p, struct nlm_res *resp)
+nlmclt_encode_testres(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp)
 {
        if (!(p = nlm_encode_testres(p, resp)))
                return -EIO;
@@ -502,7 +502,7 @@ nlmclt_encode_testres(struct rpc_rqst *req, u32 *p, struct nlm_res *resp)
 }
 
 static int
-nlmclt_decode_res(struct rpc_rqst *req, u32 *p, struct nlm_res *resp)
+nlmclt_decode_res(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp)
 {
        if (!(p = nlm_decode_cookie(p, &resp->cookie)))
                return -EIO;
index 36eb175ec3356c23b4d9bab42ffe23945266904f..f4c0b2b9f75a7e87d778981d001efdf5e158fecd 100644 (file)
@@ -44,8 +44,8 @@ loff_t_to_s64(loff_t offset)
 /*
  * XDR functions for basic NLM types
  */
-static u32 *
-nlm4_decode_cookie(u32 *p, struct nlm_cookie *c)
+static __be32 *
+nlm4_decode_cookie(__be32 *p, struct nlm_cookie *c)
 {
        unsigned int    len;
 
@@ -71,8 +71,8 @@ nlm4_decode_cookie(u32 *p, struct nlm_cookie *c)
        return p;
 }
 
-static u32 *
-nlm4_encode_cookie(u32 *p, struct nlm_cookie *c)
+static __be32 *
+nlm4_encode_cookie(__be32 *p, struct nlm_cookie *c)
 {
        *p++ = htonl(c->len);
        memcpy(p, c->data, c->len);
@@ -80,8 +80,8 @@ nlm4_encode_cookie(u32 *p, struct nlm_cookie *c)
        return p;
 }
 
-static u32 *
-nlm4_decode_fh(u32 *p, struct nfs_fh *f)
+static __be32 *
+nlm4_decode_fh(__be32 *p, struct nfs_fh *f)
 {
        memset(f->data, 0, sizeof(f->data));
        f->size = ntohl(*p++);
@@ -95,8 +95,8 @@ nlm4_decode_fh(u32 *p, struct nfs_fh *f)
        return p + XDR_QUADLEN(f->size);
 }
 
-static u32 *
-nlm4_encode_fh(u32 *p, struct nfs_fh *f)
+static __be32 *
+nlm4_encode_fh(__be32 *p, struct nfs_fh *f)
 {
        *p++ = htonl(f->size);
        if (f->size) p[XDR_QUADLEN(f->size)-1] = 0; /* don't leak anything */
@@ -107,20 +107,20 @@ nlm4_encode_fh(u32 *p, struct nfs_fh *f)
 /*
  * Encode and decode owner handle
  */
-static u32 *
-nlm4_decode_oh(u32 *p, struct xdr_netobj *oh)
+static __be32 *
+nlm4_decode_oh(__be32 *p, struct xdr_netobj *oh)
 {
        return xdr_decode_netobj(p, oh);
 }
 
-static u32 *
-nlm4_encode_oh(u32 *p, struct xdr_netobj *oh)
+static __be32 *
+nlm4_encode_oh(__be32 *p, struct xdr_netobj *oh)
 {
        return xdr_encode_netobj(p, oh);
 }
 
-static u32 *
-nlm4_decode_lock(u32 *p, struct nlm_lock *lock)
+static __be32 *
+nlm4_decode_lock(__be32 *p, struct nlm_lock *lock)
 {
        struct file_lock        *fl = &lock->fl;
        __s64                   len, start, end;
@@ -153,8 +153,8 @@ nlm4_decode_lock(u32 *p, struct nlm_lock *lock)
 /*
  * Encode a lock as part of an NLM call
  */
-static u32 *
-nlm4_encode_lock(u32 *p, struct nlm_lock *lock)
+static __be32 *
+nlm4_encode_lock(__be32 *p, struct nlm_lock *lock)
 {
        struct file_lock        *fl = &lock->fl;
        __s64                   start, len;
@@ -185,8 +185,8 @@ nlm4_encode_lock(u32 *p, struct nlm_lock *lock)
 /*
  * Encode result of a TEST/TEST_MSG call
  */
-static u32 *
-nlm4_encode_testres(u32 *p, struct nlm_res *resp)
+static __be32 *
+nlm4_encode_testres(__be32 *p, struct nlm_res *resp)
 {
        s64             start, len;
 
@@ -227,7 +227,7 @@ nlm4_encode_testres(u32 *p, struct nlm_res *resp)
  * First, the server side XDR functions
  */
 int
-nlm4svc_decode_testargs(struct svc_rqst *rqstp, u32 *p, nlm_args *argp)
+nlm4svc_decode_testargs(struct svc_rqst *rqstp, __be32 *p, nlm_args *argp)
 {
        u32     exclusive;
 
@@ -244,7 +244,7 @@ nlm4svc_decode_testargs(struct svc_rqst *rqstp, u32 *p, nlm_args *argp)
 }
 
 int
-nlm4svc_encode_testres(struct svc_rqst *rqstp, u32 *p, struct nlm_res *resp)
+nlm4svc_encode_testres(struct svc_rqst *rqstp, __be32 *p, struct nlm_res *resp)
 {
        if (!(p = nlm4_encode_testres(p, resp)))
                return 0;
@@ -252,7 +252,7 @@ nlm4svc_encode_testres(struct svc_rqst *rqstp, u32 *p, struct nlm_res *resp)
 }
 
 int
-nlm4svc_decode_lockargs(struct svc_rqst *rqstp, u32 *p, nlm_args *argp)
+nlm4svc_decode_lockargs(struct svc_rqst *rqstp, __be32 *p, nlm_args *argp)
 {
        u32     exclusive;
 
@@ -272,7 +272,7 @@ nlm4svc_decode_lockargs(struct svc_rqst *rqstp, u32 *p, nlm_args *argp)
 }
 
 int
-nlm4svc_decode_cancargs(struct svc_rqst *rqstp, u32 *p, nlm_args *argp)
+nlm4svc_decode_cancargs(struct svc_rqst *rqstp, __be32 *p, nlm_args *argp)
 {
        u32     exclusive;
 
@@ -288,7 +288,7 @@ nlm4svc_decode_cancargs(struct svc_rqst *rqstp, u32 *p, nlm_args *argp)
 }
 
 int
-nlm4svc_decode_unlockargs(struct svc_rqst *rqstp, u32 *p, nlm_args *argp)
+nlm4svc_decode_unlockargs(struct svc_rqst *rqstp, __be32 *p, nlm_args *argp)
 {
        if (!(p = nlm4_decode_cookie(p, &argp->cookie))
         || !(p = nlm4_decode_lock(p, &argp->lock)))
@@ -298,7 +298,7 @@ nlm4svc_decode_unlockargs(struct svc_rqst *rqstp, u32 *p, nlm_args *argp)
 }
 
 int
-nlm4svc_decode_shareargs(struct svc_rqst *rqstp, u32 *p, nlm_args *argp)
+nlm4svc_decode_shareargs(struct svc_rqst *rqstp, __be32 *p, nlm_args *argp)
 {
        struct nlm_lock *lock = &argp->lock;
 
@@ -319,7 +319,7 @@ nlm4svc_decode_shareargs(struct svc_rqst *rqstp, u32 *p, nlm_args *argp)
 }
 
 int
-nlm4svc_encode_shareres(struct svc_rqst *rqstp, u32 *p, struct nlm_res *resp)
+nlm4svc_encode_shareres(struct svc_rqst *rqstp, __be32 *p, struct nlm_res *resp)
 {
        if (!(p = nlm4_encode_cookie(p, &resp->cookie)))
                return 0;
@@ -329,7 +329,7 @@ nlm4svc_encode_shareres(struct svc_rqst *rqstp, u32 *p, struct nlm_res *resp)
 }
 
 int
-nlm4svc_encode_res(struct svc_rqst *rqstp, u32 *p, struct nlm_res *resp)
+nlm4svc_encode_res(struct svc_rqst *rqstp, __be32 *p, struct nlm_res *resp)
 {
        if (!(p = nlm4_encode_cookie(p, &resp->cookie)))
                return 0;
@@ -338,7 +338,7 @@ nlm4svc_encode_res(struct svc_rqst *rqstp, u32 *p, struct nlm_res *resp)
 }
 
 int
-nlm4svc_decode_notify(struct svc_rqst *rqstp, u32 *p, struct nlm_args *argp)
+nlm4svc_decode_notify(struct svc_rqst *rqstp, __be32 *p, struct nlm_args *argp)
 {
        struct nlm_lock *lock = &argp->lock;
 
@@ -350,7 +350,7 @@ nlm4svc_decode_notify(struct svc_rqst *rqstp, u32 *p, struct nlm_args *argp)
 }
 
 int
-nlm4svc_decode_reboot(struct svc_rqst *rqstp, u32 *p, struct nlm_reboot *argp)
+nlm4svc_decode_reboot(struct svc_rqst *rqstp, __be32 *p, struct nlm_reboot *argp)
 {
        if (!(p = xdr_decode_string_inplace(p, &argp->mon, &argp->len, SM_MAXSTRLEN)))
                return 0;
@@ -363,7 +363,7 @@ nlm4svc_decode_reboot(struct svc_rqst *rqstp, u32 *p, struct nlm_reboot *argp)
 }
 
 int
-nlm4svc_decode_res(struct svc_rqst *rqstp, u32 *p, struct nlm_res *resp)
+nlm4svc_decode_res(struct svc_rqst *rqstp, __be32 *p, struct nlm_res *resp)
 {
        if (!(p = nlm4_decode_cookie(p, &resp->cookie)))
                return 0;
@@ -372,13 +372,13 @@ nlm4svc_decode_res(struct svc_rqst *rqstp, u32 *p, struct nlm_res *resp)
 }
 
 int
-nlm4svc_decode_void(struct svc_rqst *rqstp, u32 *p, void *dummy)
+nlm4svc_decode_void(struct svc_rqst *rqstp, __be32 *p, void *dummy)
 {
        return xdr_argsize_check(rqstp, p);
 }
 
 int
-nlm4svc_encode_void(struct svc_rqst *rqstp, u32 *p, void *dummy)
+nlm4svc_encode_void(struct svc_rqst *rqstp, __be32 *p, void *dummy)
 {
        return xdr_ressize_check(rqstp, p);
 }
@@ -388,14 +388,14 @@ nlm4svc_encode_void(struct svc_rqst *rqstp, u32 *p, void *dummy)
  */
 #ifdef NLMCLNT_SUPPORT_SHARES
 static int
-nlm4clt_decode_void(struct rpc_rqst *req, u32 *p, void *ptr)
+nlm4clt_decode_void(struct rpc_rqst *req, __be32 *p, void *ptr)
 {
        return 0;
 }
 #endif
 
 static int
-nlm4clt_encode_testargs(struct rpc_rqst *req, u32 *p, nlm_args *argp)
+nlm4clt_encode_testargs(struct rpc_rqst *req, __be32 *p, nlm_args *argp)
 {
        struct nlm_lock *lock = &argp->lock;
 
@@ -409,7 +409,7 @@ nlm4clt_encode_testargs(struct rpc_rqst *req, u32 *p, nlm_args *argp)
 }
 
 static int
-nlm4clt_decode_testres(struct rpc_rqst *req, u32 *p, struct nlm_res *resp)
+nlm4clt_decode_testres(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp)
 {
        if (!(p = nlm4_decode_cookie(p, &resp->cookie)))
                return -EIO;
@@ -444,7 +444,7 @@ nlm4clt_decode_testres(struct rpc_rqst *req, u32 *p, struct nlm_res *resp)
 
 
 static int
-nlm4clt_encode_lockargs(struct rpc_rqst *req, u32 *p, nlm_args *argp)
+nlm4clt_encode_lockargs(struct rpc_rqst *req, __be32 *p, nlm_args *argp)
 {
        struct nlm_lock *lock = &argp->lock;
 
@@ -461,7 +461,7 @@ nlm4clt_encode_lockargs(struct rpc_rqst *req, u32 *p, nlm_args *argp)
 }
 
 static int
-nlm4clt_encode_cancargs(struct rpc_rqst *req, u32 *p, nlm_args *argp)
+nlm4clt_encode_cancargs(struct rpc_rqst *req, __be32 *p, nlm_args *argp)
 {
        struct nlm_lock *lock = &argp->lock;
 
@@ -476,7 +476,7 @@ nlm4clt_encode_cancargs(struct rpc_rqst *req, u32 *p, nlm_args *argp)
 }
 
 static int
-nlm4clt_encode_unlockargs(struct rpc_rqst *req, u32 *p, nlm_args *argp)
+nlm4clt_encode_unlockargs(struct rpc_rqst *req, __be32 *p, nlm_args *argp)
 {
        struct nlm_lock *lock = &argp->lock;
 
@@ -489,7 +489,7 @@ nlm4clt_encode_unlockargs(struct rpc_rqst *req, u32 *p, nlm_args *argp)
 }
 
 static int
-nlm4clt_encode_res(struct rpc_rqst *req, u32 *p, struct nlm_res *resp)
+nlm4clt_encode_res(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp)
 {
        if (!(p = nlm4_encode_cookie(p, &resp->cookie)))
                return -EIO;
@@ -499,7 +499,7 @@ nlm4clt_encode_res(struct rpc_rqst *req, u32 *p, struct nlm_res *resp)
 }
 
 static int
-nlm4clt_encode_testres(struct rpc_rqst *req, u32 *p, struct nlm_res *resp)
+nlm4clt_encode_testres(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp)
 {
        if (!(p = nlm4_encode_testres(p, resp)))
                return -EIO;
@@ -508,7 +508,7 @@ nlm4clt_encode_testres(struct rpc_rqst *req, u32 *p, struct nlm_res *resp)
 }
 
 static int
-nlm4clt_decode_res(struct rpc_rqst *req, u32 *p, struct nlm_res *resp)
+nlm4clt_decode_res(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp)
 {
        if (!(p = nlm4_decode_cookie(p, &resp->cookie)))
                return -EIO;
index c11a4b9fb863c5e10ae342b5637dd1ddd4dc1145..1e36bae4d0eb1a4d8a8b17140c3216fad2d5c81b 100644 (file)
@@ -149,12 +149,8 @@ static int minix_fill_super(struct super_block *s, void *data, int silent)
                return -ENOMEM;
        s->s_fs_info = sbi;
 
-       /* N.B. These should be compile-time tests.
-          Unfortunately that is impossible. */
-       if (32 != sizeof (struct minix_inode))
-               panic("bad V1 i-node size");
-       if (64 != sizeof(struct minix2_inode))
-               panic("bad V2 i-node size");
+       BUILD_BUG_ON(32 != sizeof (struct minix_inode));
+       BUILD_BUG_ON(64 != sizeof(struct minix2_inode));
 
        if (!sb_set_blocksize(s, BLOCK_SIZE))
                goto out_bad_hblock;
index a89ac84a8241a53d4e260deda2ad7d7f8c675255..589d1eac55c1c97499d8b1a13626dde1b869f3f5 100644 (file)
@@ -726,7 +726,7 @@ outrel:
                                struct compat_ncp_privatedata_ioctl user32;
                                user32.len = user.len;
                                user32.data = (unsigned long) user.data;
-                               if (copy_to_user(&user32, argp, sizeof(user32)))
+                               if (copy_to_user(argp, &user32, sizeof(user32)))
                                        return -EFAULT;
                        } else
 #endif
index 5676163d26e819c45e13617337916186e4335290..db3d7919c60131886f4272a77fd9d330d547de98 100644 (file)
@@ -31,10 +31,10 @@ struct cb_compound_hdr_arg {
 };
 
 struct cb_compound_hdr_res {
-       uint32_t *status;
+       __be32 *status;
        int taglen;
        const char *tag;
-       uint32_t *nops;
+       __be32 *nops;
 };
 
 struct cb_getattrargs {
@@ -44,7 +44,7 @@ struct cb_getattrargs {
 };
 
 struct cb_getattrres {
-       uint32_t status;
+       __be32 status;
        uint32_t bitmap[2];
        uint64_t size;
        uint64_t change_attr;
@@ -59,8 +59,8 @@ struct cb_recallargs {
        uint32_t truncate;
 };
 
-extern unsigned nfs4_callback_getattr(struct cb_getattrargs *args, struct cb_getattrres *res);
-extern unsigned nfs4_callback_recall(struct cb_recallargs *args, void *dummy);
+extern __be32 nfs4_callback_getattr(struct cb_getattrargs *args, struct cb_getattrres *res);
+extern __be32 nfs4_callback_recall(struct cb_recallargs *args, void *dummy);
 
 #ifdef CONFIG_NFS_V4
 extern int nfs_callback_up(void);
index 97cf8f71451ffbbd02e85d2d4c4061ee73dfb75a..72e55d83756d9b6d6b5e82a28040b58b0375cf9c 100644 (file)
@@ -14,7 +14,7 @@
 
 #define NFSDBG_FACILITY NFSDBG_CALLBACK
  
-unsigned nfs4_callback_getattr(struct cb_getattrargs *args, struct cb_getattrres *res)
+__be32 nfs4_callback_getattr(struct cb_getattrargs *args, struct cb_getattrres *res)
 {
        struct nfs_client *clp;
        struct nfs_delegation *delegation;
@@ -55,11 +55,11 @@ out:
        return res->status;
 }
 
-unsigned nfs4_callback_recall(struct cb_recallargs *args, void *dummy)
+__be32 nfs4_callback_recall(struct cb_recallargs *args, void *dummy)
 {
        struct nfs_client *clp;
        struct inode *inode;
-       unsigned res;
+       __be32 res;
        
        res = htonl(NFS4ERR_BADHANDLE);
        clp = nfs_find_client(args->addr, 4);
index 29f932192054004c6b0859fdacf89c530cab5a60..f8ea1f51f59094ad69ac7ec684884f5a05df7312 100644 (file)
@@ -22,9 +22,9 @@
 
 #define NFSDBG_FACILITY NFSDBG_CALLBACK
 
-typedef unsigned (*callback_process_op_t)(void *, void *);
-typedef unsigned (*callback_decode_arg_t)(struct svc_rqst *, struct xdr_stream *, void *);
-typedef unsigned (*callback_encode_res_t)(struct svc_rqst *, struct xdr_stream *, void *);
+typedef __be32 (*callback_process_op_t)(void *, void *);
+typedef __be32 (*callback_decode_arg_t)(struct svc_rqst *, struct xdr_stream *, void *);
+typedef __be32 (*callback_encode_res_t)(struct svc_rqst *, struct xdr_stream *, void *);
 
 
 struct callback_op {
@@ -36,24 +36,24 @@ struct callback_op {
 
 static struct callback_op callback_ops[];
 
-static int nfs4_callback_null(struct svc_rqst *rqstp, void *argp, void *resp)
+static __be32 nfs4_callback_null(struct svc_rqst *rqstp, void *argp, void *resp)
 {
        return htonl(NFS4_OK);
 }
 
-static int nfs4_decode_void(struct svc_rqst *rqstp, uint32_t *p, void *dummy)
+static int nfs4_decode_void(struct svc_rqst *rqstp, __be32 *p, void *dummy)
 {
        return xdr_argsize_check(rqstp, p);
 }
 
-static int nfs4_encode_void(struct svc_rqst *rqstp, uint32_t *p, void *dummy)
+static int nfs4_encode_void(struct svc_rqst *rqstp, __be32 *p, void *dummy)
 {
        return xdr_ressize_check(rqstp, p);
 }
 
-static uint32_t *read_buf(struct xdr_stream *xdr, int nbytes)
+static __be32 *read_buf(struct xdr_stream *xdr, int nbytes)
 {
-       uint32_t *p;
+       __be32 *p;
 
        p = xdr_inline_decode(xdr, nbytes);
        if (unlikely(p == NULL))
@@ -61,9 +61,9 @@ static uint32_t *read_buf(struct xdr_stream *xdr, int nbytes)
        return p;
 }
 
-static unsigned decode_string(struct xdr_stream *xdr, unsigned int *len, const char **str)
+static __be32 decode_string(struct xdr_stream *xdr, unsigned int *len, const char **str)
 {
-       uint32_t *p;
+       __be32 *p;
 
        p = read_buf(xdr, 4);
        if (unlikely(p == NULL))
@@ -81,9 +81,9 @@ static unsigned decode_string(struct xdr_stream *xdr, unsigned int *len, const c
        return 0;
 }
 
-static unsigned decode_fh(struct xdr_stream *xdr, struct nfs_fh *fh)
+static __be32 decode_fh(struct xdr_stream *xdr, struct nfs_fh *fh)
 {
-       uint32_t *p;
+       __be32 *p;
 
        p = read_buf(xdr, 4);
        if (unlikely(p == NULL))
@@ -99,9 +99,9 @@ static unsigned decode_fh(struct xdr_stream *xdr, struct nfs_fh *fh)
        return 0;
 }
 
-static unsigned decode_bitmap(struct xdr_stream *xdr, uint32_t *bitmap)
+static __be32 decode_bitmap(struct xdr_stream *xdr, uint32_t *bitmap)
 {
-       uint32_t *p;
+       __be32 *p;
        unsigned int attrlen;
 
        p = read_buf(xdr, 4);
@@ -118,9 +118,9 @@ static unsigned decode_bitmap(struct xdr_stream *xdr, uint32_t *bitmap)
        return 0;
 }
 
-static unsigned decode_stateid(struct xdr_stream *xdr, nfs4_stateid *stateid)
+static __be32 decode_stateid(struct xdr_stream *xdr, nfs4_stateid *stateid)
 {
-       uint32_t *p;
+       __be32 *p;
 
        p = read_buf(xdr, 16);
        if (unlikely(p == NULL))
@@ -129,11 +129,11 @@ static unsigned decode_stateid(struct xdr_stream *xdr, nfs4_stateid *stateid)
        return 0;
 }
 
-static unsigned decode_compound_hdr_arg(struct xdr_stream *xdr, struct cb_compound_hdr_arg *hdr)
+static __be32 decode_compound_hdr_arg(struct xdr_stream *xdr, struct cb_compound_hdr_arg *hdr)
 {
-       uint32_t *p;
+       __be32 *p;
        unsigned int minor_version;
-       unsigned status;
+       __be32 status;
 
        status = decode_string(xdr, &hdr->taglen, &hdr->tag);
        if (unlikely(status != 0))
@@ -159,9 +159,9 @@ static unsigned decode_compound_hdr_arg(struct xdr_stream *xdr, struct cb_compou
        return 0;
 }
 
-static unsigned decode_op_hdr(struct xdr_stream *xdr, unsigned int *op)
+static __be32 decode_op_hdr(struct xdr_stream *xdr, unsigned int *op)
 {
-       uint32_t *p;
+       __be32 *p;
        p = read_buf(xdr, 4);
        if (unlikely(p == NULL))
                return htonl(NFS4ERR_RESOURCE);
@@ -169,9 +169,9 @@ static unsigned decode_op_hdr(struct xdr_stream *xdr, unsigned int *op)
        return 0;
 }
 
-static unsigned decode_getattr_args(struct svc_rqst *rqstp, struct xdr_stream *xdr, struct cb_getattrargs *args)
+static __be32 decode_getattr_args(struct svc_rqst *rqstp, struct xdr_stream *xdr, struct cb_getattrargs *args)
 {
-       unsigned status;
+       __be32 status;
 
        status = decode_fh(xdr, &args->fh);
        if (unlikely(status != 0))
@@ -183,10 +183,10 @@ out:
        return status;
 }
 
-static unsigned decode_recall_args(struct svc_rqst *rqstp, struct xdr_stream *xdr, struct cb_recallargs *args)
+static __be32 decode_recall_args(struct svc_rqst *rqstp, struct xdr_stream *xdr, struct cb_recallargs *args)
 {
-       uint32_t *p;
-       unsigned status;
+       __be32 *p;
+       __be32 status;
 
        args->addr = &rqstp->rq_addr;
        status = decode_stateid(xdr, &args->stateid);
@@ -204,9 +204,9 @@ out:
        return status;
 }
 
-static unsigned encode_string(struct xdr_stream *xdr, unsigned int len, const char *str)
+static __be32 encode_string(struct xdr_stream *xdr, unsigned int len, const char *str)
 {
-       uint32_t *p;
+       __be32 *p;
 
        p = xdr_reserve_space(xdr, 4 + len);
        if (unlikely(p == NULL))
@@ -217,10 +217,10 @@ static unsigned encode_string(struct xdr_stream *xdr, unsigned int len, const ch
 
 #define CB_SUPPORTED_ATTR0 (FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE)
 #define CB_SUPPORTED_ATTR1 (FATTR4_WORD1_TIME_METADATA|FATTR4_WORD1_TIME_MODIFY)
-static unsigned encode_attr_bitmap(struct xdr_stream *xdr, const uint32_t *bitmap, uint32_t **savep)
+static __be32 encode_attr_bitmap(struct xdr_stream *xdr, const uint32_t *bitmap, __be32 **savep)
 {
-       uint32_t bm[2];
-       uint32_t *p;
+       __be32 bm[2];
+       __be32 *p;
 
        bm[0] = htonl(bitmap[0] & CB_SUPPORTED_ATTR0);
        bm[1] = htonl(bitmap[1] & CB_SUPPORTED_ATTR1);
@@ -247,9 +247,9 @@ static unsigned encode_attr_bitmap(struct xdr_stream *xdr, const uint32_t *bitma
        return 0;
 }
 
-static unsigned encode_attr_change(struct xdr_stream *xdr, const uint32_t *bitmap, uint64_t change)
+static __be32 encode_attr_change(struct xdr_stream *xdr, const uint32_t *bitmap, uint64_t change)
 {
-       uint32_t *p;
+       __be32 *p;
 
        if (!(bitmap[0] & FATTR4_WORD0_CHANGE))
                return 0;
@@ -260,9 +260,9 @@ static unsigned encode_attr_change(struct xdr_stream *xdr, const uint32_t *bitma
        return 0;
 }
 
-static unsigned encode_attr_size(struct xdr_stream *xdr, const uint32_t *bitmap, uint64_t size)
+static __be32 encode_attr_size(struct xdr_stream *xdr, const uint32_t *bitmap, uint64_t size)
 {
-       uint32_t *p;
+       __be32 *p;
 
        if (!(bitmap[0] & FATTR4_WORD0_SIZE))
                return 0;
@@ -273,9 +273,9 @@ static unsigned encode_attr_size(struct xdr_stream *xdr, const uint32_t *bitmap,
        return 0;
 }
 
-static unsigned encode_attr_time(struct xdr_stream *xdr, const struct timespec *time)
+static __be32 encode_attr_time(struct xdr_stream *xdr, const struct timespec *time)
 {
-       uint32_t *p;
+       __be32 *p;
 
        p = xdr_reserve_space(xdr, 12);
        if (unlikely(p == 0))
@@ -285,23 +285,23 @@ static unsigned encode_attr_time(struct xdr_stream *xdr, const struct timespec *
        return 0;
 }
 
-static unsigned encode_attr_ctime(struct xdr_stream *xdr, const uint32_t *bitmap, const struct timespec *time)
+static __be32 encode_attr_ctime(struct xdr_stream *xdr, const uint32_t *bitmap, const struct timespec *time)
 {
        if (!(bitmap[1] & FATTR4_WORD1_TIME_METADATA))
                return 0;
        return encode_attr_time(xdr,time);
 }
 
-static unsigned encode_attr_mtime(struct xdr_stream *xdr, const uint32_t *bitmap, const struct timespec *time)
+static __be32 encode_attr_mtime(struct xdr_stream *xdr, const uint32_t *bitmap, const struct timespec *time)
 {
        if (!(bitmap[1] & FATTR4_WORD1_TIME_MODIFY))
                return 0;
        return encode_attr_time(xdr,time);
 }
 
-static unsigned encode_compound_hdr_res(struct xdr_stream *xdr, struct cb_compound_hdr_res *hdr)
+static __be32 encode_compound_hdr_res(struct xdr_stream *xdr, struct cb_compound_hdr_res *hdr)
 {
-       unsigned status;
+       __be32 status;
 
        hdr->status = xdr_reserve_space(xdr, 4);
        if (unlikely(hdr->status == NULL))
@@ -315,9 +315,9 @@ static unsigned encode_compound_hdr_res(struct xdr_stream *xdr, struct cb_compou
        return 0;
 }
 
-static unsigned encode_op_hdr(struct xdr_stream *xdr, uint32_t op, uint32_t res)
+static __be32 encode_op_hdr(struct xdr_stream *xdr, uint32_t op, __be32 res)
 {
-       uint32_t *p;
+       __be32 *p;
        
        p = xdr_reserve_space(xdr, 8);
        if (unlikely(p == NULL))
@@ -327,10 +327,10 @@ static unsigned encode_op_hdr(struct xdr_stream *xdr, uint32_t op, uint32_t res)
        return 0;
 }
 
-static unsigned encode_getattr_res(struct svc_rqst *rqstp, struct xdr_stream *xdr, const struct cb_getattrres *res)
+static __be32 encode_getattr_res(struct svc_rqst *rqstp, struct xdr_stream *xdr, const struct cb_getattrres *res)
 {
-       uint32_t *savep = NULL;
-       unsigned status = res->status;
+       __be32 *savep = NULL;
+       __be32 status = res->status;
        
        if (unlikely(status != 0))
                goto out;
@@ -353,15 +353,15 @@ out:
        return status;
 }
 
-static unsigned process_op(struct svc_rqst *rqstp,
+static __be32 process_op(struct svc_rqst *rqstp,
                struct xdr_stream *xdr_in, void *argp,
                struct xdr_stream *xdr_out, void *resp)
 {
        struct callback_op *op = &callback_ops[0];
        unsigned int op_nr = OP_CB_ILLEGAL;
-       unsigned int status = 0;
+       __be32 status = 0;
        long maxlen;
-       unsigned res;
+       __be32 res;
 
        dprintk("%s: start\n", __FUNCTION__);
        status = decode_op_hdr(xdr_in, &op_nr);
@@ -399,20 +399,20 @@ static unsigned process_op(struct svc_rqst *rqstp,
 /*
  * Decode, process and encode a COMPOUND
  */
-static int nfs4_callback_compound(struct svc_rqst *rqstp, void *argp, void *resp)
+static __be32 nfs4_callback_compound(struct svc_rqst *rqstp, void *argp, void *resp)
 {
        struct cb_compound_hdr_arg hdr_arg;
        struct cb_compound_hdr_res hdr_res;
        struct xdr_stream xdr_in, xdr_out;
-       uint32_t *p;
-       unsigned int status;
+       __be32 *p;
+       __be32 status;
        unsigned int nops = 1;
 
        dprintk("%s: start\n", __FUNCTION__);
 
        xdr_init_decode(&xdr_in, &rqstp->rq_arg, rqstp->rq_arg.head[0].iov_base);
 
-       p = (uint32_t*)((char *)rqstp->rq_res.head[0].iov_base + rqstp->rq_res.head[0].iov_len);
+       p = (__be32*)((char *)rqstp->rq_res.head[0].iov_base + rqstp->rq_res.head[0].iov_len);
        xdr_init_encode(&xdr_out, &rqstp->rq_res, p);
 
        decode_compound_hdr_arg(&xdr_in, &hdr_arg);
index 6e4e48c5092afec39d716309ccccd5900105d4e3..5fea638743e4107aadcd8cbd18cd46d78e331cf0 100644 (file)
@@ -232,11 +232,15 @@ void nfs_put_client(struct nfs_client *clp)
  * Find a client by address
  * - caller must hold nfs_client_lock
  */
-static struct nfs_client *__nfs_find_client(const struct sockaddr_in *addr, int nfsversion)
+static struct nfs_client *__nfs_find_client(const struct sockaddr_in *addr, int nfsversion, int match_port)
 {
        struct nfs_client *clp;
 
        list_for_each_entry(clp, &nfs_client_list, cl_share_link) {
+               /* Don't match clients that failed to initialise properly */
+               if (clp->cl_cons_state < 0)
+                       continue;
+
                /* Different NFS versions cannot share the same nfs_client */
                if (clp->cl_nfsversion != nfsversion)
                        continue;
@@ -245,7 +249,7 @@ static struct nfs_client *__nfs_find_client(const struct sockaddr_in *addr, int
                           sizeof(clp->cl_addr.sin_addr)) != 0)
                        continue;
 
-               if (clp->cl_addr.sin_port == addr->sin_port)
+               if (!match_port || clp->cl_addr.sin_port == addr->sin_port)
                        goto found;
        }
 
@@ -265,11 +269,12 @@ struct nfs_client *nfs_find_client(const struct sockaddr_in *addr, int nfsversio
        struct nfs_client *clp;
 
        spin_lock(&nfs_client_lock);
-       clp = __nfs_find_client(addr, nfsversion);
+       clp = __nfs_find_client(addr, nfsversion, 0);
        spin_unlock(&nfs_client_lock);
-
-       BUG_ON(clp && clp->cl_cons_state == 0);
-
+       if (clp != NULL && clp->cl_cons_state != NFS_CS_READY) {
+               nfs_put_client(clp);
+               clp = NULL;
+       }
        return clp;
 }
 
@@ -292,7 +297,7 @@ static struct nfs_client *nfs_get_client(const char *hostname,
        do {
                spin_lock(&nfs_client_lock);
 
-               clp = __nfs_find_client(addr, nfsversion);
+               clp = __nfs_find_client(addr, nfsversion, 1);
                if (clp)
                        goto found_client;
                if (new)
@@ -322,25 +327,11 @@ found_client:
        if (new)
                nfs_free_client(new);
 
-       if (clp->cl_cons_state == NFS_CS_INITING) {
-               DECLARE_WAITQUEUE(myself, current);
-
-               add_wait_queue(&nfs_client_active_wq, &myself);
-
-               for (;;) {
-                       set_current_state(TASK_INTERRUPTIBLE);
-                       if (signal_pending(current) ||
-                           clp->cl_cons_state > NFS_CS_READY)
-                               break;
-                       schedule();
-               }
-
-               remove_wait_queue(&nfs_client_active_wq, &myself);
-
-               if (signal_pending(current)) {
-                       nfs_put_client(clp);
-                       return ERR_PTR(-ERESTARTSYS);
-               }
+       error = wait_event_interruptible(nfs_client_active_wq,
+                               clp->cl_cons_state != NFS_CS_INITING);
+       if (error < 0) {
+               nfs_put_client(clp);
+               return ERR_PTR(-ERESTARTSYS);
        }
 
        if (clp->cl_cons_state < NFS_CS_READY) {
@@ -863,6 +854,7 @@ error:
  */
 static int nfs4_init_client(struct nfs_client *clp,
                int proto, int timeo, int retrans,
+               const char *ip_addr,
                rpc_authflavor_t authflavour)
 {
        int error;
@@ -879,6 +871,7 @@ static int nfs4_init_client(struct nfs_client *clp,
        error = nfs_create_rpc_client(clp, proto, timeo, retrans, authflavour);
        if (error < 0)
                goto error;
+       memcpy(clp->cl_ipaddr, ip_addr, sizeof(clp->cl_ipaddr));
 
        error = nfs_idmap_new(clp);
        if (error < 0) {
@@ -902,6 +895,7 @@ error:
  */
 static int nfs4_set_client(struct nfs_server *server,
                const char *hostname, const struct sockaddr_in *addr,
+               const char *ip_addr,
                rpc_authflavor_t authflavour,
                int proto, int timeo, int retrans)
 {
@@ -916,7 +910,7 @@ static int nfs4_set_client(struct nfs_server *server,
                error = PTR_ERR(clp);
                goto error;
        }
-       error = nfs4_init_client(clp, proto, timeo, retrans, authflavour);
+       error = nfs4_init_client(clp, proto, timeo, retrans, ip_addr, authflavour);
        if (error < 0)
                goto error_put;
 
@@ -985,7 +979,7 @@ struct nfs_server *nfs4_create_server(const struct nfs4_mount_data *data,
                return ERR_PTR(-ENOMEM);
 
        /* Get a client record */
-       error = nfs4_set_client(server, hostname, addr, authflavour,
+       error = nfs4_set_client(server, hostname, addr, ip_addr, authflavour,
                        data->proto, data->timeo, data->retrans);
        if (error < 0)
                goto error;
@@ -1055,6 +1049,7 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data,
        /* Get a client representation.
         * Note: NFSv4 always uses TCP, */
        error = nfs4_set_client(server, data->hostname, data->addr,
+                       parent_client->cl_ipaddr,
                        data->authflavor,
                        parent_server->client->cl_xprt->prot,
                        parent_client->retrans_timeo,
index 481f8892a919489cb5705269834b0145b0d5c8f1..b34cd16f472fef71c798c0470f98cbb33f6ea10c 100644 (file)
@@ -142,12 +142,12 @@ nfs_opendir(struct inode *inode, struct file *filp)
        return res;
 }
 
-typedef u32 * (*decode_dirent_t)(u32 *, struct nfs_entry *, int);
+typedef __be32 * (*decode_dirent_t)(__be32 *, struct nfs_entry *, int);
 typedef struct {
        struct file     *file;
        struct page     *page;
        unsigned long   page_index;
-       u32             *ptr;
+       __be32          *ptr;
        u64             *dir_cookie;
        loff_t          current_index;
        struct nfs_entry *entry;
@@ -203,8 +203,10 @@ int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page *page)
         * Note: assumes we have exclusive access to this mapping either
         *       through inode->i_mutex or some other mechanism.
         */
-       if (page->index == 0)
-               invalidate_inode_pages2_range(inode->i_mapping, PAGE_CACHE_SIZE, -1);
+       if (page->index == 0 && invalidate_inode_pages2_range(inode->i_mapping, PAGE_CACHE_SIZE, -1) < 0) {
+               /* Should never happen */
+               nfs_zap_mapping(inode, inode->i_mapping);
+       }
        unlock_page(page);
        return 0;
  error:
@@ -218,7 +220,7 @@ int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page *page)
 static inline
 int dir_decode(nfs_readdir_descriptor_t *desc)
 {
-       u32     *p = desc->ptr;
+       __be32  *p = desc->ptr;
        p = desc->decode(p, desc->entry, desc->plus);
        if (IS_ERR(p))
                return PTR_ERR(p);
@@ -933,8 +935,17 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, stru
 
 no_entry:
        res = d_materialise_unique(dentry, inode);
-       if (res != NULL)
+       if (res != NULL) {
+               struct dentry *parent;
+               if (IS_ERR(res))
+                       goto out_unlock;
+               /* Was a directory renamed! */
+               parent = dget_parent(res);
+               if (!IS_ROOT(parent))
+                       nfs_mark_for_revalidate(parent->d_inode);
+               dput(parent);
                dentry = res;
+       }
        nfs_renew_times(dentry);
        nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
 out_unlock:
@@ -1130,6 +1141,8 @@ static struct dentry *nfs_readdir_lookup(nfs_readdir_descriptor_t *desc)
        alias = d_materialise_unique(dentry, inode);
        if (alias != NULL) {
                dput(dentry);
+               if (IS_ERR(alias))
+                       return NULL;
                dentry = alias;
        }
 
@@ -1517,8 +1530,8 @@ static int nfs_symlink(struct inode *dir, struct dentry *dentry, const char *sym
        pagevec_init(&lru_pvec, 0);
        if (!add_to_page_cache(page, dentry->d_inode->i_mapping, 0,
                                                        GFP_KERNEL)) {
-               if (!pagevec_add(&lru_pvec, page))
-                       __pagevec_lru_add(&lru_pvec);
+               pagevec_add(&lru_pvec, page);
+               pagevec_lru_add(&lru_pvec);
                SetPageUptodate(page);
                unlock_page(page);
        } else
index 9f7f8b9ea1e253b2e9614a658a7186720a5a80b1..bdfabf854a519af44ae5f07e83ee64e3e0089c6a 100644 (file)
@@ -497,6 +497,7 @@ static void nfs_direct_write_complete(struct nfs_direct_req *dreq, struct inode
                        if (dreq->commit_data != NULL)
                                nfs_commit_free(dreq->commit_data);
                        nfs_direct_free_writedata(dreq);
+                       nfs_zap_mapping(inode, inode->i_mapping);
                        nfs_direct_complete(dreq);
        }
 }
@@ -517,6 +518,7 @@ static void nfs_direct_write_complete(struct nfs_direct_req *dreq, struct inode
 {
        nfs_end_data_update(inode);
        nfs_direct_free_writedata(dreq);
+       nfs_zap_mapping(inode, inode->i_mapping);
        nfs_direct_complete(dreq);
 }
 #endif
@@ -532,10 +534,12 @@ static void nfs_direct_write_result(struct rpc_task *task, void *calldata)
 
        spin_lock(&dreq->lock);
 
-       if (likely(status >= 0))
-               dreq->count += data->res.count;
-       else
-               dreq->error = task->tk_status;
+       if (unlikely(status < 0)) {
+               dreq->error = status;
+               goto out_unlock;
+       }
+
+       dreq->count += data->res.count;
 
        if (data->res.verf->committed != NFS_FILE_SYNC) {
                switch (dreq->flags) {
@@ -550,7 +554,7 @@ static void nfs_direct_write_result(struct rpc_task *task, void *calldata)
                                }
                }
        }
-
+out_unlock:
        spin_unlock(&dreq->lock);
 }
 
@@ -828,17 +832,6 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, const struct iovec *iov,
 
        retval = nfs_direct_write(iocb, (unsigned long) buf, count, pos);
 
-       /*
-        * XXX: nfs_end_data_update() already ensures this file's
-        *      cached data is subsequently invalidated.  Do we really
-        *      need to call invalidate_inode_pages2() again here?
-        *
-        *      For aio writes, this invalidation will almost certainly
-        *      occur before the writes complete.  Kind of racey.
-        */
-       if (mapping->nrpages)
-               invalidate_inode_pages2(mapping);
-
        if (retval > 0)
                iocb->ki_pos = pos + retval;
 
index bc9376ca86cd28ea645ea38b889ac455faf0b141..08cc4c5919abee92f1f28b411e1154c627ff15d3 100644 (file)
@@ -131,6 +131,15 @@ void nfs_zap_caches(struct inode *inode)
        spin_unlock(&inode->i_lock);
 }
 
+void nfs_zap_mapping(struct inode *inode, struct address_space *mapping)
+{
+       if (mapping->nrpages != 0) {
+               spin_lock(&inode->i_lock);
+               NFS_I(inode)->cache_validity |= NFS_INO_INVALID_DATA;
+               spin_unlock(&inode->i_lock);
+       }
+}
+
 static void nfs_zap_acl_cache(struct inode *inode)
 {
        void (*clear_acl_cache)(struct inode *);
@@ -574,7 +583,7 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
 
        nfs_inc_stats(inode, NFSIOS_INODEREVALIDATE);
        lock_kernel();
-       if (!inode || is_bad_inode(inode))
+       if (is_bad_inode(inode))
                goto out_nowait;
        if (NFS_STALE(inode))
                goto out_nowait;
@@ -671,13 +680,20 @@ int nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping)
        if ((nfsi->cache_validity & NFS_INO_REVAL_PAGECACHE)
                        || nfs_attribute_timeout(inode))
                ret = __nfs_revalidate_inode(NFS_SERVER(inode), inode);
+       if (ret < 0)
+               goto out;
 
        if (nfsi->cache_validity & NFS_INO_INVALID_DATA) {
-               nfs_inc_stats(inode, NFSIOS_DATAINVALIDATE);
-               if (S_ISREG(inode->i_mode))
-                       nfs_sync_mapping(mapping);
-               invalidate_inode_pages2(mapping);
-
+               if (mapping->nrpages != 0) {
+                       if (S_ISREG(inode->i_mode)) {
+                               ret = nfs_sync_mapping(mapping);
+                               if (ret < 0)
+                                       goto out;
+                       }
+                       ret = invalidate_inode_pages2(mapping);
+                       if (ret < 0)
+                               goto out;
+               }
                spin_lock(&inode->i_lock);
                nfsi->cache_validity &= ~NFS_INO_INVALID_DATA;
                if (S_ISDIR(inode->i_mode)) {
@@ -687,10 +703,12 @@ int nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping)
                }
                spin_unlock(&inode->i_lock);
 
+               nfs_inc_stats(inode, NFSIOS_DATAINVALIDATE);
                dfprintk(PAGECACHE, "NFS: (%s/%Ld) data cache invalidated\n",
                                inode->i_sb->s_id,
                                (long long)NFS_FILEID(inode));
        }
+out:
        return ret;
 }
 
index bea0b016bd709de15e7c2658df4fb5e9338ef1d3..d205466233f67f932460d51f124cade1bec0a516 100644 (file)
@@ -93,15 +93,15 @@ extern void nfs_destroy_directcache(void);
 /* nfs2xdr.c */
 extern int nfs_stat_to_errno(int);
 extern struct rpc_procinfo nfs_procedures[];
-extern u32 * nfs_decode_dirent(u32 *, struct nfs_entry *, int);
+extern __be32 * nfs_decode_dirent(__be32 *, struct nfs_entry *, int);
 
 /* nfs3xdr.c */
 extern struct rpc_procinfo nfs3_procedures[];
-extern u32 *nfs3_decode_dirent(u32 *, struct nfs_entry *, int);
+extern __be32 *nfs3_decode_dirent(__be32 *, struct nfs_entry *, int);
 
 /* nfs4xdr.c */
 #ifdef CONFIG_NFS_V4
-extern u32 *nfs4_decode_dirent(u32 *p, struct nfs_entry *entry, int plus);
+extern __be32 *nfs4_decode_dirent(__be32 *p, struct nfs_entry *entry, int plus);
 #endif
 
 /* nfs4proc.c */
index d507b021207fd5ea63fc2fe15ae0474bdb5179c8..f75fe72b4160b7bdfbae6631d87c3bca8e63d496 100644 (file)
@@ -95,7 +95,7 @@ mnt_create(char *hostname, struct sockaddr_in *srvaddr, int version,
  * XDR encode/decode functions for MOUNT
  */
 static int
-xdr_encode_dirpath(struct rpc_rqst *req, u32 *p, const char *path)
+xdr_encode_dirpath(struct rpc_rqst *req, __be32 *p, const char *path)
 {
        p = xdr_encode_string(p, path);
 
@@ -104,7 +104,7 @@ xdr_encode_dirpath(struct rpc_rqst *req, u32 *p, const char *path)
 }
 
 static int
-xdr_decode_fhstatus(struct rpc_rqst *req, u32 *p, struct mnt_fhstatus *res)
+xdr_decode_fhstatus(struct rpc_rqst *req, __be32 *p, struct mnt_fhstatus *res)
 {
        struct nfs_fh *fh = res->fh;
 
@@ -116,7 +116,7 @@ xdr_decode_fhstatus(struct rpc_rqst *req, u32 *p, struct mnt_fhstatus *res)
 }
 
 static int
-xdr_decode_fhstatus3(struct rpc_rqst *req, u32 *p, struct mnt_fhstatus *res)
+xdr_decode_fhstatus3(struct rpc_rqst *req, __be32 *p, struct mnt_fhstatus *res)
 {
        struct nfs_fh *fh = res->fh;
 
index b49501fc0a7985927d87d0d69042ec2995c7dc3b..3be4e72a0227e71030709b019dd35db28897a34e 100644 (file)
 /*
  * Common NFS XDR functions as inlines
  */
-static inline u32 *
-xdr_encode_fhandle(u32 *p, struct nfs_fh *fhandle)
+static inline __be32 *
+xdr_encode_fhandle(__be32 *p, struct nfs_fh *fhandle)
 {
        memcpy(p, fhandle->data, NFS2_FHSIZE);
        return p + XDR_QUADLEN(NFS2_FHSIZE);
 }
 
-static inline u32 *
-xdr_decode_fhandle(u32 *p, struct nfs_fh *fhandle)
+static inline __be32 *
+xdr_decode_fhandle(__be32 *p, struct nfs_fh *fhandle)
 {
        /* NFSv2 handles have a fixed length */
        fhandle->size = NFS2_FHSIZE;
@@ -82,8 +82,8 @@ xdr_decode_fhandle(u32 *p, struct nfs_fh *fhandle)
        return p + XDR_QUADLEN(NFS2_FHSIZE);
 }
 
-static inline u32*
-xdr_encode_time(u32 *p, struct timespec *timep)
+static inline __be32*
+xdr_encode_time(__be32 *p, struct timespec *timep)
 {
        *p++ = htonl(timep->tv_sec);
        /* Convert nanoseconds into microseconds */
@@ -91,8 +91,8 @@ xdr_encode_time(u32 *p, struct timespec *timep)
        return p;
 }
 
-static inline u32*
-xdr_encode_current_server_time(u32 *p, struct timespec *timep)
+static inline __be32*
+xdr_encode_current_server_time(__be32 *p, struct timespec *timep)
 {
        /*
         * Passing the invalid value useconds=1000000 is a
@@ -108,8 +108,8 @@ xdr_encode_current_server_time(u32 *p, struct timespec *timep)
        return p;
 }
 
-static inline u32*
-xdr_decode_time(u32 *p, struct timespec *timep)
+static inline __be32*
+xdr_decode_time(__be32 *p, struct timespec *timep)
 {
        timep->tv_sec = ntohl(*p++);
        /* Convert microseconds into nanoseconds */
@@ -117,8 +117,8 @@ xdr_decode_time(u32 *p, struct timespec *timep)
        return p;
 }
 
-static u32 *
-xdr_decode_fattr(u32 *p, struct nfs_fattr *fattr)
+static __be32 *
+xdr_decode_fattr(__be32 *p, struct nfs_fattr *fattr)
 {
        u32 rdev;
        fattr->type = (enum nfs_ftype) ntohl(*p++);
@@ -146,10 +146,10 @@ xdr_decode_fattr(u32 *p, struct nfs_fattr *fattr)
        return p;
 }
 
-static inline u32 *
-xdr_encode_sattr(u32 *p, struct iattr *attr)
+static inline __be32 *
+xdr_encode_sattr(__be32 *p, struct iattr *attr)
 {
-       const u32 not_set = __constant_htonl(0xFFFFFFFF);
+       const __be32 not_set = __constant_htonl(0xFFFFFFFF);
 
        *p++ = (attr->ia_valid & ATTR_MODE) ? htonl(attr->ia_mode) : not_set;
        *p++ = (attr->ia_valid & ATTR_UID) ? htonl(attr->ia_uid) : not_set;
@@ -184,7 +184,7 @@ xdr_encode_sattr(u32 *p, struct iattr *attr)
  * GETATTR, READLINK, STATFS
  */
 static int
-nfs_xdr_fhandle(struct rpc_rqst *req, u32 *p, struct nfs_fh *fh)
+nfs_xdr_fhandle(struct rpc_rqst *req, __be32 *p, struct nfs_fh *fh)
 {
        p = xdr_encode_fhandle(p, fh);
        req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
@@ -195,7 +195,7 @@ nfs_xdr_fhandle(struct rpc_rqst *req, u32 *p, struct nfs_fh *fh)
  * Encode SETATTR arguments
  */
 static int
-nfs_xdr_sattrargs(struct rpc_rqst *req, u32 *p, struct nfs_sattrargs *args)
+nfs_xdr_sattrargs(struct rpc_rqst *req, __be32 *p, struct nfs_sattrargs *args)
 {
        p = xdr_encode_fhandle(p, args->fh);
        p = xdr_encode_sattr(p, args->sattr);
@@ -208,7 +208,7 @@ nfs_xdr_sattrargs(struct rpc_rqst *req, u32 *p, struct nfs_sattrargs *args)
  * LOOKUP, REMOVE, RMDIR
  */
 static int
-nfs_xdr_diropargs(struct rpc_rqst *req, u32 *p, struct nfs_diropargs *args)
+nfs_xdr_diropargs(struct rpc_rqst *req, __be32 *p, struct nfs_diropargs *args)
 {
        p = xdr_encode_fhandle(p, args->fh);
        p = xdr_encode_array(p, args->name, args->len);
@@ -222,7 +222,7 @@ nfs_xdr_diropargs(struct rpc_rqst *req, u32 *p, struct nfs_diropargs *args)
  * exactly to the page we want to fetch.
  */
 static int
-nfs_xdr_readargs(struct rpc_rqst *req, u32 *p, struct nfs_readargs *args)
+nfs_xdr_readargs(struct rpc_rqst *req, __be32 *p, struct nfs_readargs *args)
 {
        struct rpc_auth *auth = req->rq_task->tk_auth;
        unsigned int replen;
@@ -246,7 +246,7 @@ nfs_xdr_readargs(struct rpc_rqst *req, u32 *p, struct nfs_readargs *args)
  * Decode READ reply
  */
 static int
-nfs_xdr_readres(struct rpc_rqst *req, u32 *p, struct nfs_readres *res)
+nfs_xdr_readres(struct rpc_rqst *req, __be32 *p, struct nfs_readres *res)
 {
        struct kvec *iov = req->rq_rcv_buf.head;
        int     status, count, recvd, hdrlen;
@@ -286,7 +286,7 @@ nfs_xdr_readres(struct rpc_rqst *req, u32 *p, struct nfs_readres *res)
  * Write arguments. Splice the buffer to be written into the iovec.
  */
 static int
-nfs_xdr_writeargs(struct rpc_rqst *req, u32 *p, struct nfs_writeargs *args)
+nfs_xdr_writeargs(struct rpc_rqst *req, __be32 *p, struct nfs_writeargs *args)
 {
        struct xdr_buf *sndbuf = &req->rq_snd_buf;
        u32 offset = (u32)args->offset;
@@ -309,7 +309,7 @@ nfs_xdr_writeargs(struct rpc_rqst *req, u32 *p, struct nfs_writeargs *args)
  * CREATE, MKDIR
  */
 static int
-nfs_xdr_createargs(struct rpc_rqst *req, u32 *p, struct nfs_createargs *args)
+nfs_xdr_createargs(struct rpc_rqst *req, __be32 *p, struct nfs_createargs *args)
 {
        p = xdr_encode_fhandle(p, args->fh);
        p = xdr_encode_array(p, args->name, args->len);
@@ -322,7 +322,7 @@ nfs_xdr_createargs(struct rpc_rqst *req, u32 *p, struct nfs_createargs *args)
  * Encode RENAME arguments
  */
 static int
-nfs_xdr_renameargs(struct rpc_rqst *req, u32 *p, struct nfs_renameargs *args)
+nfs_xdr_renameargs(struct rpc_rqst *req, __be32 *p, struct nfs_renameargs *args)
 {
        p = xdr_encode_fhandle(p, args->fromfh);
        p = xdr_encode_array(p, args->fromname, args->fromlen);
@@ -336,7 +336,7 @@ nfs_xdr_renameargs(struct rpc_rqst *req, u32 *p, struct nfs_renameargs *args)
  * Encode LINK arguments
  */
 static int
-nfs_xdr_linkargs(struct rpc_rqst *req, u32 *p, struct nfs_linkargs *args)
+nfs_xdr_linkargs(struct rpc_rqst *req, __be32 *p, struct nfs_linkargs *args)
 {
        p = xdr_encode_fhandle(p, args->fromfh);
        p = xdr_encode_fhandle(p, args->tofh);
@@ -349,7 +349,7 @@ nfs_xdr_linkargs(struct rpc_rqst *req, u32 *p, struct nfs_linkargs *args)
  * Encode SYMLINK arguments
  */
 static int
-nfs_xdr_symlinkargs(struct rpc_rqst *req, u32 *p, struct nfs_symlinkargs *args)
+nfs_xdr_symlinkargs(struct rpc_rqst *req, __be32 *p, struct nfs_symlinkargs *args)
 {
        struct xdr_buf *sndbuf = &req->rq_snd_buf;
        size_t pad;
@@ -378,7 +378,7 @@ nfs_xdr_symlinkargs(struct rpc_rqst *req, u32 *p, struct nfs_symlinkargs *args)
  * Encode arguments to readdir call
  */
 static int
-nfs_xdr_readdirargs(struct rpc_rqst *req, u32 *p, struct nfs_readdirargs *args)
+nfs_xdr_readdirargs(struct rpc_rqst *req, __be32 *p, struct nfs_readdirargs *args)
 {
        struct rpc_task *task = req->rq_task;
        struct rpc_auth *auth = task->tk_auth;
@@ -404,7 +404,7 @@ nfs_xdr_readdirargs(struct rpc_rqst *req, u32 *p, struct nfs_readdirargs *args)
  * from nfs_readdir for each entry.
  */
 static int
-nfs_xdr_readdirres(struct rpc_rqst *req, u32 *p, void *dummy)
+nfs_xdr_readdirres(struct rpc_rqst *req, __be32 *p, void *dummy)
 {
        struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
        struct kvec *iov = rcvbuf->head;
@@ -412,7 +412,7 @@ nfs_xdr_readdirres(struct rpc_rqst *req, u32 *p, void *dummy)
        int hdrlen, recvd;
        int status, nr;
        unsigned int len, pglen;
-       u32 *end, *entry, *kaddr;
+       __be32 *end, *entry, *kaddr;
 
        if ((status = ntohl(*p++)))
                return -nfs_stat_to_errno(status);
@@ -432,8 +432,8 @@ nfs_xdr_readdirres(struct rpc_rqst *req, u32 *p, void *dummy)
        if (pglen > recvd)
                pglen = recvd;
        page = rcvbuf->pages;
-       kaddr = p = (u32 *)kmap_atomic(*page, KM_USER0);
-       end = (u32 *)((char *)p + pglen);
+       kaddr = p = kmap_atomic(*page, KM_USER0);
+       end = (__be32 *)((char *)p + pglen);
        entry = p;
        for (nr = 0; *p++; nr++) {
                if (p + 2 > end)
@@ -468,8 +468,8 @@ err_unmap:
        goto out;
 }
 
-u32 *
-nfs_decode_dirent(u32 *p, struct nfs_entry *entry, int plus)
+__be32 *
+nfs_decode_dirent(__be32 *p, struct nfs_entry *entry, int plus)
 {
        if (!*p++) {
                if (!*p)
@@ -496,7 +496,7 @@ nfs_decode_dirent(u32 *p, struct nfs_entry *entry, int plus)
  * Decode simple status reply
  */
 static int
-nfs_xdr_stat(struct rpc_rqst *req, u32 *p, void *dummy)
+nfs_xdr_stat(struct rpc_rqst *req, __be32 *p, void *dummy)
 {
        int     status;
 
@@ -510,7 +510,7 @@ nfs_xdr_stat(struct rpc_rqst *req, u32 *p, void *dummy)
  * GETATTR, SETATTR, WRITE
  */
 static int
-nfs_xdr_attrstat(struct rpc_rqst *req, u32 *p, struct nfs_fattr *fattr)
+nfs_xdr_attrstat(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
 {
        int     status;
 
@@ -525,7 +525,7 @@ nfs_xdr_attrstat(struct rpc_rqst *req, u32 *p, struct nfs_fattr *fattr)
  * LOOKUP, CREATE, MKDIR
  */
 static int
-nfs_xdr_diropres(struct rpc_rqst *req, u32 *p, struct nfs_diropok *res)
+nfs_xdr_diropres(struct rpc_rqst *req, __be32 *p, struct nfs_diropok *res)
 {
        int     status;
 
@@ -540,7 +540,7 @@ nfs_xdr_diropres(struct rpc_rqst *req, u32 *p, struct nfs_diropok *res)
  * Encode READLINK args
  */
 static int
-nfs_xdr_readlinkargs(struct rpc_rqst *req, u32 *p, struct nfs_readlinkargs *args)
+nfs_xdr_readlinkargs(struct rpc_rqst *req, __be32 *p, struct nfs_readlinkargs *args)
 {
        struct rpc_auth *auth = req->rq_task->tk_auth;
        unsigned int replen;
@@ -558,7 +558,7 @@ nfs_xdr_readlinkargs(struct rpc_rqst *req, u32 *p, struct nfs_readlinkargs *args
  * Decode READLINK reply
  */
 static int
-nfs_xdr_readlinkres(struct rpc_rqst *req, u32 *p, void *dummy)
+nfs_xdr_readlinkres(struct rpc_rqst *req, __be32 *p, void *dummy)
 {
        struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
        struct kvec *iov = rcvbuf->head;
@@ -601,7 +601,7 @@ nfs_xdr_readlinkres(struct rpc_rqst *req, u32 *p, void *dummy)
  * Decode WRITE reply
  */
 static int
-nfs_xdr_writeres(struct rpc_rqst *req, u32 *p, struct nfs_writeres *res)
+nfs_xdr_writeres(struct rpc_rqst *req, __be32 *p, struct nfs_writeres *res)
 {
        res->verf->committed = NFS_FILE_SYNC;
        return nfs_xdr_attrstat(req, p, res->fattr);
@@ -611,7 +611,7 @@ nfs_xdr_writeres(struct rpc_rqst *req, u32 *p, struct nfs_writeres *res)
  * Decode STATFS reply
  */
 static int
-nfs_xdr_statfsres(struct rpc_rqst *req, u32 *p, struct nfs2_fsstat *res)
+nfs_xdr_statfsres(struct rpc_rqst *req, __be32 *p, struct nfs2_fsstat *res)
 {
        int     status;
 
index 3b234d4601e71ac51f45e71e409526aa96fcf14d..e5f128ffc32dd7ee368946768f9ce762a44c4fe7 100644 (file)
@@ -668,7 +668,7 @@ nfs3_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
 {
        struct inode            *dir = dentry->d_inode;
        struct nfs_fattr        dir_attr;
-       u32                     *verf = NFS_COOKIEVERF(dir);
+       __be32                  *verf = NFS_COOKIEVERF(dir);
        struct nfs3_readdirargs arg = {
                .fh             = NFS_FH(dir),
                .cookie         = cookie,
index 16556fa4effb1e989aecd7301d8ee234ba1a97d1..0ace092d126f930e10e946340c8c04b8be7dfa14 100644 (file)
@@ -105,14 +105,14 @@ static struct {
 /*
  * Common NFS XDR functions as inlines
  */
-static inline u32 *
-xdr_encode_fhandle(u32 *p, struct nfs_fh *fh)
+static inline __be32 *
+xdr_encode_fhandle(__be32 *p, struct nfs_fh *fh)
 {
        return xdr_encode_array(p, fh->data, fh->size);
 }
 
-static inline u32 *
-xdr_decode_fhandle(u32 *p, struct nfs_fh *fh)
+static inline __be32 *
+xdr_decode_fhandle(__be32 *p, struct nfs_fh *fh)
 {
        if ((fh->size = ntohl(*p++)) <= NFS3_FHSIZE) {
                memcpy(fh->data, p, fh->size);
@@ -124,24 +124,24 @@ xdr_decode_fhandle(u32 *p, struct nfs_fh *fh)
 /*
  * Encode/decode time.
  */
-static inline u32 *
-xdr_encode_time3(u32 *p, struct timespec *timep)
+static inline __be32 *
+xdr_encode_time3(__be32 *p, struct timespec *timep)
 {
        *p++ = htonl(timep->tv_sec);
        *p++ = htonl(timep->tv_nsec);
        return p;
 }
 
-static inline u32 *
-xdr_decode_time3(u32 *p, struct timespec *timep)
+static inline __be32 *
+xdr_decode_time3(__be32 *p, struct timespec *timep)
 {
        timep->tv_sec = ntohl(*p++);
        timep->tv_nsec = ntohl(*p++);
        return p;
 }
 
-static u32 *
-xdr_decode_fattr(u32 *p, struct nfs_fattr *fattr)
+static __be32 *
+xdr_decode_fattr(__be32 *p, struct nfs_fattr *fattr)
 {
        unsigned int    type, major, minor;
        int             fmode;
@@ -177,8 +177,8 @@ xdr_decode_fattr(u32 *p, struct nfs_fattr *fattr)
        return p;
 }
 
-static inline u32 *
-xdr_encode_sattr(u32 *p, struct iattr *attr)
+static inline __be32 *
+xdr_encode_sattr(__be32 *p, struct iattr *attr)
 {
        if (attr->ia_valid & ATTR_MODE) {
                *p++ = xdr_one;
@@ -223,8 +223,8 @@ xdr_encode_sattr(u32 *p, struct iattr *attr)
        return p;
 }
 
-static inline u32 *
-xdr_decode_wcc_attr(u32 *p, struct nfs_fattr *fattr)
+static inline __be32 *
+xdr_decode_wcc_attr(__be32 *p, struct nfs_fattr *fattr)
 {
        p = xdr_decode_hyper(p, &fattr->pre_size);
        p = xdr_decode_time3(p, &fattr->pre_mtime);
@@ -233,16 +233,16 @@ xdr_decode_wcc_attr(u32 *p, struct nfs_fattr *fattr)
        return p;
 }
 
-static inline u32 *
-xdr_decode_post_op_attr(u32 *p, struct nfs_fattr *fattr)
+static inline __be32 *
+xdr_decode_post_op_attr(__be32 *p, struct nfs_fattr *fattr)
 {
        if (*p++)
                p = xdr_decode_fattr(p, fattr);
        return p;
 }
 
-static inline u32 *
-xdr_decode_pre_op_attr(u32 *p, struct nfs_fattr *fattr)
+static inline __be32 *
+xdr_decode_pre_op_attr(__be32 *p, struct nfs_fattr *fattr)
 {
        if (*p++)
                return xdr_decode_wcc_attr(p, fattr);
@@ -250,8 +250,8 @@ xdr_decode_pre_op_attr(u32 *p, struct nfs_fattr *fattr)
 }
 
 
-static inline u32 *
-xdr_decode_wcc_data(u32 *p, struct nfs_fattr *fattr)
+static inline __be32 *
+xdr_decode_wcc_data(__be32 *p, struct nfs_fattr *fattr)
 {
        p = xdr_decode_pre_op_attr(p, fattr);
        return xdr_decode_post_op_attr(p, fattr);
@@ -265,7 +265,7 @@ xdr_decode_wcc_data(u32 *p, struct nfs_fattr *fattr)
  * Encode file handle argument
  */
 static int
-nfs3_xdr_fhandle(struct rpc_rqst *req, u32 *p, struct nfs_fh *fh)
+nfs3_xdr_fhandle(struct rpc_rqst *req, __be32 *p, struct nfs_fh *fh)
 {
        p = xdr_encode_fhandle(p, fh);
        req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
@@ -276,7 +276,7 @@ nfs3_xdr_fhandle(struct rpc_rqst *req, u32 *p, struct nfs_fh *fh)
  * Encode SETATTR arguments
  */
 static int
-nfs3_xdr_sattrargs(struct rpc_rqst *req, u32 *p, struct nfs3_sattrargs *args)
+nfs3_xdr_sattrargs(struct rpc_rqst *req, __be32 *p, struct nfs3_sattrargs *args)
 {
        p = xdr_encode_fhandle(p, args->fh);
        p = xdr_encode_sattr(p, args->sattr);
@@ -291,7 +291,7 @@ nfs3_xdr_sattrargs(struct rpc_rqst *req, u32 *p, struct nfs3_sattrargs *args)
  * Encode directory ops argument
  */
 static int
-nfs3_xdr_diropargs(struct rpc_rqst *req, u32 *p, struct nfs3_diropargs *args)
+nfs3_xdr_diropargs(struct rpc_rqst *req, __be32 *p, struct nfs3_diropargs *args)
 {
        p = xdr_encode_fhandle(p, args->fh);
        p = xdr_encode_array(p, args->name, args->len);
@@ -303,7 +303,7 @@ nfs3_xdr_diropargs(struct rpc_rqst *req, u32 *p, struct nfs3_diropargs *args)
  * Encode access() argument
  */
 static int
-nfs3_xdr_accessargs(struct rpc_rqst *req, u32 *p, struct nfs3_accessargs *args)
+nfs3_xdr_accessargs(struct rpc_rqst *req, __be32 *p, struct nfs3_accessargs *args)
 {
        p = xdr_encode_fhandle(p, args->fh);
        *p++ = htonl(args->access);
@@ -317,7 +317,7 @@ nfs3_xdr_accessargs(struct rpc_rqst *req, u32 *p, struct nfs3_accessargs *args)
  * exactly to the page we want to fetch.
  */
 static int
-nfs3_xdr_readargs(struct rpc_rqst *req, u32 *p, struct nfs_readargs *args)
+nfs3_xdr_readargs(struct rpc_rqst *req, __be32 *p, struct nfs_readargs *args)
 {
        struct rpc_auth *auth = req->rq_task->tk_auth;
        unsigned int replen;
@@ -339,7 +339,7 @@ nfs3_xdr_readargs(struct rpc_rqst *req, u32 *p, struct nfs_readargs *args)
  * Write arguments. Splice the buffer to be written into the iovec.
  */
 static int
-nfs3_xdr_writeargs(struct rpc_rqst *req, u32 *p, struct nfs_writeargs *args)
+nfs3_xdr_writeargs(struct rpc_rqst *req, __be32 *p, struct nfs_writeargs *args)
 {
        struct xdr_buf *sndbuf = &req->rq_snd_buf;
        u32 count = args->count;
@@ -360,7 +360,7 @@ nfs3_xdr_writeargs(struct rpc_rqst *req, u32 *p, struct nfs_writeargs *args)
  * Encode CREATE arguments
  */
 static int
-nfs3_xdr_createargs(struct rpc_rqst *req, u32 *p, struct nfs3_createargs *args)
+nfs3_xdr_createargs(struct rpc_rqst *req, __be32 *p, struct nfs3_createargs *args)
 {
        p = xdr_encode_fhandle(p, args->fh);
        p = xdr_encode_array(p, args->name, args->len);
@@ -380,7 +380,7 @@ nfs3_xdr_createargs(struct rpc_rqst *req, u32 *p, struct nfs3_createargs *args)
  * Encode MKDIR arguments
  */
 static int
-nfs3_xdr_mkdirargs(struct rpc_rqst *req, u32 *p, struct nfs3_mkdirargs *args)
+nfs3_xdr_mkdirargs(struct rpc_rqst *req, __be32 *p, struct nfs3_mkdirargs *args)
 {
        p = xdr_encode_fhandle(p, args->fh);
        p = xdr_encode_array(p, args->name, args->len);
@@ -393,7 +393,7 @@ nfs3_xdr_mkdirargs(struct rpc_rqst *req, u32 *p, struct nfs3_mkdirargs *args)
  * Encode SYMLINK arguments
  */
 static int
-nfs3_xdr_symlinkargs(struct rpc_rqst *req, u32 *p, struct nfs3_symlinkargs *args)
+nfs3_xdr_symlinkargs(struct rpc_rqst *req, __be32 *p, struct nfs3_symlinkargs *args)
 {
        p = xdr_encode_fhandle(p, args->fromfh);
        p = xdr_encode_array(p, args->fromname, args->fromlen);
@@ -410,7 +410,7 @@ nfs3_xdr_symlinkargs(struct rpc_rqst *req, u32 *p, struct nfs3_symlinkargs *args
  * Encode MKNOD arguments
  */
 static int
-nfs3_xdr_mknodargs(struct rpc_rqst *req, u32 *p, struct nfs3_mknodargs *args)
+nfs3_xdr_mknodargs(struct rpc_rqst *req, __be32 *p, struct nfs3_mknodargs *args)
 {
        p = xdr_encode_fhandle(p, args->fh);
        p = xdr_encode_array(p, args->name, args->len);
@@ -429,7 +429,7 @@ nfs3_xdr_mknodargs(struct rpc_rqst *req, u32 *p, struct nfs3_mknodargs *args)
  * Encode RENAME arguments
  */
 static int
-nfs3_xdr_renameargs(struct rpc_rqst *req, u32 *p, struct nfs3_renameargs *args)
+nfs3_xdr_renameargs(struct rpc_rqst *req, __be32 *p, struct nfs3_renameargs *args)
 {
        p = xdr_encode_fhandle(p, args->fromfh);
        p = xdr_encode_array(p, args->fromname, args->fromlen);
@@ -443,7 +443,7 @@ nfs3_xdr_renameargs(struct rpc_rqst *req, u32 *p, struct nfs3_renameargs *args)
  * Encode LINK arguments
  */
 static int
-nfs3_xdr_linkargs(struct rpc_rqst *req, u32 *p, struct nfs3_linkargs *args)
+nfs3_xdr_linkargs(struct rpc_rqst *req, __be32 *p, struct nfs3_linkargs *args)
 {
        p = xdr_encode_fhandle(p, args->fromfh);
        p = xdr_encode_fhandle(p, args->tofh);
@@ -456,7 +456,7 @@ nfs3_xdr_linkargs(struct rpc_rqst *req, u32 *p, struct nfs3_linkargs *args)
  * Encode arguments to readdir call
  */
 static int
-nfs3_xdr_readdirargs(struct rpc_rqst *req, u32 *p, struct nfs3_readdirargs *args)
+nfs3_xdr_readdirargs(struct rpc_rqst *req, __be32 *p, struct nfs3_readdirargs *args)
 {
        struct rpc_auth *auth = req->rq_task->tk_auth;
        unsigned int replen;
@@ -485,7 +485,7 @@ nfs3_xdr_readdirargs(struct rpc_rqst *req, u32 *p, struct nfs3_readdirargs *args
  * We just check for syntactical correctness.
  */
 static int
-nfs3_xdr_readdirres(struct rpc_rqst *req, u32 *p, struct nfs3_readdirres *res)
+nfs3_xdr_readdirres(struct rpc_rqst *req, __be32 *p, struct nfs3_readdirres *res)
 {
        struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
        struct kvec *iov = rcvbuf->head;
@@ -493,7 +493,7 @@ nfs3_xdr_readdirres(struct rpc_rqst *req, u32 *p, struct nfs3_readdirres *res)
        int hdrlen, recvd;
        int status, nr;
        unsigned int len, pglen;
-       u32 *entry, *end, *kaddr;
+       __be32 *entry, *end, *kaddr;
 
        status = ntohl(*p++);
        /* Decode post_op_attrs */
@@ -523,8 +523,8 @@ nfs3_xdr_readdirres(struct rpc_rqst *req, u32 *p, struct nfs3_readdirres *res)
        if (pglen > recvd)
                pglen = recvd;
        page = rcvbuf->pages;
-       kaddr = p = (u32 *)kmap_atomic(*page, KM_USER0);
-       end = (u32 *)((char *)p + pglen);
+       kaddr = p = kmap_atomic(*page, KM_USER0);
+       end = (__be32 *)((char *)p + pglen);
        entry = p;
        for (nr = 0; *p++; nr++) {
                if (p + 3 > end)
@@ -583,8 +583,8 @@ err_unmap:
        goto out;
 }
 
-u32 *
-nfs3_decode_dirent(u32 *p, struct nfs_entry *entry, int plus)
+__be32 *
+nfs3_decode_dirent(__be32 *p, struct nfs_entry *entry, int plus)
 {
        struct nfs_entry old = *entry;
 
@@ -626,7 +626,7 @@ nfs3_decode_dirent(u32 *p, struct nfs_entry *entry, int plus)
  * Encode COMMIT arguments
  */
 static int
-nfs3_xdr_commitargs(struct rpc_rqst *req, u32 *p, struct nfs_writeargs *args)
+nfs3_xdr_commitargs(struct rpc_rqst *req, __be32 *p, struct nfs_writeargs *args)
 {
        p = xdr_encode_fhandle(p, args->fh);
        p = xdr_encode_hyper(p, args->offset);
@@ -640,7 +640,7 @@ nfs3_xdr_commitargs(struct rpc_rqst *req, u32 *p, struct nfs_writeargs *args)
  * Encode GETACL arguments
  */
 static int
-nfs3_xdr_getaclargs(struct rpc_rqst *req, u32 *p,
+nfs3_xdr_getaclargs(struct rpc_rqst *req, __be32 *p,
                    struct nfs3_getaclargs *args)
 {
        struct rpc_auth *auth = req->rq_task->tk_auth;
@@ -664,7 +664,7 @@ nfs3_xdr_getaclargs(struct rpc_rqst *req, u32 *p,
  * Encode SETACL arguments
  */
 static int
-nfs3_xdr_setaclargs(struct rpc_rqst *req, u32 *p,
+nfs3_xdr_setaclargs(struct rpc_rqst *req, __be32 *p,
                    struct nfs3_setaclargs *args)
 {
        struct xdr_buf *buf = &req->rq_snd_buf;
@@ -711,7 +711,7 @@ nfs3_xdr_setaclargs(struct rpc_rqst *req, u32 *p,
  * Decode attrstat reply.
  */
 static int
-nfs3_xdr_attrstat(struct rpc_rqst *req, u32 *p, struct nfs_fattr *fattr)
+nfs3_xdr_attrstat(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
 {
        int     status;
 
@@ -726,7 +726,7 @@ nfs3_xdr_attrstat(struct rpc_rqst *req, u32 *p, struct nfs_fattr *fattr)
  * SATTR, REMOVE, RMDIR
  */
 static int
-nfs3_xdr_wccstat(struct rpc_rqst *req, u32 *p, struct nfs_fattr *fattr)
+nfs3_xdr_wccstat(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
 {
        int     status;
 
@@ -740,7 +740,7 @@ nfs3_xdr_wccstat(struct rpc_rqst *req, u32 *p, struct nfs_fattr *fattr)
  * Decode LOOKUP reply
  */
 static int
-nfs3_xdr_lookupres(struct rpc_rqst *req, u32 *p, struct nfs3_diropres *res)
+nfs3_xdr_lookupres(struct rpc_rqst *req, __be32 *p, struct nfs3_diropres *res)
 {
        int     status;
 
@@ -759,7 +759,7 @@ nfs3_xdr_lookupres(struct rpc_rqst *req, u32 *p, struct nfs3_diropres *res)
  * Decode ACCESS reply
  */
 static int
-nfs3_xdr_accessres(struct rpc_rqst *req, u32 *p, struct nfs3_accessres *res)
+nfs3_xdr_accessres(struct rpc_rqst *req, __be32 *p, struct nfs3_accessres *res)
 {
        int     status = ntohl(*p++);
 
@@ -771,7 +771,7 @@ nfs3_xdr_accessres(struct rpc_rqst *req, u32 *p, struct nfs3_accessres *res)
 }
 
 static int
-nfs3_xdr_readlinkargs(struct rpc_rqst *req, u32 *p, struct nfs3_readlinkargs *args)
+nfs3_xdr_readlinkargs(struct rpc_rqst *req, __be32 *p, struct nfs3_readlinkargs *args)
 {
        struct rpc_auth *auth = req->rq_task->tk_auth;
        unsigned int replen;
@@ -789,7 +789,7 @@ nfs3_xdr_readlinkargs(struct rpc_rqst *req, u32 *p, struct nfs3_readlinkargs *ar
  * Decode READLINK reply
  */
 static int
-nfs3_xdr_readlinkres(struct rpc_rqst *req, u32 *p, struct nfs_fattr *fattr)
+nfs3_xdr_readlinkres(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
 {
        struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
        struct kvec *iov = rcvbuf->head;
@@ -837,7 +837,7 @@ nfs3_xdr_readlinkres(struct rpc_rqst *req, u32 *p, struct nfs_fattr *fattr)
  * Decode READ reply
  */
 static int
-nfs3_xdr_readres(struct rpc_rqst *req, u32 *p, struct nfs_readres *res)
+nfs3_xdr_readres(struct rpc_rqst *req, __be32 *p, struct nfs_readres *res)
 {
        struct kvec *iov = req->rq_rcv_buf.head;
        int     status, count, ocount, recvd, hdrlen;
@@ -888,7 +888,7 @@ nfs3_xdr_readres(struct rpc_rqst *req, u32 *p, struct nfs_readres *res)
  * Decode WRITE response
  */
 static int
-nfs3_xdr_writeres(struct rpc_rqst *req, u32 *p, struct nfs_writeres *res)
+nfs3_xdr_writeres(struct rpc_rqst *req, __be32 *p, struct nfs_writeres *res)
 {
        int     status;
 
@@ -910,7 +910,7 @@ nfs3_xdr_writeres(struct rpc_rqst *req, u32 *p, struct nfs_writeres *res)
  * Decode a CREATE response
  */
 static int
-nfs3_xdr_createres(struct rpc_rqst *req, u32 *p, struct nfs3_diropres *res)
+nfs3_xdr_createres(struct rpc_rqst *req, __be32 *p, struct nfs3_diropres *res)
 {
        int     status;
 
@@ -937,7 +937,7 @@ nfs3_xdr_createres(struct rpc_rqst *req, u32 *p, struct nfs3_diropres *res)
  * Decode RENAME reply
  */
 static int
-nfs3_xdr_renameres(struct rpc_rqst *req, u32 *p, struct nfs3_renameres *res)
+nfs3_xdr_renameres(struct rpc_rqst *req, __be32 *p, struct nfs3_renameres *res)
 {
        int     status;
 
@@ -952,7 +952,7 @@ nfs3_xdr_renameres(struct rpc_rqst *req, u32 *p, struct nfs3_renameres *res)
  * Decode LINK reply
  */
 static int
-nfs3_xdr_linkres(struct rpc_rqst *req, u32 *p, struct nfs3_linkres *res)
+nfs3_xdr_linkres(struct rpc_rqst *req, __be32 *p, struct nfs3_linkres *res)
 {
        int     status;
 
@@ -967,7 +967,7 @@ nfs3_xdr_linkres(struct rpc_rqst *req, u32 *p, struct nfs3_linkres *res)
  * Decode FSSTAT reply
  */
 static int
-nfs3_xdr_fsstatres(struct rpc_rqst *req, u32 *p, struct nfs_fsstat *res)
+nfs3_xdr_fsstatres(struct rpc_rqst *req, __be32 *p, struct nfs_fsstat *res)
 {
        int             status;
 
@@ -992,7 +992,7 @@ nfs3_xdr_fsstatres(struct rpc_rqst *req, u32 *p, struct nfs_fsstat *res)
  * Decode FSINFO reply
  */
 static int
-nfs3_xdr_fsinfores(struct rpc_rqst *req, u32 *p, struct nfs_fsinfo *res)
+nfs3_xdr_fsinfores(struct rpc_rqst *req, __be32 *p, struct nfs_fsinfo *res)
 {
        int             status;
 
@@ -1020,7 +1020,7 @@ nfs3_xdr_fsinfores(struct rpc_rqst *req, u32 *p, struct nfs_fsinfo *res)
  * Decode PATHCONF reply
  */
 static int
-nfs3_xdr_pathconfres(struct rpc_rqst *req, u32 *p, struct nfs_pathconf *res)
+nfs3_xdr_pathconfres(struct rpc_rqst *req, __be32 *p, struct nfs_pathconf *res)
 {
        int             status;
 
@@ -1040,7 +1040,7 @@ nfs3_xdr_pathconfres(struct rpc_rqst *req, u32 *p, struct nfs_pathconf *res)
  * Decode COMMIT reply
  */
 static int
-nfs3_xdr_commitres(struct rpc_rqst *req, u32 *p, struct nfs_writeres *res)
+nfs3_xdr_commitres(struct rpc_rqst *req, __be32 *p, struct nfs_writeres *res)
 {
        int             status;
 
@@ -1059,7 +1059,7 @@ nfs3_xdr_commitres(struct rpc_rqst *req, u32 *p, struct nfs_writeres *res)
  * Decode GETACL reply
  */
 static int
-nfs3_xdr_getaclres(struct rpc_rqst *req, u32 *p,
+nfs3_xdr_getaclres(struct rpc_rqst *req, __be32 *p,
                   struct nfs3_getaclres *res)
 {
        struct xdr_buf *buf = &req->rq_rcv_buf;
@@ -1091,7 +1091,7 @@ nfs3_xdr_getaclres(struct rpc_rqst *req, u32 *p,
  * Decode setacl reply.
  */
 static int
-nfs3_xdr_setaclres(struct rpc_rqst *req, u32 *p, struct nfs_fattr *fattr)
+nfs3_xdr_setaclres(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
 {
        int status = ntohl(*p++);
 
index 61095fe4b5ca5cd34481b18f6ac5516ec2d7cd78..6f346677332db4c99e07c867849ad7a0a705427a 100644 (file)
@@ -212,7 +212,7 @@ extern void nfs_free_seqid(struct nfs_seqid *seqid);
 extern const nfs4_stateid zero_stateid;
 
 /* nfs4xdr.c */
-extern uint32_t *nfs4_decode_dirent(uint32_t *p, struct nfs_entry *entry, int plus);
+extern __be32 *nfs4_decode_dirent(__be32 *p, struct nfs_entry *entry, int plus);
 extern struct rpc_procinfo nfs4_procedures[];
 
 struct nfs4_mount_data;
index 47c7e6e3910d738a9bdf4313e390b7349427f9d3..8118036cc4494c3a420869820cdebdb66c2c6262 100644 (file)
@@ -138,10 +138,10 @@ const u32 nfs4_fs_locations_bitmap[2] = {
        | FATTR4_WORD1_MOUNTED_ON_FILEID
 };
 
-static void nfs4_setup_readdir(u64 cookie, u32 *verifier, struct dentry *dentry,
+static void nfs4_setup_readdir(u64 cookie, __be32 *verifier, struct dentry *dentry,
                struct nfs4_readdir_arg *readdir)
 {
-       u32 *start, *p;
+       __be32 *start, *p;
 
        BUG_ON(readdir->count < 80);
        if (cookie > 2) {
@@ -162,7 +162,7 @@ static void nfs4_setup_readdir(u64 cookie, u32 *verifier, struct dentry *dentry,
         * when talking to the server, we always send cookie 0
         * instead of 1 or 2.
         */
-       start = p = (u32 *)kmap_atomic(*readdir->pages, KM_USER0);
+       start = p = kmap_atomic(*readdir->pages, KM_USER0);
        
        if (cookie == 0) {
                *p++ = xdr_one;                                  /* next */
@@ -1314,11 +1314,9 @@ nfs4_open_revalidate(struct inode *dir, struct dentry *dentry, int openflags, st
                        case -EROFS:
                                lookup_instantiate_filp(nd, (struct dentry *)state, NULL);
                                return 1;
-                       case -ENOENT:
-                               if (dentry->d_inode == NULL)
-                                       return 1;
+                       default:
+                               goto out_drop;
                }
-               goto out_drop;
        }
        if (state->inode == dentry->d_inode) {
                nfs4_intent_set_file(nd, dentry, state);
@@ -2917,11 +2915,11 @@ int nfs4_proc_setclientid(struct nfs_client *clp, u32 program, unsigned short po
                .rpc_resp = clp,
                .rpc_cred = cred,
        };
-       u32 *p;
+       __be32 *p;
        int loop = 0;
        int status;
 
-       p = (u32*)sc_verifier.data;
+       p = (__be32*)sc_verifier.data;
        *p++ = htonl((u32)clp->cl_boot_time.tv_sec);
        *p = htonl((u32)clp->cl_boot_time.tv_nsec);
 
index 3dd413f52da11d28e1b08ca4edbaca2bdca33864..0cf3fa312a332f565e8b57914eed5c60197caa21 100644 (file)
@@ -471,7 +471,7 @@ struct compound_hdr {
 
 static void encode_string(struct xdr_stream *xdr, unsigned int len, const char *str)
 {
-       uint32_t *p;
+       __be32 *p;
 
        p = xdr_reserve_space(xdr, 4 + len);
        BUG_ON(p == NULL);
@@ -480,7 +480,7 @@ static void encode_string(struct xdr_stream *xdr, unsigned int len, const char *
 
 static int encode_compound_hdr(struct xdr_stream *xdr, struct compound_hdr *hdr)
 {
-       uint32_t *p;
+       __be32 *p;
 
        dprintk("encode_compound: tag=%.*s\n", (int)hdr->taglen, hdr->tag);
        BUG_ON(hdr->taglen > NFS4_MAXTAGLEN);
@@ -494,7 +494,7 @@ static int encode_compound_hdr(struct xdr_stream *xdr, struct compound_hdr *hdr)
 
 static void encode_nfs4_verifier(struct xdr_stream *xdr, const nfs4_verifier *verf)
 {
-       uint32_t *p;
+       __be32 *p;
 
        p = xdr_reserve_space(xdr, NFS4_VERIFIER_SIZE);
        BUG_ON(p == NULL);
@@ -507,8 +507,8 @@ static int encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const s
        char owner_group[IDMAP_NAMESZ];
        int owner_namelen = 0;
        int owner_grouplen = 0;
-       uint32_t *p;
-       uint32_t *q;
+       __be32 *p;
+       __be32 *q;
        int len;
        uint32_t bmval0 = 0;
        uint32_t bmval1 = 0;
@@ -630,7 +630,7 @@ static int encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const s
 
 static int encode_access(struct xdr_stream *xdr, u32 access)
 {
-       uint32_t *p;
+       __be32 *p;
 
        RESERVE_SPACE(8);
        WRITE32(OP_ACCESS);
@@ -641,7 +641,7 @@ static int encode_access(struct xdr_stream *xdr, u32 access)
 
 static int encode_close(struct xdr_stream *xdr, const struct nfs_closeargs *arg)
 {
-       uint32_t *p;
+       __be32 *p;
 
        RESERVE_SPACE(8+sizeof(arg->stateid->data));
        WRITE32(OP_CLOSE);
@@ -653,7 +653,7 @@ static int encode_close(struct xdr_stream *xdr, const struct nfs_closeargs *arg)
 
 static int encode_commit(struct xdr_stream *xdr, const struct nfs_writeargs *args)
 {
-       uint32_t *p;
+       __be32 *p;
         
         RESERVE_SPACE(16);
         WRITE32(OP_COMMIT);
@@ -665,7 +665,7 @@ static int encode_commit(struct xdr_stream *xdr, const struct nfs_writeargs *arg
 
 static int encode_create(struct xdr_stream *xdr, const struct nfs4_create_arg *create)
 {
-       uint32_t *p;
+       __be32 *p;
        
        RESERVE_SPACE(8);
        WRITE32(OP_CREATE);
@@ -697,7 +697,7 @@ static int encode_create(struct xdr_stream *xdr, const struct nfs4_create_arg *c
 
 static int encode_getattr_one(struct xdr_stream *xdr, uint32_t bitmap)
 {
-        uint32_t *p;
+        __be32 *p;
 
         RESERVE_SPACE(12);
         WRITE32(OP_GETATTR);
@@ -708,7 +708,7 @@ static int encode_getattr_one(struct xdr_stream *xdr, uint32_t bitmap)
 
 static int encode_getattr_two(struct xdr_stream *xdr, uint32_t bm0, uint32_t bm1)
 {
-        uint32_t *p;
+        __be32 *p;
 
         RESERVE_SPACE(16);
         WRITE32(OP_GETATTR);
@@ -740,7 +740,7 @@ static int encode_fs_locations(struct xdr_stream *xdr, const u32* bitmask)
 
 static int encode_getfh(struct xdr_stream *xdr)
 {
-       uint32_t *p;
+       __be32 *p;
 
        RESERVE_SPACE(4);
        WRITE32(OP_GETFH);
@@ -750,7 +750,7 @@ static int encode_getfh(struct xdr_stream *xdr)
 
 static int encode_link(struct xdr_stream *xdr, const struct qstr *name)
 {
-       uint32_t *p;
+       __be32 *p;
 
        RESERVE_SPACE(8 + name->len);
        WRITE32(OP_LINK);
@@ -780,7 +780,7 @@ static inline uint64_t nfs4_lock_length(struct file_lock *fl)
  */
 static int encode_lock(struct xdr_stream *xdr, const struct nfs_lock_args *args)
 {
-       uint32_t *p;
+       __be32 *p;
 
        RESERVE_SPACE(32);
        WRITE32(OP_LOCK);
@@ -809,7 +809,7 @@ static int encode_lock(struct xdr_stream *xdr, const struct nfs_lock_args *args)
 
 static int encode_lockt(struct xdr_stream *xdr, const struct nfs_lockt_args *args)
 {
-       uint32_t *p;
+       __be32 *p;
 
        RESERVE_SPACE(40);
        WRITE32(OP_LOCKT);
@@ -825,7 +825,7 @@ static int encode_lockt(struct xdr_stream *xdr, const struct nfs_lockt_args *arg
 
 static int encode_locku(struct xdr_stream *xdr, const struct nfs_locku_args *args)
 {
-       uint32_t *p;
+       __be32 *p;
 
        RESERVE_SPACE(44);
        WRITE32(OP_LOCKU);
@@ -841,7 +841,7 @@ static int encode_locku(struct xdr_stream *xdr, const struct nfs_locku_args *arg
 static int encode_lookup(struct xdr_stream *xdr, const struct qstr *name)
 {
        int len = name->len;
-       uint32_t *p;
+       __be32 *p;
 
        RESERVE_SPACE(8 + len);
        WRITE32(OP_LOOKUP);
@@ -853,7 +853,7 @@ static int encode_lookup(struct xdr_stream *xdr, const struct qstr *name)
 
 static void encode_share_access(struct xdr_stream *xdr, int open_flags)
 {
-       uint32_t *p;
+       __be32 *p;
 
        RESERVE_SPACE(8);
        switch (open_flags & (FMODE_READ|FMODE_WRITE)) {
@@ -874,7 +874,7 @@ static void encode_share_access(struct xdr_stream *xdr, int open_flags)
 
 static inline void encode_openhdr(struct xdr_stream *xdr, const struct nfs_openargs *arg)
 {
-       uint32_t *p;
+       __be32 *p;
  /*
  * opcode 4, seqid 4, share_access 4, share_deny 4, clientid 8, ownerlen 4,
  * owner 4 = 32
@@ -891,7 +891,7 @@ static inline void encode_openhdr(struct xdr_stream *xdr, const struct nfs_opena
 
 static inline void encode_createmode(struct xdr_stream *xdr, const struct nfs_openargs *arg)
 {
-       uint32_t *p;
+       __be32 *p;
 
        RESERVE_SPACE(4);
        switch(arg->open_flags & O_EXCL) {
@@ -907,7 +907,7 @@ static inline void encode_createmode(struct xdr_stream *xdr, const struct nfs_op
 
 static void encode_opentype(struct xdr_stream *xdr, const struct nfs_openargs *arg)
 {
-       uint32_t *p;
+       __be32 *p;
 
        RESERVE_SPACE(4);
        switch (arg->open_flags & O_CREAT) {
@@ -923,7 +923,7 @@ static void encode_opentype(struct xdr_stream *xdr, const struct nfs_openargs *a
 
 static inline void encode_delegation_type(struct xdr_stream *xdr, int delegation_type)
 {
-       uint32_t *p;
+       __be32 *p;
 
        RESERVE_SPACE(4);
        switch (delegation_type) {
@@ -943,7 +943,7 @@ static inline void encode_delegation_type(struct xdr_stream *xdr, int delegation
 
 static inline void encode_claim_null(struct xdr_stream *xdr, const struct qstr *name)
 {
-       uint32_t *p;
+       __be32 *p;
 
        RESERVE_SPACE(4);
        WRITE32(NFS4_OPEN_CLAIM_NULL);
@@ -952,7 +952,7 @@ static inline void encode_claim_null(struct xdr_stream *xdr, const struct qstr *
 
 static inline void encode_claim_previous(struct xdr_stream *xdr, int type)
 {
-       uint32_t *p;
+       __be32 *p;
 
        RESERVE_SPACE(4);
        WRITE32(NFS4_OPEN_CLAIM_PREVIOUS);
@@ -961,7 +961,7 @@ static inline void encode_claim_previous(struct xdr_stream *xdr, int type)
 
 static inline void encode_claim_delegate_cur(struct xdr_stream *xdr, const struct qstr *name, const nfs4_stateid *stateid)
 {
-       uint32_t *p;
+       __be32 *p;
 
        RESERVE_SPACE(4+sizeof(stateid->data));
        WRITE32(NFS4_OPEN_CLAIM_DELEGATE_CUR);
@@ -991,7 +991,7 @@ static int encode_open(struct xdr_stream *xdr, const struct nfs_openargs *arg)
 
 static int encode_open_confirm(struct xdr_stream *xdr, const struct nfs_open_confirmargs *arg)
 {
-       uint32_t *p;
+       __be32 *p;
 
        RESERVE_SPACE(8+sizeof(arg->stateid->data));
        WRITE32(OP_OPEN_CONFIRM);
@@ -1003,7 +1003,7 @@ static int encode_open_confirm(struct xdr_stream *xdr, const struct nfs_open_con
 
 static int encode_open_downgrade(struct xdr_stream *xdr, const struct nfs_closeargs *arg)
 {
-       uint32_t *p;
+       __be32 *p;
 
        RESERVE_SPACE(8+sizeof(arg->stateid->data));
        WRITE32(OP_OPEN_DOWNGRADE);
@@ -1017,7 +1017,7 @@ static int
 encode_putfh(struct xdr_stream *xdr, const struct nfs_fh *fh)
 {
        int len = fh->size;
-       uint32_t *p;
+       __be32 *p;
 
        RESERVE_SPACE(8 + len);
        WRITE32(OP_PUTFH);
@@ -1029,7 +1029,7 @@ encode_putfh(struct xdr_stream *xdr, const struct nfs_fh *fh)
 
 static int encode_putrootfh(struct xdr_stream *xdr)
 {
-        uint32_t *p;
+        __be32 *p;
         
         RESERVE_SPACE(4);
         WRITE32(OP_PUTROOTFH);
@@ -1040,7 +1040,7 @@ static int encode_putrootfh(struct xdr_stream *xdr)
 static void encode_stateid(struct xdr_stream *xdr, const struct nfs_open_context *ctx)
 {
        nfs4_stateid stateid;
-       uint32_t *p;
+       __be32 *p;
 
        RESERVE_SPACE(16);
        if (ctx->state != NULL) {
@@ -1052,7 +1052,7 @@ static void encode_stateid(struct xdr_stream *xdr, const struct nfs_open_context
 
 static int encode_read(struct xdr_stream *xdr, const struct nfs_readargs *args)
 {
-       uint32_t *p;
+       __be32 *p;
 
        RESERVE_SPACE(4);
        WRITE32(OP_READ);
@@ -1074,7 +1074,7 @@ static int encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg
                FATTR4_WORD1_MOUNTED_ON_FILEID,
        };
        int replen;
-       uint32_t *p;
+       __be32 *p;
 
        RESERVE_SPACE(32+sizeof(nfs4_verifier));
        WRITE32(OP_READDIR);
@@ -1116,7 +1116,7 @@ static int encode_readlink(struct xdr_stream *xdr, const struct nfs4_readlink *r
 {
        struct rpc_auth *auth = req->rq_task->tk_auth;
        unsigned int replen;
-       uint32_t *p;
+       __be32 *p;
 
        RESERVE_SPACE(4);
        WRITE32(OP_READLINK);
@@ -1134,7 +1134,7 @@ static int encode_readlink(struct xdr_stream *xdr, const struct nfs4_readlink *r
 
 static int encode_remove(struct xdr_stream *xdr, const struct qstr *name)
 {
-       uint32_t *p;
+       __be32 *p;
 
        RESERVE_SPACE(8 + name->len);
        WRITE32(OP_REMOVE);
@@ -1146,7 +1146,7 @@ static int encode_remove(struct xdr_stream *xdr, const struct qstr *name)
 
 static int encode_rename(struct xdr_stream *xdr, const struct qstr *oldname, const struct qstr *newname)
 {
-       uint32_t *p;
+       __be32 *p;
 
        RESERVE_SPACE(8 + oldname->len);
        WRITE32(OP_RENAME);
@@ -1162,7 +1162,7 @@ static int encode_rename(struct xdr_stream *xdr, const struct qstr *oldname, con
 
 static int encode_renew(struct xdr_stream *xdr, const struct nfs_client *client_stateid)
 {
-       uint32_t *p;
+       __be32 *p;
 
        RESERVE_SPACE(12);
        WRITE32(OP_RENEW);
@@ -1174,7 +1174,7 @@ static int encode_renew(struct xdr_stream *xdr, const struct nfs_client *client_
 static int
 encode_restorefh(struct xdr_stream *xdr)
 {
-       uint32_t *p;
+       __be32 *p;
 
        RESERVE_SPACE(4);
        WRITE32(OP_RESTOREFH);
@@ -1185,7 +1185,7 @@ encode_restorefh(struct xdr_stream *xdr)
 static int
 encode_setacl(struct xdr_stream *xdr, struct nfs_setaclargs *arg)
 {
-       uint32_t *p;
+       __be32 *p;
 
        RESERVE_SPACE(4+sizeof(zero_stateid.data));
        WRITE32(OP_SETATTR);
@@ -1204,7 +1204,7 @@ encode_setacl(struct xdr_stream *xdr, struct nfs_setaclargs *arg)
 static int
 encode_savefh(struct xdr_stream *xdr)
 {
-       uint32_t *p;
+       __be32 *p;
 
        RESERVE_SPACE(4);
        WRITE32(OP_SAVEFH);
@@ -1215,7 +1215,7 @@ encode_savefh(struct xdr_stream *xdr)
 static int encode_setattr(struct xdr_stream *xdr, const struct nfs_setattrargs *arg, const struct nfs_server *server)
 {
        int status;
-       uint32_t *p;
+       __be32 *p;
        
         RESERVE_SPACE(4+sizeof(arg->stateid.data));
         WRITE32(OP_SETATTR);
@@ -1229,7 +1229,7 @@ static int encode_setattr(struct xdr_stream *xdr, const struct nfs_setattrargs *
 
 static int encode_setclientid(struct xdr_stream *xdr, const struct nfs4_setclientid *setclientid)
 {
-       uint32_t *p;
+       __be32 *p;
 
        RESERVE_SPACE(4 + sizeof(setclientid->sc_verifier->data));
        WRITE32(OP_SETCLIENTID);
@@ -1248,7 +1248,7 @@ static int encode_setclientid(struct xdr_stream *xdr, const struct nfs4_setclien
 
 static int encode_setclientid_confirm(struct xdr_stream *xdr, const struct nfs_client *client_state)
 {
-        uint32_t *p;
+        __be32 *p;
 
         RESERVE_SPACE(12 + sizeof(client_state->cl_confirm.data));
         WRITE32(OP_SETCLIENTID_CONFIRM);
@@ -1260,7 +1260,7 @@ static int encode_setclientid_confirm(struct xdr_stream *xdr, const struct nfs_c
 
 static int encode_write(struct xdr_stream *xdr, const struct nfs_writeargs *args)
 {
-       uint32_t *p;
+       __be32 *p;
 
        RESERVE_SPACE(4);
        WRITE32(OP_WRITE);
@@ -1279,7 +1279,7 @@ static int encode_write(struct xdr_stream *xdr, const struct nfs_writeargs *args
 
 static int encode_delegreturn(struct xdr_stream *xdr, const nfs4_stateid *stateid)
 {
-       uint32_t *p;
+       __be32 *p;
 
        RESERVE_SPACE(20);
 
@@ -1295,7 +1295,7 @@ static int encode_delegreturn(struct xdr_stream *xdr, const nfs4_stateid *statei
 /*
  * Encode an ACCESS request
  */
-static int nfs4_xdr_enc_access(struct rpc_rqst *req, uint32_t *p, const struct nfs4_accessargs *args)
+static int nfs4_xdr_enc_access(struct rpc_rqst *req, __be32 *p, const struct nfs4_accessargs *args)
 {
        struct xdr_stream xdr;
        struct compound_hdr hdr = {
@@ -1313,7 +1313,7 @@ static int nfs4_xdr_enc_access(struct rpc_rqst *req, uint32_t *p, const struct n
 /*
  * Encode LOOKUP request
  */
-static int nfs4_xdr_enc_lookup(struct rpc_rqst *req, uint32_t *p, const struct nfs4_lookup_arg *args)
+static int nfs4_xdr_enc_lookup(struct rpc_rqst *req, __be32 *p, const struct nfs4_lookup_arg *args)
 {
        struct xdr_stream xdr;
        struct compound_hdr hdr = {
@@ -1337,7 +1337,7 @@ out:
 /*
  * Encode LOOKUP_ROOT request
  */
-static int nfs4_xdr_enc_lookup_root(struct rpc_rqst *req, uint32_t *p, const struct nfs4_lookup_root_arg *args)
+static int nfs4_xdr_enc_lookup_root(struct rpc_rqst *req, __be32 *p, const struct nfs4_lookup_root_arg *args)
 {
        struct xdr_stream xdr;
        struct compound_hdr hdr = {
@@ -1358,7 +1358,7 @@ out:
 /*
  * Encode REMOVE request
  */
-static int nfs4_xdr_enc_remove(struct rpc_rqst *req, uint32_t *p, const struct nfs4_remove_arg *args)
+static int nfs4_xdr_enc_remove(struct rpc_rqst *req, __be32 *p, const struct nfs4_remove_arg *args)
 {
        struct xdr_stream xdr;
        struct compound_hdr hdr = {
@@ -1380,7 +1380,7 @@ out:
 /*
  * Encode RENAME request
  */
-static int nfs4_xdr_enc_rename(struct rpc_rqst *req, uint32_t *p, const struct nfs4_rename_arg *args)
+static int nfs4_xdr_enc_rename(struct rpc_rqst *req, __be32 *p, const struct nfs4_rename_arg *args)
 {
        struct xdr_stream xdr;
        struct compound_hdr hdr = {
@@ -1410,7 +1410,7 @@ out:
 /*
  * Encode LINK request
  */
-static int nfs4_xdr_enc_link(struct rpc_rqst *req, uint32_t *p, const struct nfs4_link_arg *args)
+static int nfs4_xdr_enc_link(struct rpc_rqst *req, __be32 *p, const struct nfs4_link_arg *args)
 {
        struct xdr_stream xdr;
        struct compound_hdr hdr = {
@@ -1440,7 +1440,7 @@ out:
 /*
  * Encode CREATE request
  */
-static int nfs4_xdr_enc_create(struct rpc_rqst *req, uint32_t *p, const struct nfs4_create_arg *args)
+static int nfs4_xdr_enc_create(struct rpc_rqst *req, __be32 *p, const struct nfs4_create_arg *args)
 {
        struct xdr_stream xdr;
        struct compound_hdr hdr = {
@@ -1470,7 +1470,7 @@ out:
 /*
  * Encode SYMLINK request
  */
-static int nfs4_xdr_enc_symlink(struct rpc_rqst *req, uint32_t *p, const struct nfs4_create_arg *args)
+static int nfs4_xdr_enc_symlink(struct rpc_rqst *req, __be32 *p, const struct nfs4_create_arg *args)
 {
        return nfs4_xdr_enc_create(req, p, args);
 }
@@ -1478,7 +1478,7 @@ static int nfs4_xdr_enc_symlink(struct rpc_rqst *req, uint32_t *p, const struct
 /*
  * Encode GETATTR request
  */
-static int nfs4_xdr_enc_getattr(struct rpc_rqst *req, uint32_t *p, const struct nfs4_getattr_arg *args)
+static int nfs4_xdr_enc_getattr(struct rpc_rqst *req, __be32 *p, const struct nfs4_getattr_arg *args)
 {
        struct xdr_stream xdr;
        struct compound_hdr hdr = {
@@ -1496,7 +1496,7 @@ static int nfs4_xdr_enc_getattr(struct rpc_rqst *req, uint32_t *p, const struct
 /*
  * Encode a CLOSE request
  */
-static int nfs4_xdr_enc_close(struct rpc_rqst *req, uint32_t *p, struct nfs_closeargs *args)
+static int nfs4_xdr_enc_close(struct rpc_rqst *req, __be32 *p, struct nfs_closeargs *args)
 {
         struct xdr_stream xdr;
         struct compound_hdr hdr = {
@@ -1520,7 +1520,7 @@ out:
 /*
  * Encode an OPEN request
  */
-static int nfs4_xdr_enc_open(struct rpc_rqst *req, uint32_t *p, struct nfs_openargs *args)
+static int nfs4_xdr_enc_open(struct rpc_rqst *req, __be32 *p, struct nfs_openargs *args)
 {
        struct xdr_stream xdr;
        struct compound_hdr hdr = {
@@ -1556,7 +1556,7 @@ out:
 /*
  * Encode an OPEN_CONFIRM request
  */
-static int nfs4_xdr_enc_open_confirm(struct rpc_rqst *req, uint32_t *p, struct nfs_open_confirmargs *args)
+static int nfs4_xdr_enc_open_confirm(struct rpc_rqst *req, __be32 *p, struct nfs_open_confirmargs *args)
 {
        struct xdr_stream xdr;
        struct compound_hdr hdr = {
@@ -1577,7 +1577,7 @@ out:
 /*
  * Encode an OPEN request with no attributes.
  */
-static int nfs4_xdr_enc_open_noattr(struct rpc_rqst *req, uint32_t *p, struct nfs_openargs *args)
+static int nfs4_xdr_enc_open_noattr(struct rpc_rqst *req, __be32 *p, struct nfs_openargs *args)
 {
        struct xdr_stream xdr;
        struct compound_hdr hdr = {
@@ -1601,7 +1601,7 @@ out:
 /*
  * Encode an OPEN_DOWNGRADE request
  */
-static int nfs4_xdr_enc_open_downgrade(struct rpc_rqst *req, uint32_t *p, struct nfs_closeargs *args)
+static int nfs4_xdr_enc_open_downgrade(struct rpc_rqst *req, __be32 *p, struct nfs_closeargs *args)
 {
        struct xdr_stream xdr;
        struct compound_hdr hdr = {
@@ -1625,7 +1625,7 @@ out:
 /*
  * Encode a LOCK request
  */
-static int nfs4_xdr_enc_lock(struct rpc_rqst *req, uint32_t *p, struct nfs_lock_args *args)
+static int nfs4_xdr_enc_lock(struct rpc_rqst *req, __be32 *p, struct nfs_lock_args *args)
 {
        struct xdr_stream xdr;
        struct compound_hdr hdr = {
@@ -1646,7 +1646,7 @@ out:
 /*
  * Encode a LOCKT request
  */
-static int nfs4_xdr_enc_lockt(struct rpc_rqst *req, uint32_t *p, struct nfs_lockt_args *args)
+static int nfs4_xdr_enc_lockt(struct rpc_rqst *req, __be32 *p, struct nfs_lockt_args *args)
 {
        struct xdr_stream xdr;
        struct compound_hdr hdr = {
@@ -1667,7 +1667,7 @@ out:
 /*
  * Encode a LOCKU request
  */
-static int nfs4_xdr_enc_locku(struct rpc_rqst *req, uint32_t *p, struct nfs_locku_args *args)
+static int nfs4_xdr_enc_locku(struct rpc_rqst *req, __be32 *p, struct nfs_locku_args *args)
 {
        struct xdr_stream xdr;
        struct compound_hdr hdr = {
@@ -1688,7 +1688,7 @@ out:
 /*
  * Encode a READLINK request
  */
-static int nfs4_xdr_enc_readlink(struct rpc_rqst *req, uint32_t *p, const struct nfs4_readlink *args)
+static int nfs4_xdr_enc_readlink(struct rpc_rqst *req, __be32 *p, const struct nfs4_readlink *args)
 {
        struct xdr_stream xdr;
        struct compound_hdr hdr = {
@@ -1709,7 +1709,7 @@ out:
 /*
  * Encode a READDIR request
  */
-static int nfs4_xdr_enc_readdir(struct rpc_rqst *req, uint32_t *p, const struct nfs4_readdir_arg *args)
+static int nfs4_xdr_enc_readdir(struct rpc_rqst *req, __be32 *p, const struct nfs4_readdir_arg *args)
 {
        struct xdr_stream xdr;
        struct compound_hdr hdr = {
@@ -1730,7 +1730,7 @@ out:
 /*
  * Encode a READ request
  */
-static int nfs4_xdr_enc_read(struct rpc_rqst *req, uint32_t *p, struct nfs_readargs *args)
+static int nfs4_xdr_enc_read(struct rpc_rqst *req, __be32 *p, struct nfs_readargs *args)
 {
        struct rpc_auth *auth = req->rq_task->tk_auth;
        struct xdr_stream xdr;
@@ -1762,7 +1762,7 @@ out:
 /*
  * Encode an SETATTR request
  */
-static int nfs4_xdr_enc_setattr(struct rpc_rqst *req, uint32_t *p, struct nfs_setattrargs *args)
+static int nfs4_xdr_enc_setattr(struct rpc_rqst *req, __be32 *p, struct nfs_setattrargs *args)
 
 {
         struct xdr_stream xdr;
@@ -1788,7 +1788,7 @@ out:
  * Encode a GETACL request
  */
 static int
-nfs4_xdr_enc_getacl(struct rpc_rqst *req, uint32_t *p,
+nfs4_xdr_enc_getacl(struct rpc_rqst *req, __be32 *p,
                struct nfs_getaclargs *args)
 {
        struct xdr_stream xdr;
@@ -1815,7 +1815,7 @@ out:
 /*
  * Encode a WRITE request
  */
-static int nfs4_xdr_enc_write(struct rpc_rqst *req, uint32_t *p, struct nfs_writeargs *args)
+static int nfs4_xdr_enc_write(struct rpc_rqst *req, __be32 *p, struct nfs_writeargs *args)
 {
        struct xdr_stream xdr;
        struct compound_hdr hdr = {
@@ -1839,7 +1839,7 @@ out:
 /*
  *  a COMMIT request
  */
-static int nfs4_xdr_enc_commit(struct rpc_rqst *req, uint32_t *p, struct nfs_writeargs *args)
+static int nfs4_xdr_enc_commit(struct rpc_rqst *req, __be32 *p, struct nfs_writeargs *args)
 {
        struct xdr_stream xdr;
        struct compound_hdr hdr = {
@@ -1863,7 +1863,7 @@ out:
 /*
  * FSINFO request
  */
-static int nfs4_xdr_enc_fsinfo(struct rpc_rqst *req, uint32_t *p, struct nfs4_fsinfo_arg *args)
+static int nfs4_xdr_enc_fsinfo(struct rpc_rqst *req, __be32 *p, struct nfs4_fsinfo_arg *args)
 {
        struct xdr_stream xdr;
        struct compound_hdr hdr = {
@@ -1882,7 +1882,7 @@ static int nfs4_xdr_enc_fsinfo(struct rpc_rqst *req, uint32_t *p, struct nfs4_fs
 /*
  * a PATHCONF request
  */
-static int nfs4_xdr_enc_pathconf(struct rpc_rqst *req, uint32_t *p, const struct nfs4_pathconf_arg *args)
+static int nfs4_xdr_enc_pathconf(struct rpc_rqst *req, __be32 *p, const struct nfs4_pathconf_arg *args)
 {
        struct xdr_stream xdr;
        struct compound_hdr hdr = {
@@ -1902,7 +1902,7 @@ static int nfs4_xdr_enc_pathconf(struct rpc_rqst *req, uint32_t *p, const struct
 /*
  * a STATFS request
  */
-static int nfs4_xdr_enc_statfs(struct rpc_rqst *req, uint32_t *p, const struct nfs4_statfs_arg *args)
+static int nfs4_xdr_enc_statfs(struct rpc_rqst *req, __be32 *p, const struct nfs4_statfs_arg *args)
 {
        struct xdr_stream xdr;
        struct compound_hdr hdr = {
@@ -1923,7 +1923,7 @@ static int nfs4_xdr_enc_statfs(struct rpc_rqst *req, uint32_t *p, const struct n
 /*
  * GETATTR_BITMAP request
  */
-static int nfs4_xdr_enc_server_caps(struct rpc_rqst *req, uint32_t *p, const struct nfs_fh *fhandle)
+static int nfs4_xdr_enc_server_caps(struct rpc_rqst *req, __be32 *p, const struct nfs_fh *fhandle)
 {
        struct xdr_stream xdr;
        struct compound_hdr hdr = {
@@ -1945,7 +1945,7 @@ static int nfs4_xdr_enc_server_caps(struct rpc_rqst *req, uint32_t *p, const str
 /*
  * a RENEW request
  */
-static int nfs4_xdr_enc_renew(struct rpc_rqst *req, uint32_t *p, struct nfs_client *clp)
+static int nfs4_xdr_enc_renew(struct rpc_rqst *req, __be32 *p, struct nfs_client *clp)
 {
        struct xdr_stream xdr;
        struct compound_hdr hdr = {
@@ -1960,7 +1960,7 @@ static int nfs4_xdr_enc_renew(struct rpc_rqst *req, uint32_t *p, struct nfs_clie
 /*
  * a SETCLIENTID request
  */
-static int nfs4_xdr_enc_setclientid(struct rpc_rqst *req, uint32_t *p, struct nfs4_setclientid *sc)
+static int nfs4_xdr_enc_setclientid(struct rpc_rqst *req, __be32 *p, struct nfs4_setclientid *sc)
 {
        struct xdr_stream xdr;
        struct compound_hdr hdr = {
@@ -1975,7 +1975,7 @@ static int nfs4_xdr_enc_setclientid(struct rpc_rqst *req, uint32_t *p, struct nf
 /*
  * a SETCLIENTID_CONFIRM request
  */
-static int nfs4_xdr_enc_setclientid_confirm(struct rpc_rqst *req, uint32_t *p, struct nfs_client *clp)
+static int nfs4_xdr_enc_setclientid_confirm(struct rpc_rqst *req, __be32 *p, struct nfs_client *clp)
 {
        struct xdr_stream xdr;
        struct compound_hdr hdr = {
@@ -1997,7 +1997,7 @@ static int nfs4_xdr_enc_setclientid_confirm(struct rpc_rqst *req, uint32_t *p, s
 /*
  * DELEGRETURN request
  */
-static int nfs4_xdr_enc_delegreturn(struct rpc_rqst *req, uint32_t *p, const struct nfs4_delegreturnargs *args)
+static int nfs4_xdr_enc_delegreturn(struct rpc_rqst *req, __be32 *p, const struct nfs4_delegreturnargs *args)
 {
        struct xdr_stream xdr;
        struct compound_hdr hdr = {
@@ -2021,7 +2021,7 @@ out:
 /*
  * Encode FS_LOCATIONS request
  */
-static int nfs4_xdr_enc_fs_locations(struct rpc_rqst *req, uint32_t *p, struct nfs4_fs_locations_arg *args)
+static int nfs4_xdr_enc_fs_locations(struct rpc_rqst *req, __be32 *p, struct nfs4_fs_locations_arg *args)
 {
        struct xdr_stream xdr;
        struct compound_hdr hdr = {
@@ -2086,7 +2086,7 @@ out:
 
 static int decode_opaque_inline(struct xdr_stream *xdr, unsigned int *len, char **string)
 {
-       uint32_t *p;
+       __be32 *p;
 
        READ_BUF(4);
        READ32(*len);
@@ -2097,7 +2097,7 @@ static int decode_opaque_inline(struct xdr_stream *xdr, unsigned int *len, char
 
 static int decode_compound_hdr(struct xdr_stream *xdr, struct compound_hdr *hdr)
 {
-       uint32_t *p;
+       __be32 *p;
 
        READ_BUF(8);
        READ32(hdr->status);
@@ -2112,7 +2112,7 @@ static int decode_compound_hdr(struct xdr_stream *xdr, struct compound_hdr *hdr)
 
 static int decode_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected)
 {
-       uint32_t *p;
+       __be32 *p;
        uint32_t opnum;
        int32_t nfserr;
 
@@ -2134,7 +2134,7 @@ static int decode_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected)
 /* Dummy routine */
 static int decode_ace(struct xdr_stream *xdr, void *ace, struct nfs_client *clp)
 {
-       uint32_t *p;
+       __be32 *p;
        unsigned int strlen;
        char *str;
 
@@ -2144,7 +2144,8 @@ static int decode_ace(struct xdr_stream *xdr, void *ace, struct nfs_client *clp)
 
 static int decode_attr_bitmap(struct xdr_stream *xdr, uint32_t *bitmap)
 {
-       uint32_t bmlen, *p;
+       uint32_t bmlen;
+       __be32 *p;
 
        READ_BUF(4);
        READ32(bmlen);
@@ -2159,9 +2160,9 @@ static int decode_attr_bitmap(struct xdr_stream *xdr, uint32_t *bitmap)
        return 0;
 }
 
-static inline int decode_attr_length(struct xdr_stream *xdr, uint32_t *attrlen, uint32_t **savep)
+static inline int decode_attr_length(struct xdr_stream *xdr, uint32_t *attrlen, __be32 **savep)
 {
-       uint32_t *p;
+       __be32 *p;
 
        READ_BUF(4);
        READ32(*attrlen);
@@ -2182,7 +2183,7 @@ static int decode_attr_supported(struct xdr_stream *xdr, uint32_t *bitmap, uint3
 
 static int decode_attr_type(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *type)
 {
-       uint32_t *p;
+       __be32 *p;
 
        *type = 0;
        if (unlikely(bitmap[0] & (FATTR4_WORD0_TYPE - 1U)))
@@ -2202,7 +2203,7 @@ static int decode_attr_type(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *
 
 static int decode_attr_change(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *change)
 {
-       uint32_t *p;
+       __be32 *p;
 
        *change = 0;
        if (unlikely(bitmap[0] & (FATTR4_WORD0_CHANGE - 1U)))
@@ -2219,7 +2220,7 @@ static int decode_attr_change(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t
 
 static int decode_attr_size(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *size)
 {
-       uint32_t *p;
+       __be32 *p;
 
        *size = 0;
        if (unlikely(bitmap[0] & (FATTR4_WORD0_SIZE - 1U)))
@@ -2235,7 +2236,7 @@ static int decode_attr_size(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *
 
 static int decode_attr_link_support(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res)
 {
-       uint32_t *p;
+       __be32 *p;
 
        *res = 0;
        if (unlikely(bitmap[0] & (FATTR4_WORD0_LINK_SUPPORT - 1U)))
@@ -2251,7 +2252,7 @@ static int decode_attr_link_support(struct xdr_stream *xdr, uint32_t *bitmap, ui
 
 static int decode_attr_symlink_support(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res)
 {
-       uint32_t *p;
+       __be32 *p;
 
        *res = 0;
        if (unlikely(bitmap[0] & (FATTR4_WORD0_SYMLINK_SUPPORT - 1U)))
@@ -2267,7 +2268,7 @@ static int decode_attr_symlink_support(struct xdr_stream *xdr, uint32_t *bitmap,
 
 static int decode_attr_fsid(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs_fsid *fsid)
 {
-       uint32_t *p;
+       __be32 *p;
 
        fsid->major = 0;
        fsid->minor = 0;
@@ -2287,7 +2288,7 @@ static int decode_attr_fsid(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs
 
 static int decode_attr_lease_time(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res)
 {
-       uint32_t *p;
+       __be32 *p;
 
        *res = 60;
        if (unlikely(bitmap[0] & (FATTR4_WORD0_LEASE_TIME - 1U)))
@@ -2303,7 +2304,7 @@ static int decode_attr_lease_time(struct xdr_stream *xdr, uint32_t *bitmap, uint
 
 static int decode_attr_aclsupport(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res)
 {
-       uint32_t *p;
+       __be32 *p;
 
        *res = ACL4_SUPPORT_ALLOW_ACL|ACL4_SUPPORT_DENY_ACL;
        if (unlikely(bitmap[0] & (FATTR4_WORD0_ACLSUPPORT - 1U)))
@@ -2319,7 +2320,7 @@ static int decode_attr_aclsupport(struct xdr_stream *xdr, uint32_t *bitmap, uint
 
 static int decode_attr_fileid(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *fileid)
 {
-       uint32_t *p;
+       __be32 *p;
 
        *fileid = 0;
        if (unlikely(bitmap[0] & (FATTR4_WORD0_FILEID - 1U)))
@@ -2335,7 +2336,7 @@ static int decode_attr_fileid(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t
 
 static int decode_attr_mounted_on_fileid(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *fileid)
 {
-       uint32_t *p;
+       __be32 *p;
 
        *fileid = 0;
        if (unlikely(bitmap[1] & (FATTR4_WORD1_MOUNTED_ON_FILEID - 1U)))
@@ -2351,7 +2352,7 @@ static int decode_attr_mounted_on_fileid(struct xdr_stream *xdr, uint32_t *bitma
 
 static int decode_attr_files_avail(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res)
 {
-       uint32_t *p;
+       __be32 *p;
        int status = 0;
 
        *res = 0;
@@ -2368,7 +2369,7 @@ static int decode_attr_files_avail(struct xdr_stream *xdr, uint32_t *bitmap, uin
 
 static int decode_attr_files_free(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res)
 {
-       uint32_t *p;
+       __be32 *p;
        int status = 0;
 
        *res = 0;
@@ -2385,7 +2386,7 @@ static int decode_attr_files_free(struct xdr_stream *xdr, uint32_t *bitmap, uint
 
 static int decode_attr_files_total(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res)
 {
-       uint32_t *p;
+       __be32 *p;
        int status = 0;
 
        *res = 0;
@@ -2403,7 +2404,7 @@ static int decode_attr_files_total(struct xdr_stream *xdr, uint32_t *bitmap, uin
 static int decode_pathname(struct xdr_stream *xdr, struct nfs4_pathname *path)
 {
        int n;
-       uint32_t *p;
+       __be32 *p;
        int status = 0;
 
        READ_BUF(4);
@@ -2448,7 +2449,7 @@ out_eio:
 static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs4_fs_locations *res)
 {
        int n;
-       uint32_t *p;
+       __be32 *p;
        int status = -EIO;
 
        if (unlikely(bitmap[0] & (FATTR4_WORD0_FS_LOCATIONS -1U)))
@@ -2512,7 +2513,7 @@ out_eio:
 
 static int decode_attr_maxfilesize(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res)
 {
-       uint32_t *p;
+       __be32 *p;
        int status = 0;
 
        *res = 0;
@@ -2529,7 +2530,7 @@ static int decode_attr_maxfilesize(struct xdr_stream *xdr, uint32_t *bitmap, uin
 
 static int decode_attr_maxlink(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *maxlink)
 {
-       uint32_t *p;
+       __be32 *p;
        int status = 0;
 
        *maxlink = 1;
@@ -2546,7 +2547,7 @@ static int decode_attr_maxlink(struct xdr_stream *xdr, uint32_t *bitmap, uint32_
 
 static int decode_attr_maxname(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *maxname)
 {
-       uint32_t *p;
+       __be32 *p;
        int status = 0;
 
        *maxname = 1024;
@@ -2563,7 +2564,7 @@ static int decode_attr_maxname(struct xdr_stream *xdr, uint32_t *bitmap, uint32_
 
 static int decode_attr_maxread(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res)
 {
-       uint32_t *p;
+       __be32 *p;
        int status = 0;
 
        *res = 1024;
@@ -2584,7 +2585,7 @@ static int decode_attr_maxread(struct xdr_stream *xdr, uint32_t *bitmap, uint32_
 
 static int decode_attr_maxwrite(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res)
 {
-       uint32_t *p;
+       __be32 *p;
        int status = 0;
 
        *res = 1024;
@@ -2605,7 +2606,7 @@ static int decode_attr_maxwrite(struct xdr_stream *xdr, uint32_t *bitmap, uint32
 
 static int decode_attr_mode(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *mode)
 {
-       uint32_t *p;
+       __be32 *p;
 
        *mode = 0;
        if (unlikely(bitmap[1] & (FATTR4_WORD1_MODE - 1U)))
@@ -2622,7 +2623,7 @@ static int decode_attr_mode(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *
 
 static int decode_attr_nlink(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *nlink)
 {
-       uint32_t *p;
+       __be32 *p;
 
        *nlink = 1;
        if (unlikely(bitmap[1] & (FATTR4_WORD1_NUMLINKS - 1U)))
@@ -2638,7 +2639,8 @@ static int decode_attr_nlink(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t
 
 static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs_client *clp, int32_t *uid)
 {
-       uint32_t len, *p;
+       uint32_t len;
+       __be32 *p;
 
        *uid = -2;
        if (unlikely(bitmap[1] & (FATTR4_WORD1_OWNER - 1U)))
@@ -2662,7 +2664,8 @@ static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap, struct nf
 
 static int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs_client *clp, int32_t *gid)
 {
-       uint32_t len, *p;
+       uint32_t len;
+       __be32 *p;
 
        *gid = -2;
        if (unlikely(bitmap[1] & (FATTR4_WORD1_OWNER_GROUP - 1U)))
@@ -2686,7 +2689,8 @@ static int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap, struct nf
 
 static int decode_attr_rdev(struct xdr_stream *xdr, uint32_t *bitmap, dev_t *rdev)
 {
-       uint32_t major = 0, minor = 0, *p;
+       uint32_t major = 0, minor = 0;
+       __be32 *p;
 
        *rdev = MKDEV(0,0);
        if (unlikely(bitmap[1] & (FATTR4_WORD1_RAWDEV - 1U)))
@@ -2708,7 +2712,7 @@ static int decode_attr_rdev(struct xdr_stream *xdr, uint32_t *bitmap, dev_t *rde
 
 static int decode_attr_space_avail(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res)
 {
-       uint32_t *p;
+       __be32 *p;
        int status = 0;
 
        *res = 0;
@@ -2725,7 +2729,7 @@ static int decode_attr_space_avail(struct xdr_stream *xdr, uint32_t *bitmap, uin
 
 static int decode_attr_space_free(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res)
 {
-       uint32_t *p;
+       __be32 *p;
        int status = 0;
 
        *res = 0;
@@ -2742,7 +2746,7 @@ static int decode_attr_space_free(struct xdr_stream *xdr, uint32_t *bitmap, uint
 
 static int decode_attr_space_total(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res)
 {
-       uint32_t *p;
+       __be32 *p;
        int status = 0;
 
        *res = 0;
@@ -2759,7 +2763,7 @@ static int decode_attr_space_total(struct xdr_stream *xdr, uint32_t *bitmap, uin
 
 static int decode_attr_space_used(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *used)
 {
-       uint32_t *p;
+       __be32 *p;
 
        *used = 0;
        if (unlikely(bitmap[1] & (FATTR4_WORD1_SPACE_USED - 1U)))
@@ -2776,7 +2780,7 @@ static int decode_attr_space_used(struct xdr_stream *xdr, uint32_t *bitmap, uint
 
 static int decode_attr_time(struct xdr_stream *xdr, struct timespec *time)
 {
-       uint32_t *p;
+       __be32 *p;
        uint64_t sec;
        uint32_t nsec;
 
@@ -2836,7 +2840,7 @@ static int decode_attr_time_modify(struct xdr_stream *xdr, uint32_t *bitmap, str
        return status;
 }
 
-static int verify_attr_len(struct xdr_stream *xdr, uint32_t *savep, uint32_t attrlen)
+static int verify_attr_len(struct xdr_stream *xdr, __be32 *savep, uint32_t attrlen)
 {
        unsigned int attrwords = XDR_QUADLEN(attrlen);
        unsigned int nwords = xdr->p - savep;
@@ -2854,7 +2858,7 @@ static int verify_attr_len(struct xdr_stream *xdr, uint32_t *savep, uint32_t att
 
 static int decode_change_info(struct xdr_stream *xdr, struct nfs4_change_info *cinfo)
 {
-       uint32_t *p;
+       __be32 *p;
 
        READ_BUF(20);
        READ32(cinfo->atomic);
@@ -2865,7 +2869,7 @@ static int decode_change_info(struct xdr_stream *xdr, struct nfs4_change_info *c
 
 static int decode_access(struct xdr_stream *xdr, struct nfs4_accessres *access)
 {
-       uint32_t *p;
+       __be32 *p;
        uint32_t supp, acc;
        int status;
 
@@ -2882,7 +2886,7 @@ static int decode_access(struct xdr_stream *xdr, struct nfs4_accessres *access)
 
 static int decode_close(struct xdr_stream *xdr, struct nfs_closeres *res)
 {
-       uint32_t *p;
+       __be32 *p;
        int status;
 
        status = decode_op_hdr(xdr, OP_CLOSE);
@@ -2895,7 +2899,7 @@ static int decode_close(struct xdr_stream *xdr, struct nfs_closeres *res)
 
 static int decode_commit(struct xdr_stream *xdr, struct nfs_writeres *res)
 {
-       uint32_t *p;
+       __be32 *p;
        int status;
 
        status = decode_op_hdr(xdr, OP_COMMIT);
@@ -2908,7 +2912,7 @@ static int decode_commit(struct xdr_stream *xdr, struct nfs_writeres *res)
 
 static int decode_create(struct xdr_stream *xdr, struct nfs4_change_info *cinfo)
 {
-       uint32_t *p;
+       __be32 *p;
        uint32_t bmlen;
        int status;
 
@@ -2925,7 +2929,7 @@ static int decode_create(struct xdr_stream *xdr, struct nfs4_change_info *cinfo)
 
 static int decode_server_caps(struct xdr_stream *xdr, struct nfs4_server_caps_res *res)
 {
-       uint32_t *savep;
+       __be32 *savep;
        uint32_t attrlen, 
                 bitmap[2] = {0};
        int status;
@@ -2952,7 +2956,7 @@ xdr_error:
        
 static int decode_statfs(struct xdr_stream *xdr, struct nfs_fsstat *fsstat)
 {
-       uint32_t *savep;
+       __be32 *savep;
        uint32_t attrlen, 
                 bitmap[2] = {0};
        int status;
@@ -2985,7 +2989,7 @@ xdr_error:
 
 static int decode_pathconf(struct xdr_stream *xdr, struct nfs_pathconf *pathconf)
 {
-       uint32_t *savep;
+       __be32 *savep;
        uint32_t attrlen, 
                 bitmap[2] = {0};
        int status;
@@ -3010,7 +3014,7 @@ xdr_error:
 
 static int decode_getfattr(struct xdr_stream *xdr, struct nfs_fattr *fattr, const struct nfs_server *server)
 {
-       uint32_t *savep;
+       __be32 *savep;
        uint32_t attrlen,
                 bitmap[2] = {0},
                 type;
@@ -3079,7 +3083,7 @@ xdr_error:
 
 static int decode_fsinfo(struct xdr_stream *xdr, struct nfs_fsinfo *fsinfo)
 {
-       uint32_t *savep;
+       __be32 *savep;
        uint32_t attrlen, bitmap[2];
        int status;
 
@@ -3111,7 +3115,7 @@ xdr_error:
 
 static int decode_getfh(struct xdr_stream *xdr, struct nfs_fh *fh)
 {
-       uint32_t *p;
+       __be32 *p;
        uint32_t len;
        int status;
 
@@ -3147,7 +3151,7 @@ static int decode_link(struct xdr_stream *xdr, struct nfs4_change_info *cinfo)
 static int decode_lock_denied (struct xdr_stream *xdr, struct file_lock *fl)
 {
        uint64_t offset, length, clientid;
-       uint32_t *p;
+       __be32 *p;
        uint32_t namelen, type;
 
        READ_BUF(32);
@@ -3172,7 +3176,7 @@ static int decode_lock_denied (struct xdr_stream *xdr, struct file_lock *fl)
 
 static int decode_lock(struct xdr_stream *xdr, struct nfs_lock_res *res)
 {
-       uint32_t *p;
+       __be32 *p;
        int status;
 
        status = decode_op_hdr(xdr, OP_LOCK);
@@ -3195,7 +3199,7 @@ static int decode_lockt(struct xdr_stream *xdr, struct nfs_lockt_res *res)
 
 static int decode_locku(struct xdr_stream *xdr, struct nfs_locku_res *res)
 {
-       uint32_t *p;
+       __be32 *p;
        int status;
 
        status = decode_op_hdr(xdr, OP_LOCKU);
@@ -3214,7 +3218,7 @@ static int decode_lookup(struct xdr_stream *xdr)
 /* This is too sick! */
 static int decode_space_limit(struct xdr_stream *xdr, u64 *maxsize)
 {
-        uint32_t *p;
+        __be32 *p;
        uint32_t limit_type, nblocks, blocksize;
 
        READ_BUF(12);
@@ -3233,7 +3237,7 @@ static int decode_space_limit(struct xdr_stream *xdr, u64 *maxsize)
 
 static int decode_delegation(struct xdr_stream *xdr, struct nfs_openres *res)
 {
-        uint32_t *p;
+        __be32 *p;
         uint32_t delegation_type;
 
        READ_BUF(4);
@@ -3259,7 +3263,7 @@ static int decode_delegation(struct xdr_stream *xdr, struct nfs_openres *res)
 
 static int decode_open(struct xdr_stream *xdr, struct nfs_openres *res)
 {
-        uint32_t *p;
+        __be32 *p;
         uint32_t bmlen;
         int status;
 
@@ -3287,7 +3291,7 @@ xdr_error:
 
 static int decode_open_confirm(struct xdr_stream *xdr, struct nfs_open_confirmres *res)
 {
-        uint32_t *p;
+        __be32 *p;
        int status;
 
         status = decode_op_hdr(xdr, OP_OPEN_CONFIRM);
@@ -3300,7 +3304,7 @@ static int decode_open_confirm(struct xdr_stream *xdr, struct nfs_open_confirmre
 
 static int decode_open_downgrade(struct xdr_stream *xdr, struct nfs_closeres *res)
 {
-       uint32_t *p;
+       __be32 *p;
        int status;
 
        status = decode_op_hdr(xdr, OP_OPEN_DOWNGRADE);
@@ -3324,7 +3328,7 @@ static int decode_putrootfh(struct xdr_stream *xdr)
 static int decode_read(struct xdr_stream *xdr, struct rpc_rqst *req, struct nfs_readres *res)
 {
        struct kvec *iov = req->rq_rcv_buf.head;
-       uint32_t *p;
+       __be32 *p;
        uint32_t count, eof, recvd, hdrlen;
        int status;
 
@@ -3354,7 +3358,7 @@ static int decode_readdir(struct xdr_stream *xdr, struct rpc_rqst *req, struct n
        struct page     *page = *rcvbuf->pages;
        struct kvec     *iov = rcvbuf->head;
        unsigned int    nr, pglen = rcvbuf->page_len;
-       uint32_t        *end, *entry, *p, *kaddr;
+       __be32          *end, *entry, *p, *kaddr;
        uint32_t        len, attrlen, xlen;
        int             hdrlen, recvd, status;
 
@@ -3376,7 +3380,7 @@ static int decode_readdir(struct xdr_stream *xdr, struct rpc_rqst *req, struct n
        xdr_read_pages(xdr, pglen);
 
        BUG_ON(pglen + readdir->pgbase > PAGE_CACHE_SIZE);
-       kaddr = p = (uint32_t *) kmap_atomic(page, KM_USER0);
+       kaddr = p = kmap_atomic(page, KM_USER0);
        end = p + ((pglen + readdir->pgbase) >> 2);
        entry = p;
        for (nr = 0; *p++; nr++) {
@@ -3428,7 +3432,7 @@ static int decode_readlink(struct xdr_stream *xdr, struct rpc_rqst *req)
        struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
        struct kvec *iov = rcvbuf->head;
        int hdrlen, len, recvd;
-       uint32_t *p;
+       __be32 *p;
        char *kaddr;
        int status;
 
@@ -3505,7 +3509,7 @@ decode_restorefh(struct xdr_stream *xdr)
 static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req,
                size_t *acl_len)
 {
-       uint32_t *savep;
+       __be32 *savep;
        uint32_t attrlen,
                 bitmap[2] = {0};
        struct kvec *iov = req->rq_rcv_buf.head;
@@ -3551,7 +3555,7 @@ decode_savefh(struct xdr_stream *xdr)
 
 static int decode_setattr(struct xdr_stream *xdr, struct nfs_setattrres *res)
 {
-       uint32_t *p;
+       __be32 *p;
        uint32_t bmlen;
        int status;
 
@@ -3567,7 +3571,7 @@ static int decode_setattr(struct xdr_stream *xdr, struct nfs_setattrres *res)
 
 static int decode_setclientid(struct xdr_stream *xdr, struct nfs_client *clp)
 {
-       uint32_t *p;
+       __be32 *p;
        uint32_t opnum;
        int32_t nfserr;
 
@@ -3610,7 +3614,7 @@ static int decode_setclientid_confirm(struct xdr_stream *xdr)
 
 static int decode_write(struct xdr_stream *xdr, struct nfs_writeres *res)
 {
-       uint32_t *p;
+       __be32 *p;
        int status;
 
        status = decode_op_hdr(xdr, OP_WRITE);
@@ -3632,7 +3636,7 @@ static int decode_delegreturn(struct xdr_stream *xdr)
 /*
  * Decode OPEN_DOWNGRADE response
  */
-static int nfs4_xdr_dec_open_downgrade(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_closeres *res)
+static int nfs4_xdr_dec_open_downgrade(struct rpc_rqst *rqstp, __be32 *p, struct nfs_closeres *res)
 {
         struct xdr_stream xdr;
         struct compound_hdr hdr;
@@ -3660,7 +3664,7 @@ out:
 /*
  * Decode ACCESS response
  */
-static int nfs4_xdr_dec_access(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_accessres *res)
+static int nfs4_xdr_dec_access(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_accessres *res)
 {
        struct xdr_stream xdr;
        struct compound_hdr hdr;
@@ -3678,7 +3682,7 @@ out:
 /*
  * Decode LOOKUP response
  */
-static int nfs4_xdr_dec_lookup(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_lookup_res *res)
+static int nfs4_xdr_dec_lookup(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_lookup_res *res)
 {
        struct xdr_stream xdr;
        struct compound_hdr hdr;
@@ -3701,7 +3705,7 @@ out:
 /*
  * Decode LOOKUP_ROOT response
  */
-static int nfs4_xdr_dec_lookup_root(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_lookup_res *res)
+static int nfs4_xdr_dec_lookup_root(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_lookup_res *res)
 {
        struct xdr_stream xdr;
        struct compound_hdr hdr;
@@ -3721,7 +3725,7 @@ out:
 /*
  * Decode REMOVE response
  */
-static int nfs4_xdr_dec_remove(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_remove_res *res)
+static int nfs4_xdr_dec_remove(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_remove_res *res)
 {
        struct xdr_stream xdr;
        struct compound_hdr hdr;
@@ -3742,7 +3746,7 @@ out:
 /*
  * Decode RENAME response
  */
-static int nfs4_xdr_dec_rename(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_rename_res *res)
+static int nfs4_xdr_dec_rename(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_rename_res *res)
 {
        struct xdr_stream xdr;
        struct compound_hdr hdr;
@@ -3772,7 +3776,7 @@ out:
 /*
  * Decode LINK response
  */
-static int nfs4_xdr_dec_link(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_link_res *res)
+static int nfs4_xdr_dec_link(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_link_res *res)
 {
        struct xdr_stream xdr;
        struct compound_hdr hdr;
@@ -3805,7 +3809,7 @@ out:
 /*
  * Decode CREATE response
  */
-static int nfs4_xdr_dec_create(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_create_res *res)
+static int nfs4_xdr_dec_create(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_create_res *res)
 {
        struct xdr_stream xdr;
        struct compound_hdr hdr;
@@ -3834,7 +3838,7 @@ out:
 /*
  * Decode SYMLINK response
  */
-static int nfs4_xdr_dec_symlink(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_create_res *res)
+static int nfs4_xdr_dec_symlink(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_create_res *res)
 {
        return nfs4_xdr_dec_create(rqstp, p, res);
 }
@@ -3842,7 +3846,7 @@ static int nfs4_xdr_dec_symlink(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4
 /*
  * Decode GETATTR response
  */
-static int nfs4_xdr_dec_getattr(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_getattr_res *res)
+static int nfs4_xdr_dec_getattr(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_getattr_res *res)
 {
        struct xdr_stream xdr;
        struct compound_hdr hdr;
@@ -3865,7 +3869,7 @@ out:
  * Encode an SETACL request
  */
 static int
-nfs4_xdr_enc_setacl(struct rpc_rqst *req, uint32_t *p, struct nfs_setaclargs *args)
+nfs4_xdr_enc_setacl(struct rpc_rqst *req, __be32 *p, struct nfs_setaclargs *args)
 {
         struct xdr_stream xdr;
         struct compound_hdr hdr = {
@@ -3886,7 +3890,7 @@ out:
  * Decode SETACL response
  */
 static int
-nfs4_xdr_dec_setacl(struct rpc_rqst *rqstp, uint32_t *p, void *res)
+nfs4_xdr_dec_setacl(struct rpc_rqst *rqstp, __be32 *p, void *res)
 {
        struct xdr_stream xdr;
        struct compound_hdr hdr;
@@ -3908,7 +3912,7 @@ out:
  * Decode GETACL response
  */
 static int
-nfs4_xdr_dec_getacl(struct rpc_rqst *rqstp, uint32_t *p, size_t *acl_len)
+nfs4_xdr_dec_getacl(struct rpc_rqst *rqstp, __be32 *p, size_t *acl_len)
 {
        struct xdr_stream xdr;
        struct compound_hdr hdr;
@@ -3930,7 +3934,7 @@ out:
 /*
  * Decode CLOSE response
  */
-static int nfs4_xdr_dec_close(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_closeres *res)
+static int nfs4_xdr_dec_close(struct rpc_rqst *rqstp, __be32 *p, struct nfs_closeres *res)
 {
         struct xdr_stream xdr;
         struct compound_hdr hdr;
@@ -3960,7 +3964,7 @@ out:
 /*
  * Decode OPEN response
  */
-static int nfs4_xdr_dec_open(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_openres *res)
+static int nfs4_xdr_dec_open(struct rpc_rqst *rqstp, __be32 *p, struct nfs_openres *res)
 {
         struct xdr_stream xdr;
         struct compound_hdr hdr;
@@ -3994,7 +3998,7 @@ out:
 /*
  * Decode OPEN_CONFIRM response
  */
-static int nfs4_xdr_dec_open_confirm(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_open_confirmres *res)
+static int nfs4_xdr_dec_open_confirm(struct rpc_rqst *rqstp, __be32 *p, struct nfs_open_confirmres *res)
 {
         struct xdr_stream xdr;
         struct compound_hdr hdr;
@@ -4015,7 +4019,7 @@ out:
 /*
  * Decode OPEN response
  */
-static int nfs4_xdr_dec_open_noattr(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_openres *res)
+static int nfs4_xdr_dec_open_noattr(struct rpc_rqst *rqstp, __be32 *p, struct nfs_openres *res)
 {
         struct xdr_stream xdr;
         struct compound_hdr hdr;
@@ -4039,7 +4043,7 @@ out:
 /*
  * Decode SETATTR response
  */
-static int nfs4_xdr_dec_setattr(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_setattrres *res)
+static int nfs4_xdr_dec_setattr(struct rpc_rqst *rqstp, __be32 *p, struct nfs_setattrres *res)
 {
         struct xdr_stream xdr;
         struct compound_hdr hdr;
@@ -4065,7 +4069,7 @@ out:
 /*
  * Decode LOCK response
  */
-static int nfs4_xdr_dec_lock(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_lock_res *res)
+static int nfs4_xdr_dec_lock(struct rpc_rqst *rqstp, __be32 *p, struct nfs_lock_res *res)
 {
        struct xdr_stream xdr;
        struct compound_hdr hdr;
@@ -4086,7 +4090,7 @@ out:
 /*
  * Decode LOCKT response
  */
-static int nfs4_xdr_dec_lockt(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_lockt_res *res)
+static int nfs4_xdr_dec_lockt(struct rpc_rqst *rqstp, __be32 *p, struct nfs_lockt_res *res)
 {
        struct xdr_stream xdr;
        struct compound_hdr hdr;
@@ -4107,7 +4111,7 @@ out:
 /*
  * Decode LOCKU response
  */
-static int nfs4_xdr_dec_locku(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_locku_res *res)
+static int nfs4_xdr_dec_locku(struct rpc_rqst *rqstp, __be32 *p, struct nfs_locku_res *res)
 {
        struct xdr_stream xdr;
        struct compound_hdr hdr;
@@ -4128,7 +4132,7 @@ out:
 /*
  * Decode READLINK response
  */
-static int nfs4_xdr_dec_readlink(struct rpc_rqst *rqstp, uint32_t *p, void *res)
+static int nfs4_xdr_dec_readlink(struct rpc_rqst *rqstp, __be32 *p, void *res)
 {
        struct xdr_stream xdr;
        struct compound_hdr hdr;
@@ -4149,7 +4153,7 @@ out:
 /*
  * Decode READDIR response
  */
-static int nfs4_xdr_dec_readdir(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_readdir_res *res)
+static int nfs4_xdr_dec_readdir(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_readdir_res *res)
 {
        struct xdr_stream xdr;
        struct compound_hdr hdr;
@@ -4170,7 +4174,7 @@ out:
 /*
  * Decode Read response
  */
-static int nfs4_xdr_dec_read(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_readres *res)
+static int nfs4_xdr_dec_read(struct rpc_rqst *rqstp, __be32 *p, struct nfs_readres *res)
 {
        struct xdr_stream xdr;
        struct compound_hdr hdr;
@@ -4193,7 +4197,7 @@ out:
 /*
  * Decode WRITE response
  */
-static int nfs4_xdr_dec_write(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_writeres *res)
+static int nfs4_xdr_dec_write(struct rpc_rqst *rqstp, __be32 *p, struct nfs_writeres *res)
 {
        struct xdr_stream xdr;
        struct compound_hdr hdr;
@@ -4219,7 +4223,7 @@ out:
 /*
  * Decode COMMIT response
  */
-static int nfs4_xdr_dec_commit(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_writeres *res)
+static int nfs4_xdr_dec_commit(struct rpc_rqst *rqstp, __be32 *p, struct nfs_writeres *res)
 {
        struct xdr_stream xdr;
        struct compound_hdr hdr;
@@ -4243,7 +4247,7 @@ out:
 /*
  * FSINFO request
  */
-static int nfs4_xdr_dec_fsinfo(struct rpc_rqst *req, uint32_t *p, struct nfs_fsinfo *fsinfo)
+static int nfs4_xdr_dec_fsinfo(struct rpc_rqst *req, __be32 *p, struct nfs_fsinfo *fsinfo)
 {
        struct xdr_stream xdr;
        struct compound_hdr hdr;
@@ -4263,7 +4267,7 @@ static int nfs4_xdr_dec_fsinfo(struct rpc_rqst *req, uint32_t *p, struct nfs_fsi
 /*
  * PATHCONF request
  */
-static int nfs4_xdr_dec_pathconf(struct rpc_rqst *req, uint32_t *p, struct nfs_pathconf *pathconf)
+static int nfs4_xdr_dec_pathconf(struct rpc_rqst *req, __be32 *p, struct nfs_pathconf *pathconf)
 {
        struct xdr_stream xdr;
        struct compound_hdr hdr;
@@ -4281,7 +4285,7 @@ static int nfs4_xdr_dec_pathconf(struct rpc_rqst *req, uint32_t *p, struct nfs_p
 /*
  * STATFS request
  */
-static int nfs4_xdr_dec_statfs(struct rpc_rqst *req, uint32_t *p, struct nfs_fsstat *fsstat)
+static int nfs4_xdr_dec_statfs(struct rpc_rqst *req, __be32 *p, struct nfs_fsstat *fsstat)
 {
        struct xdr_stream xdr;
        struct compound_hdr hdr;
@@ -4299,7 +4303,7 @@ static int nfs4_xdr_dec_statfs(struct rpc_rqst *req, uint32_t *p, struct nfs_fss
 /*
  * GETATTR_BITMAP request
  */
-static int nfs4_xdr_dec_server_caps(struct rpc_rqst *req, uint32_t *p, struct nfs4_server_caps_res *res)
+static int nfs4_xdr_dec_server_caps(struct rpc_rqst *req, __be32 *p, struct nfs4_server_caps_res *res)
 {
        struct xdr_stream xdr;
        struct compound_hdr hdr;
@@ -4318,7 +4322,7 @@ out:
 /*
  * Decode RENEW response
  */
-static int nfs4_xdr_dec_renew(struct rpc_rqst *rqstp, uint32_t *p, void *dummy)
+static int nfs4_xdr_dec_renew(struct rpc_rqst *rqstp, __be32 *p, void *dummy)
 {
        struct xdr_stream xdr;
        struct compound_hdr hdr;
@@ -4334,7 +4338,7 @@ static int nfs4_xdr_dec_renew(struct rpc_rqst *rqstp, uint32_t *p, void *dummy)
 /*
  * a SETCLIENTID request
  */
-static int nfs4_xdr_dec_setclientid(struct rpc_rqst *req, uint32_t *p,
+static int nfs4_xdr_dec_setclientid(struct rpc_rqst *req, __be32 *p,
                struct nfs_client *clp)
 {
        struct xdr_stream xdr;
@@ -4353,7 +4357,7 @@ static int nfs4_xdr_dec_setclientid(struct rpc_rqst *req, uint32_t *p,
 /*
  * a SETCLIENTID_CONFIRM request
  */
-static int nfs4_xdr_dec_setclientid_confirm(struct rpc_rqst *req, uint32_t *p, struct nfs_fsinfo *fsinfo)
+static int nfs4_xdr_dec_setclientid_confirm(struct rpc_rqst *req, __be32 *p, struct nfs_fsinfo *fsinfo)
 {
        struct xdr_stream xdr;
        struct compound_hdr hdr;
@@ -4375,7 +4379,7 @@ static int nfs4_xdr_dec_setclientid_confirm(struct rpc_rqst *req, uint32_t *p, s
 /*
  * DELEGRETURN request
  */
-static int nfs4_xdr_dec_delegreturn(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_delegreturnres *res)
+static int nfs4_xdr_dec_delegreturn(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_delegreturnres *res)
 {
        struct xdr_stream xdr;
        struct compound_hdr hdr;
@@ -4397,7 +4401,7 @@ out:
 /*
  * FS_LOCATIONS request
  */
-static int nfs4_xdr_dec_fs_locations(struct rpc_rqst *req, uint32_t *p, struct nfs4_fs_locations *res)
+static int nfs4_xdr_dec_fs_locations(struct rpc_rqst *req, __be32 *p, struct nfs4_fs_locations *res)
 {
        struct xdr_stream xdr;
        struct compound_hdr hdr;
@@ -4417,7 +4421,7 @@ out:
        return status;
 }
 
-uint32_t *nfs4_decode_dirent(uint32_t *p, struct nfs_entry *entry, int plus)
+__be32 *nfs4_decode_dirent(__be32 *p, struct nfs_entry *entry, int plus)
 {
        uint32_t bitmap[2] = {0};
        uint32_t len;
index 28659a919d6e47e5dfcf4ec3a0bdc7e827b4d477..28108c82b88742d6e325a0736f820bf8e044910e 100644 (file)
@@ -834,7 +834,7 @@ static int nfs4_get_sb(struct file_system_type *fs_type,
        }
        /* RFC3530: The default port for NFS is 2049 */
        if (addr.sin_port == 0)
-               addr.sin_port = NFS_PORT;
+               addr.sin_port = htons(NFS_PORT);
 
        /* Grab the authentication type */
        authflavour = RPC_AUTH_UNIX;
index f6675d2c386c29127a9e6bad4223f47a1dbd3e12..883dd4a1c157599284f3bae5127fa69418ec06e1 100644 (file)
@@ -57,6 +57,8 @@
 #include <linux/nfs_fs.h>
 #include <linux/nfs_mount.h>
 #include <linux/nfs_page.h>
+#include <linux/backing-dev.h>
+
 #include <asm/uaccess.h>
 #include <linux/smp_lock.h>
 
@@ -395,7 +397,7 @@ int nfs_writepages(struct address_space *mapping, struct writeback_control *wbc)
 out:
        clear_bit(BDI_write_congested, &bdi->state);
        wake_up_all(&nfs_write_congestion);
-       writeback_congestion_end();
+       congestion_end(WRITE);
        return err;
 }
 
@@ -588,10 +590,10 @@ static void nfs_cancel_commit_list(struct list_head *head)
 
        while(!list_empty(head)) {
                req = nfs_list_entry(head->next);
+               dec_zone_page_state(req->wb_page, NR_UNSTABLE_NFS);
                nfs_list_remove_request(req);
                nfs_inode_remove_request(req);
-               dec_zone_page_state(req->wb_page, NR_UNSTABLE_NFS);
-               nfs_clear_page_writeback(req);
+               nfs_unlock_request(req);
        }
 }
 
index 0c2be8c0307dea818c03d196e01b9e82b7ca4cff..c11f5375d7c11e7c0aa08b0f275310109bfa4f79 100644 (file)
@@ -46,7 +46,7 @@ xdr_nfsace_encode(struct xdr_array2_desc *desc, void *elem)
 {
        struct nfsacl_encode_desc *nfsacl_desc =
                (struct nfsacl_encode_desc *) desc;
-       u32 *p = (u32 *) elem;
+       __be32 *p = elem;
 
        struct posix_acl_entry *entry =
                &nfsacl_desc->acl->a_entries[nfsacl_desc->count++];
@@ -127,7 +127,7 @@ xdr_nfsace_decode(struct xdr_array2_desc *desc, void *elem)
 {
        struct nfsacl_decode_desc *nfsacl_desc =
                (struct nfsacl_decode_desc *) desc;
-       u32 *p = (u32 *) elem;
+       __be32 *p = elem;
        struct posix_acl_entry *entry;
 
        if (!nfsacl_desc->acl) {
index e13fa23bd108a2f8b86b9e3388a46509a003da64..f37df46d2eaa5d13042a0557c79a27ff2d510873 100644 (file)
@@ -1148,12 +1148,12 @@ exp_find(struct auth_domain *clp, int fsid_type, u32 *fsidv,
  * for a given NFSv4 client.   The root is defined to be the
  * export point with fsid==0
  */
-int
+__be32
 exp_pseudoroot(struct auth_domain *clp, struct svc_fh *fhp,
               struct cache_req *creq)
 {
        struct svc_export *exp;
-       int rv;
+       __be32 rv;
        u32 fsidv[2];
 
        mk_fsid_v1(fsidv, 0);
index 7b889ff15ae63a96ef47be64172c7d360ef2d61a..11fdaf7721b4e68f53d71ae6994d621b21d90a44 100644 (file)
@@ -25,7 +25,7 @@
 static u32
 nlm_fopen(struct svc_rqst *rqstp, struct nfs_fh *f, struct file **filp)
 {
-       u32             nfserr;
+       __be32          nfserr;
        struct svc_fh   fh;
 
        /* must initialize before using! but maxsize doesn't matter */
@@ -39,18 +39,20 @@ nlm_fopen(struct svc_rqst *rqstp, struct nfs_fh *f, struct file **filp)
        fh_put(&fh);
        rqstp->rq_client = NULL;
        exp_readunlock();
-       /* nlm and nfsd don't share error codes.
-        * we invent: 0 = no error
-        *            1 = stale file handle
-        *            2 = other error
+       /* We return nlm error codes as nlm doesn't know
+        * about nfsd, but nfsd does know about nlm..
         */
        switch (nfserr) {
        case nfs_ok:
                return 0;
+       case nfserr_dropit:
+               return nlm_drop_reply;
+#ifdef CONFIG_LOCKD_V4
        case nfserr_stale:
-               return 1;
+               return nlm4_stale_fh;
+#endif
        default:
-               return 2;
+               return nlm_lck_denied;
        }
 }
 
index 9187755661df06d9aec879a08167e9848c26c399..e3eca0816986fd2b6410f020ad9919c2b5f9e5e4 100644 (file)
@@ -21,7 +21,7 @@
 /*
  * NULL call.
  */
-static int
+static __be32
 nfsacld_proc_null(struct svc_rqst *rqstp, void *argp, void *resp)
 {
        return nfs_ok;
@@ -30,12 +30,12 @@ nfsacld_proc_null(struct svc_rqst *rqstp, void *argp, void *resp)
 /*
  * Get the Access and/or Default ACL of a file.
  */
-static int nfsacld_proc_getacl(struct svc_rqst * rqstp,
+static __be32 nfsacld_proc_getacl(struct svc_rqst * rqstp,
                struct nfsd3_getaclargs *argp, struct nfsd3_getaclres *resp)
 {
        svc_fh *fh;
        struct posix_acl *acl;
-       int nfserr = 0;
+       __be32 nfserr = 0;
 
        dprintk("nfsd: GETACL(2acl)   %s\n", SVCFH_fmt(&argp->fh));
 
@@ -97,12 +97,12 @@ fail:
 /*
  * Set the Access and/or Default ACL of a file.
  */
-static int nfsacld_proc_setacl(struct svc_rqst * rqstp,
+static __be32 nfsacld_proc_setacl(struct svc_rqst * rqstp,
                struct nfsd3_setaclargs *argp,
                struct nfsd_attrstat *resp)
 {
        svc_fh *fh;
-       int nfserr = 0;
+       __be32 nfserr = 0;
 
        dprintk("nfsd: SETACL(2acl)   %s\n", SVCFH_fmt(&argp->fh));
 
@@ -128,7 +128,7 @@ static int nfsacld_proc_setacl(struct svc_rqst * rqstp,
 /*
  * Check file attributes
  */
-static int nfsacld_proc_getattr(struct svc_rqst * rqstp,
+static __be32 nfsacld_proc_getattr(struct svc_rqst * rqstp,
                struct nfsd_fhandle *argp, struct nfsd_attrstat *resp)
 {
        dprintk("nfsd: GETATTR  %s\n", SVCFH_fmt(&argp->fh));
@@ -140,10 +140,10 @@ static int nfsacld_proc_getattr(struct svc_rqst * rqstp,
 /*
  * Check file access
  */
-static int nfsacld_proc_access(struct svc_rqst *rqstp, struct nfsd3_accessargs *argp,
+static __be32 nfsacld_proc_access(struct svc_rqst *rqstp, struct nfsd3_accessargs *argp,
                struct nfsd3_accessres *resp)
 {
-       int nfserr;
+       __be32 nfserr;
 
        dprintk("nfsd: ACCESS(2acl)   %s 0x%x\n",
                        SVCFH_fmt(&argp->fh),
@@ -158,7 +158,7 @@ static int nfsacld_proc_access(struct svc_rqst *rqstp, struct nfsd3_accessargs *
 /*
  * XDR decode functions
  */
-static int nfsaclsvc_decode_getaclargs(struct svc_rqst *rqstp, u32 *p,
+static int nfsaclsvc_decode_getaclargs(struct svc_rqst *rqstp, __be32 *p,
                struct nfsd3_getaclargs *argp)
 {
        if (!(p = nfs2svc_decode_fh(p, &argp->fh)))
@@ -169,7 +169,7 @@ static int nfsaclsvc_decode_getaclargs(struct svc_rqst *rqstp, u32 *p,
 }
 
 
-static int nfsaclsvc_decode_setaclargs(struct svc_rqst *rqstp, u32 *p,
+static int nfsaclsvc_decode_setaclargs(struct svc_rqst *rqstp, __be32 *p,
                struct nfsd3_setaclargs *argp)
 {
        struct kvec *head = rqstp->rq_arg.head;
@@ -194,7 +194,7 @@ static int nfsaclsvc_decode_setaclargs(struct svc_rqst *rqstp, u32 *p,
        return (n > 0);
 }
 
-static int nfsaclsvc_decode_fhandleargs(struct svc_rqst *rqstp, u32 *p,
+static int nfsaclsvc_decode_fhandleargs(struct svc_rqst *rqstp, __be32 *p,
                struct nfsd_fhandle *argp)
 {
        if (!(p = nfs2svc_decode_fh(p, &argp->fh)))
@@ -202,7 +202,7 @@ static int nfsaclsvc_decode_fhandleargs(struct svc_rqst *rqstp, u32 *p,
        return xdr_argsize_check(rqstp, p);
 }
 
-static int nfsaclsvc_decode_accessargs(struct svc_rqst *rqstp, u32 *p,
+static int nfsaclsvc_decode_accessargs(struct svc_rqst *rqstp, __be32 *p,
                struct nfsd3_accessargs *argp)
 {
        if (!(p = nfs2svc_decode_fh(p, &argp->fh)))
@@ -217,7 +217,7 @@ static int nfsaclsvc_decode_accessargs(struct svc_rqst *rqstp, u32 *p,
  */
 
 /* GETACL */
-static int nfsaclsvc_encode_getaclres(struct svc_rqst *rqstp, u32 *p,
+static int nfsaclsvc_encode_getaclres(struct svc_rqst *rqstp, __be32 *p,
                struct nfsd3_getaclres *resp)
 {
        struct dentry *dentry = resp->fh.fh_dentry;
@@ -259,7 +259,7 @@ static int nfsaclsvc_encode_getaclres(struct svc_rqst *rqstp, u32 *p,
        return 1;
 }
 
-static int nfsaclsvc_encode_attrstatres(struct svc_rqst *rqstp, u32 *p,
+static int nfsaclsvc_encode_attrstatres(struct svc_rqst *rqstp, __be32 *p,
                struct nfsd_attrstat *resp)
 {
        p = nfs2svc_encode_fattr(rqstp, p, &resp->fh);
@@ -267,7 +267,7 @@ static int nfsaclsvc_encode_attrstatres(struct svc_rqst *rqstp, u32 *p,
 }
 
 /* ACCESS */
-static int nfsaclsvc_encode_accessres(struct svc_rqst *rqstp, u32 *p,
+static int nfsaclsvc_encode_accessres(struct svc_rqst *rqstp, __be32 *p,
                struct nfsd3_accessres *resp)
 {
        p = nfs2svc_encode_fattr(rqstp, p, &resp->fh);
@@ -278,7 +278,7 @@ static int nfsaclsvc_encode_accessres(struct svc_rqst *rqstp, u32 *p,
 /*
  * XDR release functions
  */
-static int nfsaclsvc_release_getacl(struct svc_rqst *rqstp, u32 *p,
+static int nfsaclsvc_release_getacl(struct svc_rqst *rqstp, __be32 *p,
                struct nfsd3_getaclres *resp)
 {
        fh_put(&resp->fh);
@@ -287,7 +287,7 @@ static int nfsaclsvc_release_getacl(struct svc_rqst *rqstp, u32 *p,
        return 1;
 }
 
-static int nfsaclsvc_release_fhandle(struct svc_rqst *rqstp, u32 *p,
+static int nfsaclsvc_release_fhandle(struct svc_rqst *rqstp, __be32 *p,
                struct nfsd_fhandle *resp)
 {
        fh_put(&resp->fh);
index d4bdc00c1169cc3f462a1fe11e2ebae0e72b15a9..fcad2895ddb00dd288fb07618c1047d919b75076 100644 (file)
@@ -19,7 +19,7 @@
 /*
  * NULL call.
  */
-static int
+static __be32
 nfsd3_proc_null(struct svc_rqst *rqstp, void *argp, void *resp)
 {
        return nfs_ok;
@@ -28,12 +28,12 @@ nfsd3_proc_null(struct svc_rqst *rqstp, void *argp, void *resp)
 /*
  * Get the Access and/or Default ACL of a file.
  */
-static int nfsd3_proc_getacl(struct svc_rqst * rqstp,
+static __be32 nfsd3_proc_getacl(struct svc_rqst * rqstp,
                struct nfsd3_getaclargs *argp, struct nfsd3_getaclres *resp)
 {
        svc_fh *fh;
        struct posix_acl *acl;
-       int nfserr = 0;
+       __be32 nfserr = 0;
 
        fh = fh_copy(&resp->fh, &argp->fh);
        if ((nfserr = fh_verify(rqstp, &resp->fh, 0, MAY_NOP)))
@@ -93,12 +93,12 @@ fail:
 /*
  * Set the Access and/or Default ACL of a file.
  */
-static int nfsd3_proc_setacl(struct svc_rqst * rqstp,
+static __be32 nfsd3_proc_setacl(struct svc_rqst * rqstp,
                struct nfsd3_setaclargs *argp,
                struct nfsd3_attrstat *resp)
 {
        svc_fh *fh;
-       int nfserr = 0;
+       __be32 nfserr = 0;
 
        fh = fh_copy(&resp->fh, &argp->fh);
        nfserr = fh_verify(rqstp, &resp->fh, 0, MAY_SATTR);
@@ -122,7 +122,7 @@ static int nfsd3_proc_setacl(struct svc_rqst * rqstp,
 /*
  * XDR decode functions
  */
-static int nfs3svc_decode_getaclargs(struct svc_rqst *rqstp, u32 *p,
+static int nfs3svc_decode_getaclargs(struct svc_rqst *rqstp, __be32 *p,
                struct nfsd3_getaclargs *args)
 {
        if (!(p = nfs3svc_decode_fh(p, &args->fh)))
@@ -133,7 +133,7 @@ static int nfs3svc_decode_getaclargs(struct svc_rqst *rqstp, u32 *p,
 }
 
 
-static int nfs3svc_decode_setaclargs(struct svc_rqst *rqstp, u32 *p,
+static int nfs3svc_decode_setaclargs(struct svc_rqst *rqstp, __be32 *p,
                struct nfsd3_setaclargs *args)
 {
        struct kvec *head = rqstp->rq_arg.head;
@@ -163,7 +163,7 @@ static int nfs3svc_decode_setaclargs(struct svc_rqst *rqstp, u32 *p,
  */
 
 /* GETACL */
-static int nfs3svc_encode_getaclres(struct svc_rqst *rqstp, u32 *p,
+static int nfs3svc_encode_getaclres(struct svc_rqst *rqstp, __be32 *p,
                struct nfsd3_getaclres *resp)
 {
        struct dentry *dentry = resp->fh.fh_dentry;
@@ -208,7 +208,7 @@ static int nfs3svc_encode_getaclres(struct svc_rqst *rqstp, u32 *p,
 }
 
 /* SETACL */
-static int nfs3svc_encode_setaclres(struct svc_rqst *rqstp, u32 *p,
+static int nfs3svc_encode_setaclres(struct svc_rqst *rqstp, __be32 *p,
                struct nfsd3_attrstat *resp)
 {
        p = nfs3svc_encode_post_op_attr(rqstp, p, &resp->fh);
@@ -219,7 +219,7 @@ static int nfs3svc_encode_setaclres(struct svc_rqst *rqstp, u32 *p,
 /*
  * XDR release functions
  */
-static int nfs3svc_release_getacl(struct svc_rqst *rqstp, u32 *p,
+static int nfs3svc_release_getacl(struct svc_rqst *rqstp, __be32 *p,
                struct nfsd3_getaclres *resp)
 {
        fh_put(&resp->fh);
index a5ebc7dbb3842d7d1a3f9a7de6256831a07d026b..64db601c2bd2e90848aa653c1fca55710fdeef4a 100644 (file)
@@ -43,7 +43,7 @@ static int    nfs3_ftypes[] = {
 /*
  * NULL call.
  */
-static int
+static __be32
 nfsd3_proc_null(struct svc_rqst *rqstp, void *argp, void *resp)
 {
        return nfs_ok;
@@ -52,11 +52,12 @@ nfsd3_proc_null(struct svc_rqst *rqstp, void *argp, void *resp)
 /*
  * Get a file's attributes
  */
-static int
+static __be32
 nfsd3_proc_getattr(struct svc_rqst *rqstp, struct nfsd_fhandle  *argp,
                                           struct nfsd3_attrstat *resp)
 {
-       int     err, nfserr;
+       int     err;
+       __be32  nfserr;
 
        dprintk("nfsd: GETATTR(3)  %s\n",
                SVCFH_fmt(&argp->fh));
@@ -76,11 +77,11 @@ nfsd3_proc_getattr(struct svc_rqst *rqstp, struct nfsd_fhandle  *argp,
 /*
  * Set a file's attributes
  */
-static int
+static __be32
 nfsd3_proc_setattr(struct svc_rqst *rqstp, struct nfsd3_sattrargs *argp,
                                           struct nfsd3_attrstat  *resp)
 {
-       int     nfserr;
+       __be32  nfserr;
 
        dprintk("nfsd: SETATTR(3)  %s\n",
                                SVCFH_fmt(&argp->fh));
@@ -94,11 +95,11 @@ nfsd3_proc_setattr(struct svc_rqst *rqstp, struct nfsd3_sattrargs *argp,
 /*
  * Look up a path name component
  */
-static int
+static __be32
 nfsd3_proc_lookup(struct svc_rqst *rqstp, struct nfsd3_diropargs *argp,
                                          struct nfsd3_diropres  *resp)
 {
-       int     nfserr;
+       __be32  nfserr;
 
        dprintk("nfsd: LOOKUP(3)   %s %.*s\n",
                                SVCFH_fmt(&argp->fh),
@@ -118,11 +119,11 @@ nfsd3_proc_lookup(struct svc_rqst *rqstp, struct nfsd3_diropargs *argp,
 /*
  * Check file access
  */
-static int
+static __be32
 nfsd3_proc_access(struct svc_rqst *rqstp, struct nfsd3_accessargs *argp,
                                          struct nfsd3_accessres *resp)
 {
-       int     nfserr;
+       __be32  nfserr;
 
        dprintk("nfsd: ACCESS(3)   %s 0x%x\n",
                                SVCFH_fmt(&argp->fh),
@@ -137,11 +138,11 @@ nfsd3_proc_access(struct svc_rqst *rqstp, struct nfsd3_accessargs *argp,
 /*
  * Read a symlink.
  */
-static int
+static __be32
 nfsd3_proc_readlink(struct svc_rqst *rqstp, struct nfsd3_readlinkargs *argp,
                                           struct nfsd3_readlinkres *resp)
 {
-       int nfserr;
+       __be32 nfserr;
 
        dprintk("nfsd: READLINK(3) %s\n", SVCFH_fmt(&argp->fh));
 
@@ -155,11 +156,11 @@ nfsd3_proc_readlink(struct svc_rqst *rqstp, struct nfsd3_readlinkargs *argp,
 /*
  * Read a portion of a file.
  */
-static int
+static __be32
 nfsd3_proc_read(struct svc_rqst *rqstp, struct nfsd3_readargs *argp,
                                        struct nfsd3_readres  *resp)
 {
-       int     nfserr;
+       __be32  nfserr;
        u32     max_blocksize = svc_max_payload(rqstp);
 
        dprintk("nfsd: READ(3) %s %lu bytes at %lu\n",
@@ -195,11 +196,11 @@ nfsd3_proc_read(struct svc_rqst *rqstp, struct nfsd3_readargs *argp,
 /*
  * Write data to a file
  */
-static int
+static __be32
 nfsd3_proc_write(struct svc_rqst *rqstp, struct nfsd3_writeargs *argp,
                                         struct nfsd3_writeres  *resp)
 {
-       int     nfserr;
+       __be32  nfserr;
 
        dprintk("nfsd: WRITE(3)    %s %d bytes at %ld%s\n",
                                SVCFH_fmt(&argp->fh),
@@ -223,13 +224,13 @@ nfsd3_proc_write(struct svc_rqst *rqstp, struct nfsd3_writeargs *argp,
  * At least in theory; we'll see how it fares in practice when the
  * first reports about SunOS compatibility problems start to pour in...
  */
-static int
+static __be32
 nfsd3_proc_create(struct svc_rqst *rqstp, struct nfsd3_createargs *argp,
                                          struct nfsd3_diropres   *resp)
 {
        svc_fh          *dirfhp, *newfhp = NULL;
        struct iattr    *attr;
-       u32             nfserr;
+       __be32          nfserr;
 
        dprintk("nfsd: CREATE(3)   %s %.*s\n",
                                SVCFH_fmt(&argp->fh),
@@ -265,11 +266,11 @@ nfsd3_proc_create(struct svc_rqst *rqstp, struct nfsd3_createargs *argp,
 /*
  * Make directory. This operation is not idempotent.
  */
-static int
+static __be32
 nfsd3_proc_mkdir(struct svc_rqst *rqstp, struct nfsd3_createargs *argp,
                                         struct nfsd3_diropres   *resp)
 {
-       int     nfserr;
+       __be32  nfserr;
 
        dprintk("nfsd: MKDIR(3)    %s %.*s\n",
                                SVCFH_fmt(&argp->fh),
@@ -285,11 +286,11 @@ nfsd3_proc_mkdir(struct svc_rqst *rqstp, struct nfsd3_createargs *argp,
        RETURN_STATUS(nfserr);
 }
 
-static int
+static __be32
 nfsd3_proc_symlink(struct svc_rqst *rqstp, struct nfsd3_symlinkargs *argp,
                                           struct nfsd3_diropres    *resp)
 {
-       int     nfserr;
+       __be32  nfserr;
 
        dprintk("nfsd: SYMLINK(3)  %s %.*s -> %.*s\n",
                                SVCFH_fmt(&argp->ffh),
@@ -307,11 +308,12 @@ nfsd3_proc_symlink(struct svc_rqst *rqstp, struct nfsd3_symlinkargs *argp,
 /*
  * Make socket/fifo/device.
  */
-static int
+static __be32
 nfsd3_proc_mknod(struct svc_rqst *rqstp, struct nfsd3_mknodargs *argp,
                                         struct nfsd3_diropres  *resp)
 {
-       int     nfserr, type;
+       __be32  nfserr;
+       int type;
        dev_t   rdev = 0;
 
        dprintk("nfsd: MKNOD(3)    %s %.*s\n",
@@ -343,11 +345,11 @@ nfsd3_proc_mknod(struct svc_rqst *rqstp, struct nfsd3_mknodargs *argp,
 /*
  * Remove file/fifo/socket etc.
  */
-static int
+static __be32
 nfsd3_proc_remove(struct svc_rqst *rqstp, struct nfsd3_diropargs *argp,
                                          struct nfsd3_attrstat  *resp)
 {
-       int     nfserr;
+       __be32  nfserr;
 
        dprintk("nfsd: REMOVE(3)   %s %.*s\n",
                                SVCFH_fmt(&argp->fh),
@@ -363,11 +365,11 @@ nfsd3_proc_remove(struct svc_rqst *rqstp, struct nfsd3_diropargs *argp,
 /*
  * Remove a directory
  */
-static int
+static __be32
 nfsd3_proc_rmdir(struct svc_rqst *rqstp, struct nfsd3_diropargs *argp,
                                         struct nfsd3_attrstat  *resp)
 {
-       int     nfserr;
+       __be32  nfserr;
 
        dprintk("nfsd: RMDIR(3)    %s %.*s\n",
                                SVCFH_fmt(&argp->fh),
@@ -379,11 +381,11 @@ nfsd3_proc_rmdir(struct svc_rqst *rqstp, struct nfsd3_diropargs *argp,
        RETURN_STATUS(nfserr);
 }
 
-static int
+static __be32
 nfsd3_proc_rename(struct svc_rqst *rqstp, struct nfsd3_renameargs *argp,
                                          struct nfsd3_renameres  *resp)
 {
-       int     nfserr;
+       __be32  nfserr;
 
        dprintk("nfsd: RENAME(3)   %s %.*s ->\n",
                                SVCFH_fmt(&argp->ffh),
@@ -401,11 +403,11 @@ nfsd3_proc_rename(struct svc_rqst *rqstp, struct nfsd3_renameargs *argp,
        RETURN_STATUS(nfserr);
 }
 
-static int
+static __be32
 nfsd3_proc_link(struct svc_rqst *rqstp, struct nfsd3_linkargs *argp,
                                        struct nfsd3_linkres  *resp)
 {
-       int     nfserr;
+       __be32  nfserr;
 
        dprintk("nfsd: LINK(3)     %s ->\n",
                                SVCFH_fmt(&argp->ffh));
@@ -424,11 +426,12 @@ nfsd3_proc_link(struct svc_rqst *rqstp, struct nfsd3_linkargs *argp,
 /*
  * Read a portion of a directory.
  */
-static int
+static __be32
 nfsd3_proc_readdir(struct svc_rqst *rqstp, struct nfsd3_readdirargs *argp,
                                           struct nfsd3_readdirres  *resp)
 {
-       int             nfserr, count;
+       __be32          nfserr;
+       int             count;
 
        dprintk("nfsd: READDIR(3)  %s %d bytes at %d\n",
                                SVCFH_fmt(&argp->fh),
@@ -459,11 +462,12 @@ nfsd3_proc_readdir(struct svc_rqst *rqstp, struct nfsd3_readdirargs *argp,
  * Read a portion of a directory, including file handles and attrs.
  * For now, we choose to ignore the dircount parameter.
  */
-static int
+static __be32
 nfsd3_proc_readdirplus(struct svc_rqst *rqstp, struct nfsd3_readdirargs *argp,
                                               struct nfsd3_readdirres  *resp)
 {
-       int     nfserr, count = 0;
+       __be32  nfserr;
+       int     count = 0;
        loff_t  offset;
        int     i;
        caddr_t page_addr = NULL;
@@ -517,11 +521,11 @@ nfsd3_proc_readdirplus(struct svc_rqst *rqstp, struct nfsd3_readdirargs *argp,
 /*
  * Get file system stats
  */
-static int
+static __be32
 nfsd3_proc_fsstat(struct svc_rqst * rqstp, struct nfsd_fhandle    *argp,
                                           struct nfsd3_fsstatres *resp)
 {
-       int     nfserr;
+       __be32  nfserr;
 
        dprintk("nfsd: FSSTAT(3)   %s\n",
                                SVCFH_fmt(&argp->fh));
@@ -534,11 +538,11 @@ nfsd3_proc_fsstat(struct svc_rqst * rqstp, struct nfsd_fhandle    *argp,
 /*
  * Get file system info
  */
-static int
+static __be32
 nfsd3_proc_fsinfo(struct svc_rqst * rqstp, struct nfsd_fhandle    *argp,
                                           struct nfsd3_fsinfores *resp)
 {
-       int     nfserr;
+       __be32  nfserr;
        u32     max_blocksize = svc_max_payload(rqstp);
 
        dprintk("nfsd: FSINFO(3)   %s\n",
@@ -576,11 +580,11 @@ nfsd3_proc_fsinfo(struct svc_rqst * rqstp, struct nfsd_fhandle    *argp,
 /*
  * Get pathconf info for the specified file
  */
-static int
+static __be32
 nfsd3_proc_pathconf(struct svc_rqst * rqstp, struct nfsd_fhandle      *argp,
                                             struct nfsd3_pathconfres *resp)
 {
-       int     nfserr;
+       __be32  nfserr;
 
        dprintk("nfsd: PATHCONF(3) %s\n",
                                SVCFH_fmt(&argp->fh));
@@ -619,11 +623,11 @@ nfsd3_proc_pathconf(struct svc_rqst * rqstp, struct nfsd_fhandle      *argp,
 /*
  * Commit a file (range) to stable storage.
  */
-static int
+static __be32
 nfsd3_proc_commit(struct svc_rqst * rqstp, struct nfsd3_commitargs *argp,
                                           struct nfsd3_commitres  *resp)
 {
-       int     nfserr;
+       __be32  nfserr;
 
        dprintk("nfsd: COMMIT(3)   %s %u@%Lu\n",
                                SVCFH_fmt(&argp->fh),
index 247d518248bf71b2a95b5ce04b460374dd88c51f..b4baca3053c35a96b526107096f1864e349848f6 100644 (file)
@@ -42,23 +42,23 @@ static u32  nfs3_ftypes[] = {
 /*
  * XDR functions for basic NFS types
  */
-static inline u32 *
-encode_time3(u32 *p, struct timespec *time)
+static inline __be32 *
+encode_time3(__be32 *p, struct timespec *time)
 {
        *p++ = htonl((u32) time->tv_sec); *p++ = htonl(time->tv_nsec);
        return p;
 }
 
-static inline u32 *
-decode_time3(u32 *p, struct timespec *time)
+static inline __be32 *
+decode_time3(__be32 *p, struct timespec *time)
 {
        time->tv_sec = ntohl(*p++);
        time->tv_nsec = ntohl(*p++);
        return p;
 }
 
-static inline u32 *
-decode_fh(u32 *p, struct svc_fh *fhp)
+static inline __be32 *
+decode_fh(__be32 *p, struct svc_fh *fhp)
 {
        unsigned int size;
        fh_init(fhp, NFS3_FHSIZE);
@@ -72,13 +72,13 @@ decode_fh(u32 *p, struct svc_fh *fhp)
 }
 
 /* Helper function for NFSv3 ACL code */
-u32 *nfs3svc_decode_fh(u32 *p, struct svc_fh *fhp)
+__be32 *nfs3svc_decode_fh(__be32 *p, struct svc_fh *fhp)
 {
        return decode_fh(p, fhp);
 }
 
-static inline u32 *
-encode_fh(u32 *p, struct svc_fh *fhp)
+static inline __be32 *
+encode_fh(__be32 *p, struct svc_fh *fhp)
 {
        unsigned int size = fhp->fh_handle.fh_size;
        *p++ = htonl(size);
@@ -91,8 +91,8 @@ encode_fh(u32 *p, struct svc_fh *fhp)
  * Decode a file name and make sure that the path contains
  * no slashes or null bytes.
  */
-static inline u32 *
-decode_filename(u32 *p, char **namp, int *lenp)
+static inline __be32 *
+decode_filename(__be32 *p, char **namp, int *lenp)
 {
        char            *name;
        int             i;
@@ -107,8 +107,8 @@ decode_filename(u32 *p, char **namp, int *lenp)
        return p;
 }
 
-static inline u32 *
-decode_sattr3(u32 *p, struct iattr *iap)
+static inline __be32 *
+decode_sattr3(__be32 *p, struct iattr *iap)
 {
        u32     tmp;
 
@@ -153,8 +153,8 @@ decode_sattr3(u32 *p, struct iattr *iap)
        return p;
 }
 
-static inline u32 *
-encode_fattr3(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp,
+static inline __be32 *
+encode_fattr3(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp,
              struct kstat *stat)
 {
        struct dentry   *dentry = fhp->fh_dentry;
@@ -186,8 +186,8 @@ encode_fattr3(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp,
        return p;
 }
 
-static inline u32 *
-encode_saved_post_attr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp)
+static inline __be32 *
+encode_saved_post_attr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp)
 {
        struct inode    *inode = fhp->fh_dentry->d_inode;
 
@@ -224,8 +224,8 @@ encode_saved_post_attr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp)
  * The inode may be NULL if the call failed because of a stale file
  * handle. In this case, no attributes are returned.
  */
-static u32 *
-encode_post_op_attr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp)
+static __be32 *
+encode_post_op_attr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp)
 {
        struct dentry *dentry = fhp->fh_dentry;
        if (dentry && dentry->d_inode != NULL) {
@@ -243,8 +243,8 @@ encode_post_op_attr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp)
 }
 
 /* Helper for NFSv3 ACLs */
-u32 *
-nfs3svc_encode_post_op_attr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp)
+__be32 *
+nfs3svc_encode_post_op_attr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp)
 {
        return encode_post_op_attr(rqstp, p, fhp);
 }
@@ -252,8 +252,8 @@ nfs3svc_encode_post_op_attr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp)
 /*
  * Enocde weak cache consistency data
  */
-static u32 *
-encode_wcc_data(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp)
+static __be32 *
+encode_wcc_data(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp)
 {
        struct dentry   *dentry = fhp->fh_dentry;
 
@@ -278,7 +278,7 @@ encode_wcc_data(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp)
  * XDR decode functions
  */
 int
-nfs3svc_decode_fhandle(struct svc_rqst *rqstp, u32 *p, struct nfsd_fhandle *args)
+nfs3svc_decode_fhandle(struct svc_rqst *rqstp, __be32 *p, struct nfsd_fhandle *args)
 {
        if (!(p = decode_fh(p, &args->fh)))
                return 0;
@@ -286,7 +286,7 @@ nfs3svc_decode_fhandle(struct svc_rqst *rqstp, u32 *p, struct nfsd_fhandle *args
 }
 
 int
-nfs3svc_decode_sattrargs(struct svc_rqst *rqstp, u32 *p,
+nfs3svc_decode_sattrargs(struct svc_rqst *rqstp, __be32 *p,
                                        struct nfsd3_sattrargs *args)
 {
        if (!(p = decode_fh(p, &args->fh))
@@ -303,7 +303,7 @@ nfs3svc_decode_sattrargs(struct svc_rqst *rqstp, u32 *p,
 }
 
 int
-nfs3svc_decode_diropargs(struct svc_rqst *rqstp, u32 *p,
+nfs3svc_decode_diropargs(struct svc_rqst *rqstp, __be32 *p,
                                        struct nfsd3_diropargs *args)
 {
        if (!(p = decode_fh(p, &args->fh))
@@ -314,7 +314,7 @@ nfs3svc_decode_diropargs(struct svc_rqst *rqstp, u32 *p,
 }
 
 int
-nfs3svc_decode_accessargs(struct svc_rqst *rqstp, u32 *p,
+nfs3svc_decode_accessargs(struct svc_rqst *rqstp, __be32 *p,
                                        struct nfsd3_accessargs *args)
 {
        if (!(p = decode_fh(p, &args->fh)))
@@ -325,7 +325,7 @@ nfs3svc_decode_accessargs(struct svc_rqst *rqstp, u32 *p,
 }
 
 int
-nfs3svc_decode_readargs(struct svc_rqst *rqstp, u32 *p,
+nfs3svc_decode_readargs(struct svc_rqst *rqstp, __be32 *p,
                                        struct nfsd3_readargs *args)
 {
        unsigned int len;
@@ -355,7 +355,7 @@ nfs3svc_decode_readargs(struct svc_rqst *rqstp, u32 *p,
 }
 
 int
-nfs3svc_decode_writeargs(struct svc_rqst *rqstp, u32 *p,
+nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p,
                                        struct nfsd3_writeargs *args)
 {
        unsigned int len, v, hdr;
@@ -393,7 +393,7 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, u32 *p,
 }
 
 int
-nfs3svc_decode_createargs(struct svc_rqst *rqstp, u32 *p,
+nfs3svc_decode_createargs(struct svc_rqst *rqstp, __be32 *p,
                                        struct nfsd3_createargs *args)
 {
        if (!(p = decode_fh(p, &args->fh))
@@ -417,7 +417,7 @@ nfs3svc_decode_createargs(struct svc_rqst *rqstp, u32 *p,
        return xdr_argsize_check(rqstp, p);
 }
 int
-nfs3svc_decode_mkdirargs(struct svc_rqst *rqstp, u32 *p,
+nfs3svc_decode_mkdirargs(struct svc_rqst *rqstp, __be32 *p,
                                        struct nfsd3_createargs *args)
 {
        if (!(p = decode_fh(p, &args->fh))
@@ -429,7 +429,7 @@ nfs3svc_decode_mkdirargs(struct svc_rqst *rqstp, u32 *p,
 }
 
 int
-nfs3svc_decode_symlinkargs(struct svc_rqst *rqstp, u32 *p,
+nfs3svc_decode_symlinkargs(struct svc_rqst *rqstp, __be32 *p,
                                        struct nfsd3_symlinkargs *args)
 {
        unsigned int len;
@@ -481,7 +481,7 @@ nfs3svc_decode_symlinkargs(struct svc_rqst *rqstp, u32 *p,
 }
 
 int
-nfs3svc_decode_mknodargs(struct svc_rqst *rqstp, u32 *p,
+nfs3svc_decode_mknodargs(struct svc_rqst *rqstp, __be32 *p,
                                        struct nfsd3_mknodargs *args)
 {
        if (!(p = decode_fh(p, &args->fh))
@@ -505,7 +505,7 @@ nfs3svc_decode_mknodargs(struct svc_rqst *rqstp, u32 *p,
 }
 
 int
-nfs3svc_decode_renameargs(struct svc_rqst *rqstp, u32 *p,
+nfs3svc_decode_renameargs(struct svc_rqst *rqstp, __be32 *p,
                                        struct nfsd3_renameargs *args)
 {
        if (!(p = decode_fh(p, &args->ffh))
@@ -518,7 +518,7 @@ nfs3svc_decode_renameargs(struct svc_rqst *rqstp, u32 *p,
 }
 
 int
-nfs3svc_decode_readlinkargs(struct svc_rqst *rqstp, u32 *p,
+nfs3svc_decode_readlinkargs(struct svc_rqst *rqstp, __be32 *p,
                                        struct nfsd3_readlinkargs *args)
 {
        if (!(p = decode_fh(p, &args->fh)))
@@ -530,7 +530,7 @@ nfs3svc_decode_readlinkargs(struct svc_rqst *rqstp, u32 *p,
 }
 
 int
-nfs3svc_decode_linkargs(struct svc_rqst *rqstp, u32 *p,
+nfs3svc_decode_linkargs(struct svc_rqst *rqstp, __be32 *p,
                                        struct nfsd3_linkargs *args)
 {
        if (!(p = decode_fh(p, &args->ffh))
@@ -542,7 +542,7 @@ nfs3svc_decode_linkargs(struct svc_rqst *rqstp, u32 *p,
 }
 
 int
-nfs3svc_decode_readdirargs(struct svc_rqst *rqstp, u32 *p,
+nfs3svc_decode_readdirargs(struct svc_rqst *rqstp, __be32 *p,
                                        struct nfsd3_readdirargs *args)
 {
        if (!(p = decode_fh(p, &args->fh)))
@@ -562,7 +562,7 @@ nfs3svc_decode_readdirargs(struct svc_rqst *rqstp, u32 *p,
 }
 
 int
-nfs3svc_decode_readdirplusargs(struct svc_rqst *rqstp, u32 *p,
+nfs3svc_decode_readdirplusargs(struct svc_rqst *rqstp, __be32 *p,
                                        struct nfsd3_readdirargs *args)
 {
        int len, pn;
@@ -590,7 +590,7 @@ nfs3svc_decode_readdirplusargs(struct svc_rqst *rqstp, u32 *p,
 }
 
 int
-nfs3svc_decode_commitargs(struct svc_rqst *rqstp, u32 *p,
+nfs3svc_decode_commitargs(struct svc_rqst *rqstp, __be32 *p,
                                        struct nfsd3_commitargs *args)
 {
        if (!(p = decode_fh(p, &args->fh)))
@@ -609,14 +609,14 @@ nfs3svc_decode_commitargs(struct svc_rqst *rqstp, u32 *p,
  * will work properly.
  */
 int
-nfs3svc_encode_voidres(struct svc_rqst *rqstp, u32 *p, void *dummy)
+nfs3svc_encode_voidres(struct svc_rqst *rqstp, __be32 *p, void *dummy)
 {
        return xdr_ressize_check(rqstp, p);
 }
 
 /* GETATTR */
 int
-nfs3svc_encode_attrstat(struct svc_rqst *rqstp, u32 *p,
+nfs3svc_encode_attrstat(struct svc_rqst *rqstp, __be32 *p,
                                        struct nfsd3_attrstat *resp)
 {
        if (resp->status == 0)
@@ -626,7 +626,7 @@ nfs3svc_encode_attrstat(struct svc_rqst *rqstp, u32 *p,
 
 /* SETATTR, REMOVE, RMDIR */
 int
-nfs3svc_encode_wccstat(struct svc_rqst *rqstp, u32 *p,
+nfs3svc_encode_wccstat(struct svc_rqst *rqstp, __be32 *p,
                                        struct nfsd3_attrstat *resp)
 {
        p = encode_wcc_data(rqstp, p, &resp->fh);
@@ -635,7 +635,7 @@ nfs3svc_encode_wccstat(struct svc_rqst *rqstp, u32 *p,
 
 /* LOOKUP */
 int
-nfs3svc_encode_diropres(struct svc_rqst *rqstp, u32 *p,
+nfs3svc_encode_diropres(struct svc_rqst *rqstp, __be32 *p,
                                        struct nfsd3_diropres *resp)
 {
        if (resp->status == 0) {
@@ -648,7 +648,7 @@ nfs3svc_encode_diropres(struct svc_rqst *rqstp, u32 *p,
 
 /* ACCESS */
 int
-nfs3svc_encode_accessres(struct svc_rqst *rqstp, u32 *p,
+nfs3svc_encode_accessres(struct svc_rqst *rqstp, __be32 *p,
                                        struct nfsd3_accessres *resp)
 {
        p = encode_post_op_attr(rqstp, p, &resp->fh);
@@ -659,7 +659,7 @@ nfs3svc_encode_accessres(struct svc_rqst *rqstp, u32 *p,
 
 /* READLINK */
 int
-nfs3svc_encode_readlinkres(struct svc_rqst *rqstp, u32 *p,
+nfs3svc_encode_readlinkres(struct svc_rqst *rqstp, __be32 *p,
                                        struct nfsd3_readlinkres *resp)
 {
        p = encode_post_op_attr(rqstp, p, &resp->fh);
@@ -680,7 +680,7 @@ nfs3svc_encode_readlinkres(struct svc_rqst *rqstp, u32 *p,
 
 /* READ */
 int
-nfs3svc_encode_readres(struct svc_rqst *rqstp, u32 *p,
+nfs3svc_encode_readres(struct svc_rqst *rqstp, __be32 *p,
                                        struct nfsd3_readres *resp)
 {
        p = encode_post_op_attr(rqstp, p, &resp->fh);
@@ -704,7 +704,7 @@ nfs3svc_encode_readres(struct svc_rqst *rqstp, u32 *p,
 
 /* WRITE */
 int
-nfs3svc_encode_writeres(struct svc_rqst *rqstp, u32 *p,
+nfs3svc_encode_writeres(struct svc_rqst *rqstp, __be32 *p,
                                        struct nfsd3_writeres *resp)
 {
        p = encode_wcc_data(rqstp, p, &resp->fh);
@@ -719,7 +719,7 @@ nfs3svc_encode_writeres(struct svc_rqst *rqstp, u32 *p,
 
 /* CREATE, MKDIR, SYMLINK, MKNOD */
 int
-nfs3svc_encode_createres(struct svc_rqst *rqstp, u32 *p,
+nfs3svc_encode_createres(struct svc_rqst *rqstp, __be32 *p,
                                        struct nfsd3_diropres *resp)
 {
        if (resp->status == 0) {
@@ -733,7 +733,7 @@ nfs3svc_encode_createres(struct svc_rqst *rqstp, u32 *p,
 
 /* RENAME */
 int
-nfs3svc_encode_renameres(struct svc_rqst *rqstp, u32 *p,
+nfs3svc_encode_renameres(struct svc_rqst *rqstp, __be32 *p,
                                        struct nfsd3_renameres *resp)
 {
        p = encode_wcc_data(rqstp, p, &resp->ffh);
@@ -743,7 +743,7 @@ nfs3svc_encode_renameres(struct svc_rqst *rqstp, u32 *p,
 
 /* LINK */
 int
-nfs3svc_encode_linkres(struct svc_rqst *rqstp, u32 *p,
+nfs3svc_encode_linkres(struct svc_rqst *rqstp, __be32 *p,
                                        struct nfsd3_linkres *resp)
 {
        p = encode_post_op_attr(rqstp, p, &resp->fh);
@@ -753,7 +753,7 @@ nfs3svc_encode_linkres(struct svc_rqst *rqstp, u32 *p,
 
 /* READDIR */
 int
-nfs3svc_encode_readdirres(struct svc_rqst *rqstp, u32 *p,
+nfs3svc_encode_readdirres(struct svc_rqst *rqstp, __be32 *p,
                                        struct nfsd3_readdirres *resp)
 {
        p = encode_post_op_attr(rqstp, p, &resp->fh);
@@ -776,8 +776,8 @@ nfs3svc_encode_readdirres(struct svc_rqst *rqstp, u32 *p,
                return xdr_ressize_check(rqstp, p);
 }
 
-static inline u32 *
-encode_entry_baggage(struct nfsd3_readdirres *cd, u32 *p, const char *name,
+static inline __be32 *
+encode_entry_baggage(struct nfsd3_readdirres *cd, __be32 *p, const char *name,
             int namlen, ino_t ino)
 {
        *p++ = xdr_one;                          /* mark entry present */
@@ -790,8 +790,8 @@ encode_entry_baggage(struct nfsd3_readdirres *cd, u32 *p, const char *name,
        return p;
 }
 
-static inline u32 *
-encode_entryplus_baggage(struct nfsd3_readdirres *cd, u32 *p,
+static inline __be32 *
+encode_entryplus_baggage(struct nfsd3_readdirres *cd, __be32 *p,
                struct svc_fh *fhp)
 {
                p = encode_post_op_attr(cd->rqstp, p, fhp);
@@ -853,7 +853,7 @@ encode_entry(struct readdir_cd *ccd, const char *name,
 {
        struct nfsd3_readdirres *cd = container_of(ccd, struct nfsd3_readdirres,
                                                        common);
-       u32             *p = cd->buffer;
+       __be32          *p = cd->buffer;
        caddr_t         curr_page_addr = NULL;
        int             pn;             /* current page number */
        int             slen;           /* string (name) length */
@@ -919,7 +919,7 @@ encode_entry(struct readdir_cd *ccd, const char *name,
        } else if (cd->rqstp->rq_respages[pn+1] != NULL) {
                /* temporarily encode entry into next page, then move back to
                 * current and next page in rq_respages[] */
-               u32 *p1, *tmp;
+               __be32 *p1, *tmp;
                int len1, len2;
 
                /* grab next page for temporary storage of entry */
@@ -1009,7 +1009,7 @@ nfs3svc_encode_entry_plus(struct readdir_cd *cd, const char *name,
 
 /* FSSTAT */
 int
-nfs3svc_encode_fsstatres(struct svc_rqst *rqstp, u32 *p,
+nfs3svc_encode_fsstatres(struct svc_rqst *rqstp, __be32 *p,
                                        struct nfsd3_fsstatres *resp)
 {
        struct kstatfs  *s = &resp->stats;
@@ -1031,7 +1031,7 @@ nfs3svc_encode_fsstatres(struct svc_rqst *rqstp, u32 *p,
 
 /* FSINFO */
 int
-nfs3svc_encode_fsinfores(struct svc_rqst *rqstp, u32 *p,
+nfs3svc_encode_fsinfores(struct svc_rqst *rqstp, __be32 *p,
                                        struct nfsd3_fsinfores *resp)
 {
        *p++ = xdr_zero;        /* no post_op_attr */
@@ -1055,7 +1055,7 @@ nfs3svc_encode_fsinfores(struct svc_rqst *rqstp, u32 *p,
 
 /* PATHCONF */
 int
-nfs3svc_encode_pathconfres(struct svc_rqst *rqstp, u32 *p,
+nfs3svc_encode_pathconfres(struct svc_rqst *rqstp, __be32 *p,
                                        struct nfsd3_pathconfres *resp)
 {
        *p++ = xdr_zero;        /* no post_op_attr */
@@ -1074,7 +1074,7 @@ nfs3svc_encode_pathconfres(struct svc_rqst *rqstp, u32 *p,
 
 /* COMMIT */
 int
-nfs3svc_encode_commitres(struct svc_rqst *rqstp, u32 *p,
+nfs3svc_encode_commitres(struct svc_rqst *rqstp, __be32 *p,
                                        struct nfsd3_commitres *resp)
 {
        p = encode_wcc_data(rqstp, p, &resp->fh);
@@ -1090,7 +1090,7 @@ nfs3svc_encode_commitres(struct svc_rqst *rqstp, u32 *p,
  * XDR release functions
  */
 int
-nfs3svc_release_fhandle(struct svc_rqst *rqstp, u32 *p,
+nfs3svc_release_fhandle(struct svc_rqst *rqstp, __be32 *p,
                                        struct nfsd3_attrstat *resp)
 {
        fh_put(&resp->fh);
@@ -1098,7 +1098,7 @@ nfs3svc_release_fhandle(struct svc_rqst *rqstp, u32 *p,
 }
 
 int
-nfs3svc_release_fhandle2(struct svc_rqst *rqstp, u32 *p,
+nfs3svc_release_fhandle2(struct svc_rqst *rqstp, __be32 *p,
                                        struct nfsd3_fhandle_pair *resp)
 {
        fh_put(&resp->fh1);
index f6ca9fb3fc63fb7b78870bd387d8844c648e5b57..f57655a7a2b66b9ae1b1567e9d5500b581a5c9ae 100644 (file)
@@ -85,8 +85,8 @@ enum nfs_cb_opnum4 {
 /*
 * Generic encode routines from fs/nfs/nfs4xdr.c
 */
-static inline u32 *
-xdr_writemem(u32 *p, const void *ptr, int nbytes)
+static inline __be32 *
+xdr_writemem(__be32 *p, const void *ptr, int nbytes)
 {
        int tmp = XDR_QUADLEN(nbytes);
        if (!tmp)
@@ -205,7 +205,7 @@ nfs_cb_stat_to_errno(int stat)
 static int
 encode_cb_compound_hdr(struct xdr_stream *xdr, struct nfs4_cb_compound_hdr *hdr)
 {
-       u32 * p;
+       __be32 * p;
 
        RESERVE_SPACE(16);
        WRITE32(0);            /* tag length is always 0 */
@@ -218,7 +218,7 @@ encode_cb_compound_hdr(struct xdr_stream *xdr, struct nfs4_cb_compound_hdr *hdr)
 static int
 encode_cb_recall(struct xdr_stream *xdr, struct nfs4_cb_recall *cb_rec)
 {
-       u32 *p;
+       __be32 *p;
        int len = cb_rec->cbr_fhlen;
 
        RESERVE_SPACE(12+sizeof(cb_rec->cbr_stateid) + len);
@@ -231,7 +231,7 @@ encode_cb_recall(struct xdr_stream *xdr, struct nfs4_cb_recall *cb_rec)
 }
 
 static int
-nfs4_xdr_enc_cb_null(struct rpc_rqst *req, u32 *p)
+nfs4_xdr_enc_cb_null(struct rpc_rqst *req, __be32 *p)
 {
        struct xdr_stream xdrs, *xdr = &xdrs;
 
@@ -241,7 +241,7 @@ nfs4_xdr_enc_cb_null(struct rpc_rqst *req, u32 *p)
 }
 
 static int
-nfs4_xdr_enc_cb_recall(struct rpc_rqst *req, u32 *p, struct nfs4_cb_recall *args)
+nfs4_xdr_enc_cb_recall(struct rpc_rqst *req, __be32 *p, struct nfs4_cb_recall *args)
 {
        struct xdr_stream xdr;
        struct nfs4_cb_compound_hdr hdr = {
@@ -257,7 +257,7 @@ nfs4_xdr_enc_cb_recall(struct rpc_rqst *req, u32 *p, struct nfs4_cb_recall *args
 
 static int
 decode_cb_compound_hdr(struct xdr_stream *xdr, struct nfs4_cb_compound_hdr *hdr){
-        u32 *p;
+        __be32 *p;
 
         READ_BUF(8);
         READ32(hdr->status);
@@ -272,7 +272,7 @@ decode_cb_compound_hdr(struct xdr_stream *xdr, struct nfs4_cb_compound_hdr *hdr)
 static int
 decode_cb_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected)
 {
-       u32 *p;
+       __be32 *p;
        u32 op;
        int32_t nfserr;
 
@@ -291,13 +291,13 @@ decode_cb_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected)
 }
 
 static int
-nfs4_xdr_dec_cb_null(struct rpc_rqst *req, u32 *p)
+nfs4_xdr_dec_cb_null(struct rpc_rqst *req, __be32 *p)
 {
        return 0;
 }
 
 static int
-nfs4_xdr_dec_cb_recall(struct rpc_rqst *rqstp, u32 *p)
+nfs4_xdr_dec_cb_recall(struct rpc_rqst *rqstp, __be32 *p)
 {
        struct xdr_stream xdr;
        struct nfs4_cb_compound_hdr hdr;
@@ -421,7 +421,7 @@ nfsd4_probe_callback(struct nfs4_client *clp)
 
        /* Create RPC client */
        cb->cb_client = rpc_create(&args);
-       if (!cb->cb_client) {
+       if (IS_ERR(cb->cb_client)) {
                dprintk("NFSD: couldn't create callback client\n");
                goto out_err;
        }
@@ -448,10 +448,10 @@ nfsd4_probe_callback(struct nfs4_client *clp)
 out_rpciod:
        atomic_dec(&clp->cl_count);
        rpciod_down();
-       cb->cb_client = NULL;
 out_clnt:
        rpc_shutdown_client(cb->cb_client);
 out_err:
+       cb->cb_client = NULL;
        dprintk("NFSD: warning: no callback path to client %.*s\n",
                (int)clp->cl_name.len, clp->cl_name.data);
 }
@@ -461,7 +461,7 @@ nfs4_cb_null(struct rpc_task *task, void *dummy)
 {
        struct nfs4_client *clp = (struct nfs4_client *)task->tk_msg.rpc_argp;
        struct nfs4_callback *cb = &clp->cl_callback;
-       u32 addr = htonl(cb->cb_addr);
+       __be32 addr = htonl(cb->cb_addr);
 
        dprintk("NFSD: nfs4_cb_null task->tk_status %d\n", task->tk_status);
 
index 8333db12caca56207a0142fcb9a94000f962ad69..0a7bbdc4a10aba9ea8d01059864851c7a05de179 100644 (file)
@@ -67,32 +67,32 @@ fh_dup2(struct svc_fh *dst, struct svc_fh *src)
        *dst = *src;
 }
 
-static int
-do_open_permission(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open)
+static __be32
+do_open_permission(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open, int accmode)
 {
-       int accmode, status;
+       __be32 status;
 
        if (open->op_truncate &&
                !(open->op_share_access & NFS4_SHARE_ACCESS_WRITE))
                return nfserr_inval;
 
-       accmode = MAY_NOP;
        if (open->op_share_access & NFS4_SHARE_ACCESS_READ)
-               accmode = MAY_READ;
-       if (open->op_share_deny & NFS4_SHARE_ACCESS_WRITE)
+               accmode |= MAY_READ;
+       if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE)
                accmode |= (MAY_WRITE | MAY_TRUNC);
-       accmode |= MAY_OWNER_OVERRIDE;
+       if (open->op_share_deny & NFS4_SHARE_DENY_WRITE)
+               accmode |= MAY_WRITE;
 
        status = fh_verify(rqstp, current_fh, S_IFREG, accmode);
 
        return status;
 }
 
-static int
+static __be32
 do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open)
 {
        struct svc_fh resfh;
-       int status;
+       __be32 status;
 
        fh_init(&resfh, NFS4_FHSIZE);
        open->op_truncate = 0;
@@ -124,17 +124,17 @@ do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_o
                                &resfh.fh_handle.fh_base,
                                resfh.fh_handle.fh_size);
 
-               status = do_open_permission(rqstp, current_fh, open);
+               status = do_open_permission(rqstp, current_fh, open, MAY_NOP);
        }
 
        fh_put(&resfh);
        return status;
 }
 
-static int
+static __be32
 do_open_fhandle(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open)
 {
-       int status;
+       __be32 status;
 
        /* Only reclaims from previously confirmed clients are valid */
        if ((status = nfs4_check_open_reclaim(&open->op_clientid)))
@@ -155,16 +155,16 @@ do_open_fhandle(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_
        open->op_truncate = (open->op_iattr.ia_valid & ATTR_SIZE) &&
                (open->op_iattr.ia_size == 0);
 
-       status = do_open_permission(rqstp, current_fh, open);
+       status = do_open_permission(rqstp, current_fh, open, MAY_OWNER_OVERRIDE);
 
        return status;
 }
 
 
-static inline int
+static inline __be32
 nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open, struct nfs4_stateowner **replay_owner)
 {
-       int status;
+       __be32 status;
        dprintk("NFSD: nfsd4_open filename %.*s op_stateowner %p\n",
                (int)open->op_fname.len, open->op_fname.data,
                open->op_stateowner);
@@ -177,7 +177,7 @@ nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open
 
        /* check seqid for replay. set nfs4_owner */
        status = nfsd4_process_open1(open);
-       if (status == NFSERR_REPLAY_ME) {
+       if (status == nfserr_replay_me) {
                struct nfs4_replay *rp = &open->op_stateowner->so_replay;
                fh_put(current_fh);
                current_fh->fh_handle.fh_size = rp->rp_openfh_len;
@@ -188,7 +188,7 @@ nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open
                        dprintk("nfsd4_open: replay failed"
                                " restoring previous filehandle\n");
                else
-                       status = NFSERR_REPLAY_ME;
+                       status = nfserr_replay_me;
        }
        if (status)
                goto out;
@@ -261,7 +261,7 @@ out:
 /*
  * filehandle-manipulating ops.
  */
-static inline int
+static inline __be32
 nfsd4_getfh(struct svc_fh *current_fh, struct svc_fh **getfh)
 {
        if (!current_fh->fh_dentry)
@@ -271,7 +271,7 @@ nfsd4_getfh(struct svc_fh *current_fh, struct svc_fh **getfh)
        return nfs_ok;
 }
 
-static inline int
+static inline __be32
 nfsd4_putfh(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_putfh *putfh)
 {
        fh_put(current_fh);
@@ -280,10 +280,10 @@ nfsd4_putfh(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_putf
        return fh_verify(rqstp, current_fh, 0, MAY_NOP);
 }
 
-static inline int
+static inline __be32
 nfsd4_putrootfh(struct svc_rqst *rqstp, struct svc_fh *current_fh)
 {
-       int status;
+       __be32 status;
 
        fh_put(current_fh);
        status = exp_pseudoroot(rqstp->rq_client, current_fh,
@@ -291,7 +291,7 @@ nfsd4_putrootfh(struct svc_rqst *rqstp, struct svc_fh *current_fh)
        return status;
 }
 
-static inline int
+static inline __be32
 nfsd4_restorefh(struct svc_fh *current_fh, struct svc_fh *save_fh)
 {
        if (!save_fh->fh_dentry)
@@ -301,7 +301,7 @@ nfsd4_restorefh(struct svc_fh *current_fh, struct svc_fh *save_fh)
        return nfs_ok;
 }
 
-static inline int
+static inline __be32
 nfsd4_savefh(struct svc_fh *current_fh, struct svc_fh *save_fh)
 {
        if (!current_fh->fh_dentry)
@@ -314,7 +314,7 @@ nfsd4_savefh(struct svc_fh *current_fh, struct svc_fh *save_fh)
 /*
  * misc nfsv4 ops
  */
-static inline int
+static inline __be32
 nfsd4_access(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_access *access)
 {
        if (access->ac_req_access & ~NFS3_ACCESS_FULL)
@@ -324,10 +324,10 @@ nfsd4_access(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_acc
        return nfsd_access(rqstp, current_fh, &access->ac_resp_access, &access->ac_supported);
 }
 
-static inline int
+static inline __be32
 nfsd4_commit(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_commit *commit)
 {
-       int status;
+       __be32 status;
 
        u32 *p = (u32 *)commit->co_verf.data;
        *p++ = nfssvc_boot.tv_sec;
@@ -339,11 +339,11 @@ nfsd4_commit(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_com
        return status;
 }
 
-static int
+static __be32
 nfsd4_create(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_create *create)
 {
        struct svc_fh resfh;
-       int status;
+       __be32 status;
        dev_t rdev;
 
        fh_init(&resfh, NFS4_FHSIZE);
@@ -423,10 +423,10 @@ nfsd4_create(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_cre
        return status;
 }
 
-static inline int
+static inline __be32
 nfsd4_getattr(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_getattr *getattr)
 {
-       int status;
+       __be32 status;
 
        status = fh_verify(rqstp, current_fh, 0, MAY_NOP);
        if (status)
@@ -442,11 +442,11 @@ nfsd4_getattr(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_ge
        return nfs_ok;
 }
 
-static inline int
+static inline __be32
 nfsd4_link(struct svc_rqst *rqstp, struct svc_fh *current_fh,
           struct svc_fh *save_fh, struct nfsd4_link *link)
 {
-       int status = nfserr_nofilehandle;
+       __be32 status = nfserr_nofilehandle;
 
        if (!save_fh->fh_dentry)
                return status;
@@ -456,11 +456,11 @@ nfsd4_link(struct svc_rqst *rqstp, struct svc_fh *current_fh,
        return status;
 }
 
-static int
+static __be32
 nfsd4_lookupp(struct svc_rqst *rqstp, struct svc_fh *current_fh)
 {
        struct svc_fh tmp_fh;
-       int ret;
+       __be32 ret;
 
        fh_init(&tmp_fh, NFS4_FHSIZE);
        if((ret = exp_pseudoroot(rqstp->rq_client, &tmp_fh,
@@ -474,16 +474,16 @@ nfsd4_lookupp(struct svc_rqst *rqstp, struct svc_fh *current_fh)
        return nfsd_lookup(rqstp, current_fh, "..", 2, current_fh);
 }
 
-static inline int
+static inline __be32
 nfsd4_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lookup *lookup)
 {
        return nfsd_lookup(rqstp, current_fh, lookup->lo_name, lookup->lo_len, current_fh);
 }
 
-static inline int
+static inline __be32
 nfsd4_read(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_read *read)
 {
-       int status;
+       __be32 status;
 
        /* no need to check permission - this will be done in nfsd_read() */
 
@@ -508,7 +508,7 @@ out:
        return status;
 }
 
-static inline int
+static inline __be32
 nfsd4_readdir(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_readdir *readdir)
 {
        u64 cookie = readdir->rd_cookie;
@@ -531,7 +531,7 @@ nfsd4_readdir(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_re
        return nfs_ok;
 }
 
-static inline int
+static inline __be32
 nfsd4_readlink(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_readlink *readlink)
 {
        readlink->rl_rqstp = rqstp;
@@ -539,10 +539,10 @@ nfsd4_readlink(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_r
        return nfs_ok;
 }
 
-static inline int
+static inline __be32
 nfsd4_remove(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_remove *remove)
 {
-       int status;
+       __be32 status;
 
        if (nfs4_in_grace())
                return nfserr_grace;
@@ -556,11 +556,11 @@ nfsd4_remove(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_rem
        return status;
 }
 
-static inline int
+static inline __be32
 nfsd4_rename(struct svc_rqst *rqstp, struct svc_fh *current_fh,
             struct svc_fh *save_fh, struct nfsd4_rename *rename)
 {
-       int status = nfserr_nofilehandle;
+       __be32 status = nfserr_nofilehandle;
 
        if (!save_fh->fh_dentry)
                return status;
@@ -589,10 +589,10 @@ nfsd4_rename(struct svc_rqst *rqstp, struct svc_fh *current_fh,
        return status;
 }
 
-static inline int
+static inline __be32
 nfsd4_setattr(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_setattr *setattr)
 {
-       int status = nfs_ok;
+       __be32 status = nfs_ok;
 
        if (setattr->sa_iattr.ia_valid & ATTR_SIZE) {
                nfs4_lock_state();
@@ -614,13 +614,13 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_se
        return status;
 }
 
-static inline int
+static inline __be32
 nfsd4_write(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_write *write)
 {
        stateid_t *stateid = &write->wr_stateid;
        struct file *filp = NULL;
        u32 *p;
-       int status = nfs_ok;
+       __be32 status = nfs_ok;
 
        /* no need to check permission - this will be done in nfsd_write() */
 
@@ -661,12 +661,12 @@ nfsd4_write(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_writ
  * attributes matched.  VERIFY is implemented by mapping NFSERR_SAME
  * to NFS_OK after the call; NVERIFY by mapping NFSERR_NOT_SAME to NFS_OK.
  */
-static int
+static __be32
 nfsd4_verify(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_verify *verify)
 {
-       u32 *buf, *p;
+       __be32 *buf, *p;
        int count;
-       int status;
+       __be32 status;
 
        status = fh_verify(rqstp, current_fh, 0, MAY_NOP);
        if (status)
@@ -715,7 +715,7 @@ out_kfree:
 /*
  * NULL call.
  */
-static int
+static __be32
 nfsd4_proc_null(struct svc_rqst *rqstp, void *argp, void *resp)
 {
        return nfs_ok;
@@ -731,7 +731,7 @@ static inline void nfsd4_increment_op_stats(u32 opnum)
 /*
  * COMPOUND call.
  */
-static int
+static __be32
 nfsd4_proc_compound(struct svc_rqst *rqstp,
                    struct nfsd4_compoundargs *args,
                    struct nfsd4_compoundres *resp)
@@ -741,7 +741,7 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
        struct svc_fh   *save_fh = NULL;
        struct nfs4_stateowner *replay_owner = NULL;
        int             slack_space;    /* in words, not bytes! */
-       int             status;
+       __be32          status;
 
        status = nfserr_resource;
        current_fh = kmalloc(sizeof(*current_fh), GFP_KERNEL);
@@ -937,7 +937,7 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
                }
 
 encode_op:
-               if (op->status == NFSERR_REPLAY_ME) {
+               if (op->status == nfserr_replay_me) {
                        op->replay = &replay_owner->so_replay;
                        nfsd4_encode_replay(resp, op);
                        status = op->status = op->replay->rp_status;
index 1cbd2e4ee12252bb30c8a5c37a5aa50486584252..e9d07704680e7f5e99adad09c643f24e16442ee1 100644 (file)
@@ -83,13 +83,13 @@ md5_to_hex(char *out, char *md5)
        *out = '\0';
 }
 
-int
+__be32
 nfs4_make_rec_clidname(char *dname, struct xdr_netobj *clname)
 {
        struct xdr_netobj cksum;
        struct hash_desc desc;
        struct scatterlist sg[1];
-       int status = nfserr_resource;
+       __be32 status = nfserr_resource;
 
        dprintk("NFSD: nfs4_make_rec_clidname for %.*s\n",
                        clname->len, clname->data);
@@ -193,7 +193,7 @@ nfsd4_build_dentrylist(void *arg, const char *name, int namlen,
        struct dentry_list *child;
 
        if (name && isdotent(name, namlen))
-               return nfs_ok;
+               return 0;
        dentry = lookup_one_len(name, parent, namlen);
        if (IS_ERR(dentry))
                return PTR_ERR(dentry);
@@ -333,14 +333,14 @@ purge_old(struct dentry *parent, struct dentry *child)
        int status;
 
        if (nfs4_has_reclaimed_state(child->d_name.name))
-               return nfs_ok;
+               return 0;
 
        status = nfsd4_clear_clid_dir(parent, child);
        if (status)
                printk("failed to remove client recovery directory %s\n",
                                child->d_name.name);
        /* Keep trying, success or failure: */
-       return nfs_ok;
+       return 0;
 }
 
 void
@@ -365,10 +365,10 @@ load_recdir(struct dentry *parent, struct dentry *child)
                printk("nfsd4: illegal name %s in recovery directory\n",
                                child->d_name.name);
                /* Keep trying; maybe the others are OK: */
-               return nfs_ok;
+               return 0;
        }
        nfs4_client_to_reclaim(child->d_name.name);
-       return nfs_ok;
+       return 0;
 }
 
 int
index ebcf226a9e4a1fb65d04baa8e6ac10dc7f845071..293b6495829f863a16e45504f26b6d47d12d2128 100644 (file)
@@ -710,10 +710,10 @@ out_err:
  *             as described above.
  *
  */
-int
+__be32
 nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_setclientid *setclid)
 {
-       u32                     ip_addr = rqstp->rq_addr.sin_addr.s_addr;
+       __be32                  ip_addr = rqstp->rq_addr.sin_addr.s_addr;
        struct xdr_netobj       clname = { 
                .len = setclid->se_namelen,
                .data = setclid->se_name,
@@ -721,7 +721,7 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_setclientid *setclid)
        nfs4_verifier           clverifier = setclid->se_verf;
        unsigned int            strhashval;
        struct nfs4_client      *conf, *unconf, *new;
-       int                     status;
+       __be32                  status;
        char                    dname[HEXDIR_LEN];
        
        if (!check_name(clname))
@@ -875,14 +875,14 @@ out:
  *
  * NOTE: callback information will be processed here in a future patch
  */
-int
+__be32
 nfsd4_setclientid_confirm(struct svc_rqst *rqstp, struct nfsd4_setclientid_confirm *setclientid_confirm)
 {
-       u32 ip_addr = rqstp->rq_addr.sin_addr.s_addr;
+       __be32 ip_addr = rqstp->rq_addr.sin_addr.s_addr;
        struct nfs4_client *conf, *unconf;
        nfs4_verifier confirm = setclientid_confirm->sc_confirm; 
        clientid_t * clid = &setclientid_confirm->sc_clientid;
-       int status;
+       __be32 status;
 
        if (STALE_CLIENTID(clid))
                return nfserr_stale_clientid;
@@ -1280,13 +1280,13 @@ test_share(struct nfs4_stateid *stp, struct nfsd4_open *open) {
  * Called to check deny when READ with all zero stateid or
  * WRITE with all zero or all one stateid
  */
-static int
+static __be32
 nfs4_share_conflict(struct svc_fh *current_fh, unsigned int deny_type)
 {
        struct inode *ino = current_fh->fh_dentry->d_inode;
        struct nfs4_file *fp;
        struct nfs4_stateid *stp;
-       int ret;
+       __be32 ret;
 
        dprintk("NFSD: nfs4_share_conflict\n");
 
@@ -1444,7 +1444,7 @@ static struct lock_manager_operations nfsd_lease_mng_ops = {
 };
 
 
-int
+__be32
 nfsd4_process_open1(struct nfsd4_open *open)
 {
        clientid_t *clientid = &open->op_clientid;
@@ -1477,7 +1477,7 @@ nfsd4_process_open1(struct nfsd4_open *open)
        }
        if (open->op_seqid == sop->so_seqid - 1) {
                if (sop->so_replay.rp_buflen)
-                       return NFSERR_REPLAY_ME;
+                       return nfserr_replay_me;
                /* The original OPEN failed so spectacularly
                 * that we don't even have replay data saved!
                 * Therefore, we have no choice but to continue
@@ -1501,7 +1501,7 @@ renew:
        return nfs_ok;
 }
 
-static inline int
+static inline __be32
 nfs4_check_delegmode(struct nfs4_delegation *dp, int flags)
 {
        if ((flags & WR_STATE) && (dp->dl_type == NFS4_OPEN_DELEGATE_READ))
@@ -1522,12 +1522,12 @@ find_delegation_file(struct nfs4_file *fp, stateid_t *stid)
        return NULL;
 }
 
-static int
+static __be32
 nfs4_check_deleg(struct nfs4_file *fp, struct nfsd4_open *open,
                struct nfs4_delegation **dp)
 {
        int flags;
-       int status = nfserr_bad_stateid;
+       __be32 status = nfserr_bad_stateid;
 
        *dp = find_delegation_file(fp, &open->op_delegate_stateid);
        if (*dp == NULL)
@@ -1546,11 +1546,11 @@ out:
        return nfs_ok;
 }
 
-static int
+static __be32
 nfs4_check_open(struct nfs4_file *fp, struct nfsd4_open *open, struct nfs4_stateid **stpp)
 {
        struct nfs4_stateid *local;
-       int status = nfserr_share_denied;
+       __be32 status = nfserr_share_denied;
        struct nfs4_stateowner *sop = open->op_stateowner;
 
        list_for_each_entry(local, &fp->fi_stateids, st_perfile) {
@@ -1575,7 +1575,7 @@ nfs4_alloc_stateid(void)
        return kmem_cache_alloc(stateid_slab, GFP_KERNEL);
 }
 
-static int
+static __be32
 nfs4_new_open(struct svc_rqst *rqstp, struct nfs4_stateid **stpp,
                struct nfs4_delegation *dp,
                struct svc_fh *cur_fh, int flags)
@@ -1590,7 +1590,7 @@ nfs4_new_open(struct svc_rqst *rqstp, struct nfs4_stateid **stpp,
                get_file(dp->dl_vfs_file);
                stp->st_vfs_file = dp->dl_vfs_file;
        } else {
-               int status;
+               __be32 status;
                status = nfsd_open(rqstp, cur_fh, S_IFREG, flags,
                                &stp->st_vfs_file);
                if (status) {
@@ -1604,7 +1604,7 @@ nfs4_new_open(struct svc_rqst *rqstp, struct nfs4_stateid **stpp,
        return 0;
 }
 
-static inline int
+static inline __be32
 nfsd4_truncate(struct svc_rqst *rqstp, struct svc_fh *fh,
                struct nfsd4_open *open)
 {
@@ -1619,22 +1619,22 @@ nfsd4_truncate(struct svc_rqst *rqstp, struct svc_fh *fh,
        return nfsd_setattr(rqstp, fh, &iattr, 0, (time_t)0);
 }
 
-static int
+static __be32
 nfs4_upgrade_open(struct svc_rqst *rqstp, struct svc_fh *cur_fh, struct nfs4_stateid *stp, struct nfsd4_open *open)
 {
        struct file *filp = stp->st_vfs_file;
        struct inode *inode = filp->f_dentry->d_inode;
        unsigned int share_access, new_writer;
-       int status;
+       __be32 status;
 
        set_access(&share_access, stp->st_access_bmap);
        new_writer = (~share_access) & open->op_share_access
                        & NFS4_SHARE_ACCESS_WRITE;
 
        if (new_writer) {
-               status = get_write_access(inode);
-               if (status)
-                       return nfserrno(status);
+               int err = get_write_access(inode);
+               if (err)
+                       return nfserrno(err);
        }
        status = nfsd4_truncate(rqstp, cur_fh, open);
        if (status) {
@@ -1738,14 +1738,14 @@ out:
 /*
  * called with nfs4_lock_state() held.
  */
-int
+__be32
 nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open)
 {
        struct nfs4_file *fp = NULL;
        struct inode *ino = current_fh->fh_dentry->d_inode;
        struct nfs4_stateid *stp = NULL;
        struct nfs4_delegation *dp = NULL;
-       int status;
+       __be32 status;
 
        status = nfserr_inval;
        if (!access_valid(open->op_share_access)
@@ -1833,11 +1833,11 @@ static struct work_struct laundromat_work;
 static void laundromat_main(void *);
 static DECLARE_WORK(laundromat_work, laundromat_main, NULL);
 
-int 
+__be32
 nfsd4_renew(clientid_t *clid)
 {
        struct nfs4_client *clp;
-       int status;
+       __be32 status;
 
        nfs4_lock_state();
        dprintk("process_renew(%08x/%08x): starting\n", 
@@ -1996,9 +1996,9 @@ access_permit_write(unsigned long access_bmap)
 }
 
 static
-int nfs4_check_openmode(struct nfs4_stateid *stp, int flags)
+__be32 nfs4_check_openmode(struct nfs4_stateid *stp, int flags)
 {
-        int status = nfserr_openmode;
+        __be32 status = nfserr_openmode;
 
        if ((flags & WR_STATE) && (!access_permit_write(stp->st_access_bmap)))
                 goto out;
@@ -2009,7 +2009,7 @@ out:
        return status;
 }
 
-static inline int
+static inline __be32
 check_special_stateids(svc_fh *current_fh, stateid_t *stateid, int flags)
 {
        /* Trying to call delegreturn with a special stateid? Yuch: */
@@ -2043,14 +2043,14 @@ io_during_grace_disallowed(struct inode *inode, int flags)
 /*
 * Checks for stateid operations
 */
-int
+__be32
 nfs4_preprocess_stateid_op(struct svc_fh *current_fh, stateid_t *stateid, int flags, struct file **filpp)
 {
        struct nfs4_stateid *stp = NULL;
        struct nfs4_delegation *dp = NULL;
        stateid_t *stidp;
        struct inode *ino = current_fh->fh_dentry->d_inode;
-       int status;
+       __be32 status;
 
        dprintk("NFSD: preprocess_stateid_op: stateid = (%08x/%08x/%08x/%08x)\n",
                stateid->si_boot, stateid->si_stateownerid, 
@@ -2125,7 +2125,7 @@ setlkflg (int type)
 /* 
  * Checks for sequence id mutating operations. 
  */
-static int
+static __be32
 nfs4_preprocess_seqid_op(struct svc_fh *current_fh, u32 seqid, stateid_t *stateid, int flags, struct nfs4_stateowner **sopp, struct nfs4_stateid **stpp, struct nfsd4_lock *lock)
 {
        struct nfs4_stateid *stp;
@@ -2169,7 +2169,7 @@ nfs4_preprocess_seqid_op(struct svc_fh *current_fh, u32 seqid, stateid_t *statei
                clientid_t *lockclid = &lock->v.new.clientid;
                struct nfs4_client *clp = sop->so_client;
                int lkflg = 0;
-               int status;
+               __be32 status;
 
                lkflg = setlkflg(lock->lk_type);
 
@@ -2233,7 +2233,7 @@ check_replay:
        if (seqid == sop->so_seqid - 1) {
                dprintk("NFSD: preprocess_seqid_op: retransmission?\n");
                /* indicate replay to calling function */
-               return NFSERR_REPLAY_ME;
+               return nfserr_replay_me;
        }
        printk("NFSD: preprocess_seqid_op: bad seqid (expected %d, got %d)\n",
                        sop->so_seqid, seqid);
@@ -2241,10 +2241,10 @@ check_replay:
        return nfserr_bad_seqid;
 }
 
-int
+__be32
 nfsd4_open_confirm(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open_confirm *oc, struct nfs4_stateowner **replay_owner)
 {
-       int status;
+       __be32 status;
        struct nfs4_stateowner *sop;
        struct nfs4_stateid *stp;
 
@@ -2310,10 +2310,10 @@ reset_union_bmap_deny(unsigned long deny, unsigned long *bmap)
        }
 }
 
-int
+__be32
 nfsd4_open_downgrade(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open_downgrade *od, struct nfs4_stateowner **replay_owner)
 {
-       int status;
+       __be32 status;
        struct nfs4_stateid *stp;
        unsigned int share_access;
 
@@ -2365,10 +2365,10 @@ out:
 /*
  * nfs4_unlock_state() called after encode
  */
-int
+__be32
 nfsd4_close(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_close *close, struct nfs4_stateowner **replay_owner)
 {
-       int status;
+       __be32 status;
        struct nfs4_stateid *stp;
 
        dprintk("NFSD: nfsd4_close on file %.*s\n", 
@@ -2404,10 +2404,10 @@ out:
        return status;
 }
 
-int
+__be32
 nfsd4_delegreturn(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_delegreturn *dr)
 {
-       int status;
+       __be32 status;
 
        if ((status = fh_verify(rqstp, current_fh, S_IFREG, 0)))
                goto out;
@@ -2635,7 +2635,7 @@ check_lock_length(u64 offset, u64 length)
 /*
  *  LOCK operation 
  */
-int
+__be32
 nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock *lock, struct nfs4_stateowner **replay_owner)
 {
        struct nfs4_stateowner *open_sop = NULL;
@@ -2644,8 +2644,9 @@ nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock
        struct file *filp;
        struct file_lock file_lock;
        struct file_lock conflock;
-       int status = 0;
+       __be32 status = 0;
        unsigned int strhashval;
+       int err;
 
        dprintk("NFSD: nfsd4_lock: start=%Ld length=%Ld\n",
                (long long) lock->lk_offset,
@@ -2758,13 +2759,14 @@ nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock
         * locks_copy_lock: */
        conflock.fl_ops = NULL;
        conflock.fl_lmops = NULL;
-       status = posix_lock_file_conf(filp, &file_lock, &conflock);
+       err = posix_lock_file_conf(filp, &file_lock, &conflock);
        dprintk("NFSD: nfsd4_lock: posix_lock_file_conf status %d\n",status);
-       switch (-status) {
+       switch (-err) {
        case 0: /* success! */
                update_stateid(&lock_stp->st_stateid);
                memcpy(&lock->lk_resp_stateid, &lock_stp->st_stateid, 
                                sizeof(stateid_t));
+               status = 0;
                break;
        case (EAGAIN):          /* conflock holds conflicting lock */
                status = nfserr_denied;
@@ -2775,7 +2777,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock
                status = nfserr_deadlock;
                break;
        default:        
-               dprintk("NFSD: nfsd4_lock: posix_lock_file_conf() failed! status %d\n",status);
+               dprintk("NFSD: nfsd4_lock: posix_lock_file_conf() failed! status %d\n",err);
                status = nfserr_resource;
                break;
        }
@@ -2793,14 +2795,14 @@ out:
 /*
  * LOCKT operation
  */
-int
+__be32
 nfsd4_lockt(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lockt *lockt)
 {
        struct inode *inode;
        struct file file;
        struct file_lock file_lock;
        struct file_lock conflock;
-       int status;
+       __be32 status;
 
        if (nfs4_in_grace())
                return nfserr_grace;
@@ -2873,13 +2875,14 @@ out:
        return status;
 }
 
-int
+__be32
 nfsd4_locku(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_locku *locku, struct nfs4_stateowner **replay_owner)
 {
        struct nfs4_stateid *stp;
        struct file *filp = NULL;
        struct file_lock file_lock;
-       int status;
+       __be32 status;
+       int err;
                                                        
        dprintk("NFSD: nfsd4_locku: start=%Ld length=%Ld\n",
                (long long) locku->lu_offset,
@@ -2917,8 +2920,8 @@ nfsd4_locku(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock
        /*
        *  Try to unlock the file in the VFS.
        */
-       status = posix_lock_file(filp, &file_lock); 
-       if (status) {
+       err = posix_lock_file(filp, &file_lock);
+       if (err) {
                dprintk("NFSD: nfs4_locku: posix_lock_file failed!\n");
                goto out_nfserr;
        }
@@ -2937,7 +2940,7 @@ out:
        return status;
 
 out_nfserr:
-       status = nfserrno(status);
+       status = nfserrno(err);
        goto out;
 }
 
@@ -2965,7 +2968,7 @@ out:
        return status;
 }
 
-int
+__be32
 nfsd4_release_lockowner(struct svc_rqst *rqstp, struct nfsd4_release_lockowner *rlockowner)
 {
        clientid_t *clid = &rlockowner->rl_clientid;
@@ -2974,7 +2977,7 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp, struct nfsd4_release_lockowner *
        struct xdr_netobj *owner = &rlockowner->rl_owner;
        struct list_head matches;
        int i;
-       int status;
+       __be32 status;
 
        dprintk("nfsd4_release_lockowner clientid: (%08x/%08x):\n",
                clid->cl_boot, clid->cl_id);
@@ -3111,7 +3114,7 @@ nfs4_find_reclaim_client(clientid_t *clid)
 /*
 * Called from OPEN. Look for clientid in reclaim list.
 */
-int
+__be32
 nfs4_check_open_reclaim(clientid_t *clid)
 {
        return nfs4_find_reclaim_client(clid) ? nfs_ok : nfserr_reclaim_bad;
index 41fc241b729aa2a3ad78e0c91f25b751cd3cad0e..f3f239db04bb1b0d54f1a18ff78f4ffce3d18ee1 100644 (file)
@@ -68,8 +68,8 @@
 #define NFS4_REFERRAL_FSID_MAJOR       0x8000000ULL
 #define NFS4_REFERRAL_FSID_MINOR       0x8000000ULL
 
-static int
-check_filename(char *str, int len, int err)
+static __be32
+check_filename(char *str, int len, __be32 err)
 {
        int i;
 
@@ -94,8 +94,8 @@ check_filename(char *str, int len, int err)
  * consistent with the style used in NFSv2/v3...
  */
 #define DECODE_HEAD                            \
-       u32 *p;                                 \
-       int status
+       __be32 *p;                              \
+       __be32 status
 #define DECODE_TAIL                            \
        status = 0;                             \
 out:                                           \
@@ -144,13 +144,13 @@ xdr_error:                                        \
        }                                       \
 } while (0)
 
-static u32 *read_buf(struct nfsd4_compoundargs *argp, int nbytes)
+static __be32 *read_buf(struct nfsd4_compoundargs *argp, int nbytes)
 {
        /* We want more bytes than seem to be available.
         * Maybe we need a new page, maybe we have just run out
         */
        int avail = (char*)argp->end - (char*)argp->p;
-       u32 *p;
+       __be32 *p;
        if (avail + argp->pagelen < nbytes)
                return NULL;
        if (avail + PAGE_SIZE < nbytes) /* need more than a page !! */
@@ -197,7 +197,7 @@ defer_free(struct nfsd4_compoundargs *argp,
        return 0;
 }
 
-static char *savemem(struct nfsd4_compoundargs *argp, u32 *p, int nbytes)
+static char *savemem(struct nfsd4_compoundargs *argp, __be32 *p, int nbytes)
 {
        void *new = NULL;
        if (p == argp->tmp) {
@@ -217,7 +217,7 @@ static char *savemem(struct nfsd4_compoundargs *argp, u32 *p, int nbytes)
 }
 
 
-static int
+static __be32
 nfsd4_decode_bitmap(struct nfsd4_compoundargs *argp, u32 *bmval)
 {
        u32 bmlen;
@@ -240,13 +240,14 @@ nfsd4_decode_bitmap(struct nfsd4_compoundargs *argp, u32 *bmval)
        DECODE_TAIL;
 }
 
-static int
+static __be32
 nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, struct iattr *iattr,
     struct nfs4_acl **acl)
 {
        int expected_len, len = 0;
        u32 dummy32;
        char *buf;
+       int host_err;
 
        DECODE_HEAD;
        iattr->ia_valid = 0;
@@ -280,7 +281,7 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, struct iattr *ia
 
                *acl = nfs4_acl_new();
                if (*acl == NULL) {
-                       status = -ENOMEM;
+                       host_err = -ENOMEM;
                        goto out_nfserr;
                }
                defer_free(argp, (void (*)(const void *))nfs4_acl_free, *acl);
@@ -295,20 +296,20 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, struct iattr *ia
                        len += XDR_QUADLEN(dummy32) << 2;
                        READMEM(buf, dummy32);
                        ace.whotype = nfs4_acl_get_whotype(buf, dummy32);
-                       status = 0;
+                       host_err = 0;
                        if (ace.whotype != NFS4_ACL_WHO_NAMED)
                                ace.who = 0;
                        else if (ace.flag & NFS4_ACE_IDENTIFIER_GROUP)
-                               status = nfsd_map_name_to_gid(argp->rqstp,
+                               host_err = nfsd_map_name_to_gid(argp->rqstp,
                                                buf, dummy32, &ace.who);
                        else
-                               status = nfsd_map_name_to_uid(argp->rqstp,
+                               host_err = nfsd_map_name_to_uid(argp->rqstp,
                                                buf, dummy32, &ace.who);
-                       if (status)
+                       if (host_err)
                                goto out_nfserr;
-                       status = nfs4_acl_add_ace(*acl, ace.type, ace.flag,
+                       host_err = nfs4_acl_add_ace(*acl, ace.type, ace.flag,
                                 ace.access_mask, ace.whotype, ace.who);
-                       if (status)
+                       if (host_err)
                                goto out_nfserr;
                }
        } else
@@ -327,7 +328,7 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, struct iattr *ia
                READ_BUF(dummy32);
                len += (XDR_QUADLEN(dummy32) << 2);
                READMEM(buf, dummy32);
-               if ((status = nfsd_map_name_to_uid(argp->rqstp, buf, dummy32, &iattr->ia_uid)))
+               if ((host_err = nfsd_map_name_to_uid(argp->rqstp, buf, dummy32, &iattr->ia_uid)))
                        goto out_nfserr;
                iattr->ia_valid |= ATTR_UID;
        }
@@ -338,7 +339,7 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, struct iattr *ia
                READ_BUF(dummy32);
                len += (XDR_QUADLEN(dummy32) << 2);
                READMEM(buf, dummy32);
-               if ((status = nfsd_map_name_to_gid(argp->rqstp, buf, dummy32, &iattr->ia_gid)))
+               if ((host_err = nfsd_map_name_to_gid(argp->rqstp, buf, dummy32, &iattr->ia_gid)))
                        goto out_nfserr;
                iattr->ia_valid |= ATTR_GID;
        }
@@ -414,11 +415,11 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, struct iattr *ia
        DECODE_TAIL;
 
 out_nfserr:
-       status = nfserrno(status);
+       status = nfserrno(host_err);
        goto out;
 }
 
-static int
+static __be32
 nfsd4_decode_access(struct nfsd4_compoundargs *argp, struct nfsd4_access *access)
 {
        DECODE_HEAD;
@@ -429,7 +430,7 @@ nfsd4_decode_access(struct nfsd4_compoundargs *argp, struct nfsd4_access *access
        DECODE_TAIL;
 }
 
-static int
+static __be32
 nfsd4_decode_close(struct nfsd4_compoundargs *argp, struct nfsd4_close *close)
 {
        DECODE_HEAD;
@@ -444,7 +445,7 @@ nfsd4_decode_close(struct nfsd4_compoundargs *argp, struct nfsd4_close *close)
 }
 
 
-static int
+static __be32
 nfsd4_decode_commit(struct nfsd4_compoundargs *argp, struct nfsd4_commit *commit)
 {
        DECODE_HEAD;
@@ -456,7 +457,7 @@ nfsd4_decode_commit(struct nfsd4_compoundargs *argp, struct nfsd4_commit *commit
        DECODE_TAIL;
 }
 
-static int
+static __be32
 nfsd4_decode_create(struct nfsd4_compoundargs *argp, struct nfsd4_create *create)
 {
        DECODE_HEAD;
@@ -496,7 +497,7 @@ nfsd4_decode_create(struct nfsd4_compoundargs *argp, struct nfsd4_create *create
        DECODE_TAIL;
 }
 
-static inline int
+static inline __be32
 nfsd4_decode_delegreturn(struct nfsd4_compoundargs *argp, struct nfsd4_delegreturn *dr)
 {
        DECODE_HEAD;
@@ -508,13 +509,13 @@ nfsd4_decode_delegreturn(struct nfsd4_compoundargs *argp, struct nfsd4_delegretu
        DECODE_TAIL;
 }
 
-static inline int
+static inline __be32
 nfsd4_decode_getattr(struct nfsd4_compoundargs *argp, struct nfsd4_getattr *getattr)
 {
        return nfsd4_decode_bitmap(argp, getattr->ga_bmval);
 }
 
-static int
+static __be32
 nfsd4_decode_link(struct nfsd4_compoundargs *argp, struct nfsd4_link *link)
 {
        DECODE_HEAD;
@@ -529,7 +530,7 @@ nfsd4_decode_link(struct nfsd4_compoundargs *argp, struct nfsd4_link *link)
        DECODE_TAIL;
 }
 
-static int
+static __be32
 nfsd4_decode_lock(struct nfsd4_compoundargs *argp, struct nfsd4_lock *lock)
 {
        DECODE_HEAD;
@@ -568,7 +569,7 @@ nfsd4_decode_lock(struct nfsd4_compoundargs *argp, struct nfsd4_lock *lock)
        DECODE_TAIL;
 }
 
-static int
+static __be32
 nfsd4_decode_lockt(struct nfsd4_compoundargs *argp, struct nfsd4_lockt *lockt)
 {
        DECODE_HEAD;
@@ -587,7 +588,7 @@ nfsd4_decode_lockt(struct nfsd4_compoundargs *argp, struct nfsd4_lockt *lockt)
        DECODE_TAIL;
 }
 
-static int
+static __be32
 nfsd4_decode_locku(struct nfsd4_compoundargs *argp, struct nfsd4_locku *locku)
 {
        DECODE_HEAD;
@@ -606,7 +607,7 @@ nfsd4_decode_locku(struct nfsd4_compoundargs *argp, struct nfsd4_locku *locku)
        DECODE_TAIL;
 }
 
-static int
+static __be32
 nfsd4_decode_lookup(struct nfsd4_compoundargs *argp, struct nfsd4_lookup *lookup)
 {
        DECODE_HEAD;
@@ -621,7 +622,7 @@ nfsd4_decode_lookup(struct nfsd4_compoundargs *argp, struct nfsd4_lookup *lookup
        DECODE_TAIL;
 }
 
-static int
+static __be32
 nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
 {
        DECODE_HEAD;
@@ -699,7 +700,7 @@ nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
        DECODE_TAIL;
 }
 
-static int
+static __be32
 nfsd4_decode_open_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_open_confirm *open_conf)
 {
        DECODE_HEAD;
@@ -713,7 +714,7 @@ nfsd4_decode_open_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_open_con
        DECODE_TAIL;
 }
 
-static int
+static __be32
 nfsd4_decode_open_downgrade(struct nfsd4_compoundargs *argp, struct nfsd4_open_downgrade *open_down)
 {
        DECODE_HEAD;
@@ -729,7 +730,7 @@ nfsd4_decode_open_downgrade(struct nfsd4_compoundargs *argp, struct nfsd4_open_d
        DECODE_TAIL;
 }
 
-static int
+static __be32
 nfsd4_decode_putfh(struct nfsd4_compoundargs *argp, struct nfsd4_putfh *putfh)
 {
        DECODE_HEAD;
@@ -744,7 +745,7 @@ nfsd4_decode_putfh(struct nfsd4_compoundargs *argp, struct nfsd4_putfh *putfh)
        DECODE_TAIL;
 }
 
-static int
+static __be32
 nfsd4_decode_read(struct nfsd4_compoundargs *argp, struct nfsd4_read *read)
 {
        DECODE_HEAD;
@@ -758,7 +759,7 @@ nfsd4_decode_read(struct nfsd4_compoundargs *argp, struct nfsd4_read *read)
        DECODE_TAIL;
 }
 
-static int
+static __be32
 nfsd4_decode_readdir(struct nfsd4_compoundargs *argp, struct nfsd4_readdir *readdir)
 {
        DECODE_HEAD;
@@ -774,7 +775,7 @@ nfsd4_decode_readdir(struct nfsd4_compoundargs *argp, struct nfsd4_readdir *read
        DECODE_TAIL;
 }
 
-static int
+static __be32
 nfsd4_decode_remove(struct nfsd4_compoundargs *argp, struct nfsd4_remove *remove)
 {
        DECODE_HEAD;
@@ -789,7 +790,7 @@ nfsd4_decode_remove(struct nfsd4_compoundargs *argp, struct nfsd4_remove *remove
        DECODE_TAIL;
 }
 
-static int
+static __be32
 nfsd4_decode_rename(struct nfsd4_compoundargs *argp, struct nfsd4_rename *rename)
 {
        DECODE_HEAD;
@@ -809,7 +810,7 @@ nfsd4_decode_rename(struct nfsd4_compoundargs *argp, struct nfsd4_rename *rename
        DECODE_TAIL;
 }
 
-static int
+static __be32
 nfsd4_decode_renew(struct nfsd4_compoundargs *argp, clientid_t *clientid)
 {
        DECODE_HEAD;
@@ -820,7 +821,7 @@ nfsd4_decode_renew(struct nfsd4_compoundargs *argp, clientid_t *clientid)
        DECODE_TAIL;
 }
 
-static int
+static __be32
 nfsd4_decode_setattr(struct nfsd4_compoundargs *argp, struct nfsd4_setattr *setattr)
 {
        DECODE_HEAD;
@@ -834,7 +835,7 @@ nfsd4_decode_setattr(struct nfsd4_compoundargs *argp, struct nfsd4_setattr *seta
        DECODE_TAIL;
 }
 
-static int
+static __be32
 nfsd4_decode_setclientid(struct nfsd4_compoundargs *argp, struct nfsd4_setclientid *setclientid)
 {
        DECODE_HEAD;
@@ -859,7 +860,7 @@ nfsd4_decode_setclientid(struct nfsd4_compoundargs *argp, struct nfsd4_setclient
        DECODE_TAIL;
 }
 
-static int
+static __be32
 nfsd4_decode_setclientid_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_setclientid_confirm *scd_c)
 {
        DECODE_HEAD;
@@ -872,7 +873,7 @@ nfsd4_decode_setclientid_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_s
 }
 
 /* Also used for NVERIFY */
-static int
+static __be32
 nfsd4_decode_verify(struct nfsd4_compoundargs *argp, struct nfsd4_verify *verify)
 {
 #if 0
@@ -908,7 +909,7 @@ nfsd4_decode_verify(struct nfsd4_compoundargs *argp, struct nfsd4_verify *verify
        DECODE_TAIL;
 }
 
-static int
+static __be32
 nfsd4_decode_write(struct nfsd4_compoundargs *argp, struct nfsd4_write *write)
 {
        int avail;
@@ -951,15 +952,15 @@ nfsd4_decode_write(struct nfsd4_compoundargs *argp, struct nfsd4_write *write)
                        argp->pagelen -= len;
                }
        }
-       argp->end = (u32*) (argp->rqstp->rq_vec[v].iov_base + argp->rqstp->rq_vec[v].iov_len);
-       argp->p = (u32*)  (argp->rqstp->rq_vec[v].iov_base + (XDR_QUADLEN(len) << 2));
+       argp->end = (__be32*) (argp->rqstp->rq_vec[v].iov_base + argp->rqstp->rq_vec[v].iov_len);
+       argp->p = (__be32*)  (argp->rqstp->rq_vec[v].iov_base + (XDR_QUADLEN(len) << 2));
        argp->rqstp->rq_vec[v].iov_len = len;
        write->wr_vlen = v+1;
 
        DECODE_TAIL;
 }
 
-static int
+static __be32
 nfsd4_decode_release_lockowner(struct nfsd4_compoundargs *argp, struct nfsd4_release_lockowner *rlockowner)
 {
        DECODE_HEAD;
@@ -973,7 +974,7 @@ nfsd4_decode_release_lockowner(struct nfsd4_compoundargs *argp, struct nfsd4_rel
        DECODE_TAIL;
 }
 
-static int
+static __be32
 nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
 {
        DECODE_HEAD;
@@ -1179,7 +1180,7 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
  * task to translate them into Linux-specific versions which are more
  * consistent with the style used in NFSv2/v3...
  */
-#define ENCODE_HEAD              u32 *p
+#define ENCODE_HEAD              __be32 *p
 
 #define WRITE32(n)               *p++ = htonl(n)
 #define WRITE64(n)               do {                          \
@@ -1209,8 +1210,8 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
  * Header routine to setup seqid operation replay cache
  */
 #define ENCODE_SEQID_OP_HEAD                                   \
-       u32 *p;                                                 \
-       u32 *save;                                              \
+       __be32 *p;                                              \
+       __be32 *save;                                           \
                                                                \
        save = resp->p;
 
@@ -1234,11 +1235,11 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
 /* Encode as an array of strings the string given with components
  * seperated @sep.
  */
-static int nfsd4_encode_components(char sep, char *components,
-                                  u32 **pp, int *buflen)
+static __be32 nfsd4_encode_components(char sep, char *components,
+                                  __be32 **pp, int *buflen)
 {
-       u32 *p = *pp;
-       u32 *countp = p;
+       __be32 *p = *pp;
+       __be32 *countp = p;
        int strlen, count=0;
        char *str, *end;
 
@@ -1271,11 +1272,11 @@ static int nfsd4_encode_components(char sep, char *components,
 /*
  * encode a location element of a fs_locations structure
  */
-static int nfsd4_encode_fs_location4(struct nfsd4_fs_location *location,
-                                   u32 **pp, int *buflen)
+static __be32 nfsd4_encode_fs_location4(struct nfsd4_fs_location *location,
+                                   __be32 **pp, int *buflen)
 {
-       int status;
-       u32 *p = *pp;
+       __be32 status;
+       __be32 *p = *pp;
 
        status = nfsd4_encode_components(':', location->hosts, &p, buflen);
        if (status)
@@ -1292,16 +1293,15 @@ static int nfsd4_encode_fs_location4(struct nfsd4_fs_location *location,
  * Returned string is safe to use as long as the caller holds a reference
  * to @exp.
  */
-static char *nfsd4_path(struct svc_rqst *rqstp, struct svc_export *exp)
+static char *nfsd4_path(struct svc_rqst *rqstp, struct svc_export *exp, __be32 *stat)
 {
        struct svc_fh tmp_fh;
        char *path, *rootpath;
-       int stat;
 
        fh_init(&tmp_fh, NFS4_FHSIZE);
-       stat = exp_pseudoroot(rqstp->rq_client, &tmp_fh, &rqstp->rq_chandle);
-       if (stat)
-               return ERR_PTR(stat);
+       *stat = exp_pseudoroot(rqstp->rq_client, &tmp_fh, &rqstp->rq_chandle);
+       if (*stat)
+               return NULL;
        rootpath = tmp_fh.fh_export->ex_path;
 
        path = exp->ex_path;
@@ -1309,7 +1309,8 @@ static char *nfsd4_path(struct svc_rqst *rqstp, struct svc_export *exp)
        if (strncmp(path, rootpath, strlen(rootpath))) {
                printk("nfsd: fs_locations failed;"
                        "%s is not contained in %s\n", path, rootpath);
-               return ERR_PTR(-EOPNOTSUPP);
+               *stat = nfserr_notsupp;
+               return NULL;
        }
 
        return path + strlen(rootpath);
@@ -1318,17 +1319,18 @@ static char *nfsd4_path(struct svc_rqst *rqstp, struct svc_export *exp)
 /*
  *  encode a fs_locations structure
  */
-static int nfsd4_encode_fs_locations(struct svc_rqst *rqstp,
+static __be32 nfsd4_encode_fs_locations(struct svc_rqst *rqstp,
                                     struct svc_export *exp,
-                                    u32 **pp, int *buflen)
+                                    __be32 **pp, int *buflen)
 {
-       int status, i;
-       u32 *p = *pp;
+       __be32 status;
+       int i;
+       __be32 *p = *pp;
        struct nfsd4_fs_locations *fslocs = &exp->ex_fslocs;
-       char *root = nfsd4_path(rqstp, exp);
+       char *root = nfsd4_path(rqstp, exp, &status);
 
-       if (IS_ERR(root))
-               return PTR_ERR(root);
+       if (status)
+               return status;
        status = nfsd4_encode_components('/', root, &p, buflen);
        if (status)
                return status;
@@ -1352,9 +1354,9 @@ static u32 nfs4_ftypes[16] = {
         NF4SOCK, NF4BAD,  NF4LNK, NF4BAD,
 };
 
-static int
+static __be32
 nfsd4_encode_name(struct svc_rqst *rqstp, int whotype, uid_t id, int group,
-                       u32 **p, int *buflen)
+                       __be32 **p, int *buflen)
 {
        int status;
 
@@ -1374,21 +1376,21 @@ nfsd4_encode_name(struct svc_rqst *rqstp, int whotype, uid_t id, int group,
        return 0;
 }
 
-static inline int
-nfsd4_encode_user(struct svc_rqst *rqstp, uid_t uid, u32 **p, int *buflen)
+static inline __be32
+nfsd4_encode_user(struct svc_rqst *rqstp, uid_t uid, __be32 **p, int *buflen)
 {
        return nfsd4_encode_name(rqstp, NFS4_ACL_WHO_NAMED, uid, 0, p, buflen);
 }
 
-static inline int
-nfsd4_encode_group(struct svc_rqst *rqstp, uid_t gid, u32 **p, int *buflen)
+static inline __be32
+nfsd4_encode_group(struct svc_rqst *rqstp, uid_t gid, __be32 **p, int *buflen)
 {
        return nfsd4_encode_name(rqstp, NFS4_ACL_WHO_NAMED, gid, 1, p, buflen);
 }
 
-static inline int
+static inline __be32
 nfsd4_encode_aclname(struct svc_rqst *rqstp, int whotype, uid_t id, int group,
-               u32 **p, int *buflen)
+               __be32 **p, int *buflen)
 {
        return nfsd4_encode_name(rqstp, whotype, id, group, p, buflen);
 }
@@ -1397,7 +1399,7 @@ nfsd4_encode_aclname(struct svc_rqst *rqstp, int whotype, uid_t id, int group,
                              FATTR4_WORD0_RDATTR_ERROR)
 #define WORD1_ABSENT_FS_ATTRS FATTR4_WORD1_MOUNTED_ON_FILEID
 
-static int fattr_handle_absent_fs(u32 *bmval0, u32 *bmval1, u32 *rdattr_err)
+static __be32 fattr_handle_absent_fs(u32 *bmval0, u32 *bmval1, u32 *rdattr_err)
 {
        /* As per referral draft:  */
        if (*bmval0 & ~WORD0_ABSENT_FS_ATTRS ||
@@ -1420,9 +1422,9 @@ static int fattr_handle_absent_fs(u32 *bmval0, u32 *bmval1, u32 *rdattr_err)
  * @countp is the buffer size in _words_; upon successful return this becomes
  * replaced with the number of words written.
  */
-int
+__be32
 nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
-               struct dentry *dentry, u32 *buffer, int *countp, u32 *bmval,
+               struct dentry *dentry, __be32 *buffer, int *countp, u32 *bmval,
                struct svc_rqst *rqstp)
 {
        u32 bmval0 = bmval[0];
@@ -1431,12 +1433,13 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
        struct svc_fh tempfh;
        struct kstatfs statfs;
        int buflen = *countp << 2;
-       u32 *attrlenp;
+       __be32 *attrlenp;
        u32 dummy;
        u64 dummy64;
        u32 rdattr_err = 0;
-       u32 *p = buffer;
-       int status;
+       __be32 *p = buffer;
+       __be32 status;
+       int err;
        int aclsupport = 0;
        struct nfs4_acl *acl = NULL;
 
@@ -1450,14 +1453,14 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
                        goto out;
        }
 
-       status = vfs_getattr(exp->ex_mnt, dentry, &stat);
-       if (status)
+       err = vfs_getattr(exp->ex_mnt, dentry, &stat);
+       if (err)
                goto out_nfserr;
        if ((bmval0 & (FATTR4_WORD0_FILES_FREE | FATTR4_WORD0_FILES_TOTAL)) ||
            (bmval1 & (FATTR4_WORD1_SPACE_AVAIL | FATTR4_WORD1_SPACE_FREE |
                       FATTR4_WORD1_SPACE_TOTAL))) {
-               status = vfs_statfs(dentry, &statfs);
-               if (status)
+               err = vfs_statfs(dentry, &statfs);
+               if (err)
                        goto out_nfserr;
        }
        if ((bmval0 & (FATTR4_WORD0_FILEHANDLE | FATTR4_WORD0_FSID)) && !fhp) {
@@ -1469,15 +1472,15 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
        }
        if (bmval0 & (FATTR4_WORD0_ACL | FATTR4_WORD0_ACLSUPPORT
                        | FATTR4_WORD0_SUPPORTED_ATTRS)) {
-               status = nfsd4_get_nfs4_acl(rqstp, dentry, &acl);
-               aclsupport = (status == 0);
+               err = nfsd4_get_nfs4_acl(rqstp, dentry, &acl);
+               aclsupport = (err == 0);
                if (bmval0 & FATTR4_WORD0_ACL) {
-                       if (status == -EOPNOTSUPP)
+                       if (err == -EOPNOTSUPP)
                                bmval0 &= ~FATTR4_WORD0_ACL;
-                       else if (status == -EINVAL) {
+                       else if (err == -EINVAL) {
                                status = nfserr_attrnotsupp;
                                goto out;
-                       } else if (status != 0)
+                       } else if (err != 0)
                                goto out_nfserr;
                }
        }
@@ -1817,7 +1820,7 @@ out:
                fh_put(&tempfh);
        return status;
 out_nfserr:
-       status = nfserrno(status);
+       status = nfserrno(err);
        goto out;
 out_resource:
        *countp = 0;
@@ -1828,13 +1831,13 @@ out_serverfault:
        goto out;
 }
 
-static int
+static __be32
 nfsd4_encode_dirent_fattr(struct nfsd4_readdir *cd,
-               const char *name, int namlen, u32 *p, int *buflen)
+               const char *name, int namlen, __be32 *p, int *buflen)
 {
        struct svc_export *exp = cd->rd_fhp->fh_export;
        struct dentry *dentry;
-       int nfserr;
+       __be32 nfserr;
 
        dentry = lookup_one_len(name, cd->rd_fhp->fh_dentry, namlen);
        if (IS_ERR(dentry))
@@ -1863,10 +1866,10 @@ out_put:
        return nfserr;
 }
 
-static u32 *
-nfsd4_encode_rdattr_error(u32 *p, int buflen, int nfserr)
+static __be32 *
+nfsd4_encode_rdattr_error(__be32 *p, int buflen, __be32 nfserr)
 {
-       u32 *attrlenp;
+       __be32 *attrlenp;
 
        if (buflen < 6)
                return NULL;
@@ -1886,8 +1889,8 @@ nfsd4_encode_dirent(struct readdir_cd *ccd, const char *name, int namlen,
 {
        struct nfsd4_readdir *cd = container_of(ccd, struct nfsd4_readdir, common);
        int buflen;
-       u32 *p = cd->buffer;
-       int nfserr = nfserr_toosmall;
+       __be32 *p = cd->buffer;
+       __be32 nfserr = nfserr_toosmall;
 
        /* In nfsv4, "." and ".." never make it onto the wire.. */
        if (name && isdotent(name, namlen)) {
@@ -1943,7 +1946,7 @@ fail:
 }
 
 static void
-nfsd4_encode_access(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_access *access)
+nfsd4_encode_access(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_access *access)
 {
        ENCODE_HEAD;
 
@@ -1956,7 +1959,7 @@ nfsd4_encode_access(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_acc
 }
 
 static void
-nfsd4_encode_close(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_close *close)
+nfsd4_encode_close(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_close *close)
 {
        ENCODE_SEQID_OP_HEAD;
 
@@ -1971,7 +1974,7 @@ nfsd4_encode_close(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_clos
 
 
 static void
-nfsd4_encode_commit(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_commit *commit)
+nfsd4_encode_commit(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_commit *commit)
 {
        ENCODE_HEAD;
 
@@ -1983,7 +1986,7 @@ nfsd4_encode_commit(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_com
 }
 
 static void
-nfsd4_encode_create(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_create *create)
+nfsd4_encode_create(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_create *create)
 {
        ENCODE_HEAD;
 
@@ -1997,8 +2000,8 @@ nfsd4_encode_create(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_cre
        }
 }
 
-static int
-nfsd4_encode_getattr(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_getattr *getattr)
+static __be32
+nfsd4_encode_getattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_getattr *getattr)
 {
        struct svc_fh *fhp = getattr->ga_fhp;
        int buflen;
@@ -2016,7 +2019,7 @@ nfsd4_encode_getattr(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_ge
 }
 
 static void
-nfsd4_encode_getfh(struct nfsd4_compoundres *resp, int nfserr, struct svc_fh *fhp)
+nfsd4_encode_getfh(struct nfsd4_compoundres *resp, __be32 nfserr, struct svc_fh *fhp)
 {
        unsigned int len;
        ENCODE_HEAD;
@@ -2056,7 +2059,7 @@ nfsd4_encode_lock_denied(struct nfsd4_compoundres *resp, struct nfsd4_lock_denie
 }
 
 static void
-nfsd4_encode_lock(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_lock *lock)
+nfsd4_encode_lock(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lock *lock)
 {
        ENCODE_SEQID_OP_HEAD;
 
@@ -2072,14 +2075,14 @@ nfsd4_encode_lock(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_lock
 }
 
 static void
-nfsd4_encode_lockt(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_lockt *lockt)
+nfsd4_encode_lockt(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lockt *lockt)
 {
        if (nfserr == nfserr_denied)
                nfsd4_encode_lock_denied(resp, &lockt->lt_denied);
 }
 
 static void
-nfsd4_encode_locku(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_locku *locku)
+nfsd4_encode_locku(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_locku *locku)
 {
        ENCODE_SEQID_OP_HEAD;
 
@@ -2095,7 +2098,7 @@ nfsd4_encode_locku(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_lock
 
 
 static void
-nfsd4_encode_link(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_link *link)
+nfsd4_encode_link(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_link *link)
 {
        ENCODE_HEAD;
 
@@ -2108,7 +2111,7 @@ nfsd4_encode_link(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_link
 
 
 static void
-nfsd4_encode_open(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_open *open)
+nfsd4_encode_open(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open *open)
 {
        ENCODE_SEQID_OP_HEAD;
 
@@ -2173,7 +2176,7 @@ out:
 }
 
 static void
-nfsd4_encode_open_confirm(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_open_confirm *oc)
+nfsd4_encode_open_confirm(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open_confirm *oc)
 {
        ENCODE_SEQID_OP_HEAD;
                                        
@@ -2188,7 +2191,7 @@ nfsd4_encode_open_confirm(struct nfsd4_compoundres *resp, int nfserr, struct nfs
 }
 
 static void
-nfsd4_encode_open_downgrade(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_open_downgrade *od)
+nfsd4_encode_open_downgrade(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open_downgrade *od)
 {
        ENCODE_SEQID_OP_HEAD;
                                        
@@ -2202,8 +2205,8 @@ nfsd4_encode_open_downgrade(struct nfsd4_compoundres *resp, int nfserr, struct n
        ENCODE_SEQID_OP_TAIL(od->od_stateowner);
 }
 
-static int
-nfsd4_encode_read(struct nfsd4_compoundres *resp, int nfserr,
+static __be32
+nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,
                  struct nfsd4_read *read)
 {
        u32 eof;
@@ -2267,8 +2270,8 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, int nfserr,
        return 0;
 }
 
-static int
-nfsd4_encode_readlink(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_readlink *readlink)
+static __be32
+nfsd4_encode_readlink(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_readlink *readlink)
 {
        int maxcount;
        char *page;
@@ -2315,12 +2318,12 @@ nfsd4_encode_readlink(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_r
        return 0;
 }
 
-static int
-nfsd4_encode_readdir(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_readdir *readdir)
+static __be32
+nfsd4_encode_readdir(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_readdir *readdir)
 {
        int maxcount;
        loff_t offset;
-       u32 *page, *savep, *tailbase;
+       __be32 *page, *savep, *tailbase;
        ENCODE_HEAD;
 
        if (nfserr)
@@ -2395,7 +2398,7 @@ err_no_verf:
 }
 
 static void
-nfsd4_encode_remove(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_remove *remove)
+nfsd4_encode_remove(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_remove *remove)
 {
        ENCODE_HEAD;
 
@@ -2407,7 +2410,7 @@ nfsd4_encode_remove(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_rem
 }
 
 static void
-nfsd4_encode_rename(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_rename *rename)
+nfsd4_encode_rename(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_rename *rename)
 {
        ENCODE_HEAD;
 
@@ -2424,7 +2427,7 @@ nfsd4_encode_rename(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_ren
  * regardless of the error status.
  */
 static void
-nfsd4_encode_setattr(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_setattr *setattr)
+nfsd4_encode_setattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_setattr *setattr)
 {
        ENCODE_HEAD;
 
@@ -2443,7 +2446,7 @@ nfsd4_encode_setattr(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_se
 }
 
 static void
-nfsd4_encode_setclientid(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_setclientid *scd)
+nfsd4_encode_setclientid(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_setclientid *scd)
 {
        ENCODE_HEAD;
 
@@ -2462,7 +2465,7 @@ nfsd4_encode_setclientid(struct nfsd4_compoundres *resp, int nfserr, struct nfsd
 }
 
 static void
-nfsd4_encode_write(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_write *write)
+nfsd4_encode_write(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_write *write)
 {
        ENCODE_HEAD;
 
@@ -2478,7 +2481,7 @@ nfsd4_encode_write(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_writ
 void
 nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
 {
-       u32 *statp;
+       __be32 *statp;
        ENCODE_HEAD;
 
        RESERVE_SPACE(8);
@@ -2616,7 +2619,7 @@ nfsd4_encode_replay(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
  */
 
 int
-nfs4svc_encode_voidres(struct svc_rqst *rqstp, u32 *p, void *dummy)
+nfs4svc_encode_voidres(struct svc_rqst *rqstp, __be32 *p, void *dummy)
 {
         return xdr_ressize_check(rqstp, p);
 }
@@ -2638,9 +2641,9 @@ void nfsd4_release_compoundargs(struct nfsd4_compoundargs *args)
 }
 
 int
-nfs4svc_decode_compoundargs(struct svc_rqst *rqstp, u32 *p, struct nfsd4_compoundargs *args)
+nfs4svc_decode_compoundargs(struct svc_rqst *rqstp, __be32 *p, struct nfsd4_compoundargs *args)
 {
-       int status;
+       __be32 status;
 
        args->p = p;
        args->end = rqstp->rq_arg.head[0].iov_base + rqstp->rq_arg.head[0].iov_len;
@@ -2659,7 +2662,7 @@ nfs4svc_decode_compoundargs(struct svc_rqst *rqstp, u32 *p, struct nfsd4_compoun
 }
 
 int
-nfs4svc_encode_compoundres(struct svc_rqst *rqstp, u32 *p, struct nfsd4_compoundres *resp)
+nfs4svc_encode_compoundres(struct svc_rqst *rqstp, __be32 *p, struct nfsd4_compoundres *resp)
 {
        /*
         * All that remains is to write the tag and operation count...
index fdf7cf3dfadcf0f7775f4aa54cd4acf43e7ffed1..6100bbe27432d6b6f826733a47b3a87dfdbc3041 100644 (file)
@@ -29,7 +29,7 @@
  */
 #define CACHESIZE              1024
 #define HASHSIZE               64
-#define REQHASH(xid)           ((((xid) >> 24) ^ (xid)) & (HASHSIZE-1))
+#define REQHASH(xid)           (((((__force __u32)xid) >> 24) ^ ((__force __u32)xid)) & (HASHSIZE-1))
 
 static struct hlist_head *     hash_list;
 static struct list_head        lru_head;
@@ -127,8 +127,8 @@ nfsd_cache_lookup(struct svc_rqst *rqstp, int type)
        struct hlist_node       *hn;
        struct hlist_head       *rh;
        struct svc_cacherep     *rp;
-       u32                     xid = rqstp->rq_xid,
-                               proto =  rqstp->rq_prot,
+       __be32                  xid = rqstp->rq_xid;
+       u32                     proto =  rqstp->rq_prot,
                                vers = rqstp->rq_vers,
                                proc = rqstp->rq_proc;
        unsigned long           age;
@@ -258,7 +258,7 @@ found_entry:
  * In this case, nfsd_cache_update is called with statp == NULL.
  */
 void
-nfsd_cache_update(struct svc_rqst *rqstp, int cachetype, u32 *statp)
+nfsd_cache_update(struct svc_rqst *rqstp, int cachetype, __be32 *statp)
 {
        struct svc_cacherep *rp;
        struct kvec     *resv = &rqstp->rq_res.head[0], *cachv;
index 501d83884530859e767bfaeb8341a51105b01206..727ab3bd450d54bffee6183ddf8fea3e1d3bdb75 100644 (file)
@@ -76,7 +76,7 @@ static int nfsd_acceptable(void *expv, struct dentry *dentry)
  * comment in the NFSv3 spec says this is incorrect (implementation notes for
  * the write call).
  */
-static inline int
+static inline __be32
 nfsd_mode_check(struct svc_rqst *rqstp, umode_t mode, int type)
 {
        /* Type can be negative when creating hardlinks - not to a dir */
@@ -110,13 +110,13 @@ nfsd_mode_check(struct svc_rqst *rqstp, umode_t mode, int type)
  * This is only called at the start of an nfsproc call, so fhp points to
  * a svc_fh which is all 0 except for the over-the-wire file handle.
  */
-u32
+__be32
 fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
 {
        struct knfsd_fh *fh = &fhp->fh_handle;
        struct svc_export *exp = NULL;
        struct dentry   *dentry;
-       u32             error = 0;
+       __be32          error = 0;
 
        dprintk("nfsd: fh_verify(%s)\n", SVCFH_fmt(fhp));
 
@@ -315,7 +315,7 @@ static inline void _fh_update_old(struct dentry *dentry,
                fh->ofh_dirino = 0;
 }
 
-int
+__be32
 fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, struct svc_fh *ref_fh)
 {
        /* ref_fh is a reference file handle.
@@ -451,7 +451,7 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, st
  * Update file handle information after changing a dentry.
  * This is only called by nfsd_create, nfsd_create_v3 and nfsd_proc_create
  */
-int
+__be32
 fh_update(struct svc_fh *fhp)
 {
        struct dentry *dentry;
index 9ee1dab5d44adc09214469af2014735f132c50cc..ec983b777680ded981c59dbb65c81ebb0c5637dc 100644 (file)
@@ -30,22 +30,22 @@ typedef struct svc_buf      svc_buf;
 #define NFSDDBG_FACILITY               NFSDDBG_PROC
 
 
-static int
+static __be32
 nfsd_proc_null(struct svc_rqst *rqstp, void *argp, void *resp)
 {
        return nfs_ok;
 }
 
-static int
-nfsd_return_attrs(int err, struct nfsd_attrstat *resp)
+static __be32
+nfsd_return_attrs(__be32 err, struct nfsd_attrstat *resp)
 {
        if (err) return err;
        return nfserrno(vfs_getattr(resp->fh.fh_export->ex_mnt,
                                    resp->fh.fh_dentry,
                                    &resp->stat));
 }
-static int
-nfsd_return_dirop(int err, struct nfsd_diropres *resp)
+static __be32
+nfsd_return_dirop(__be32 err, struct nfsd_diropres *resp)
 {
        if (err) return err;
        return nfserrno(vfs_getattr(resp->fh.fh_export->ex_mnt,
@@ -56,11 +56,11 @@ nfsd_return_dirop(int err, struct nfsd_diropres *resp)
  * Get a file's attributes
  * N.B. After this call resp->fh needs an fh_put
  */
-static int
+static __be32
 nfsd_proc_getattr(struct svc_rqst *rqstp, struct nfsd_fhandle  *argp,
                                          struct nfsd_attrstat *resp)
 {
-       int nfserr;
+       __be32 nfserr;
        dprintk("nfsd: GETATTR  %s\n", SVCFH_fmt(&argp->fh));
 
        fh_copy(&resp->fh, &argp->fh);
@@ -72,11 +72,11 @@ nfsd_proc_getattr(struct svc_rqst *rqstp, struct nfsd_fhandle  *argp,
  * Set a file's attributes
  * N.B. After this call resp->fh needs an fh_put
  */
-static int
+static __be32
 nfsd_proc_setattr(struct svc_rqst *rqstp, struct nfsd_sattrargs *argp,
                                          struct nfsd_attrstat  *resp)
 {
-       int nfserr;
+       __be32 nfserr;
        dprintk("nfsd: SETATTR  %s, valid=%x, size=%ld\n",
                SVCFH_fmt(&argp->fh),
                argp->attrs.ia_valid, (long) argp->attrs.ia_size);
@@ -92,11 +92,11 @@ nfsd_proc_setattr(struct svc_rqst *rqstp, struct nfsd_sattrargs *argp,
  * doesn't exist yet.
  * N.B. After this call resp->fh needs an fh_put
  */
-static int
+static __be32
 nfsd_proc_lookup(struct svc_rqst *rqstp, struct nfsd_diropargs *argp,
                                         struct nfsd_diropres  *resp)
 {
-       int     nfserr;
+       __be32  nfserr;
 
        dprintk("nfsd: LOOKUP   %s %.*s\n",
                SVCFH_fmt(&argp->fh), argp->len, argp->name);
@@ -112,11 +112,11 @@ nfsd_proc_lookup(struct svc_rqst *rqstp, struct nfsd_diropargs *argp,
 /*
  * Read a symlink.
  */
-static int
+static __be32
 nfsd_proc_readlink(struct svc_rqst *rqstp, struct nfsd_readlinkargs *argp,
                                           struct nfsd_readlinkres *resp)
 {
-       int     nfserr;
+       __be32  nfserr;
 
        dprintk("nfsd: READLINK %s\n", SVCFH_fmt(&argp->fh));
 
@@ -132,11 +132,11 @@ nfsd_proc_readlink(struct svc_rqst *rqstp, struct nfsd_readlinkargs *argp,
  * Read a portion of a file.
  * N.B. After this call resp->fh needs an fh_put
  */
-static int
+static __be32
 nfsd_proc_read(struct svc_rqst *rqstp, struct nfsd_readargs *argp,
                                       struct nfsd_readres  *resp)
 {
-       int     nfserr;
+       __be32  nfserr;
 
        dprintk("nfsd: READ    %s %d bytes at %d\n",
                SVCFH_fmt(&argp->fh),
@@ -172,11 +172,11 @@ nfsd_proc_read(struct svc_rqst *rqstp, struct nfsd_readargs *argp,
  * Write data to a file
  * N.B. After this call resp->fh needs an fh_put
  */
-static int
+static __be32
 nfsd_proc_write(struct svc_rqst *rqstp, struct nfsd_writeargs *argp,
                                        struct nfsd_attrstat  *resp)
 {
-       int     nfserr;
+       __be32  nfserr;
        int     stable = 1;
 
        dprintk("nfsd: WRITE    %s %d bytes at %d\n",
@@ -197,7 +197,7 @@ nfsd_proc_write(struct svc_rqst *rqstp, struct nfsd_writeargs *argp,
  * and the actual create() call in compliance with VFS protocols.
  * N.B. After this call _both_ argp->fh and resp->fh need an fh_put
  */
-static int
+static __be32
 nfsd_proc_create(struct svc_rqst *rqstp, struct nfsd_createargs *argp,
                                         struct nfsd_diropres   *resp)
 {
@@ -206,7 +206,8 @@ nfsd_proc_create(struct svc_rqst *rqstp, struct nfsd_createargs *argp,
        struct iattr    *attr = &argp->attrs;
        struct inode    *inode;
        struct dentry   *dchild;
-       int             nfserr, type, mode;
+       int             type, mode;
+       __be32          nfserr;
        dev_t           rdev = 0, wanted = new_decode_dev(attr->ia_size);
 
        dprintk("nfsd: CREATE   %s %.*s\n",
@@ -348,11 +349,11 @@ done:
        return nfsd_return_dirop(nfserr, resp);
 }
 
-static int
+static __be32
 nfsd_proc_remove(struct svc_rqst *rqstp, struct nfsd_diropargs *argp,
                                         void                  *resp)
 {
-       int     nfserr;
+       __be32  nfserr;
 
        dprintk("nfsd: REMOVE   %s %.*s\n", SVCFH_fmt(&argp->fh),
                argp->len, argp->name);
@@ -363,11 +364,11 @@ nfsd_proc_remove(struct svc_rqst *rqstp, struct nfsd_diropargs *argp,
        return nfserr;
 }
 
-static int
+static __be32
 nfsd_proc_rename(struct svc_rqst *rqstp, struct nfsd_renameargs *argp,
                                         void                   *resp)
 {
-       int     nfserr;
+       __be32  nfserr;
 
        dprintk("nfsd: RENAME   %s %.*s -> \n",
                SVCFH_fmt(&argp->ffh), argp->flen, argp->fname);
@@ -381,11 +382,11 @@ nfsd_proc_rename(struct svc_rqst *rqstp, struct nfsd_renameargs *argp,
        return nfserr;
 }
 
-static int
+static __be32
 nfsd_proc_link(struct svc_rqst *rqstp, struct nfsd_linkargs *argp,
                                void                        *resp)
 {
-       int     nfserr;
+       __be32  nfserr;
 
        dprintk("nfsd: LINK     %s ->\n",
                SVCFH_fmt(&argp->ffh));
@@ -401,12 +402,12 @@ nfsd_proc_link(struct svc_rqst *rqstp, struct nfsd_linkargs *argp,
        return nfserr;
 }
 
-static int
+static __be32
 nfsd_proc_symlink(struct svc_rqst *rqstp, struct nfsd_symlinkargs *argp,
                                          void                    *resp)
 {
        struct svc_fh   newfh;
-       int             nfserr;
+       __be32          nfserr;
 
        dprintk("nfsd: SYMLINK  %s %.*s -> %.*s\n",
                SVCFH_fmt(&argp->ffh), argp->flen, argp->fname,
@@ -430,11 +431,11 @@ nfsd_proc_symlink(struct svc_rqst *rqstp, struct nfsd_symlinkargs *argp,
  * Make directory. This operation is not idempotent.
  * N.B. After this call resp->fh needs an fh_put
  */
-static int
+static __be32
 nfsd_proc_mkdir(struct svc_rqst *rqstp, struct nfsd_createargs *argp,
                                        struct nfsd_diropres   *resp)
 {
-       int     nfserr;
+       __be32  nfserr;
 
        dprintk("nfsd: MKDIR    %s %.*s\n", SVCFH_fmt(&argp->fh), argp->len, argp->name);
 
@@ -454,11 +455,11 @@ nfsd_proc_mkdir(struct svc_rqst *rqstp, struct nfsd_createargs *argp,
 /*
  * Remove a directory
  */
-static int
+static __be32
 nfsd_proc_rmdir(struct svc_rqst *rqstp, struct nfsd_diropargs *argp,
                                        void                  *resp)
 {
-       int     nfserr;
+       __be32  nfserr;
 
        dprintk("nfsd: RMDIR    %s %.*s\n", SVCFH_fmt(&argp->fh), argp->len, argp->name);
 
@@ -470,11 +471,12 @@ nfsd_proc_rmdir(struct svc_rqst *rqstp, struct nfsd_diropargs *argp,
 /*
  * Read a portion of a directory.
  */
-static int
+static __be32
 nfsd_proc_readdir(struct svc_rqst *rqstp, struct nfsd_readdirargs *argp,
                                          struct nfsd_readdirres  *resp)
 {
-       int             nfserr, count;
+       int             count;
+       __be32          nfserr;
        loff_t          offset;
 
        dprintk("nfsd: READDIR  %s %d bytes at %d\n",
@@ -509,11 +511,11 @@ nfsd_proc_readdir(struct svc_rqst *rqstp, struct nfsd_readdirargs *argp,
 /*
  * Get file system info
  */
-static int
+static __be32
 nfsd_proc_statfs(struct svc_rqst * rqstp, struct nfsd_fhandle   *argp,
                                          struct nfsd_statfsres *resp)
 {
-       int     nfserr;
+       __be32  nfserr;
 
        dprintk("nfsd: STATFS   %s\n", SVCFH_fmt(&argp->fh));
 
@@ -579,11 +581,11 @@ struct svc_version        nfsd_version2 = {
 /*
  * Map errnos to NFS errnos.
  */
-int
+__be32
 nfserrno (int errno)
 {
        static struct {
-               int     nfserr;
+               __be32  nfserr;
                int     syserr;
        } nfs_errtbl[] = {
                { nfs_ok, 0 },
@@ -615,11 +617,10 @@ nfserrno (int errno)
                { nfserr_badname, -ESRCH },
                { nfserr_io, -ETXTBSY },
                { nfserr_notsupp, -EOPNOTSUPP },
-               { -1, -EIO }
        };
        int     i;
 
-       for (i = 0; nfs_errtbl[i].nfserr != -1; i++) {
+       for (i = 0; i < ARRAY_SIZE(nfs_errtbl); i++) {
                if (nfs_errtbl[i].syserr == errno)
                        return nfs_errtbl[i].nfserr;
        }
index 6fa6340a5fb892e217e180218d3199bc4e4b3e55..0aaccb03bf769a582ce6070d7e04ecfa261ae9f8 100644 (file)
@@ -217,7 +217,7 @@ int nfsd_create_serv(void)
 
        atomic_set(&nfsd_busy, 0);
        nfsd_serv = svc_create_pooled(&nfsd_program,
-                                     NFSD_BUFSIZE - NFSSVC_MAXBLKSIZE + nfsd_max_blksize,
+                                     nfsd_max_blksize,
                                      nfsd_last_thread,
                                      nfsd, SIG_NOCLEAN, THIS_MODULE);
        if (nfsd_serv == NULL)
@@ -491,12 +491,12 @@ out:
 }
 
 int
-nfsd_dispatch(struct svc_rqst *rqstp, u32 *statp)
+nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp)
 {
        struct svc_procedure    *proc;
        kxdrproc_t              xdr;
-       u32                     nfserr;
-       u32                     *nfserrp;
+       __be32                  nfserr;
+       __be32                  *nfserrp;
 
        dprintk("nfsd_dispatch: vers %d proc %d\n",
                                rqstp->rq_vers, rqstp->rq_proc);
@@ -515,7 +515,7 @@ nfsd_dispatch(struct svc_rqst *rqstp, u32 *statp)
 
        /* Decode arguments */
        xdr = proc->pc_decode;
-       if (xdr && !xdr(rqstp, (u32*)rqstp->rq_arg.head[0].iov_base,
+       if (xdr && !xdr(rqstp, (__be32*)rqstp->rq_arg.head[0].iov_base,
                        rqstp->rq_argp)) {
                dprintk("nfsd: failed to decode arguments!\n");
                nfsd_cache_update(rqstp, RC_NOCACHE, NULL);
@@ -528,7 +528,7 @@ nfsd_dispatch(struct svc_rqst *rqstp, u32 *statp)
         */
        nfserrp = rqstp->rq_res.head[0].iov_base
                + rqstp->rq_res.head[0].iov_len;
-       rqstp->rq_res.head[0].iov_len += sizeof(u32);
+       rqstp->rq_res.head[0].iov_len += sizeof(__be32);
 
        /* Now call the procedure handler, and encode NFS status. */
        nfserr = proc->pc_func(rqstp, rqstp->rq_argp, rqstp->rq_resp);
index 1135c0d145574a7feb8fdb70c4a19cfd40c7dad1..56ebb1443e0eb7bf067a773690dee36a1d60f2ee 100644 (file)
@@ -37,8 +37,8 @@ static u32    nfs_ftypes[] = {
 /*
  * XDR functions for basic NFS types
  */
-static u32 *
-decode_fh(u32 *p, struct svc_fh *fhp)
+static __be32 *
+decode_fh(__be32 *p, struct svc_fh *fhp)
 {
        fh_init(fhp, NFS_FHSIZE);
        memcpy(&fhp->fh_handle.fh_base, p, NFS_FHSIZE);
@@ -50,13 +50,13 @@ decode_fh(u32 *p, struct svc_fh *fhp)
 }
 
 /* Helper function for NFSv2 ACL code */
-u32 *nfs2svc_decode_fh(u32 *p, struct svc_fh *fhp)
+__be32 *nfs2svc_decode_fh(__be32 *p, struct svc_fh *fhp)
 {
        return decode_fh(p, fhp);
 }
 
-static inline u32 *
-encode_fh(u32 *p, struct svc_fh *fhp)
+static inline __be32 *
+encode_fh(__be32 *p, struct svc_fh *fhp)
 {
        memcpy(p, &fhp->fh_handle.fh_base, NFS_FHSIZE);
        return p + (NFS_FHSIZE>> 2);
@@ -66,8 +66,8 @@ encode_fh(u32 *p, struct svc_fh *fhp)
  * Decode a file name and make sure that the path contains
  * no slashes or null bytes.
  */
-static inline u32 *
-decode_filename(u32 *p, char **namp, int *lenp)
+static inline __be32 *
+decode_filename(__be32 *p, char **namp, int *lenp)
 {
        char            *name;
        int             i;
@@ -82,8 +82,8 @@ decode_filename(u32 *p, char **namp, int *lenp)
        return p;
 }
 
-static inline u32 *
-decode_pathname(u32 *p, char **namp, int *lenp)
+static inline __be32 *
+decode_pathname(__be32 *p, char **namp, int *lenp)
 {
        char            *name;
        int             i;
@@ -98,8 +98,8 @@ decode_pathname(u32 *p, char **namp, int *lenp)
        return p;
 }
 
-static inline u32 *
-decode_sattr(u32 *p, struct iattr *iap)
+static inline __be32 *
+decode_sattr(__be32 *p, struct iattr *iap)
 {
        u32     tmp, tmp1;
 
@@ -151,8 +151,8 @@ decode_sattr(u32 *p, struct iattr *iap)
        return p;
 }
 
-static u32 *
-encode_fattr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp,
+static __be32 *
+encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp,
             struct kstat *stat)
 {
        struct dentry   *dentry = fhp->fh_dentry;
@@ -195,7 +195,7 @@ encode_fattr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp,
 }
 
 /* Helper function for NFSv2 ACL code */
-u32 *nfs2svc_encode_fattr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp)
+__be32 *nfs2svc_encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp)
 {
        struct kstat stat;
        vfs_getattr(fhp->fh_export->ex_mnt, fhp->fh_dentry, &stat);
@@ -206,13 +206,13 @@ u32 *nfs2svc_encode_fattr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp)
  * XDR decode functions
  */
 int
-nfssvc_decode_void(struct svc_rqst *rqstp, u32 *p, void *dummy)
+nfssvc_decode_void(struct svc_rqst *rqstp, __be32 *p, void *dummy)
 {
        return xdr_argsize_check(rqstp, p);
 }
 
 int
-nfssvc_decode_fhandle(struct svc_rqst *rqstp, u32 *p, struct nfsd_fhandle *args)
+nfssvc_decode_fhandle(struct svc_rqst *rqstp, __be32 *p, struct nfsd_fhandle *args)
 {
        if (!(p = decode_fh(p, &args->fh)))
                return 0;
@@ -220,7 +220,7 @@ nfssvc_decode_fhandle(struct svc_rqst *rqstp, u32 *p, struct nfsd_fhandle *args)
 }
 
 int
-nfssvc_decode_sattrargs(struct svc_rqst *rqstp, u32 *p,
+nfssvc_decode_sattrargs(struct svc_rqst *rqstp, __be32 *p,
                                        struct nfsd_sattrargs *args)
 {
        if (!(p = decode_fh(p, &args->fh))
@@ -231,7 +231,7 @@ nfssvc_decode_sattrargs(struct svc_rqst *rqstp, u32 *p,
 }
 
 int
-nfssvc_decode_diropargs(struct svc_rqst *rqstp, u32 *p,
+nfssvc_decode_diropargs(struct svc_rqst *rqstp, __be32 *p,
                                        struct nfsd_diropargs *args)
 {
        if (!(p = decode_fh(p, &args->fh))
@@ -242,7 +242,7 @@ nfssvc_decode_diropargs(struct svc_rqst *rqstp, u32 *p,
 }
 
 int
-nfssvc_decode_readargs(struct svc_rqst *rqstp, u32 *p,
+nfssvc_decode_readargs(struct svc_rqst *rqstp, __be32 *p,
                                        struct nfsd_readargs *args)
 {
        unsigned int len;
@@ -273,7 +273,7 @@ nfssvc_decode_readargs(struct svc_rqst *rqstp, u32 *p,
 }
 
 int
-nfssvc_decode_writeargs(struct svc_rqst *rqstp, u32 *p,
+nfssvc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p,
                                        struct nfsd_writeargs *args)
 {
        unsigned int len;
@@ -303,7 +303,7 @@ nfssvc_decode_writeargs(struct svc_rqst *rqstp, u32 *p,
 }
 
 int
-nfssvc_decode_createargs(struct svc_rqst *rqstp, u32 *p,
+nfssvc_decode_createargs(struct svc_rqst *rqstp, __be32 *p,
                                        struct nfsd_createargs *args)
 {
        if (!(p = decode_fh(p, &args->fh))
@@ -315,7 +315,7 @@ nfssvc_decode_createargs(struct svc_rqst *rqstp, u32 *p,
 }
 
 int
-nfssvc_decode_renameargs(struct svc_rqst *rqstp, u32 *p,
+nfssvc_decode_renameargs(struct svc_rqst *rqstp, __be32 *p,
                                        struct nfsd_renameargs *args)
 {
        if (!(p = decode_fh(p, &args->ffh))
@@ -328,7 +328,7 @@ nfssvc_decode_renameargs(struct svc_rqst *rqstp, u32 *p,
 }
 
 int
-nfssvc_decode_readlinkargs(struct svc_rqst *rqstp, u32 *p, struct nfsd_readlinkargs *args)
+nfssvc_decode_readlinkargs(struct svc_rqst *rqstp, __be32 *p, struct nfsd_readlinkargs *args)
 {
        if (!(p = decode_fh(p, &args->fh)))
                return 0;
@@ -338,7 +338,7 @@ nfssvc_decode_readlinkargs(struct svc_rqst *rqstp, u32 *p, struct nfsd_readlinka
 }
 
 int
-nfssvc_decode_linkargs(struct svc_rqst *rqstp, u32 *p,
+nfssvc_decode_linkargs(struct svc_rqst *rqstp, __be32 *p,
                                        struct nfsd_linkargs *args)
 {
        if (!(p = decode_fh(p, &args->ffh))
@@ -350,7 +350,7 @@ nfssvc_decode_linkargs(struct svc_rqst *rqstp, u32 *p,
 }
 
 int
-nfssvc_decode_symlinkargs(struct svc_rqst *rqstp, u32 *p,
+nfssvc_decode_symlinkargs(struct svc_rqst *rqstp, __be32 *p,
                                        struct nfsd_symlinkargs *args)
 {
        if (!(p = decode_fh(p, &args->ffh))
@@ -363,7 +363,7 @@ nfssvc_decode_symlinkargs(struct svc_rqst *rqstp, u32 *p,
 }
 
 int
-nfssvc_decode_readdirargs(struct svc_rqst *rqstp, u32 *p,
+nfssvc_decode_readdirargs(struct svc_rqst *rqstp, __be32 *p,
                                        struct nfsd_readdirargs *args)
 {
        if (!(p = decode_fh(p, &args->fh)))
@@ -382,13 +382,13 @@ nfssvc_decode_readdirargs(struct svc_rqst *rqstp, u32 *p,
  * XDR encode functions
  */
 int
-nfssvc_encode_void(struct svc_rqst *rqstp, u32 *p, void *dummy)
+nfssvc_encode_void(struct svc_rqst *rqstp, __be32 *p, void *dummy)
 {
        return xdr_ressize_check(rqstp, p);
 }
 
 int
-nfssvc_encode_attrstat(struct svc_rqst *rqstp, u32 *p,
+nfssvc_encode_attrstat(struct svc_rqst *rqstp, __be32 *p,
                                        struct nfsd_attrstat *resp)
 {
        p = encode_fattr(rqstp, p, &resp->fh, &resp->stat);
@@ -396,7 +396,7 @@ nfssvc_encode_attrstat(struct svc_rqst *rqstp, u32 *p,
 }
 
 int
-nfssvc_encode_diropres(struct svc_rqst *rqstp, u32 *p,
+nfssvc_encode_diropres(struct svc_rqst *rqstp, __be32 *p,
                                        struct nfsd_diropres *resp)
 {
        p = encode_fh(p, &resp->fh);
@@ -405,7 +405,7 @@ nfssvc_encode_diropres(struct svc_rqst *rqstp, u32 *p,
 }
 
 int
-nfssvc_encode_readlinkres(struct svc_rqst *rqstp, u32 *p,
+nfssvc_encode_readlinkres(struct svc_rqst *rqstp, __be32 *p,
                                        struct nfsd_readlinkres *resp)
 {
        *p++ = htonl(resp->len);
@@ -421,7 +421,7 @@ nfssvc_encode_readlinkres(struct svc_rqst *rqstp, u32 *p,
 }
 
 int
-nfssvc_encode_readres(struct svc_rqst *rqstp, u32 *p,
+nfssvc_encode_readres(struct svc_rqst *rqstp, __be32 *p,
                                        struct nfsd_readres *resp)
 {
        p = encode_fattr(rqstp, p, &resp->fh, &resp->stat);
@@ -440,7 +440,7 @@ nfssvc_encode_readres(struct svc_rqst *rqstp, u32 *p,
 }
 
 int
-nfssvc_encode_readdirres(struct svc_rqst *rqstp, u32 *p,
+nfssvc_encode_readdirres(struct svc_rqst *rqstp, __be32 *p,
                                        struct nfsd_readdirres *resp)
 {
        xdr_ressize_check(rqstp, p);
@@ -453,7 +453,7 @@ nfssvc_encode_readdirres(struct svc_rqst *rqstp, u32 *p,
 }
 
 int
-nfssvc_encode_statfsres(struct svc_rqst *rqstp, u32 *p,
+nfssvc_encode_statfsres(struct svc_rqst *rqstp, __be32 *p,
                                        struct nfsd_statfsres *resp)
 {
        struct kstatfs  *stat = &resp->stats;
@@ -471,7 +471,7 @@ nfssvc_encode_entry(struct readdir_cd *ccd, const char *name,
                    int namlen, loff_t offset, ino_t ino, unsigned int d_type)
 {
        struct nfsd_readdirres *cd = container_of(ccd, struct nfsd_readdirres, common);
-       u32     *p = cd->buffer;
+       __be32  *p = cd->buffer;
        int     buflen, slen;
 
        /*
@@ -497,7 +497,7 @@ nfssvc_encode_entry(struct readdir_cd *ccd, const char *name,
        *p++ = htonl((u32) ino);                /* file id */
        p    = xdr_encode_array(p, name, namlen);/* name length & name */
        cd->offset = p;                 /* remember pointer */
-       *p++ = ~(u32) 0;                /* offset of next entry */
+       *p++ = htonl(~0U);              /* offset of next entry */
 
        cd->buflen = buflen;
        cd->buffer = p;
@@ -509,7 +509,7 @@ nfssvc_encode_entry(struct readdir_cd *ccd, const char *name,
  * XDR release functions
  */
 int
-nfssvc_release_fhandle(struct svc_rqst *rqstp, u32 *p,
+nfssvc_release_fhandle(struct svc_rqst *rqstp, __be32 *p,
                                        struct nfsd_fhandle *resp)
 {
        fh_put(&resp->fh);
index 1141bd29e4e3ee3b6f3b9711ace4d7323e42bd5d..f21e917bb8ed18519e7e1eeb4aa1c28b94af4fa3 100644 (file)
@@ -110,7 +110,7 @@ nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry **dpp,
        struct dentry *dentry = *dpp;
        struct vfsmount *mnt = mntget(exp->ex_mnt);
        struct dentry *mounts = dget(dentry);
-       int err = nfs_ok;
+       int err = 0;
 
        while (follow_down(&mnt,&mounts)&&d_mountpoint(mounts));
 
@@ -148,14 +148,15 @@ out:
  *   clients and is explicitly disallowed for NFSv3
  *      NeilBrown <neilb@cse.unsw.edu.au>
  */
-int
+__be32
 nfsd_lookup(struct svc_rqst *rqstp, struct svc_fh *fhp, const char *name,
                                        int len, struct svc_fh *resfh)
 {
        struct svc_export       *exp;
        struct dentry           *dparent;
        struct dentry           *dentry;
-       int                     err;
+       __be32                  err;
+       int                     host_err;
 
        dprintk("nfsd: nfsd_lookup(fh %s, %.*s)\n", SVCFH_fmt(fhp), len,name);
 
@@ -193,7 +194,7 @@ nfsd_lookup(struct svc_rqst *rqstp, struct svc_fh *fhp, const char *name,
                        exp2 = exp_parent(exp->ex_client, mnt, dentry,
                                          &rqstp->rq_chandle);
                        if (IS_ERR(exp2)) {
-                               err = PTR_ERR(exp2);
+                               host_err = PTR_ERR(exp2);
                                dput(dentry);
                                mntput(mnt);
                                goto out_nfserr;
@@ -210,14 +211,14 @@ nfsd_lookup(struct svc_rqst *rqstp, struct svc_fh *fhp, const char *name,
        } else {
                fh_lock(fhp);
                dentry = lookup_one_len(name, dparent, len);
-               err = PTR_ERR(dentry);
+               host_err = PTR_ERR(dentry);
                if (IS_ERR(dentry))
                        goto out_nfserr;
                /*
                 * check if we have crossed a mount point ...
                 */
                if (d_mountpoint(dentry)) {
-                       if ((err = nfsd_cross_mnt(rqstp, &dentry, &exp))) {
+                       if ((host_err = nfsd_cross_mnt(rqstp, &dentry, &exp))) {
                                dput(dentry);
                                goto out_nfserr;
                        }
@@ -236,7 +237,7 @@ out:
        return err;
 
 out_nfserr:
-       err = nfserrno(err);
+       err = nfserrno(host_err);
        goto out;
 }
 
@@ -244,7 +245,7 @@ out_nfserr:
  * Set various file attributes.
  * N.B. After this call fhp needs an fh_put
  */
-int
+__be32
 nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
             int check_guard, time_t guardtime)
 {
@@ -253,7 +254,8 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
        int             accmode = MAY_SATTR;
        int             ftype = 0;
        int             imode;
-       int             err;
+       __be32          err;
+       int             host_err;
        int             size_change = 0;
 
        if (iap->ia_valid & (ATTR_ATIME | ATTR_MTIME | ATTR_SIZE))
@@ -319,19 +321,19 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
                 * If we are changing the size of the file, then
                 * we need to break all leases.
                 */
-               err = break_lease(inode, FMODE_WRITE | O_NONBLOCK);
-               if (err == -EWOULDBLOCK)
-                       err = -ETIMEDOUT;
-               if (err) /* ENOMEM or EWOULDBLOCK */
+               host_err = break_lease(inode, FMODE_WRITE | O_NONBLOCK);
+               if (host_err == -EWOULDBLOCK)
+                       host_err = -ETIMEDOUT;
+               if (host_err) /* ENOMEM or EWOULDBLOCK */
                        goto out_nfserr;
 
-               err = get_write_access(inode);
-               if (err)
+               host_err = get_write_access(inode);
+               if (host_err)
                        goto out_nfserr;
 
                size_change = 1;
-               err = locks_verify_truncate(inode, NULL, iap->ia_size);
-               if (err) {
+               host_err = locks_verify_truncate(inode, NULL, iap->ia_size);
+               if (host_err) {
                        put_write_access(inode);
                        goto out_nfserr;
                }
@@ -357,8 +359,8 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
        err = nfserr_notsync;
        if (!check_guard || guardtime == inode->i_ctime.tv_sec) {
                fh_lock(fhp);
-               err = notify_change(dentry, iap);
-               err = nfserrno(err);
+               host_err = notify_change(dentry, iap);
+               err = nfserrno(host_err);
                fh_unlock(fhp);
        }
        if (size_change)
@@ -370,7 +372,7 @@ out:
        return err;
 
 out_nfserr:
-       err = nfserrno(err);
+       err = nfserrno(host_err);
        goto out;
 }
 
@@ -420,11 +422,12 @@ out:
        return error;
 }
 
-int
+__be32
 nfsd4_set_nfs4_acl(struct svc_rqst *rqstp, struct svc_fh *fhp,
     struct nfs4_acl *acl)
 {
-       int error;
+       __be32 error;
+       int host_error;
        struct dentry *dentry;
        struct inode *inode;
        struct posix_acl *pacl = NULL, *dpacl = NULL;
@@ -440,20 +443,20 @@ nfsd4_set_nfs4_acl(struct svc_rqst *rqstp, struct svc_fh *fhp,
        if (S_ISDIR(inode->i_mode))
                flags = NFS4_ACL_DIR;
 
-       error = nfs4_acl_nfsv4_to_posix(acl, &pacl, &dpacl, flags);
-       if (error == -EINVAL) {
+       host_error = nfs4_acl_nfsv4_to_posix(acl, &pacl, &dpacl, flags);
+       if (host_error == -EINVAL) {
                error = nfserr_attrnotsupp;
                goto out;
-       } else if (error < 0)
+       } else if (host_error < 0)
                goto out_nfserr;
 
-       error = set_nfsv4_acl_one(dentry, pacl, POSIX_ACL_XATTR_ACCESS);
-       if (error < 0)
+       host_error = set_nfsv4_acl_one(dentry, pacl, POSIX_ACL_XATTR_ACCESS);
+       if (host_error < 0)
                goto out_nfserr;
 
        if (S_ISDIR(inode->i_mode)) {
-               error = set_nfsv4_acl_one(dentry, dpacl, POSIX_ACL_XATTR_DEFAULT);
-               if (error < 0)
+               host_error = set_nfsv4_acl_one(dentry, dpacl, POSIX_ACL_XATTR_DEFAULT);
+               if (host_error < 0)
                        goto out_nfserr;
        }
 
@@ -464,7 +467,7 @@ out:
        posix_acl_release(dpacl);
        return (error);
 out_nfserr:
-       error = nfserrno(error);
+       error = nfserrno(host_error);
        goto out;
 }
 
@@ -571,14 +574,14 @@ static struct accessmap   nfs3_anyaccess[] = {
     {  0,                      0                               }
 };
 
-int
+__be32
 nfsd_access(struct svc_rqst *rqstp, struct svc_fh *fhp, u32 *access, u32 *supported)
 {
        struct accessmap        *map;
        struct svc_export       *export;
        struct dentry           *dentry;
        u32                     query, result = 0, sresult = 0;
-       unsigned int            error;
+       __be32                  error;
 
        error = fh_verify(rqstp, fhp, 0, MAY_NOP);
        if (error)
@@ -598,7 +601,7 @@ nfsd_access(struct svc_rqst *rqstp, struct svc_fh *fhp, u32 *access, u32 *suppor
        query = *access;
        for  (; map->access; map++) {
                if (map->access & query) {
-                       unsigned int err2;
+                       __be32 err2;
 
                        sresult |= map->access;
 
@@ -637,13 +640,15 @@ nfsd_access(struct svc_rqst *rqstp, struct svc_fh *fhp, u32 *access, u32 *suppor
  * The access argument indicates the type of open (read/write/lock)
  * N.B. After this call fhp needs an fh_put
  */
-int
+__be32
 nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
                        int access, struct file **filp)
 {
        struct dentry   *dentry;
        struct inode    *inode;
-       int             flags = O_RDONLY|O_LARGEFILE, err;
+       int             flags = O_RDONLY|O_LARGEFILE;
+       __be32          err;
+       int             host_err;
 
        /*
         * If we get here, then the client has already done an "open",
@@ -673,10 +678,10 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
         * Check to see if there are any leases on this file.
         * This may block while leases are broken.
         */
-       err = break_lease(inode, O_NONBLOCK | ((access & MAY_WRITE) ? FMODE_WRITE : 0));
-       if (err == -EWOULDBLOCK)
-               err = -ETIMEDOUT;
-       if (err) /* NOMEM or WOULDBLOCK */
+       host_err = break_lease(inode, O_NONBLOCK | ((access & MAY_WRITE) ? FMODE_WRITE : 0));
+       if (host_err == -EWOULDBLOCK)
+               host_err = -ETIMEDOUT;
+       if (host_err) /* NOMEM or WOULDBLOCK */
                goto out_nfserr;
 
        if (access & MAY_WRITE) {
@@ -689,10 +694,9 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
        }
        *filp = dentry_open(dget(dentry), mntget(fhp->fh_export->ex_mnt), flags);
        if (IS_ERR(*filp))
-               err = PTR_ERR(*filp);
+               host_err = PTR_ERR(*filp);
 out_nfserr:
-       if (err)
-               err = nfserrno(err);
+       err = nfserrno(host_err);
 out:
        return err;
 }
@@ -830,14 +834,15 @@ nfsd_read_actor(read_descriptor_t *desc, struct page *page, unsigned long offset
        return size;
 }
 
-static int
+static __be32
 nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
               loff_t offset, struct kvec *vec, int vlen, unsigned long *count)
 {
        struct inode *inode;
        struct raparms  *ra;
        mm_segment_t    oldfs;
-       int             err;
+       __be32          err;
+       int             host_err;
 
        err = nfserr_perm;
        inode = file->f_dentry->d_inode;
@@ -855,12 +860,12 @@ nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
 
        if (file->f_op->sendfile && rqstp->rq_sendfile_ok) {
                rqstp->rq_resused = 1;
-               err = file->f_op->sendfile(file, &offset, *count,
+               host_err = file->f_op->sendfile(file, &offset, *count,
                                                 nfsd_read_actor, rqstp);
        } else {
                oldfs = get_fs();
                set_fs(KERNEL_DS);
-               err = vfs_readv(file, (struct iovec __user *)vec, vlen, &offset);
+               host_err = vfs_readv(file, (struct iovec __user *)vec, vlen, &offset);
                set_fs(oldfs);
        }
 
@@ -874,13 +879,13 @@ nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
                spin_unlock(&rab->pb_lock);
        }
 
-       if (err >= 0) {
-               nfsdstats.io_read += err;
-               *count = err;
+       if (host_err >= 0) {
+               nfsdstats.io_read += host_err;
+               *count = host_err;
                err = 0;
                fsnotify_access(file->f_dentry);
        } else 
-               err = nfserrno(err);
+               err = nfserrno(host_err);
 out:
        return err;
 }
@@ -895,7 +900,7 @@ static void kill_suid(struct dentry *dentry)
        mutex_unlock(&dentry->d_inode->i_mutex);
 }
 
-static int
+static __be32
 nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
                                loff_t offset, struct kvec *vec, int vlen,
                                unsigned long cnt, int *stablep)
@@ -904,7 +909,8 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
        struct dentry           *dentry;
        struct inode            *inode;
        mm_segment_t            oldfs;
-       int                     err = 0;
+       __be32                  err = 0;
+       int                     host_err;
        int                     stable = *stablep;
 
 #ifdef MSNFS
@@ -940,18 +946,18 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
 
        /* Write the data. */
        oldfs = get_fs(); set_fs(KERNEL_DS);
-       err = vfs_writev(file, (struct iovec __user *)vec, vlen, &offset);
+       host_err = vfs_writev(file, (struct iovec __user *)vec, vlen, &offset);
        set_fs(oldfs);
-       if (err >= 0) {
+       if (host_err >= 0) {
                nfsdstats.io_write += cnt;
                fsnotify_modify(file->f_dentry);
        }
 
        /* clear setuid/setgid flag after write */
-       if (err >= 0 && (inode->i_mode & (S_ISUID | S_ISGID)))
+       if (host_err >= 0 && (inode->i_mode & (S_ISUID | S_ISGID)))
                kill_suid(dentry);
 
-       if (err >= 0 && stable) {
+       if (host_err >= 0 && stable) {
                static ino_t    last_ino;
                static dev_t    last_dev;
 
@@ -977,7 +983,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
 
                        if (inode->i_state & I_DIRTY) {
                                dprintk("nfsd: write sync %d\n", current->pid);
-                               err=nfsd_sync(file);
+                               host_err=nfsd_sync(file);
                        }
 #if 0
                        wake_up(&inode->i_wait);
@@ -987,11 +993,11 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
                last_dev = inode->i_sb->s_dev;
        }
 
-       dprintk("nfsd: write complete err=%d\n", err);
-       if (err >= 0)
+       dprintk("nfsd: write complete host_err=%d\n", host_err);
+       if (host_err >= 0)
                err = 0;
        else 
-               err = nfserrno(err);
+               err = nfserrno(host_err);
 out:
        return err;
 }
@@ -1001,12 +1007,12 @@ out:
  * on entry. On return, *count contains the number of bytes actually read.
  * N.B. After this call fhp needs an fh_put
  */
-int
+__be32
 nfsd_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
                loff_t offset, struct kvec *vec, int vlen,
                unsigned long *count)
 {
-       int             err;
+       __be32          err;
 
        if (file) {
                err = nfsd_permission(fhp->fh_export, fhp->fh_dentry,
@@ -1030,12 +1036,12 @@ out:
  * The stable flag requests synchronous writes.
  * N.B. After this call fhp needs an fh_put
  */
-int
+__be32
 nfsd_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
                loff_t offset, struct kvec *vec, int vlen, unsigned long cnt,
                int *stablep)
 {
-       int                     err = 0;
+       __be32                  err = 0;
 
        if (file) {
                err = nfsd_permission(fhp->fh_export, fhp->fh_dentry,
@@ -1067,12 +1073,12 @@ out:
  * Unfortunately we cannot lock the file to make sure we return full WCC
  * data to the client, as locking happens lower down in the filesystem.
  */
-int
+__be32
 nfsd_commit(struct svc_rqst *rqstp, struct svc_fh *fhp,
                loff_t offset, unsigned long count)
 {
        struct file     *file;
-       int             err;
+       __be32          err;
 
        if ((u64)count > ~(u64)offset)
                return nfserr_inval;
@@ -1100,14 +1106,15 @@ nfsd_commit(struct svc_rqst *rqstp, struct svc_fh *fhp,
  *
  * N.B. Every call to nfsd_create needs an fh_put for _both_ fhp and resfhp
  */
-int
+__be32
 nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
                char *fname, int flen, struct iattr *iap,
                int type, dev_t rdev, struct svc_fh *resfhp)
 {
        struct dentry   *dentry, *dchild = NULL;
        struct inode    *dirp;
-       int             err;
+       __be32          err;
+       int             host_err;
 
        err = nfserr_perm;
        if (!flen)
@@ -1134,7 +1141,7 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
                /* called from nfsd_proc_mkdir, or possibly nfsd3_proc_create */
                fh_lock_nested(fhp, I_MUTEX_PARENT);
                dchild = lookup_one_len(fname, dentry, flen);
-               err = PTR_ERR(dchild);
+               host_err = PTR_ERR(dchild);
                if (IS_ERR(dchild))
                        goto out_nfserr;
                err = fh_compose(resfhp, fhp->fh_export, dchild, fhp);
@@ -1173,22 +1180,22 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
        err = nfserr_perm;
        switch (type) {
        case S_IFREG:
-               err = vfs_create(dirp, dchild, iap->ia_mode, NULL);
+               host_err = vfs_create(dirp, dchild, iap->ia_mode, NULL);
                break;
        case S_IFDIR:
-               err = vfs_mkdir(dirp, dchild, iap->ia_mode);
+               host_err = vfs_mkdir(dirp, dchild, iap->ia_mode);
                break;
        case S_IFCHR:
        case S_IFBLK:
        case S_IFIFO:
        case S_IFSOCK:
-               err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev);
+               host_err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev);
                break;
        default:
                printk("nfsd: bad file type %o in nfsd_create\n", type);
-               err = -EINVAL;
+               host_err = -EINVAL;
        }
-       if (err < 0)
+       if (host_err < 0)
                goto out_nfserr;
 
        if (EX_ISSYNC(fhp->fh_export)) {
@@ -1203,7 +1210,7 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
         * directories via NFS.
         */
        if ((iap->ia_valid &= ~(ATTR_UID|ATTR_GID|ATTR_MODE)) != 0) {
-               int err2 = nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0);
+               __be32 err2 = nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0);
                if (err2)
                        err = err2;
        }
@@ -1218,7 +1225,7 @@ out:
        return err;
 
 out_nfserr:
-       err = nfserrno(err);
+       err = nfserrno(host_err);
        goto out;
 }
 
@@ -1226,7 +1233,7 @@ out_nfserr:
 /*
  * NFSv3 version of nfsd_create
  */
-int
+__be32
 nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
                char *fname, int flen, struct iattr *iap,
                struct svc_fh *resfhp, int createmode, u32 *verifier,
@@ -1234,7 +1241,8 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
 {
        struct dentry   *dentry, *dchild = NULL;
        struct inode    *dirp;
-       int             err;
+       __be32          err;
+       int             host_err;
        __u32           v_mtime=0, v_atime=0;
        int             v_mode=0;
 
@@ -1264,7 +1272,7 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
         * Compose the response file handle.
         */
        dchild = lookup_one_len(fname, dentry, flen);
-       err = PTR_ERR(dchild);
+       host_err = PTR_ERR(dchild);
        if (IS_ERR(dchild))
                goto out_nfserr;
 
@@ -1320,8 +1328,8 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
                goto out;
        }
 
-       err = vfs_create(dirp, dchild, iap->ia_mode, NULL);
-       if (err < 0)
+       host_err = vfs_create(dirp, dchild, iap->ia_mode, NULL);
+       if (host_err < 0)
                goto out_nfserr;
 
        if (EX_ISSYNC(fhp->fh_export)) {
@@ -1350,7 +1358,7 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
         */
  set_attr:
        if ((iap->ia_valid &= ~(ATTR_UID|ATTR_GID)) != 0) {
-               int err2 = nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0);
+               __be32 err2 = nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0);
                if (err2)
                        err = err2;
        }
@@ -1368,7 +1376,7 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
        return err;
  
  out_nfserr:
-       err = nfserrno(err);
+       err = nfserrno(host_err);
        goto out;
 }
 #endif /* CONFIG_NFSD_V3 */
@@ -1378,13 +1386,14 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
  * fits into the buffer. On return, it contains the true length.
  * N.B. After this call fhp needs an fh_put
  */
-int
+__be32
 nfsd_readlink(struct svc_rqst *rqstp, struct svc_fh *fhp, char *buf, int *lenp)
 {
        struct dentry   *dentry;
        struct inode    *inode;
        mm_segment_t    oldfs;
-       int             err;
+       __be32          err;
+       int             host_err;
 
        err = fh_verify(rqstp, fhp, S_IFLNK, MAY_NOP);
        if (err)
@@ -1403,18 +1412,18 @@ nfsd_readlink(struct svc_rqst *rqstp, struct svc_fh *fhp, char *buf, int *lenp)
         */
 
        oldfs = get_fs(); set_fs(KERNEL_DS);
-       err = inode->i_op->readlink(dentry, buf, *lenp);
+       host_err = inode->i_op->readlink(dentry, buf, *lenp);
        set_fs(oldfs);
 
-       if (err < 0)
+       if (host_err < 0)
                goto out_nfserr;
-       *lenp = err;
+       *lenp = host_err;
        err = 0;
 out:
        return err;
 
 out_nfserr:
-       err = nfserrno(err);
+       err = nfserrno(host_err);
        goto out;
 }
 
@@ -1422,7 +1431,7 @@ out_nfserr:
  * Create a symlink and look up its inode
  * N.B. After this call _both_ fhp and resfhp need an fh_put
  */
-int
+__be32
 nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp,
                                char *fname, int flen,
                                char *path,  int plen,
@@ -1430,7 +1439,8 @@ nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp,
                                struct iattr *iap)
 {
        struct dentry   *dentry, *dnew;
-       int             err, cerr;
+       __be32          err, cerr;
+       int             host_err;
        umode_t         mode;
 
        err = nfserr_noent;
@@ -1446,7 +1456,7 @@ nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp,
        fh_lock(fhp);
        dentry = fhp->fh_dentry;
        dnew = lookup_one_len(fname, dentry, flen);
-       err = PTR_ERR(dnew);
+       host_err = PTR_ERR(dnew);
        if (IS_ERR(dnew))
                goto out_nfserr;
 
@@ -1458,21 +1468,21 @@ nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp,
        if (unlikely(path[plen] != 0)) {
                char *path_alloced = kmalloc(plen+1, GFP_KERNEL);
                if (path_alloced == NULL)
-                       err = -ENOMEM;
+                       host_err = -ENOMEM;
                else {
                        strncpy(path_alloced, path, plen);
                        path_alloced[plen] = 0;
-                       err = vfs_symlink(dentry->d_inode, dnew, path_alloced, mode);
+                       host_err = vfs_symlink(dentry->d_inode, dnew, path_alloced, mode);
                        kfree(path_alloced);
                }
        } else
-               err = vfs_symlink(dentry->d_inode, dnew, path, mode);
+               host_err = vfs_symlink(dentry->d_inode, dnew, path, mode);
 
-       if (!err)
+       if (!host_err) {
                if (EX_ISSYNC(fhp->fh_export))
-                       err = nfsd_sync_dir(dentry);
-       if (err)
-               err = nfserrno(err);
+                       host_err = nfsd_sync_dir(dentry);
+       }
+       err = nfserrno(host_err);
        fh_unlock(fhp);
 
        cerr = fh_compose(resfhp, fhp->fh_export, dnew, fhp);
@@ -1482,7 +1492,7 @@ out:
        return err;
 
 out_nfserr:
-       err = nfserrno(err);
+       err = nfserrno(host_err);
        goto out;
 }
 
@@ -1490,13 +1500,14 @@ out_nfserr:
  * Create a hardlink
  * N.B. After this call _both_ ffhp and tfhp need an fh_put
  */
-int
+__be32
 nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp,
                                char *name, int len, struct svc_fh *tfhp)
 {
        struct dentry   *ddir, *dnew, *dold;
        struct inode    *dirp, *dest;
-       int             err;
+       __be32          err;
+       int             host_err;
 
        err = fh_verify(rqstp, ffhp, S_IFDIR, MAY_CREATE);
        if (err)
@@ -1517,24 +1528,25 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp,
        dirp = ddir->d_inode;
 
        dnew = lookup_one_len(name, ddir, len);
-       err = PTR_ERR(dnew);
+       host_err = PTR_ERR(dnew);
        if (IS_ERR(dnew))
                goto out_nfserr;
 
        dold = tfhp->fh_dentry;
        dest = dold->d_inode;
 
-       err = vfs_link(dold, dirp, dnew);
-       if (!err) {
+       host_err = vfs_link(dold, dirp, dnew);
+       if (!host_err) {
                if (EX_ISSYNC(ffhp->fh_export)) {
                        err = nfserrno(nfsd_sync_dir(ddir));
                        write_inode_now(dest, 1);
                }
+               err = 0;
        } else {
-               if (err == -EXDEV && rqstp->rq_vers == 2)
+               if (host_err == -EXDEV && rqstp->rq_vers == 2)
                        err = nfserr_acces;
                else
-                       err = nfserrno(err);
+                       err = nfserrno(host_err);
        }
 
        dput(dnew);
@@ -1544,7 +1556,7 @@ out:
        return err;
 
 out_nfserr:
-       err = nfserrno(err);
+       err = nfserrno(host_err);
        goto out_unlock;
 }
 
@@ -1552,13 +1564,14 @@ out_nfserr:
  * Rename a file
  * N.B. After this call _both_ ffhp and tfhp need an fh_put
  */
-int
+__be32
 nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen,
                            struct svc_fh *tfhp, char *tname, int tlen)
 {
        struct dentry   *fdentry, *tdentry, *odentry, *ndentry, *trap;
        struct inode    *fdir, *tdir;
-       int             err;
+       __be32          err;
+       int             host_err;
 
        err = fh_verify(rqstp, ffhp, S_IFDIR, MAY_REMOVE);
        if (err)
@@ -1589,22 +1602,22 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen,
        fill_pre_wcc(tfhp);
 
        odentry = lookup_one_len(fname, fdentry, flen);
-       err = PTR_ERR(odentry);
+       host_err = PTR_ERR(odentry);
        if (IS_ERR(odentry))
                goto out_nfserr;
 
-       err = -ENOENT;
+       host_err = -ENOENT;
        if (!odentry->d_inode)
                goto out_dput_old;
-       err = -EINVAL;
+       host_err = -EINVAL;
        if (odentry == trap)
                goto out_dput_old;
 
        ndentry = lookup_one_len(tname, tdentry, tlen);
-       err = PTR_ERR(ndentry);
+       host_err = PTR_ERR(ndentry);
        if (IS_ERR(ndentry))
                goto out_dput_old;
-       err = -ENOTEMPTY;
+       host_err = -ENOTEMPTY;
        if (ndentry == trap)
                goto out_dput_new;
 
@@ -1612,14 +1625,14 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen,
        if ((ffhp->fh_export->ex_flags & NFSEXP_MSNFS) &&
                ((atomic_read(&odentry->d_count) > 1)
                 || (atomic_read(&ndentry->d_count) > 1))) {
-                       err = -EPERM;
+                       host_err = -EPERM;
        } else
 #endif
-       err = vfs_rename(fdir, odentry, tdir, ndentry);
-       if (!err && EX_ISSYNC(tfhp->fh_export)) {
-               err = nfsd_sync_dir(tdentry);
-               if (!err)
-                       err = nfsd_sync_dir(fdentry);
+       host_err = vfs_rename(fdir, odentry, tdir, ndentry);
+       if (!host_err && EX_ISSYNC(tfhp->fh_export)) {
+               host_err = nfsd_sync_dir(tdentry);
+               if (!host_err)
+                       host_err = nfsd_sync_dir(fdentry);
        }
 
  out_dput_new:
@@ -1627,8 +1640,7 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen,
  out_dput_old:
        dput(odentry);
  out_nfserr:
-       if (err)
-               err = nfserrno(err);
+       err = nfserrno(host_err);
 
        /* we cannot reply on fh_unlock on the two filehandles,
         * as that would do the wrong thing if the two directories
@@ -1647,13 +1659,14 @@ out:
  * Unlink a file or directory
  * N.B. After this call fhp needs an fh_put
  */
-int
+__be32
 nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
                                char *fname, int flen)
 {
        struct dentry   *dentry, *rdentry;
        struct inode    *dirp;
-       int             err;
+       __be32          err;
+       int             host_err;
 
        err = nfserr_acces;
        if (!flen || isdotent(fname, flen))
@@ -1667,7 +1680,7 @@ nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
        dirp = dentry->d_inode;
 
        rdentry = lookup_one_len(fname, dentry, flen);
-       err = PTR_ERR(rdentry);
+       host_err = PTR_ERR(rdentry);
        if (IS_ERR(rdentry))
                goto out_nfserr;
 
@@ -1684,22 +1697,23 @@ nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
 #ifdef MSNFS
                if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) &&
                        (atomic_read(&rdentry->d_count) > 1)) {
-                       err = -EPERM;
+                       host_err = -EPERM;
                } else
 #endif
-               err = vfs_unlink(dirp, rdentry);
+               host_err = vfs_unlink(dirp, rdentry);
        } else { /* It's RMDIR */
-               err = vfs_rmdir(dirp, rdentry);
+               host_err = vfs_rmdir(dirp, rdentry);
        }
 
        dput(rdentry);
 
-       if (err == 0 &&
-           EX_ISSYNC(fhp->fh_export))
-                       err = nfsd_sync_dir(dentry);
+       if (host_err)
+               goto out_nfserr;
+       if (EX_ISSYNC(fhp->fh_export))
+               host_err = nfsd_sync_dir(dentry);
 
 out_nfserr:
-       err = nfserrno(err);
+       err = nfserrno(host_err);
 out:
        return err;
 }
@@ -1708,11 +1722,12 @@ out:
  * Read entries from a directory.
  * The  NFSv3/4 verifier we ignore for now.
  */
-int
+__be32
 nfsd_readdir(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t *offsetp, 
             struct readdir_cd *cdp, encode_dent_fn func)
 {
-       int             err;
+       __be32          err;
+       int             host_err;
        struct file     *file;
        loff_t          offset = *offsetp;
 
@@ -1734,10 +1749,10 @@ nfsd_readdir(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t *offsetp,
 
        do {
                cdp->err = nfserr_eof; /* will be cleared on successful read */
-               err = vfs_readdir(file, (filldir_t) func, cdp);
-       } while (err >=0 && cdp->err == nfs_ok);
-       if (err)
-               err = nfserrno(err);
+               host_err = vfs_readdir(file, (filldir_t) func, cdp);
+       } while (host_err >=0 && cdp->err == nfs_ok);
+       if (host_err)
+               err = nfserrno(host_err);
        else
                err = cdp->err;
        *offsetp = vfs_llseek(file, 0, 1);
@@ -1754,10 +1769,10 @@ out:
  * Get file system stats
  * N.B. After this call fhp needs an fh_put
  */
-int
+__be32
 nfsd_statfs(struct svc_rqst *rqstp, struct svc_fh *fhp, struct kstatfs *stat)
 {
-       int err = fh_verify(rqstp, fhp, 0, MAY_NOP);
+       __be32 err = fh_verify(rqstp, fhp, 0, MAY_NOP);
        if (!err && vfs_statfs(fhp->fh_dentry,stat))
                err = nfserr_io;
        return err;
@@ -1766,7 +1781,7 @@ nfsd_statfs(struct svc_rqst *rqstp, struct svc_fh *fhp, struct kstatfs *stat)
 /*
  * Check for a user's access permissions to this inode.
  */
-int
+__be32
 nfsd_permission(struct svc_export *exp, struct dentry *dentry, int acc)
 {
        struct inode    *inode = dentry->d_inode;
index e1fceb8aa32d612973de79f9967f1b74f9bd0964..d11753c50bc1452822befe923c149f8e79202c0c 100644 (file)
@@ -152,14 +152,16 @@ static struct o2nm_node *o2nm_node_ip_tree_lookup(struct o2nm_cluster *cluster,
        struct o2nm_node *node, *ret = NULL;
 
        while (*p) {
+               int cmp;
+
                parent = *p;
                node = rb_entry(parent, struct o2nm_node, nd_ip_node);
 
-               if (memcmp(&ip_needle, &node->nd_ipv4_address,
-                          sizeof(ip_needle)) < 0)
+               cmp = memcmp(&ip_needle, &node->nd_ipv4_address,
+                               sizeof(ip_needle));
+               if (cmp < 0)
                        p = &(*p)->rb_left;
-               else if (memcmp(&ip_needle, &node->nd_ipv4_address,
-                               sizeof(ip_needle)) > 0)
+               else if (cmp > 0)
                        p = &(*p)->rb_right;
                else {
                        ret = node;
index d9ba0a931a03b89aa5c9a894b040470db459e05b..1be74c4e78148f4cd79df11a62c6796fc7b642e4 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/highmem.h>
 #include <linux/pagemap.h>
 #include <linux/uio.h>
+#include <linux/sched.h>
 
 #define MLOG_MASK_PREFIX ML_INODE
 #include <cluster/masklog.h>
@@ -691,6 +692,12 @@ static int ocfs2_zero_extend(struct inode *inode,
                }
 
                start_off += sb->s_blocksize;
+
+               /*
+                * Very large extends have the potential to lock up
+                * the cpu for extended periods of time.
+                */
+               cond_resched();
        }
 
 out:
@@ -728,31 +735,36 @@ static int ocfs2_extend_file(struct inode *inode,
        clusters_to_add = ocfs2_clusters_for_bytes(inode->i_sb, new_i_size) - 
                OCFS2_I(inode)->ip_clusters;
 
-       if (clusters_to_add) {
-               /* 
-                * protect the pages that ocfs2_zero_extend is going to
-                * be pulling into the page cache.. we do this before the
-                * metadata extend so that we don't get into the situation
-                * where we've extended the metadata but can't get the data
-                * lock to zero.
-                */
-               ret = ocfs2_data_lock(inode, 1);
-               if (ret < 0) {
-                       mlog_errno(ret);
-                       goto out;
-               }
+       /* 
+        * protect the pages that ocfs2_zero_extend is going to be
+        * pulling into the page cache.. we do this before the
+        * metadata extend so that we don't get into the situation
+        * where we've extended the metadata but can't get the data
+        * lock to zero.
+        */
+       ret = ocfs2_data_lock(inode, 1);
+       if (ret < 0) {
+               mlog_errno(ret);
+               goto out;
+       }
 
+       if (clusters_to_add) {
                ret = ocfs2_extend_allocation(inode, clusters_to_add);
                if (ret < 0) {
                        mlog_errno(ret);
                        goto out_unlock;
                }
+       }
 
-               ret = ocfs2_zero_extend(inode, (u64)new_i_size - tail_to_skip);
-               if (ret < 0) {
-                       mlog_errno(ret);
-                       goto out_unlock;
-               }
+       /*
+        * Call this even if we don't add any clusters to the tree. We
+        * still need to zero the area between the old i_size and the
+        * new i_size.
+        */
+       ret = ocfs2_zero_extend(inode, (u64)new_i_size - tail_to_skip);
+       if (ret < 0) {
+               mlog_errno(ret);
+               goto out_unlock;
        }
 
        if (!tail_to_skip) {
@@ -764,8 +776,7 @@ static int ocfs2_extend_file(struct inode *inode,
        }
 
 out_unlock:
-       if (clusters_to_add) /* this is the only case in which we lock */
-               ocfs2_data_unlock(inode, 1);
+       ocfs2_data_unlock(inode, 1);
 
 out:
        return ret;
index 259155f0eb2e97ce20a39b7d990ee497b59a5725..a57b751d4f40e3fad3cf7bc1df95b09816f8307c 100644 (file)
@@ -1085,14 +1085,6 @@ static int ocfs2_rename(struct inode *old_dir,
                        BUG();
        }
 
-       if (atomic_read(&old_dentry->d_count) > 2) {
-               shrink_dcache_parent(old_dentry);
-               if (atomic_read(&old_dentry->d_count) > 2) {
-                       status = -EBUSY;
-                       goto bail;
-               }
-       }
-
        /* Assume a directory heirarchy thusly:
         * a/b/c
         * a/d
index 4c29cd7cc8e6e22f876daf0116f5bafd32ddca8e..76b46ebbb10c1b36f17b11879f329b77433ec825 100644 (file)
@@ -339,7 +339,7 @@ static unsigned long long ocfs2_max_file_offset(unsigned int blockshift)
 
 #if BITS_PER_LONG == 32
 # if defined(CONFIG_LBD)
-       BUG_ON(sizeof(sector_t) != 8);
+       BUILD_BUG_ON(sizeof(sector_t) != 8);
        pagefactor = PAGE_CACHE_SIZE;
        bitshift = BITS_PER_LONG;
 # else
index 51c6a748df4921947659abb114fc189f2508fa95..6fb4b6150d7701cd57085f80a0f9222f31be53ed 100644 (file)
@@ -376,18 +376,48 @@ static char *make_block_name(struct gendisk *disk)
        return name;
 }
 
-static void disk_sysfs_symlinks(struct gendisk *disk)
+static int disk_sysfs_symlinks(struct gendisk *disk)
 {
        struct device *target = get_device(disk->driverfs_dev);
+       int err;
+       char *disk_name = NULL;
+
        if (target) {
-               char *disk_name = make_block_name(disk);
-               sysfs_create_link(&disk->kobj,&target->kobj,"device");
-               if (disk_name) {
-                       sysfs_create_link(&target->kobj,&disk->kobj,disk_name);
-                       kfree(disk_name);
+               disk_name = make_block_name(disk);
+               if (!disk_name) {
+                       err = -ENOMEM;
+                       goto err_out;
                }
+
+               err = sysfs_create_link(&disk->kobj, &target->kobj, "device");
+               if (err)
+                       goto err_out_disk_name;
+
+               err = sysfs_create_link(&target->kobj, &disk->kobj, disk_name);
+               if (err)
+                       goto err_out_dev_link;
        }
-       sysfs_create_link(&disk->kobj, &block_subsys.kset.kobj, "subsystem");
+
+       err = sysfs_create_link(&disk->kobj, &block_subsys.kset.kobj,
+                               "subsystem");
+       if (err)
+               goto err_out_disk_name_lnk;
+
+       kfree(disk_name);
+
+       return 0;
+
+err_out_disk_name_lnk:
+       if (target) {
+               sysfs_remove_link(&target->kobj, disk_name);
+err_out_dev_link:
+               sysfs_remove_link(&disk->kobj, "device");
+err_out_disk_name:
+               kfree(disk_name);
+err_out:
+               put_device(target);
+       }
+       return err;
 }
 
 /* Not exported, helper to add_disk(). */
@@ -406,7 +436,11 @@ void register_disk(struct gendisk *disk)
                *s = '!';
        if ((err = kobject_add(&disk->kobj)))
                return;
-       disk_sysfs_symlinks(disk);
+       err = disk_sysfs_symlinks(disk);
+       if (err) {
+               kobject_del(&disk->kobj);
+               return;
+       }
        disk_sysfs_add_subdirs(disk);
 
        /* No minors to use for partitions */
index 4f8df71e49d330038614c4f81a300f477b6f9a95..8c7af1777819e2b2d5cdeabc49ef87298ca89c19 100644 (file)
 #include <asm/unaligned.h>
 
 #define SYS_IND(p)     (get_unaligned(&p->sys_ind))
-#define NR_SECTS(p)    ({ __typeof__(p->nr_sects) __a =        \
-                               get_unaligned(&p->nr_sects);    \
+#define NR_SECTS(p)    ({ __le32 __a = get_unaligned(&p->nr_sects);    \
                                le32_to_cpu(__a); \
                        })
 
-#define START_SECT(p)  ({ __typeof__(p->start_sect) __a =      \
-                               get_unaligned(&p->start_sect);  \
+#define START_SECT(p)  ({ __le32 __a = get_unaligned(&p->start_sect);  \
                                le32_to_cpu(__a); \
                        })
 
index 82da55b5cffef804f4528bf1bed4d94645f7df2d..8df27401d29207683e3dd1ad1a0d0ac5b5508adb 100644 (file)
@@ -72,6 +72,7 @@
 #include <linux/audit.h>
 #include <linux/poll.h>
 #include <linux/nsproxy.h>
+#include <linux/oom.h>
 #include "internal.h"
 
 /* NOTE:
@@ -86,7 +87,7 @@
 
 
 /* Worst case buffer size needed for holding an integer. */
-#define PROC_NUMBUF 10
+#define PROC_NUMBUF 13
 
 struct pid_entry {
        int len;
@@ -689,7 +690,8 @@ static ssize_t oom_adjust_write(struct file *file, const char __user *buf,
        if (copy_from_user(buffer, buf, count))
                return -EFAULT;
        oom_adjust = simple_strtol(buffer, &end, 0);
-       if ((oom_adjust < -16 || oom_adjust > 15) && oom_adjust != OOM_DISABLE)
+       if ((oom_adjust < OOM_ADJUST_MIN || oom_adjust > OOM_ADJUST_MAX) &&
+            oom_adjust != OOM_DISABLE)
                return -EINVAL;
        if (*end == '\n')
                end++;
index 8d88e58ed5cca648a75a514766f41a80f883d5d7..93c43b676e59f374813e9ae7095470ce9c23b87c 100644 (file)
@@ -647,7 +647,7 @@ static ssize_t write_sysrq_trigger(struct file *file, const char __user *buf,
 
                if (get_user(c, buf))
                        return -EFAULT;
-               __handle_sysrq(c, NULL, NULL, 0);
+               __handle_sysrq(c, NULL, 0);
        }
        return count;
 }
index 1bfae42117ca714d1951a179d26d037f12226767..e3d466a228d40bd9756bafe76a4f5a419b43a8cf 100644 (file)
@@ -1304,8 +1304,8 @@ struct buffer_head *reiserfs_read_bitmap_block(struct super_block *sb,
 
        bh = sb_bread(sb, block);
        if (bh == NULL)
-               reiserfs_warning(sb, "sh-2029: %s: bitmap block (#%lu) "
-                                "reading failed", __FUNCTION__, bh->b_blocknr);
+               reiserfs_warning(sb, "sh-2029: %s: bitmap block (#%u) "
+                                "reading failed", __FUNCTION__, block);
        else {
                if (buffer_locked(bh)) {
                        PROC_INFO_INC(sb, scan_bitmap.wait);
index ad8cbc49883ab7d1e1051f9c72dff211b45a80e8..85ce23268302931e0a23a6bd6cc2a20a36581e56 100644 (file)
@@ -53,6 +53,7 @@
 #include <linux/workqueue.h>
 #include <linux/writeback.h>
 #include <linux/blkdev.h>
+#include <linux/backing-dev.h>
 
 /* gets a struct reiserfs_journal_list * from a list head */
 #define JOURNAL_LIST_ENTRY(h) (list_entry((h), struct reiserfs_journal_list, \
@@ -970,7 +971,7 @@ int reiserfs_async_progress_wait(struct super_block *s)
        DEFINE_WAIT(wait);
        struct reiserfs_journal *j = SB_JOURNAL(s);
        if (atomic_read(&j->j_async_throttle))
-               blk_congestion_wait(WRITE, HZ / 10);
+               congestion_wait(WRITE, HZ / 10);
        return 0;
 }
 
index c89aa2338191af86e6299496e18882756ccb78d2..9041802df83216f4cb6951d1e5cac7fd30f56743 100644 (file)
@@ -430,20 +430,29 @@ int remove_save_link(struct inode *inode, int truncate)
        return journal_end(&th, inode->i_sb, JOURNAL_PER_BALANCE_CNT);
 }
 
-static void reiserfs_put_super(struct super_block *s)
+static void reiserfs_kill_sb(struct super_block *s)
 {
-       struct reiserfs_transaction_handle th;
-       th.t_trans_id = 0;
+       if (REISERFS_SB(s)) {
+               if (REISERFS_SB(s)->xattr_root) {
+                       d_invalidate(REISERFS_SB(s)->xattr_root);
+                       dput(REISERFS_SB(s)->xattr_root);
+                       REISERFS_SB(s)->xattr_root = NULL;
+               }
 
-       if (REISERFS_SB(s)->xattr_root) {
-               d_invalidate(REISERFS_SB(s)->xattr_root);
-               dput(REISERFS_SB(s)->xattr_root);
+               if (REISERFS_SB(s)->priv_root) {
+                       d_invalidate(REISERFS_SB(s)->priv_root);
+                       dput(REISERFS_SB(s)->priv_root);
+                       REISERFS_SB(s)->priv_root = NULL;
+               }
        }
 
-       if (REISERFS_SB(s)->priv_root) {
-               d_invalidate(REISERFS_SB(s)->priv_root);
-               dput(REISERFS_SB(s)->priv_root);
-       }
+       kill_block_super(s);
+}
+
+static void reiserfs_put_super(struct super_block *s)
+{
+       struct reiserfs_transaction_handle th;
+       th.t_trans_id = 0;
 
        /* change file system state to current state if it was mounted with read-write permissions */
        if (!(s->s_flags & MS_RDONLY)) {
@@ -2156,7 +2165,7 @@ struct file_system_type reiserfs_fs_type = {
        .owner = THIS_MODULE,
        .name = "reiserfs",
        .get_sb = get_super_block,
-       .kill_sb = kill_block_super,
+       .kill_sb = reiserfs_kill_sb,
        .fs_flags = FS_REQUIRES_DEV,
 };
 
index 13e92dd19fbb1b9165f6cd05e02128c2a0a39cd8..49fb9f129938845589570d622803b9189ed172c4 100644 (file)
@@ -607,7 +607,7 @@ find_page:
                        ret = -ENOMEM;
                        page = page_cache_alloc_cold(mapping);
                        if (unlikely(!page))
-                               goto out_nomem;
+                               goto out_ret;
 
                        /*
                         * This will also lock the page
@@ -666,7 +666,7 @@ find_page:
                if (sd->pos + this_len > isize)
                        vmtruncate(mapping->host, isize);
 
-               goto out;
+               goto out_ret;
        }
 
        if (buf->page != page) {
@@ -698,7 +698,7 @@ find_page:
 out:
        page_cache_release(page);
        unlock_page(page);
-out_nomem:
+out_ret:
        return ret;
 }
 
@@ -707,9 +707,9 @@ out_nomem:
  * key here is the 'actor' worker passed in that actually moves the data
  * to the wanted destination. See pipe_to_file/pipe_to_sendpage above.
  */
-ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out,
-                        loff_t *ppos, size_t len, unsigned int flags,
-                        splice_actor *actor)
+static ssize_t __splice_from_pipe(struct pipe_inode_info *pipe,
+                                 struct file *out, loff_t *ppos, size_t len,
+                                 unsigned int flags, splice_actor *actor)
 {
        int ret, do_wakeup, err;
        struct splice_desc sd;
@@ -722,9 +722,6 @@ ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out,
        sd.file = out;
        sd.pos = *ppos;
 
-       if (pipe->inode)
-               mutex_lock(&pipe->inode->i_mutex);
-
        for (;;) {
                if (pipe->nrbufs) {
                        struct pipe_buffer *buf = pipe->bufs + pipe->curbuf;
@@ -797,9 +794,6 @@ ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out,
                pipe_wait(pipe);
        }
 
-       if (pipe->inode)
-               mutex_unlock(&pipe->inode->i_mutex);
-
        if (do_wakeup) {
                smp_mb();
                if (waitqueue_active(&pipe->wait))
@@ -810,6 +804,73 @@ ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out,
        return ret;
 }
 
+ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out,
+                        loff_t *ppos, size_t len, unsigned int flags,
+                        splice_actor *actor)
+{
+       ssize_t ret;
+       struct inode *inode = out->f_mapping->host;
+
+       /*
+        * The actor worker might be calling ->prepare_write and
+        * ->commit_write. Most of the time, these expect i_mutex to
+        * be held. Since this may result in an ABBA deadlock with
+        * pipe->inode, we have to order lock acquiry here.
+        */
+       inode_double_lock(inode, pipe->inode);
+       ret = __splice_from_pipe(pipe, out, ppos, len, flags, actor);
+       inode_double_unlock(inode, pipe->inode);
+
+       return ret;
+}
+
+/**
+ * generic_file_splice_write_nolock - generic_file_splice_write without mutexes
+ * @pipe:      pipe info
+ * @out:       file to write to
+ * @len:       number of bytes to splice
+ * @flags:     splice modifier flags
+ *
+ * Will either move or copy pages (determined by @flags options) from
+ * the given pipe inode to the given file. The caller is responsible
+ * for acquiring i_mutex on both inodes.
+ *
+ */
+ssize_t
+generic_file_splice_write_nolock(struct pipe_inode_info *pipe, struct file *out,
+                                loff_t *ppos, size_t len, unsigned int flags)
+{
+       struct address_space *mapping = out->f_mapping;
+       struct inode *inode = mapping->host;
+       ssize_t ret;
+       int err;
+
+       err = remove_suid(out->f_dentry);
+       if (unlikely(err))
+               return err;
+
+       ret = __splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_file);
+       if (ret > 0) {
+               *ppos += ret;
+
+               /*
+                * If file or inode is SYNC and we actually wrote some data,
+                * sync it.
+                */
+               if (unlikely((out->f_flags & O_SYNC) || IS_SYNC(inode))) {
+                       err = generic_osync_inode(inode, mapping,
+                                                 OSYNC_METADATA|OSYNC_DATA);
+
+                       if (err)
+                               ret = err;
+               }
+       }
+
+       return ret;
+}
+
+EXPORT_SYMBOL(generic_file_splice_write_nolock);
+
 /**
  * generic_file_splice_write - splice data from a pipe to a file
  * @pipe:      pipe info
@@ -826,12 +887,21 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out,
                          loff_t *ppos, size_t len, unsigned int flags)
 {
        struct address_space *mapping = out->f_mapping;
+       struct inode *inode = mapping->host;
        ssize_t ret;
+       int err;
+
+       err = should_remove_suid(out->f_dentry);
+       if (unlikely(err)) {
+               mutex_lock(&inode->i_mutex);
+               err = __remove_suid(out->f_dentry, err);
+               mutex_unlock(&inode->i_mutex);
+               if (err)
+                       return err;
+       }
 
        ret = splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_file);
        if (ret > 0) {
-               struct inode *inode = mapping->host;
-
                *ppos += ret;
 
                /*
@@ -839,8 +909,6 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out,
                 * sync it.
                 */
                if (unlikely((out->f_flags & O_SYNC) || IS_SYNC(inode))) {
-                       int err;
-
                        mutex_lock(&inode->i_mutex);
                        err = generic_osync_inode(inode, mapping,
                                                  OSYNC_METADATA|OSYNC_DATA);
@@ -1400,13 +1468,7 @@ static int link_pipe(struct pipe_inode_info *ipipe,
         * grabbing by inode address. Otherwise two different processes
         * could deadlock (one doing tee from A -> B, the other from B -> A).
         */
-       if (ipipe->inode < opipe->inode) {
-               mutex_lock_nested(&ipipe->inode->i_mutex, I_MUTEX_PARENT);
-               mutex_lock_nested(&opipe->inode->i_mutex, I_MUTEX_CHILD);
-       } else {
-               mutex_lock_nested(&opipe->inode->i_mutex, I_MUTEX_PARENT);
-               mutex_lock_nested(&ipipe->inode->i_mutex, I_MUTEX_CHILD);
-       }
+       inode_double_lock(ipipe->inode, opipe->inode);
 
        do {
                if (!opipe->readers) {
@@ -1450,8 +1512,7 @@ static int link_pipe(struct pipe_inode_info *ipipe,
                i++;
        } while (len);
 
-       mutex_unlock(&ipipe->inode->i_mutex);
-       mutex_unlock(&opipe->inode->i_mutex);
+       inode_double_unlock(ipipe->inode, opipe->inode);
 
        /*
         * If we put data in the output pipe, wakeup any potential readers.
index aec99ddbe53f726a526d4cd0b02abb9f55179e0b..47e554c12e768bc0c5b0ad10b10d3a3a92a90e46 100644 (file)
@@ -260,17 +260,17 @@ int fsync_super(struct super_block *sb)
  *     that need destruction out of superblock, call generic_shutdown_super()
  *     and release aforementioned objects.  Note: dentries and inodes _are_
  *     taken care of and do not need specific handling.
+ *
+ *     Upon calling this function, the filesystem may no longer alter or
+ *     rearrange the set of dentries belonging to this super_block, nor may it
+ *     change the attachments of dentries to inodes.
  */
 void generic_shutdown_super(struct super_block *sb)
 {
-       struct dentry *root = sb->s_root;
        struct super_operations *sop = sb->s_op;
 
-       if (root) {
-               sb->s_root = NULL;
-               shrink_dcache_parent(root);
-               shrink_dcache_sb(sb);
-               dput(root);
+       if (sb->s_root) {
+               shrink_dcache_for_umount(sb);
                fsync_super(sb);
                lock_super(sb);
                sb->s_flags &= ~MS_ACTIVE;
index 146f1dedec844ced95a9055e31e701365b4b241e..298303b5a7169f37402fe45557385e0a43e0ab56 100644 (file)
@@ -483,17 +483,12 @@ int sysfs_update_file(struct kobject * kobj, const struct attribute * attr)
                    (victim->d_parent->d_inode == dir->d_inode)) {
                        victim->d_inode->i_mtime = CURRENT_TIME;
                        fsnotify_modify(victim);
-
-                       /**
-                        * Drop reference from initial sysfs_get_dentry().
-                        */
-                       dput(victim);
                        res = 0;
                } else
                        d_drop(victim);
                
                /**
-                * Drop the reference acquired from sysfs_get_dentry() above.
+                * Drop the reference acquired from lookup_one_len() above.
                 */
                dput(victim);
        }
index 350cba5d68034f8dd4bdbb2732e2d5bc0cc17f9a..dc9e7dc07fb7d1be9a8c899f940cccd2fb2000be 100644 (file)
@@ -358,16 +358,11 @@ static int sysv_fill_super(struct super_block *sb, void *data, int silent)
        unsigned long blocknr;
        int size = 0, i;
        
-       if (1024 != sizeof (struct xenix_super_block))
-               panic("Xenix FS: bad superblock size");
-       if (512 != sizeof (struct sysv4_super_block))
-               panic("SystemV FS: bad superblock size");
-       if (512 != sizeof (struct sysv2_super_block))
-               panic("SystemV FS: bad superblock size");
-       if (500 != sizeof (struct coh_super_block))
-               panic("Coherent FS: bad superblock size");
-       if (64 != sizeof (struct sysv_inode))
-               panic("sysv fs: bad inode size");
+       BUILD_BUG_ON(1024 != sizeof (struct xenix_super_block));
+       BUILD_BUG_ON(512 != sizeof (struct sysv4_super_block));
+       BUILD_BUG_ON(512 != sizeof (struct sysv2_super_block));
+       BUILD_BUG_ON(500 != sizeof (struct coh_super_block));
+       BUILD_BUG_ON(64 != sizeof (struct sysv_inode));
 
        sbi = kzalloc(sizeof(struct sysv_sb_info), GFP_KERNEL);
        if (!sbi)
index 1d3b5d2070e5474cbf2b212b457166487e32fbde..1aea6a4f9a4ab1ce76c3d452be99313f76f7dd1d 100644 (file)
@@ -1621,9 +1621,10 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
                goto error_out;
        }
 
-       if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_READ_ONLY)
+       if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_READ_ONLY) {
                printk("UDF-fs: Partition marked readonly; forcing readonly mount\n");
                sb->s_flags |= MS_RDONLY;
+       }
 
        if ( udf_find_fileset(sb, &fileset, &rootdir) )
        {
index 22f820a9b15c782dace5e86fc2a6bf9d9ad74ab0..17437574f79c1e23e6ef8f533fa16767dd432580 100644 (file)
@@ -184,14 +184,13 @@ void _ubh_memcpyubh_(struct ufs_sb_private_info * uspi,
 dev_t
 ufs_get_inode_dev(struct super_block *sb, struct ufs_inode_info *ufsi)
 {
-       __fs32 fs32;
+       __u32 fs32;
        dev_t dev;
 
        if ((UFS_SB(sb)->s_flags & UFS_ST_MASK) == UFS_ST_SUNx86)
-               fs32 = ufsi->i_u1.i_data[1];
+               fs32 = fs32_to_cpu(sb, ufsi->i_u1.i_data[1]);
        else
-               fs32 = ufsi->i_u1.i_data[0];
-       fs32 = fs32_to_cpu(sb, fs32);
+               fs32 = fs32_to_cpu(sb, ufsi->i_u1.i_data[0]);
        switch (UFS_SB(sb)->s_flags & UFS_ST_MASK) {
        case UFS_ST_SUNx86:
        case UFS_ST_SUN:
@@ -212,7 +211,7 @@ ufs_get_inode_dev(struct super_block *sb, struct ufs_inode_info *ufsi)
 void
 ufs_set_inode_dev(struct super_block *sb, struct ufs_inode_info *ufsi, dev_t dev)
 {
-       __fs32 fs32;
+       __u32 fs32;
 
        switch (UFS_SB(sb)->s_flags & UFS_ST_MASK) {
        case UFS_ST_SUNx86:
@@ -227,11 +226,10 @@ ufs_set_inode_dev(struct super_block *sb, struct ufs_inode_info *ufsi, dev_t dev
                fs32 = old_encode_dev(dev);
                break;
        }
-       fs32 = cpu_to_fs32(sb, fs32);
        if ((UFS_SB(sb)->s_flags & UFS_ST_MASK) == UFS_ST_SUNx86)
-               ufsi->i_u1.i_data[1] = fs32;
+               ufsi->i_u1.i_data[1] = cpu_to_fs32(sb, fs32);
        else
-               ufsi->i_u1.i_data[0] = fs32;
+               ufsi->i_u1.i_data[0] = cpu_to_fs32(sb, fs32);
 }
 
 /**
index c32f15b5f60fd29d69ec8f4aa7a4f3eec0501fd6..395635100f77a45784057546b0a0c4a490b03249 100644 (file)
@@ -135,6 +135,26 @@ vfs_getxattr(struct dentry *dentry, char *name, void *value, size_t size)
 }
 EXPORT_SYMBOL_GPL(vfs_getxattr);
 
+ssize_t
+vfs_listxattr(struct dentry *d, char *list, size_t size)
+{
+       ssize_t error;
+
+       error = security_inode_listxattr(d);
+       if (error)
+               return error;
+       error = -EOPNOTSUPP;
+       if (d->d_inode->i_op && d->d_inode->i_op->listxattr) {
+               error = d->d_inode->i_op->listxattr(d, list, size);
+       } else {
+               error = security_inode_listsecurity(d->d_inode, list, size);
+               if (size && error > size)
+                       error = -ERANGE;
+       }
+       return error;
+}
+EXPORT_SYMBOL_GPL(vfs_listxattr);
+
 int
 vfs_removexattr(struct dentry *dentry, char *name)
 {
@@ -346,17 +366,7 @@ listxattr(struct dentry *d, char __user *list, size_t size)
                        return -ENOMEM;
        }
 
-       error = security_inode_listxattr(d);
-       if (error)
-               goto out;
-       error = -EOPNOTSUPP;
-       if (d->d_inode->i_op && d->d_inode->i_op->listxattr) {
-               error = d->d_inode->i_op->listxattr(d, klist, size);
-       } else {
-               error = security_inode_listsecurity(d->d_inode, klist, size);
-               if (size && error > size)
-                       error = -ERANGE;
-       }
+       error = vfs_listxattr(d, klist, size);
        if (error > 0) {
                if (size && copy_to_user(list, klist, error))
                        error = -EFAULT;
@@ -365,7 +375,6 @@ listxattr(struct dentry *d, char __user *list, size_t size)
                   than XATTR_LIST_MAX bytes. Not possible. */
                error = -E2BIG;
        }
-out:
        kfree(klist);
        return error;
 }
index d59737589815c8048c00d432867606a719d0fa31..004baf6006110ae7cd8beee0f1e7f90f618c5550 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/highmem.h>
 #include <linux/swap.h>
 #include <linux/blkdev.h>
+#include <linux/backing-dev.h>
 #include "time.h"
 #include "kmem.h"
 
@@ -53,7 +54,7 @@ kmem_alloc(size_t size, unsigned int __nocast flags)
                        printk(KERN_ERR "XFS: possible memory allocation "
                                        "deadlock in %s (mode:0x%x)\n",
                                        __FUNCTION__, lflags);
-               blk_congestion_wait(WRITE, HZ/50);
+               congestion_wait(WRITE, HZ/50);
        } while (1);
 }
 
@@ -131,7 +132,7 @@ kmem_zone_alloc(kmem_zone_t *zone, unsigned int __nocast flags)
                        printk(KERN_ERR "XFS: possible memory allocation "
                                        "deadlock in %s (mode:0x%x)\n",
                                        __FUNCTION__, lflags);
-               blk_congestion_wait(WRITE, HZ/50);
+               congestion_wait(WRITE, HZ/50);
        } while (1);
 }
 
index 9bbadafdcb00285a8644a350a0ef033c7889f139..db5f5a3608ca3b4f09b8ae2bb0627c6c3c0ae38d 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/hash.h>
 #include <linux/kthread.h>
 #include <linux/migrate.h>
+#include <linux/backing-dev.h>
 #include "xfs_linux.h"
 
 STATIC kmem_zone_t *xfs_buf_zone;
@@ -395,7 +396,7 @@ _xfs_buf_lookup_pages(
 
                        XFS_STATS_INC(xb_page_retries);
                        xfsbufd_wakeup(0, gfp_mask);
-                       blk_congestion_wait(WRITE, HZ/50);
+                       congestion_wait(WRITE, HZ/50);
                        goto retry;
                }
 
index a4d0e73d5acac5084e3a0671651cac13edb6b583..063c4b54290f254d7ba22ec933be53ca03fcb561 100644 (file)
@@ -708,7 +708,7 @@ struct acpi_bit_register_info {
  * must be preserved.
  */
 #define ACPI_PM1_STATUS_PRESERVED_BITS          0x0800 /* Bit 11 */
-#define ACPI_PM1_CONTROL_PRESERVED_BITS         0x0201 /* Bit 9, Bit 0 (SCI_EN) */
+#define ACPI_PM1_CONTROL_PRESERVED_BITS         0x0200 /* Bit 9 (whatever) */
 
 /*
  * Register IDs
index c5472be6f3a2c41744471e61dafa0386bf038397..e72bfdd887f9b285ccbb3530be8096d61aeb74a8 100644 (file)
@@ -13,6 +13,7 @@
 #define ACPI_PDC_SMP_C_SWCOORD         (0x0040)
 #define ACPI_PDC_SMP_T_SWCOORD         (0x0080)
 #define ACPI_PDC_C_C1_FFH              (0x0100)
+#define ACPI_PDC_C_C2C3_FFH            (0x0200)
 
 #define ACPI_PDC_EST_CAPABILITY_SMP    (ACPI_PDC_SMP_C1PT | \
                                         ACPI_PDC_C_C1_HALT | \
                                         ACPI_PDC_SMP_P_SWCOORD | \
                                         ACPI_PDC_P_FFH)
 
-#define ACPI_PDC_C_CAPABILITY_SMP      (ACPI_PDC_SMP_C2C3 | \
-                                        ACPI_PDC_SMP_C1PT | \
-                                        ACPI_PDC_C_C1_HALT)
+#define ACPI_PDC_C_CAPABILITY_SMP      (ACPI_PDC_SMP_C2C3  | \
+                                        ACPI_PDC_SMP_C1PT  | \
+                                        ACPI_PDC_C_C1_HALT | \
+                                        ACPI_PDC_C_C1_FFH  | \
+                                        ACPI_PDC_C_C2C3_FFH)
 
 #endif                         /* __PDC_INTEL_H__ */
index 9dd5b75961f84c19ba9a731eb071f15950577d75..7798d2a9f793aaab8005c2a45d3362a35029ea5b 100644 (file)
@@ -29,6 +29,9 @@
 #define DOMAIN_COORD_TYPE_SW_ANY       0xfd
 #define DOMAIN_COORD_TYPE_HW_ALL       0xfe
 
+#define ACPI_CSTATE_SYSTEMIO   (0)
+#define ACPI_CSTATE_FFH                (1)
+
 /* Power Management */
 
 struct acpi_processor_cx;
@@ -58,6 +61,8 @@ struct acpi_processor_cx {
        u8 valid;
        u8 type;
        u32 address;
+       u8 space_id;
+       u8 index;
        u32 latency;
        u32 latency_ticks;
        u32 power;
@@ -206,6 +211,9 @@ void arch_acpi_processor_init_pdc(struct acpi_processor *pr);
 #ifdef ARCH_HAS_POWER_INIT
 void acpi_processor_power_init_bm_check(struct acpi_processor_flags *flags,
                                        unsigned int cpu);
+int acpi_processor_ffh_cstate_probe(unsigned int cpu,
+               struct acpi_processor_cx *cx, struct acpi_power_register *reg);
+void acpi_processor_ffh_cstate_enter(struct acpi_processor_cx *cstate);
 #else
 static inline void acpi_processor_power_init_bm_check(struct
                                                      acpi_processor_flags
@@ -214,6 +222,16 @@ static inline void acpi_processor_power_init_bm_check(struct
        flags->bm_check = 1;
        return;
 }
+static inline int acpi_processor_ffh_cstate_probe(unsigned int cpu,
+               struct acpi_processor_cx *cx, struct acpi_power_register *reg)
+{
+       return -1;
+}
+static inline void acpi_processor_ffh_cstate_enter(
+               struct acpi_processor_cx *cstate)
+{
+       return;
+}
 #endif
 
 /* in processor_perflib.c */
index f5ae98c25d1f4f0f4fb2627b8916ec1648ce20fd..5d15af24573b9f90fa0e6f9bb6dc12bd6363a241 100644 (file)
@@ -533,19 +533,6 @@ extern void outsl (unsigned long port, const void *src, unsigned long count);
 #define eth_io_copy_and_sum(skb,src,len,unused) \
   memcpy_fromio((skb)->data,src,len)
 
-static inline int
-check_signature(const volatile void __iomem *io_addr,
-               const unsigned char *signature, int length)
-{
-       do {
-               if (readb(io_addr) != *signature)
-                       return 0;
-               io_addr++;
-               signature++;
-       } while (--length);
-       return 1;
-}
-
 /*
  * The Alpha Jensen hardware for some rather strange reason puts
  * the RTC clock at 0x170 instead of 0x70. Probably due to some
diff --git a/include/asm-alpha/irq_regs.h b/include/asm-alpha/irq_regs.h
new file mode 100644 (file)
index 0000000..3dd9c0b
--- /dev/null
@@ -0,0 +1 @@
+#include <asm-generic/irq_regs.h>
index aced22f91752e454ae446c2d8ac3014de49dee41..a86c083cdf7f19e6556c9267cc4912a2f3b28118 100644 (file)
@@ -15,7 +15,6 @@
 
 struct task_struct;
 struct mm_struct;
-struct pt_regs;
 struct vm_area_struct;
 struct linux_hose_info;
 struct pci_dev;
@@ -79,8 +78,8 @@ struct alpha_machine_vector
 
        void (*update_irq_hw)(unsigned long, unsigned long, int);
        void (*ack_irq)(unsigned long);
-       void (*device_interrupt)(unsigned long vector, struct pt_regs *regs);
-       void (*machine_check)(u64 vector, u64 la, struct pt_regs *regs);
+       void (*device_interrupt)(unsigned long vector);
+       void (*machine_check)(u64 vector, u64 la);
 
        void (*smp_callin)(void);
        void (*init_arch)(void);
index 0e4a3901d3b36b0afa8ea1acbff9165e1bf515db..5edaae1c61d315a4ee2f36a11c08c36a6423b0b8 100644 (file)
@@ -26,8 +26,9 @@ extern void clps711x_setup_timer(void);
  * IRQ handler for the timer
  */
 static irqreturn_t
-p720t_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+p720t_timer_interrupt(int irq, void *dev_id)
 {
+       struct pt_regs *regs = get_irq_regs();
        do_leds();
        do_timer(1);
 #ifndef CONFIG_SMP
index 599f03e5a9efa5782914126797a9714d16a92d56..5b1066da4e1ffa2b9586ad1f03406fdfadbde13c 100644 (file)
@@ -45,8 +45,8 @@
 
 struct imx_dma_channel {
        const char *name;
-       void (*irq_handler) (int, void *, struct pt_regs *);
-       void (*err_handler) (int, void *, struct pt_regs *, int errcode);
+       void (*irq_handler) (int, void *);
+       void (*err_handler) (int, void *, int errcode);
        void *data;
        dmamode_t  dma_mode;
        struct scatterlist *sg;
@@ -77,8 +77,8 @@ imx_dma_setup_sg(imx_dmach_t dma_ch,
 
 int
 imx_dma_setup_handlers(imx_dmach_t dma_ch,
-               void (*irq_handler) (int, void *, struct pt_regs *),
-               void (*err_handler) (int, void *, struct pt_regs *, int), void *data);
+               void (*irq_handler) (int, void *),
+               void (*err_handler) (int, void *, int), void *data);
 
 void imx_dma_enable(imx_dmach_t dma_ch);
 
index c69cb508735f74aed3db85f0d7e1e662eba0896e..ea22f7fff9cd7131401fa67695486dea82d4e6bc 100644 (file)
@@ -43,8 +43,9 @@
  * Handler for RTC timer interrupt
  */
 static irqreturn_t
-timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+timer_interrupt(int irq, void *dev_id)
 {
+       struct pt_regs *regs = get_irq_regs();
        do_timer(1);
 #ifndef CONFIG_SMP
        update_process_times(user_mode(regs));
index 3aee1204795bd367f0b301847a9ffeb22b1df606..418f15283ff1539efbaf564ac8ac42754e74c623 100644 (file)
@@ -137,7 +137,7 @@ extern void pnx4008_free_ll_entry(struct pnx4008_dma_ll *, dma_addr_t);
 extern void pnx4008_free_ll(u32 ll_dma, struct pnx4008_dma_ll *);
 
 extern int pnx4008_request_channel(char *, int,
-                                  void (*)(int, int, void *, struct pt_regs *),
+                                  void (*)(int, int, void *),
                                   void *);
 extern void pnx4008_free_channel(int);
 extern int pnx4008_config_dma(int, int, int);
index a008150abc59f2775e8ce25e03b3bb0f2b1476ec..bed042d71d68dd7154e5cf5ed0c4035230858706 100644 (file)
@@ -56,7 +56,7 @@ for (                                                                 \
 
 int pxa_request_dma (char *name,
                         pxa_dma_prio prio,
-                        void (*irq_handler)(int, void *, struct pt_regs *),
+                        void (*irq_handler)(int, void *),
                         void *data);
 
 void pxa_free_dma (int dma_ch);
index 88c17dd02ed2dc21366f02bd0ccbfa98ce966b67..a38a28c4bbd8ea1a0518b529270e9a1d2d9cd5ea 100644 (file)
@@ -10,7 +10,7 @@ struct mmc_host;
 struct pxamci_platform_data {
        unsigned int ocr_mask;                  /* available voltages */
        unsigned long detect_delay;             /* delay in jiffies before detecting cards after interrupt */
-       int (*init)(struct device *, irqreturn_t (*)(int, void *, struct pt_regs *), void *);
+       int (*init)(struct device *, irq_handler_t , void *);
        int (*get_ro)(struct device *);
        void (*setpower)(struct device *, unsigned int);
        void (*exit)(struct device *, void *);
index f5cc65dd7d0d31e4e08abfaf19a488c6580c8dc0..68731e0923a4caebc86dd6134248ddc790691795 100644 (file)
 #define SSSR_TINT              (1 << 19)       /* Receiver Time-out Interrupt */
 #define SSSR_PINT              (1 << 18)       /* Peripheral Trailing Byte Interrupt */
 
+#define SSPSP_FSRT             (1 << 25)       /* Frame Sync Relative Timing */
 #define SSPSP_DMYSTOP(x)       (x << 23)       /* Dummy Stop */
 #define SSPSP_SFRMWDTH(x)      (x << 16)       /* Serial Frame Width */
 #define SSPSP_SFRMDLY(x)       (x << 9)        /* Serial Frame Delay */
index 1b8e8a304800748cd43179add4c10de2df40a91b..3f37ca07806dc046f25dd832f8b9a52d4da86af2 100644 (file)
 #define GPIO_JORNADA720_KEYBOARD_IRQ   IRQ_GPIO0
 #define GPIO_JORNADA720_MOUSE_IRQ              IRQ_GPIO9
 
+/* MCU COMMANDS */
+#define MCU_GetBatteryData  0xc0
+#define MCU_GetScanKeyCode  0x90
+#define MCU_GetTouchSamples 0xa0
+#define MCU_GetContrast     0xD0
+#define MCU_SetContrast     0xD1
+#define MCU_GetBrightness   0xD2
+#define MCU_SetBrightness   0xD3
+#define MCU_ContrastOff     0xD8
+#define MCU_BrightnessOff   0xD9
+#define MCU_PWMOFF          0xDF
+#define MCU_TxDummy         0x11
+#define MCU_ErrorCode       0x00
+
 #ifndef __ASSEMBLY__
 
 void jornada720_mcu_init(void);
index 41c1bee342ad0ba04c5a4644a2e2c291c79ff78d..edc06598d187d4664f891f519d98a59b8669b924 100644 (file)
@@ -28,8 +28,8 @@
 /*
  * PCI space virtual addresses
  */
-#define VERSATILE_PCI_VIRT_BASE                0xe8000000
-#define VERSATILE_PCI_CFG_VIRT_BASE    0xe9000000
+#define VERSATILE_PCI_VIRT_BASE                (void __iomem *)0xe8000000ul
+#define VERSATILE_PCI_CFG_VIRT_BASE    (void __iomem *)0xe9000000ul
 
 #if 0
 #define VERSATILE_PCI_VIRT_MEM_BASE0   0xf4000000
index a836e76a14f7de1b8b8c8da0215304de6ad8801a..2d00db22b9818b7a9669ff9c9061437fddb9ad0c 100644 (file)
@@ -100,7 +100,7 @@ extern struct sharpsl_pm_status sharpsl_pm;
 
 void sharpsl_battery_kick(void);
 void sharpsl_pm_led(int val);
-irqreturn_t sharpsl_ac_isr(int irq, void *dev_id, struct pt_regs *fp);
-irqreturn_t sharpsl_chrg_full_isr(int irq, void *dev_id, struct pt_regs *fp);
-irqreturn_t sharpsl_fatal_isr(int irq, void *dev_id, struct pt_regs *fp);
+irqreturn_t sharpsl_ac_isr(int irq, void *dev_id);
+irqreturn_t sharpsl_chrg_full_isr(int irq, void *dev_id);
+irqreturn_t sharpsl_fatal_isr(int irq, void *dev_id);
 
index ea856971989a261e3127678ce0d5d06bd68a5795..98d594a973d6c821d5314afb6c13c08d22871fd1 100644 (file)
@@ -12,7 +12,7 @@
        if (!(action->flags & IRQF_TIMER) && system_timer->dyn_tick) {  \
                write_seqlock(&xtime_lock);                             \
                if (system_timer->dyn_tick->state & DYN_TICK_ENABLED)   \
-                       system_timer->dyn_tick->handler(irq, 0, regs);  \
+                       system_timer->dyn_tick->handler(irq, NULL);     \
                write_sequnlock(&xtime_lock);                           \
        }
 #endif
index 8076a85c367541479c6e6aaa4dd54e358cb3ba6f..ae999fd5dc679e74108bd81678e2eeea1e90c11c 100644 (file)
@@ -63,7 +63,7 @@ extern void __raw_readsl(const void __iomem *addr, void *data, int longlen);
  */
 extern void __iomem * __ioremap_pfn(unsigned long, unsigned long, size_t, unsigned long);
 extern void __iomem * __ioremap(unsigned long, size_t, unsigned long);
-extern void __iounmap(void __iomem *addr);
+extern void __iounmap(volatile void __iomem *addr);
 
 /*
  * Bad read/write accesses...
@@ -193,23 +193,6 @@ extern void _memset_io(volatile void __iomem *, int, size_t);
 #define eth_io_copy_and_sum(s,c,l,b) \
                                eth_copy_and_sum((s),__mem_pci(c),(l),(b))
 
-static inline int
-check_signature(void __iomem *io_addr, const unsigned char *signature,
-               int length)
-{
-       int retval = 0;
-       do {
-               if (readb(io_addr) != *signature)
-                       goto out;
-               io_addr++;
-               signature++;
-               length--;
-       } while (length);
-       retval = 1;
-out:
-       return retval;
-}
-
 #elif !defined(readb)
 
 #define readb(c)                       (__readwrite_bug("readb"),0)
diff --git a/include/asm-arm/irq_regs.h b/include/asm-arm/irq_regs.h
new file mode 100644 (file)
index 0000000..3dd9c0b
--- /dev/null
@@ -0,0 +1 @@
+#include <asm-generic/irq_regs.h>
index 131f33733d25597167f4d67462a032455920f5d4..0e017ecf20966f01a7a4d4abbb10926dc8c23c6f 100644 (file)
@@ -30,10 +30,9 @@ extern int show_fiq_list(struct seq_file *, void *);
 /*
  * Obsolete inline function for calling irq descriptor handlers.
  */
-static inline void desc_handle_irq(unsigned int irq, struct irq_desc *desc,
-                                  struct pt_regs *regs)
+static inline void desc_handle_irq(unsigned int irq, struct irq_desc *desc)
 {
-       desc->handle_irq(irq, desc, regs);
+       desc->handle_irq(irq, desc);
 }
 
 void set_irq_flags(unsigned int irq, unsigned int flags);
@@ -51,10 +50,10 @@ void set_irq_flags(unsigned int irq, unsigned int flags);
 #define irqdesc                irq_desc
 #define irqchip                irq_chip
 
-#define do_bad_IRQ(irq,desc,regs)                      \
+#define do_bad_IRQ(irq,desc)                           \
 do {                                                   \
        spin_lock(&desc->lock);                         \
-       handle_bad_irq(irq, desc, regs);                \
+       handle_bad_irq(irq, desc);                      \
        spin_unlock(&desc->lock);                       \
 } while(0)
 
index 1eb93f5c0d6cf921c6bfc3cf211bf84b654687c6..5dc357013b7943356c2ee7b09f147dbbde5273b6 100644 (file)
@@ -57,7 +57,7 @@ struct dyn_tick_timer {
        int             (*enable)(void);        /* Enables dynamic tick */
        int             (*disable)(void);       /* Disables dynamic tick */
        void            (*reprogram)(unsigned long); /* Reprograms the timer */
-       int             (*handler)(int, void *, struct pt_regs *);
+       int             (*handler)(int, void *);
 };
 
 void timer_dyn_reprogram(void);
@@ -66,7 +66,7 @@ void timer_dyn_reprogram(void);
 #endif
 
 extern struct sys_timer *system_timer;
-extern void timer_tick(struct pt_regs *);
+extern void timer_tick(void);
 
 /*
  * Kernel time keeping support.
index 87aba57a66c40d5b0f10fe199c3159fa5710a9e3..09ad0cab90149f3a7a17d755f92c8742ad0841a8 100644 (file)
@@ -110,7 +110,7 @@ extern int __get_user_4(void *);
 #define get_user(x,p)                                                  \
        ({                                                              \
                const register typeof(*(p)) __user *__p asm("r0") = (p);\
-               register unsigned int __r2 asm("r2");                   \
+               register unsigned long __r2 asm("r2");                  \
                register int __e asm("r0");                             \
                switch (sizeof(*(__p))) {                               \
                case 1:                                                 \
diff --git a/include/asm-avr32/irq_regs.h b/include/asm-avr32/irq_regs.h
new file mode 100644 (file)
index 0000000..3dd9c0b
--- /dev/null
@@ -0,0 +1 @@
+#include <asm-generic/irq_regs.h>
index 18d6bb8f84fcb0543f0b3f3b6c93d68aba215b31..683c47d48a5bfa7cd94b561826c9b5ea795cc8db 100644 (file)
 /*
  * FRV DMA controller management
  */
-struct pt_regs;
-
-typedef irqreturn_t (*dma_irq_handler_t)(int dmachan, unsigned long cstr, void *data,
-                                        struct pt_regs *regs);
+typedef irqreturn_t (*dma_irq_handler_t)(int dmachan, unsigned long cstr, void *data);
 
 extern void frv_dma_init(void);
 
index e2247c22a638aec316a72383d7bc9f77e191dcb6..0f390f41f81680a70c12fe26cdae314644466344 100644 (file)
@@ -82,11 +82,11 @@ extern struct page *kmap_atomic_to_page(void *ptr);
        dampr = paddr | xAMPRx_L | xAMPRx_M | xAMPRx_S | xAMPRx_SS_16Kb | xAMPRx_V;             \
                                                                                                \
        if (type != __KM_CACHE)                                                                 \
-               asm volatile("movgs %0,dampr"#ampr :: "r"(dampr));                              \
+               asm volatile("movgs %0,dampr"#ampr :: "r"(dampr) : "memory");                   \
        else                                                                                    \
                asm volatile("movgs %0,iampr"#ampr"\n"                                          \
                             "movgs %0,dampr"#ampr"\n"                                          \
-                            :: "r"(dampr)                                                      \
+                            :: "r"(dampr) : "memory"                                           \
                             );                                                                 \
                                                                                                \
        asm("movsg damlr"#ampr",%0" : "=r"(damlr));                                             \
@@ -104,7 +104,7 @@ extern struct page *kmap_atomic_to_page(void *ptr);
        asm volatile("movgs %0,tplr \n"                                                           \
                     "movgs %1,tppr \n"                                                           \
                     "tlbpr %0,gr0,#2,#1"                                                         \
-                    : : "r"(damlr), "r"(dampr));                                                 \
+                    : : "r"(damlr), "r"(dampr) : "memory");                                      \
                                                                                                  \
        /*printk("TLB: SECN sl=%d L=%08lx P=%08lx\n", slot, damlr, dampr);*/                      \
                                                                                                  \
@@ -115,7 +115,7 @@ static inline void *kmap_atomic(struct page *page, enum km_type type)
 {
        unsigned long paddr;
 
-       preempt_disable();
+       inc_preempt_count();
        paddr = page_to_phys(page);
 
        switch (type) {
@@ -138,16 +138,16 @@ static inline void *kmap_atomic(struct page *page, enum km_type type)
        }
 }
 
-#define __kunmap_atomic_primary(type, ampr)                    \
-do {                                                           \
-       asm volatile("movgs gr0,dampr"#ampr"\n");               \
-       if (type == __KM_CACHE)                                 \
-               asm volatile("movgs gr0,iampr"#ampr"\n");       \
+#define __kunmap_atomic_primary(type, ampr)                            \
+do {                                                                   \
+       asm volatile("movgs gr0,dampr"#ampr"\n" ::: "memory");          \
+       if (type == __KM_CACHE)                                         \
+               asm volatile("movgs gr0,iampr"#ampr"\n" ::: "memory");  \
 } while(0)
 
-#define __kunmap_atomic_secondary(slot, vaddr)                 \
-do {                                                           \
-       asm volatile("tlbpr %0,gr0,#4,#1" : : "r"(vaddr));      \
+#define __kunmap_atomic_secondary(slot, vaddr)                         \
+do {                                                                   \
+       asm volatile("tlbpr %0,gr0,#4,#1" : : "r"(vaddr) : "memory");   \
 } while(0)
 
 static inline void kunmap_atomic(void *kvaddr, enum km_type type)
@@ -170,7 +170,8 @@ static inline void kunmap_atomic(void *kvaddr, enum km_type type)
        default:
                BUG();
        }
-       preempt_enable();
+       dec_preempt_count();
+       preempt_check_resched();
 }
 
 #endif /* !__ASSEMBLY__ */
index 7765f5528894009886a62e647a08d8eeb96fc1fa..20e44fe00abf66f6b74b0daf482bea26d1dcebc7 100644 (file)
@@ -385,27 +385,6 @@ static inline void pci_iounmap(struct pci_dev *dev, void __iomem *p)
  */
 #define xlate_dev_kmem_ptr(p)  p
 
-/*
- * Check BIOS signature
- */
-static inline int check_signature(volatile void __iomem *io_addr,
-                                 const unsigned char *signature, int length)
-{
-       int retval = 0;
-
-       do {
-               if (readb(io_addr) != *signature)
-                       goto out;
-               io_addr++;
-               signature++;
-               length--;
-       } while (length);
-
-       retval = 1;
-out:
-       return retval;
-}
-
 #endif /* __KERNEL__ */
 
 #endif /* _ASM_IO_H */
diff --git a/include/asm-frv/irq_regs.h b/include/asm-frv/irq_regs.h
new file mode 100644 (file)
index 0000000..d22e832
--- /dev/null
@@ -0,0 +1,27 @@
+/* FRV per-CPU frame pointer holder
+ *
+ * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_IRQ_REGS_H
+#define _ASM_IRQ_REGS_H
+
+/*
+ * Per-cpu current frame pointer - the location of the last exception frame on
+ * the stack
+ * - on FRV, GR28 is dedicated to keeping a pointer to the current exception
+ *   frame
+ */
+#define ARCH_HAS_OWN_IRQ_REGS
+
+#ifndef __ASSEMBLY__
+#define get_irq_regs() (__frame)
+#endif
+
+#endif /* _ASM_IRQ_REGS_H */
index 7ff525162a723b8a2549db3534289a355ed54df8..9a2241b8eb1e03647f3c5cadefea0cf3a6da5a2e 100644 (file)
@@ -12,6 +12,7 @@
 #define _ASM_PTRACE_H
 
 #include <asm/registers.h>
+#include <asm/irq_regs.h>
 
 #define in_syscall(regs) (((regs)->tbr & TBR_TT) == TBR_TT_TRAP0)
 
index 5ef93a4d009fd6e43e506b5b3e9febc0e27ecaba..815bb01480601f7ca1a96e81113fb030df89062d 100644 (file)
@@ -15,7 +15,7 @@ static inline int sched_find_first_bit(const unsigned long *b)
 #if BITS_PER_LONG == 64
        if (unlikely(b[0]))
                return __ffs(b[0]);
-       if (unlikely(b[1]))
+       if (likely(b[1]))
                return __ffs(b[1]) + 64;
        return __ffs(b[2]) + 128;
 #elif BITS_PER_LONG == 32
index a5250895155ef6e5affcae708a4a79f692f037e2..c92ae0f166ff44f1757f456a132202b22f0f5368 100644 (file)
 #endif
 
 #ifndef HAVE_ARCH_WARN_ON
-#define WARN_ON(condition) unlikely((condition))
+#define WARN_ON(condition) ({                                          \
+       typeof(condition) __ret_warn_on = (condition);                  \
+       unlikely(__ret_warn_on);                                        \
+})
 #endif
 #endif
 
-#define WARN_ON_ONCE(condition)        ({                      \
-       static int __warn_once = 1;                     \
-       typeof(condition) __ret_warn_once = (condition);\
-                                                       \
-       if (likely(__warn_once))                        \
-               if (WARN_ON(__ret_warn_once))           \
-                       __warn_once = 0;                \
-       unlikely(__ret_warn_once);                      \
+#define WARN_ON_ONCE(condition)        ({                              \
+       static int __warned;                                    \
+       typeof(condition) __ret_warn_once = (condition);        \
+                                                               \
+       if (unlikely(__ret_warn_once))                          \
+               if (WARN_ON(!__warned))                         \
+                       __warned = 1;                           \
+       unlikely(__ret_warn_once);                              \
 })
 
 #ifdef CONFIG_SMP
diff --git a/include/asm-generic/irq_regs.h b/include/asm-generic/irq_regs.h
new file mode 100644 (file)
index 0000000..5ae1d07
--- /dev/null
@@ -0,0 +1,37 @@
+/* Fallback per-CPU frame pointer holder
+ *
+ * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_GENERIC_IRQ_REGS_H
+#define _ASM_GENERIC_IRQ_REGS_H
+
+#include <linux/percpu.h>
+
+/*
+ * Per-cpu current frame pointer - the location of the last exception frame on
+ * the stack
+ */
+DECLARE_PER_CPU(struct pt_regs *, __irq_regs);
+
+static inline struct pt_regs *get_irq_regs(void)
+{
+       return __get_cpu_var(__irq_regs);
+}
+
+static inline struct pt_regs *set_irq_regs(struct pt_regs *new_regs)
+{
+       struct pt_regs *old_regs, **pp_regs = &__get_cpu_var(__irq_regs);
+
+       old_regs = *pp_regs;
+       *pp_regs = new_regs;
+       return old_regs;
+}
+
+#endif /* _ASM_GENERIC_IRQ_REGS_H */
index 6d45ee5472aff9668de59dbefb9ea8e3e8d53391..196376262240470ba6d5d3a11990e55690099629 100644 (file)
@@ -15,7 +15,7 @@ extern unsigned long __per_cpu_offset[NR_CPUS];
 
 /* var is in discarded region: offset to particular copy we want */
 #define per_cpu(var, cpu) (*({                         \
-       extern int simple_indentifier_##var(void);      \
+       extern int simple_identifier_##var(void);       \
        RELOC_HIDE(&per_cpu__##var, __per_cpu_offset[cpu]); }))
 #define __get_cpu_var(var) per_cpu(var, smp_processor_id())
 #define __raw_get_cpu_var(var) per_cpu(var, raw_smp_processor_id())
index 69240b52f8e17931d939c96c6c2901978717b9b9..9d0d11c180d958674922d37e2d36c757fcd6142a 100644 (file)
                *(__param)                                              \
                VMLINUX_SYMBOL(__stop___param) = .;                     \
        }                                                               \
+                                                                       \
+       /* Unwind data binary search table */                           \
+       EH_FRAME_HDR                                                    \
+                                                                       \
        __end_rodata = .;                                               \
        . = ALIGN(4096);
 
                *(.kprobes.text)                                        \
                VMLINUX_SYMBOL(__kprobes_text_end) = .;
 
+#ifdef CONFIG_STACK_UNWIND
+               /* Unwind data binary search table */
+#define EH_FRAME_HDR                                                   \
+               .eh_frame_hdr : AT(ADDR(.eh_frame_hdr) - LOAD_OFFSET) { \
+                       VMLINUX_SYMBOL(__start_unwind_hdr) = .;         \
+                       *(.eh_frame_hdr)                                \
+                       VMLINUX_SYMBOL(__end_unwind_hdr) = .;           \
+               }
+#else
+#define EH_FRAME_HDR
+#endif
+
                /* DWARF debug sections.
                Symbols in the DWARF debugging sections are relative to
                the beginning of the section so we begin them at 0.  */
index 3a42b7d6fc92ac916608c31c7fc7c3ffd3fdbd4c..b9529578fc37e4549d89520266a9b9e1605906ce 100644 (file)
@@ -98,7 +98,7 @@ extern void sync_Arb_IDs (void);
 extern void init_bsp_APIC (void);
 extern void setup_local_APIC (void);
 extern void init_apic_mappings (void);
-extern void smp_local_timer_interrupt (struct pt_regs * regs);
+extern void smp_local_timer_interrupt (void);
 extern void setup_boot_APIC_clock (void);
 extern void setup_secondary_APIC_clock (void);
 extern int APIC_init_uniprocessor (void);
@@ -107,7 +107,7 @@ extern void enable_APIC_timer(void);
 
 extern void enable_NMI_through_LVT0 (void * dummy);
 
-void smp_send_timer_broadcast_ipi(struct pt_regs *regs);
+void smp_send_timer_broadcast_ipi(void);
 void switch_APIC_timer_to_ipi(void *cpumask);
 void switch_ipi_to_APIC_timer(void *cpumask);
 #define ARCH_APICTIMER_STOPS_ON_C3     1
index 238cf4275b9678df85637e9f71ed037b985571aa..a8c1fca9726dbcb47c69b96fc203701f63c66589 100644 (file)
@@ -14,7 +14,7 @@
 extern void init_ISA_irqs(void);
 extern void apic_intr_init(void);
 extern void smp_intr_init(void);
-extern irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+extern irqreturn_t timer_interrupt(int irq, void *dev_id);
 
 /* these are the defined hooks */
 extern void intr_init_hook(void);
index 359ead60b7189f33e5b3989e78e4bff1fd732341..44ef2f55a8e9c0970e789d007be7108d2ce0fb5f 100644 (file)
@@ -51,7 +51,7 @@ static char *virtual_dma_addr;
 static int virtual_dma_mode;
 static int doing_pdma;
 
-static irqreturn_t floppy_hardint(int irq, void *dev_id, struct pt_regs * regs)
+static irqreturn_t floppy_hardint(int irq, void *dev_id)
 {
        register unsigned char st;
 
@@ -63,7 +63,7 @@ static irqreturn_t floppy_hardint(int irq, void *dev_id, struct pt_regs * regs)
        static int dma_wait=0;
 #endif
        if (!doing_pdma)
-               return floppy_interrupt(irq, dev_id, regs);
+               return floppy_interrupt(irq, dev_id);
 
 #ifdef TRACE_FLPY_INT
        if(!calls)
@@ -106,7 +106,7 @@ static irqreturn_t floppy_hardint(int irq, void *dev_id, struct pt_regs * regs)
                dma_wait=0;
 #endif
                doing_pdma = 0;
-               floppy_interrupt(irq, dev_id, regs);
+               floppy_interrupt(irq, dev_id);
                return IRQ_HANDLED;
        }
 #ifdef TRACE_FLPY_INT
index af5d435519d15592a0f30bce4aabe29d9c2efa87..e47be9a56cc23aa8455e842af5eca1b8e4c58ff4 100644 (file)
@@ -108,7 +108,7 @@ extern int hpet_set_alarm_time(unsigned char hrs, unsigned char min, unsigned ch
 extern int hpet_set_periodic_freq(unsigned long freq);
 extern int hpet_rtc_dropped_irq(void);
 extern int hpet_rtc_timer_init(void);
-extern irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+extern irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id);
 #endif /* CONFIG_HPET_EMULATE_RTC */
 #endif /* CONFIG_HPET_TIMER */
 #endif /* _I386_HPET_H */
index 88f02a0735615d7be2796249ad9bbb73036a4e20..0bedbdf5e9078af5d579f80832a057911067f6b8 100644 (file)
@@ -26,9 +26,6 @@
  * Interrupt entry/exit code at both C and assembly level
  */
 
-extern u8 irq_vector[NR_IRQ_VECTORS];
-#define IO_APIC_VECTOR(irq)    (irq_vector[irq])
-
 extern void (*interrupt[NR_IRQS])(void);
 
 #ifdef CONFIG_SMP
@@ -41,7 +38,7 @@ fastcall void call_function_interrupt(void);
 fastcall void apic_timer_interrupt(void);
 fastcall void error_interrupt(void);
 fastcall void spurious_interrupt(void);
-fastcall void thermal_interrupt(struct pt_regs *);
+fastcall void thermal_interrupt(void);
 #define platform_legacy_irq(irq)       ((irq) < 16)
 #endif
 
index b3724fe93ff1008111dad9d1fc993defdafdda11..68df0dc3ab8ff3e52379a0e6a0afda589c9346b1 100644 (file)
@@ -224,33 +224,6 @@ static inline void memcpy_toio(volatile void __iomem *dst, const void *src, int
 
 #define eth_io_copy_and_sum(a,b,c,d)           eth_copy_and_sum((a),(void __force *)(b),(c),(d))
 
-/**
- *     check_signature         -       find BIOS signatures
- *     @io_addr: mmio address to check 
- *     @signature:  signature block
- *     @length: length of signature
- *
- *     Perform a signature comparison with the mmio address io_addr. This
- *     address should have been obtained by ioremap.
- *     Returns 1 on a match.
- */
-static inline int check_signature(volatile void __iomem * io_addr,
-       const unsigned char *signature, int length)
-{
-       int retval = 0;
-       do {
-               if (readb(io_addr) != *signature)
-                       goto out;
-               io_addr++;
-               signature++;
-               length--;
-       } while (length);
-       retval = 1;
-out:
-       return retval;
-}
-
 /*
  *     Cache management
  *
diff --git a/include/asm-i386/irq_regs.h b/include/asm-i386/irq_regs.h
new file mode 100644 (file)
index 0000000..3dd9c0b
--- /dev/null
@@ -0,0 +1 @@
+#include <asm-generic/irq_regs.h>
index 4182c347ef85052178ee67b193d3c5750c14aa58..7d606e3364aec30d667c9b21c6c5368671c40ca0 100644 (file)
  *     timer interrupt as a means of triggering reschedules etc.
  **/
 
-static inline void do_timer_interrupt_hook(struct pt_regs *regs)
+static inline void do_timer_interrupt_hook(void)
 {
        do_timer(1);
 #ifndef CONFIG_SMP
-       update_process_times(user_mode_vm(regs));
+       update_process_times(user_mode_vm(get_irq_regs()));
 #endif
 /*
  * In the SMP case we use the local APIC timer interrupt to do the
@@ -26,10 +26,10 @@ static inline void do_timer_interrupt_hook(struct pt_regs *regs)
  * system, in that case we have to call the local interrupt handler.
  */
 #ifndef CONFIG_X86_LOCAL_APIC
-       profile_tick(CPU_PROFILING, regs);
+       profile_tick(CPU_PROFILING);
 #else
        if (!using_apic_timer)
-               smp_local_timer_interrupt(regs);
+               smp_local_timer_interrupt();
 #endif
 }
 
index 8db618c5a72b0e50ec0502e7b0d6b8baadec456c..21cd696d4d0feadf9df7d8f1f9314758f8178bfd 100644 (file)
@@ -4,14 +4,14 @@
 #include <asm/i8259.h>
 #include "cobalt.h"
 
-static inline void do_timer_interrupt_hook(struct pt_regs *regs)
+static inline void do_timer_interrupt_hook(void)
 {
        /* Clear the interrupt */
        co_cpu_write(CO_CPU_STAT,co_cpu_read(CO_CPU_STAT) & ~CO_STAT_TIMEINTR);
 
        do_timer(1);
 #ifndef CONFIG_SMP
-       update_process_times(user_mode_vm(regs));
+       update_process_times(user_mode_vm(irq_regs));
 #endif
 /*
  * In the SMP case we use the local APIC timer interrupt to do the
@@ -19,10 +19,10 @@ static inline void do_timer_interrupt_hook(struct pt_regs *regs)
  * system, in that case we have to call the local interrupt handler.
  */
 #ifndef CONFIG_X86_LOCAL_APIC
-       profile_tick(CPU_PROFILING, regs);
+       profile_tick(CPU_PROFILING);
 #else
        if (!using_apic_timer)
-               smp_local_timer_interrupt(regs);
+               smp_local_timer_interrupt();
 #endif
 }
 
index 099fe9f5c1b2bcc922079c7fa64b21b197d864b7..04e69c104a74616fa18b3e926a31682a520b9cf2 100644 (file)
@@ -1,14 +1,14 @@
 /* defines for inline arch setup functions */
 #include <asm/voyager.h>
 
-static inline void do_timer_interrupt_hook(struct pt_regs *regs)
+static inline void do_timer_interrupt_hook(void)
 {
        do_timer(1);
 #ifndef CONFIG_SMP
-       update_process_times(user_mode_vm(regs));
+       update_process_times(user_mode_vm(irq_regs));
 #endif
 
-       voyager_timer_interrupt(regs);
+       voyager_timer_interrupt();
 }
 
 static inline int do_timer_overflow(int count)
index 2277127696d264579687a2e693768a6e4d8ba206..e0ddca94d50c8f42c71e05e1796086fdf84ad0ef 100644 (file)
@@ -306,6 +306,8 @@ static inline void __mwait(unsigned long eax, unsigned long ecx)
                : :"a" (eax), "c" (ecx));
 }
 
+extern void mwait_idle_with_hints(unsigned long eax, unsigned long ecx);
+
 /* from system description table in BIOS.  Mostly for MCA use, but
 others may find it useful. */
 extern unsigned int machine_id;
index 6aa1206f6e2a9b17ffd120f94625db0552916f71..bd59c1508e7127bd592bdd09d9d69e6a528ba3e9 100644 (file)
@@ -46,8 +46,6 @@ extern u8 x86_cpu_to_apicid[];
 
 #define cpu_physical_id(cpu)   x86_cpu_to_apicid[cpu]
 
-extern u8 apicid_2_node[];
-
 #ifdef CONFIG_HOTPLUG_CPU
 extern void cpu_exit_clear(void);
 extern void cpu_uninit(void);
@@ -101,6 +99,9 @@ extern unsigned int num_processors;
 #endif
 
 #ifndef __ASSEMBLY__
+
+extern u8 apicid_2_node[];
+
 #ifdef CONFIG_X86_LOCAL_APIC
 static __inline int logical_smp_processor_id(void)
 {
index 54d905ebc63dd9738e00f592ee0787b371ef1e62..eef5133b9ce2a03b73b5f4c73f0e771a12b52aa8 100644 (file)
@@ -404,20 +404,6 @@ unsigned long __must_check __copy_from_user_ll_nocache_nozero(void *to,
  * anything, so this is accurate.
  */
 
-/**
- * __copy_to_user: - Copy a block of data into user space, with less checking.
- * @to:   Destination address, in user space.
- * @from: Source address, in kernel space.
- * @n:    Number of bytes to copy.
- *
- * Context: User context only.  This function may sleep.
- *
- * Copy data from kernel space to user space.  Caller must check
- * the specified block with access_ok() before calling this function.
- *
- * Returns number of bytes that could not be copied.
- * On success, this will be zero.
- */
 static __always_inline unsigned long __must_check
 __copy_to_user_inatomic(void __user *to, const void *from, unsigned long n)
 {
@@ -439,35 +425,27 @@ __copy_to_user_inatomic(void __user *to, const void *from, unsigned long n)
        return __copy_to_user_ll(to, from, n);
 }
 
-static __always_inline unsigned long __must_check
-__copy_to_user(void __user *to, const void *from, unsigned long n)
-{
-       might_sleep();
-       return __copy_to_user_inatomic(to, from, n);
-}
-
 /**
- * __copy_from_user: - Copy a block of data from user space, with less checking.
- * @to:   Destination address, in kernel space.
- * @from: Source address, in user space.
+ * __copy_to_user: - Copy a block of data into user space, with less checking.
+ * @to:   Destination address, in user space.
+ * @from: Source address, in kernel space.
  * @n:    Number of bytes to copy.
  *
  * Context: User context only.  This function may sleep.
  *
- * Copy data from user space to kernel space.  Caller must check
+ * Copy data from kernel space to user space.  Caller must check
  * the specified block with access_ok() before calling this function.
  *
  * Returns number of bytes that could not be copied.
  * On success, this will be zero.
- *
- * If some data could not be copied, this function will pad the copied
- * data to the requested size using zero bytes.
- *
- * An alternate version - __copy_from_user_inatomic() - may be called from
- * atomic context and will fail rather than sleep.  In this case the
- * uncopied bytes will *NOT* be padded with zeros.  See fs/filemap.h
- * for explanation of why this is needed.
  */
+static __always_inline unsigned long __must_check
+__copy_to_user(void __user *to, const void *from, unsigned long n)
+{
+       might_sleep();
+       return __copy_to_user_inatomic(to, from, n);
+}
+
 static __always_inline unsigned long
 __copy_from_user_inatomic(void *to, const void __user *from, unsigned long n)
 {
@@ -493,6 +471,29 @@ __copy_from_user_inatomic(void *to, const void __user *from, unsigned long n)
        }
        return __copy_from_user_ll_nozero(to, from, n);
 }
+
+/**
+ * __copy_from_user: - Copy a block of data from user space, with less checking.
+ * @to:   Destination address, in kernel space.
+ * @from: Source address, in user space.
+ * @n:    Number of bytes to copy.
+ *
+ * Context: User context only.  This function may sleep.
+ *
+ * Copy data from user space to kernel space.  Caller must check
+ * the specified block with access_ok() before calling this function.
+ *
+ * Returns number of bytes that could not be copied.
+ * On success, this will be zero.
+ *
+ * If some data could not be copied, this function will pad the copied
+ * data to the requested size using zero bytes.
+ *
+ * An alternate version - __copy_from_user_inatomic() - may be called from
+ * atomic context and will fail rather than sleep.  In this case the
+ * uncopied bytes will *NOT* be padded with zeros.  See fs/filemap.h
+ * for explanation of why this is needed.
+ */
 static __always_inline unsigned long
 __copy_from_user(void *to, const void __user *from, unsigned long n)
 {
index 3ca7ab963d7d6ad2f152bd927314e15639223d29..beeeaf6b054a178db754757b6b9547fa784725d3 100644 (file)
 #define __NR_vmsplice          316
 #define __NR_move_pages                317
 #define __NR_getcpu            318
+#define __NR_epoll_pwait       319
 
 #ifdef __KERNEL__
 
-#define NR_syscalls 319
+#define NR_syscalls 320
 #include <linux/err.h>
 
 /*
index 4abfcfb91eb8446cf439af7df1cdd8aa7582375e..53100f35361280f31e6fcf1cdd60542b0d9cb191 100644 (file)
@@ -58,4 +58,4 @@ static const int VIC_CPI_Registers[] =
 
 #define VIC_BOOT_INTERRUPT_MASK                0xfe
 
-extern void smp_vic_timer_interrupt(struct pt_regs *regs);
+extern void smp_vic_timer_interrupt(void);
index aaf432dd767308c7db41a8e0051c88177f69de8c..5b27838905b234fe2991b0f5c90c217a9552d55a 100644 (file)
@@ -118,33 +118,33 @@ typedef struct voyager_module {
 } voyager_module_t;
 
 typedef struct voyager_eeprom_hdr {
-        __u8  module_id[4] __attribute__((packed)); 
-        __u8  version_id __attribute__((packed));
-        __u8  config_id __attribute__((packed)); 
-        __u16 boundry_id __attribute__((packed));      /* boundary scan id */
-        __u16 ee_size __attribute__((packed));         /* size of EEPROM */
-        __u8  assembly[11] __attribute__((packed));    /* assembly # */
-        __u8  assembly_rev __attribute__((packed));    /* assembly rev */
-        __u8  tracer[4] __attribute__((packed));       /* tracer number */
-        __u16 assembly_cksum __attribute__((packed));  /* asm checksum */
-        __u16 power_consump __attribute__((packed));   /* pwr requirements */
-        __u16 num_asics __attribute__((packed));       /* number of asics */
-        __u16 bist_time __attribute__((packed));       /* min. bist time */
-        __u16 err_log_offset __attribute__((packed));  /* error log offset */
-        __u16 scan_path_offset __attribute__((packed));/* scan path offset */
-        __u16 cct_offset __attribute__((packed));
-        __u16 log_length __attribute__((packed));      /* length of err log */
-        __u16 xsum_end __attribute__((packed));        /* offset to end of
+        __u8  module_id[4];
+        __u8  version_id;
+        __u8  config_id;
+        __u16 boundry_id;      /* boundary scan id */
+        __u16 ee_size;         /* size of EEPROM */
+        __u8  assembly[11];    /* assembly # */
+        __u8  assembly_rev;    /* assembly rev */
+        __u8  tracer[4];       /* tracer number */
+        __u16 assembly_cksum;  /* asm checksum */
+        __u16 power_consump;   /* pwr requirements */
+        __u16 num_asics;       /* number of asics */
+        __u16 bist_time;       /* min. bist time */
+        __u16 err_log_offset;  /* error log offset */
+        __u16 scan_path_offset;/* scan path offset */
+        __u16 cct_offset;
+        __u16 log_length;      /* length of err log */
+        __u16 xsum_end;        /* offset to end of
                                                           checksum */
-        __u8  reserved[4] __attribute__((packed));
-        __u8  sflag __attribute__((packed));           /* starting sentinal */
-        __u8  part_number[13] __attribute__((packed)); /* prom part number */
-        __u8  version[10] __attribute__((packed));     /* version number */
-        __u8  signature[8] __attribute__((packed));
-        __u16 eeprom_chksum __attribute__((packed));
-        __u32  data_stamp_offset __attribute__((packed));
-        __u8  eflag  __attribute__((packed));           /* ending sentinal */
-} voyager_eprom_hdr_t;
+        __u8  reserved[4];
+        __u8  sflag;           /* starting sentinal */
+        __u8  part_number[13]; /* prom part number */
+        __u8  version[10];     /* version number */
+        __u8  signature[8];
+        __u16 eeprom_chksum;
+        __u32  data_stamp_offset;
+        __u8  eflag ;           /* ending sentinal */
+} __attribute__((packed)) voyager_eprom_hdr_t;
 
 
 
@@ -155,30 +155,30 @@ typedef struct voyager_eeprom_hdr {
  * in the module EPROMs.  We really only care about the IDs and
  * offsets */
 typedef struct voyager_sp_table {
-       __u8 asic_id __attribute__((packed));
-       __u8 bypass_flag __attribute__((packed));
-       __u16 asic_data_offset __attribute__((packed));
-       __u16 config_data_offset __attribute__((packed));
-} voyager_sp_table_t;
+       __u8 asic_id;
+       __u8 bypass_flag;
+       __u16 asic_data_offset;
+       __u16 config_data_offset;
+} __attribute__((packed)) voyager_sp_table_t;
 
 typedef struct voyager_jtag_table {
-       __u8 icode[4] __attribute__((packed));
-       __u8 runbist[4] __attribute__((packed));
-       __u8 intest[4] __attribute__((packed));
-       __u8 samp_preld[4] __attribute__((packed));
-       __u8 ireg_len __attribute__((packed));
-} voyager_jtt_t;
+       __u8 icode[4];
+       __u8 runbist[4];
+       __u8 intest[4];
+       __u8 samp_preld[4];
+       __u8 ireg_len;
+} __attribute__((packed)) voyager_jtt_t;
 
 typedef struct voyager_asic_data_table {
-       __u8 jtag_id[4] __attribute__((packed));
-       __u16 length_bsr __attribute__((packed));
-       __u16 length_bist_reg __attribute__((packed));
-       __u32 bist_clk __attribute__((packed));
-       __u16 subaddr_bits __attribute__((packed));
-       __u16 seed_bits __attribute__((packed));
-       __u16 sig_bits __attribute__((packed));
-       __u16 jtag_offset __attribute__((packed));
-} voyager_at_t;
+       __u8 jtag_id[4];
+       __u16 length_bsr;
+       __u16 length_bist_reg;
+       __u32 bist_clk;
+       __u16 subaddr_bits;
+       __u16 seed_bits;
+       __u16 sig_bits;
+       __u16 jtag_offset;
+} __attribute__((packed)) voyager_at_t;
 
 /* Voyager Interrupt Controller (VIC) registers */
 
@@ -328,52 +328,52 @@ struct voyager_bios_info {
 #define NUMBER_OF_POS_REGS     8
 
 typedef struct {
-       __u8    MC_Slot __attribute__((packed));
-       __u8    POS_Values[NUMBER_OF_POS_REGS] __attribute__((packed));
-} MC_SlotInformation_t;
+       __u8    MC_Slot;
+       __u8    POS_Values[NUMBER_OF_POS_REGS];
+} __attribute__((packed)) MC_SlotInformation_t;
 
 struct QuadDescription {
-       __u8  Type __attribute__((packed));     /* for type 0 (DYADIC or MONADIC) all fields
+       __u8  Type;     /* for type 0 (DYADIC or MONADIC) all fields
                          * will be zero except for slot */
-       __u8 StructureVersion __attribute__((packed));
-       __u32 CPI_BaseAddress __attribute__((packed));
-       __u32  LARC_BankSize __attribute__((packed));   
-       __u32 LocalMemoryStateBits __attribute__((packed));
-       __u8  Slot __attribute__((packed)); /* Processor slots 1 - 4 */
-}
+       __u8 StructureVersion;
+       __u32 CPI_BaseAddress;
+       __u32  LARC_BankSize;
+       __u32 LocalMemoryStateBits;
+       __u8  Slot; /* Processor slots 1 - 4 */
+} __attribute__((packed));
 
 struct ProcBoardInfo { 
-       __u8 Type __attribute__((packed));    
-       __u8 StructureVersion __attribute__((packed));
-       __u8 NumberOfBoards __attribute__((packed));
-       struct QuadDescription QuadData[MAX_PROCESSOR_BOARDS] __attribute__((packed));
-};
+       __u8 Type;
+       __u8 StructureVersion;
+       __u8 NumberOfBoards;
+       struct QuadDescription QuadData[MAX_PROCESSOR_BOARDS];
+} __attribute__((packed));
 
 struct CacheDescription {
-       __u8 Level __attribute__((packed));
-       __u32 TotalSize __attribute__((packed));
-       __u16 LineSize __attribute__((packed));
-       __u8  Associativity __attribute__((packed));
-       __u8  CacheType __attribute__((packed));
-       __u8  WriteType __attribute__((packed));
-       __u8  Number_CPUs_SharedBy __attribute__((packed));
-       __u8  Shared_CPUs_Hardware_IDs[MAX_SHARED_CPUS] __attribute__((packed));
+       __u8 Level;
+       __u32 TotalSize;
+       __u16 LineSize;
+       __u8  Associativity;
+       __u8  CacheType;
+       __u8  WriteType;
+       __u8  Number_CPUs_SharedBy;
+       __u8  Shared_CPUs_Hardware_IDs[MAX_SHARED_CPUS];
 
-};
+} __attribute__((packed));
 
 struct CPU_Description {
-       __u8 CPU_HardwareId __attribute__((packed));
-       char *FRU_String __attribute__((packed));
-       __u8 NumberOfCacheLevels __attribute__((packed));
-       struct CacheDescription CacheLevelData[MAX_CACHE_LEVELS] __attribute__((packed));
-};
+       __u8 CPU_HardwareId;
+       char *FRU_String;
+       __u8 NumberOfCacheLevels;
+       struct CacheDescription CacheLevelData[MAX_CACHE_LEVELS];
+} __attribute__((packed));
 
 struct CPU_Info {
-       __u8 Type __attribute__((packed));
-       __u8 StructureVersion __attribute__((packed));
-       __u8 NumberOf_CPUs __attribute__((packed));
-       struct CPU_Description CPU_Data[MAX_CPUS] __attribute__((packed));
-};
+       __u8 Type;
+       __u8 StructureVersion;
+       __u8 NumberOf_CPUs;
+       struct CPU_Description CPU_Data[MAX_CPUS];
+} __attribute__((packed));
 
 
 /*
@@ -505,8 +505,8 @@ extern int voyager_memory_detect(int region, __u32 *addr, __u32 *length);
 extern void voyager_smp_intr_init(void);
 extern __u8 voyager_extended_cmos_read(__u16 cmos_address);
 extern void voyager_smp_dump(void);
-extern void voyager_timer_interrupt(struct pt_regs *regs);
-extern void smp_local_timer_interrupt(struct pt_regs * regs);
+extern void voyager_timer_interrupt(void);
+extern void smp_local_timer_interrupt(void);
 extern void voyager_power_off(void);
 extern void smp_voyager_power_off(void *dummy);
 extern void voyager_restart(void);
index 43bfff6c6b87fffbc6e36cac2aea43e7cebf7351..855c30af72a9d8fdecabf10c25e320f5daea5201 100644 (file)
@@ -417,6 +417,8 @@ __writeq (unsigned long val, volatile void __iomem *addr)
 # define outl_p                outl
 #endif
 
+# ifdef __KERNEL__
+
 extern void __iomem * ioremap(unsigned long offset, unsigned long size);
 extern void __iomem * ioremap_nocache (unsigned long offset, unsigned long size);
 
@@ -430,8 +432,6 @@ iounmap (volatile void __iomem *addr)
 #define dmi_iounmap(x,l) iounmap(x)
 #define dmi_alloc(l) kmalloc(l, GFP_ATOMIC)
 
-# ifdef __KERNEL__
-
 /*
  * String version of IO memory access ops:
  */
diff --git a/include/asm-ia64/irq_regs.h b/include/asm-ia64/irq_regs.h
new file mode 100644 (file)
index 0000000..3dd9c0b
--- /dev/null
@@ -0,0 +1 @@
+#include <asm-generic/irq_regs.h>
index 90cba967df356f01e1ea0934819ce4cfdc31c270..7ffbddf5306f7fe3e00598460ace0dbc438487fd 100644 (file)
@@ -26,7 +26,7 @@ typedef void ia64_mv_setup_t (char **);
 typedef void ia64_mv_cpu_init_t (void);
 typedef void ia64_mv_irq_init_t (void);
 typedef void ia64_mv_send_ipi_t (int, int, int, int);
-typedef void ia64_mv_timer_interrupt_t (int, void *, struct pt_regs *);
+typedef void ia64_mv_timer_interrupt_t (int, void *);
 typedef void ia64_mv_global_tlb_purge_t (struct mm_struct *, unsigned long, unsigned long, unsigned long);
 typedef void ia64_mv_tlb_migrate_finish_t (struct mm_struct *);
 typedef unsigned int ia64_mv_local_vector_to_irq (u8);
@@ -96,7 +96,7 @@ machvec_noop_task (struct task_struct *task)
 }
 
 extern void machvec_setup (char **);
-extern void machvec_timer_interrupt (int, void *, struct pt_regs *);
+extern void machvec_timer_interrupt (int, void *);
 extern void machvec_dma_sync_single (struct device *, dma_addr_t, size_t, int);
 extern void machvec_dma_sync_sg (struct device *, struct scatterlist *, int, int);
 extern void machvec_tlb_migrate_finish (struct mm_struct *);
index 2c8fd92d0ece088e36b15548588947a59fd5cea7..4283ddcc25fbf69a50cfce33483fbbf203023ff9 100644 (file)
@@ -764,7 +764,7 @@ struct ia64_pal_retval {
  * (generally 0) MUST be passed.  Reserved parameters are not optional
  * parameters.
  */
-extern struct ia64_pal_retval ia64_pal_call_static (u64, u64, u64, u64, u64);
+extern struct ia64_pal_retval ia64_pal_call_static (u64, u64, u64, u64);
 extern struct ia64_pal_retval ia64_pal_call_stacked (u64, u64, u64, u64);
 extern struct ia64_pal_retval ia64_pal_call_phys_static (u64, u64, u64, u64);
 extern struct ia64_pal_retval ia64_pal_call_phys_stacked (u64, u64, u64, u64);
@@ -774,14 +774,7 @@ extern void ia64_load_scratch_fpregs (struct ia64_fpreg *);
 #define PAL_CALL(iprv,a0,a1,a2,a3) do {                        \
        struct ia64_fpreg fr[6];                        \
        ia64_save_scratch_fpregs(fr);                   \
-       iprv = ia64_pal_call_static(a0, a1, a2, a3, 0); \
-       ia64_load_scratch_fpregs(fr);                   \
-} while (0)
-
-#define PAL_CALL_IC_OFF(iprv,a0,a1,a2,a3) do {         \
-       struct ia64_fpreg fr[6];                        \
-       ia64_save_scratch_fpregs(fr);                   \
-       iprv = ia64_pal_call_static(a0, a1, a2, a3, 1); \
+       iprv = ia64_pal_call_static(a0, a1, a2, a3);    \
        ia64_load_scratch_fpregs(fr);                   \
 } while (0)
 
index e3b0c3fe5eed88205682f38423e3f46ff2b93882..da3eade0cae2cbbfdfca830403cf0889be10b58e 100644 (file)
@@ -135,7 +135,7 @@ extern void             pcireg_intr_addr_addr_set(struct pcibus_info *, int, u64
 extern void             pcireg_force_intr_set(struct pcibus_info *, int);
 extern u64         pcireg_wrb_flush_get(struct pcibus_info *, int);
 extern void             pcireg_int_ate_set(struct pcibus_info *, int, u64);
-extern u64 *   pcireg_int_ate_addr(struct pcibus_info *, int);
+extern u64 __iomem *   pcireg_int_ate_addr(struct pcibus_info *, int);
 extern void            pcibr_force_interrupt(struct sn_irq_info *sn_irq_info);
 extern void            pcibr_change_devices_irq(struct sn_irq_info *sn_irq_info);
 extern int             pcibr_ate_alloc(struct pcibus_info *, int);
index 65cdd73c2a57a641e3c32461f55053c04c1c16da..9a820ac61be338347f23d5d939e009bce8d52a7d 100644 (file)
@@ -162,11 +162,11 @@ static inline void
 tioca_tlbflush(struct tioca_kernel *tioca_kernel)
 {
        volatile u64 tmp;
-       volatile struct tioca *ca_base;
+       volatile struct tioca __iomem *ca_base;
        struct tioca_common *tioca_common;
 
        tioca_common = tioca_kernel->ca_common;
-       ca_base = (struct tioca *)tioca_common->ca_common.bs_base;
+       ca_base = (struct tioca __iomem *)tioca_common->ca_common.bs_base;
 
        /*
         * Explicit flushes not needed if GART is in cached mode
index 6d62b13f7ae7c7daedb3153d7c86fd72f86fdfb2..32c32f30b0998b1f22877ff23a8784c253313fe0 100644 (file)
@@ -53,7 +53,7 @@ struct tioce_dmamap {
        u64             ct_start;       /* coretalk start address */
        u64             pci_start;      /* bus start address */
 
-       u64             *ate_hw;        /* hw ptr of first ate in map */
+       u64             __iomem *ate_hw;/* hw ptr of first ate in map */
        u64             *ate_shadow;    /* shadow ptr of firat ate */
        u16             ate_count;      /* # ate's in the map */
 };
index 35e1386f37ab5f046828554e36383ca8b045e8c3..1d45e1518fb3e3eca05b7cbdcedb9ef51754ee60 100644 (file)
@@ -669,7 +669,7 @@ extern struct device *xpc_part;
 extern struct device *xpc_chan;
 extern int xpc_disengage_request_timelimit;
 extern int xpc_disengage_request_timedout;
-extern irqreturn_t xpc_notify_IRQ_handler(int, void *, struct pt_regs *);
+extern irqreturn_t xpc_notify_IRQ_handler(int, void *);
 extern void xpc_dropped_IPI_check(struct xpc_partition *);
 extern void xpc_activate_partition(struct xpc_partition *);
 extern void xpc_activate_kthreads(struct xpc_channel *, int);
index 70ad1c949c2b498cf691cdfc6326877ecb284681..d06933bd631825cfbbb096b92ecd0a166649aedc 100644 (file)
@@ -166,38 +166,6 @@ static inline void _writel(unsigned long l, unsigned long addr)
 
 #define flush_write_buffers() do { } while (0)  /* M32R_FIXME */
 
-/**
- *     check_signature         -       find BIOS signatures
- *     @io_addr: mmio address to check
- *     @signature:  signature block
- *     @length: length of signature
- *
- *     Perform a signature comparison with the ISA mmio address io_addr.
- *     Returns 1 on a match.
- *
- *     This function is deprecated. New drivers should use ioremap and
- *     check_signature.
- */
-
-static inline int check_signature(void __iomem *io_addr,
-        const unsigned char *signature, int length)
-{
-        int retval = 0;
-#if 0
-printk("check_signature\n");
-        do {
-                if (readb(io_addr) != *signature)
-                        goto out;
-                io_addr++;
-                signature++;
-                length--;
-        } while (length);
-        retval = 1;
-out:
-#endif
-        return retval;
-}
-
 static inline void
 memset_io(volatile void __iomem *addr, unsigned char val, int count)
 {
diff --git a/include/asm-m32r/irq_regs.h b/include/asm-m32r/irq_regs.h
new file mode 100644 (file)
index 0000000..3dd9c0b
--- /dev/null
@@ -0,0 +1 @@
+#include <asm-generic/irq_regs.h>
index b4eadf8527387292c19023b7c4dca8c36b8db7cd..8e389b7fa70c88ff3db422de4bfa7c2306d098ce 100644 (file)
@@ -8,8 +8,7 @@
 
 /***************************** Prototypes *****************************/
 
-void stdma_lock(irqreturn_t (*handler)(int, void *, struct pt_regs *),
-               void *data);
+void stdma_lock(irq_handler_t handler, void *data);
 void stdma_release( void );
 int stdma_others_waiting( void );
 int stdma_islocked( void );
index cebbb03370eca37fdb33d3ab8a71611be0280489..d90d841d3dfde278269de086af882d87346a9892 100644 (file)
@@ -5,6 +5,7 @@
 
 struct scatterlist;
 
+#ifndef CONFIG_MMU_SUN3
 static inline int dma_supported(struct device *dev, u64 mask)
 {
        return 1;
@@ -26,7 +27,7 @@ static inline int dma_is_consistent(dma_addr_t dma_addr)
 }
 
 extern void *dma_alloc_coherent(struct device *, size_t,
-                               dma_addr_t *, int);
+                               dma_addr_t *, gfp_t);
 extern void dma_free_coherent(struct device *, size_t,
                              void *, dma_addr_t);
 
@@ -88,4 +89,8 @@ static inline int dma_mapping_error(dma_addr_t handle)
        return 0;
 }
 
+#else
+#include <asm-generic/dma-mapping-broken.h>
+#endif
+
 #endif  /* _M68K_DMA_MAPPING_H */
index 57f4fdda65ab264cda6aad4c28de27af34bf8d78..45dc908932a3993a8295dd0a27575b07415b640a 100644 (file)
@@ -17,8 +17,7 @@
 
 #include <linux/vmalloc.h>
 
-asmlinkage irqreturn_t floppy_hardint(int irq, void *dev_id,
-                                     struct pt_regs *regs);
+asmlinkage irqreturn_t floppy_hardint(int irq, void *dev_id);
 
 /* constants... */
 
@@ -184,8 +183,7 @@ static void fd_disable_dma(void)
 
 /* this is the only truly Q40 specific function */
 
-asmlinkage irqreturn_t floppy_hardint(int irq, void *dev_id,
-                                     struct pt_regs *regs)
+asmlinkage irqreturn_t floppy_hardint(int irq, void *dev_id)
 {
        register unsigned char st;
 
@@ -198,7 +196,7 @@ asmlinkage irqreturn_t floppy_hardint(int irq, void *dev_id,
        static int dma_wait=0;
 #endif
        if(!doing_pdma) {
-               floppy_interrupt(irq, dev_id, regs);
+               floppy_interrupt(irq, dev_id);
                return IRQ_HANDLED;
        }
 
@@ -246,7 +244,7 @@ asmlinkage irqreturn_t floppy_hardint(int irq, void *dev_id,
                dma_wait=0;
 #endif
                doing_pdma = 0;
-               floppy_interrupt(irq, dev_id, regs);
+               floppy_interrupt(irq, dev_id);
                return IRQ_HANDLED;
        }
 #ifdef TRACE_FLPY_INT
index 365f76fb8013fbfa1c1ae0e531abe6d45ea93d51..f9ffb2cbbae826c571d0feaeee632b2eac68b5f5 100644 (file)
@@ -123,7 +123,7 @@ static __inline__ void ide_release_lock (void)
 }
 
 static __inline__ void
-ide_get_lock(irqreturn_t (*handler)(int, void *, struct pt_regs *), void *data)
+ide_get_lock(irq_handler_t handler, void *data)
 {
        if (MACH_IS_ATARI) {
                if (falconide_intr_lock == 0) {
index 3257f9881002dd3d69a9d6023620629b1a929c72..4901cb105e2fe9d7a33c3ae40c1637e651201392 100644 (file)
@@ -83,7 +83,7 @@ struct pt_regs;
  * interrupt source (if it supports chaining).
  */
 typedef struct irq_node {
-       int             (*handler)(int, void *, struct pt_regs *);
+       int             (*handler)(int, void *);
        void            *dev_id;
        struct irq_node *next;
        unsigned long   flags;
@@ -93,12 +93,12 @@ typedef struct irq_node {
 /*
  * This structure has only 4 elements for speed reasons
  */
-typedef struct irq_handler {
-       int             (*handler)(int, void *, struct pt_regs *);
+struct irq_handler {
+       int             (*handler)(int, void *);
        unsigned long   flags;
        void            *dev_id;
        const char      *devname;
-} irq_handler_t;
+};
 
 struct irq_controller {
        const char *name;
@@ -122,6 +122,7 @@ extern void m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt,
                                      void (*handler)(unsigned int, struct pt_regs *));
 extern void m68k_setup_irq_controller(struct irq_controller *, unsigned int, unsigned int);
 
-asmlinkage void m68k_handle_int(unsigned int, struct pt_regs *);
+asmlinkage void m68k_handle_int(unsigned int);
+asmlinkage void __m68k_handle_int(unsigned int, struct pt_regs *);
 
 #endif /* _M68K_IRQ_H_ */
diff --git a/include/asm-m68k/irq_regs.h b/include/asm-m68k/irq_regs.h
new file mode 100644 (file)
index 0000000..3dd9c0b
--- /dev/null
@@ -0,0 +1 @@
+#include <asm-generic/irq_regs.h>
index b0d2e347353777780f26e2943bef041307153358..a2c7e6fcca38c7bce09d665af394d1ac7015c480 100644 (file)
@@ -143,17 +143,17 @@ struct iop_msg {
        int     status;                 /* status of this message            */
        __u8    message[IOP_MSG_LEN];   /* the message being sent/received   */
        __u8    reply[IOP_MSG_LEN];     /* the reply to the message          */
-       void    (*handler)(struct iop_msg *, struct pt_regs *);
+       void    (*handler)(struct iop_msg *);
                                        /* function to call when reply recvd */
 };
 
 extern int iop_scc_present,iop_ism_present;
 
 extern int iop_listen(uint, uint,
-                       void (*handler)(struct iop_msg *, struct pt_regs *),
+                       void (*handler)(struct iop_msg *),
                        const char *);
 extern int iop_send_message(uint, uint, void *, uint, __u8 *,
-                           void (*)(struct iop_msg *, struct pt_regs *));
+                           void (*)(struct iop_msg *));
 extern void iop_complete_message(struct iop_msg *);
 extern void iop_upload_code(uint, __u8 *, uint, __u16);
 extern void iop_download_code(uint, __u8 *, uint, __u16);
index df898f27e4346e33fc54ec542d3f71ee0c304f0b..26d2b91209c5e9f701341865300b0a9cccf2a952 100644 (file)
@@ -10,7 +10,7 @@ struct rtc_time;
 struct rtc_pll_info;
 struct buffer_head;
 
-extern void (*mach_sched_init) (irqreturn_t (*handler)(int, void *, struct pt_regs *));
+extern void (*mach_sched_init) (irq_handler_t handler);
 /* machine dependent irq functions */
 extern void (*mach_init_IRQ) (void);
 extern void (*mach_get_model) (char *model);
index de1ba6ead3b4391de37e71bbb14fe2dcae92ed40..3db8a81942f12ac98d9319f1fc92a4b4f58f30b8 100644 (file)
@@ -198,6 +198,7 @@ static inline int sigfindinword(unsigned long word)
        return word ^ 31;
 }
 
+struct pt_regs;
 extern void ptrace_signal_deliver(struct pt_regs *regs, void *cookie);
 
 #endif /* __KERNEL__ */
index 6c59215b285e0b9ab1d57c69bc582767edb9e483..2eb7df1e0f5d08623b0444f69909f482cdc36555 100644 (file)
 #ifndef _M68K_STRING_H_
 #define _M68K_STRING_H_
 
-#include <asm/setup.h>
-#include <asm/page.h>
+#include <linux/types.h>
+#include <linux/compiler.h>
 
-#define __HAVE_ARCH_STRCPY
-static inline char * strcpy(char * dest,const char *src)
+static inline size_t __kernel_strlen(const char *s)
 {
-  char *xdest = dest;
-
-  __asm__ __volatile__
-       ("1:\tmoveb %1@+,%0@+\n\t"
-        "jne 1b"
-       : "=a" (dest), "=a" (src)
-        : "0" (dest), "1" (src) : "memory");
-  return xdest;
-}
+       const char *sc;
 
-#define __HAVE_ARCH_STRNCPY
-static inline char * strncpy(char *dest, const char *src, size_t n)
-{
-  char *xdest = dest;
-
-  if (n == 0)
-    return xdest;
-
-  __asm__ __volatile__
-       ("1:\tmoveb %1@+,%0@+\n\t"
-       "jeq 2f\n\t"
-        "subql #1,%2\n\t"
-        "jne 1b\n\t"
-        "2:"
-        : "=a" (dest), "=a" (src), "=d" (n)
-        : "0" (dest), "1" (src), "2" (n)
-        : "memory");
-  return xdest;
+       for (sc = s; *sc++; )
+               ;
+       return sc - s - 1;
 }
 
-#define __HAVE_ARCH_STRCAT
-static inline char * strcat(char * dest, const char * src)
+static inline char *__kernel_strcpy(char *dest, const char *src)
 {
-       char *tmp = dest;
-
-       while (*dest)
-               dest++;
-       while ((*dest++ = *src++))
-               ;
-
-       return tmp;
+       char *xdest = dest;
+
+       asm volatile ("\n"
+               "1:     move.b  (%1)+,(%0)+\n"
+               "       jne     1b"
+               : "+a" (dest), "+a" (src)
+               : : "memory");
+       return xdest;
 }
 
-#define __HAVE_ARCH_STRNCAT
-static inline char * strncat(char *dest, const char *src, size_t count)
-{
-       char *tmp = dest;
-
-       if (count) {
-               while (*dest)
-                       dest++;
-               while ((*dest++ = *src++)) {
-                       if (--count == 0) {
-                               *dest++='\0';
-                               break;
-                       }
-               }
-       }
+#ifndef __IN_STRING_C
 
-       return tmp;
-}
+#define __HAVE_ARCH_STRLEN
+#define strlen(s)      (__builtin_constant_p(s) ?      \
+                        __builtin_strlen(s) :          \
+                        __kernel_strlen(s))
 
-#define __HAVE_ARCH_STRCHR
-static inline char * strchr(const char * s, int c)
+#define __HAVE_ARCH_STRNLEN
+static inline size_t strnlen(const char *s, size_t count)
 {
-  const char ch = c;
-
-  for(; *s != ch; ++s)
-    if (*s == '\0')
-      return( NULL );
-  return( (char *) s);
+       const char *sc = s;
+
+       asm volatile ("\n"
+               "1:     subq.l  #1,%1\n"
+               "       jcs     2f\n"
+               "       tst.b   (%0)+\n"
+               "       jne     1b\n"
+               "       subq.l  #1,%0\n"
+               "2:"
+               : "+a" (sc), "+d" (count));
+       return sc - s;
 }
 
-/* strstr !! */
+#define __HAVE_ARCH_STRCPY
+#if __GNUC__ >= 4
+#define strcpy(d, s)   (__builtin_constant_p(s) &&     \
+                        __builtin_strlen(s) <= 32 ?    \
+                        __builtin_strcpy(d, s) :       \
+                        __kernel_strcpy(d, s))
+#else
+#define strcpy(d, s)   __kernel_strcpy(d, s)
+#endif
 
-#define __HAVE_ARCH_STRLEN
-static inline size_t strlen(const char * s)
+#define __HAVE_ARCH_STRNCPY
+static inline char *strncpy(char *dest, const char *src, size_t n)
 {
-  const char *sc;
-  for (sc = s; *sc != '\0'; ++sc) ;
-  return(sc - s);
+       char *xdest = dest;
+
+       asm volatile ("\n"
+               "       jra     2f\n"
+               "1:     move.b  (%1),(%0)+\n"
+               "       jeq     2f\n"
+               "       addq.l  #1,%1\n"
+               "2:     subq.l  #1,%2\n"
+               "       jcc     1b\n"
+               : "+a" (dest), "+a" (src), "+d" (n)
+               : : "memory");
+       return xdest;
 }
 
-/* strnlen !! */
+#define __HAVE_ARCH_STRCAT
+#define strcat(d, s)   ({                      \
+       char *__d = (d);                        \
+       strcpy(__d + strlen(__d), (s));         \
+})
 
-#define __HAVE_ARCH_STRCMP
-static inline int strcmp(const char * cs,const char * ct)
+#define __HAVE_ARCH_STRCHR
+static inline char *strchr(const char *s, int c)
 {
-  char __res;
-
-  __asm__
-       ("1:\tmoveb %0@+,%2\n\t" /* get *cs */
-        "cmpb %1@+,%2\n\t"      /* compare a byte */
-        "jne  2f\n\t"           /* not equal, break out */
-        "tstb %2\n\t"           /* at end of cs? */
-        "jne  1b\n\t"           /* no, keep going */
-        "jra  3f\n\t"          /* strings are equal */
-        "2:\tsubb %1@-,%2\n\t"  /* *cs - *ct */
-        "3:"
-        : "=a" (cs), "=a" (ct), "=d" (__res)
-        : "0" (cs), "1" (ct));
-  return __res;
+       char sc, ch = c;
+
+       for (; (sc = *s++) != ch; ) {
+               if (!sc)
+                       return NULL;
+       }
+       return (char *)s - 1;
 }
 
-#define __HAVE_ARCH_STRNCMP
-static inline int strncmp(const char * cs,const char * ct,size_t count)
+#define __HAVE_ARCH_STRCMP
+static inline int strcmp(const char *cs, const char *ct)
 {
-  char __res;
-
-  if (!count)
-    return 0;
-  __asm__
-       ("1:\tmovb %0@+,%3\n\t"          /* get *cs */
-        "cmpb   %1@+,%3\n\t"            /* compare a byte */
-        "jne    3f\n\t"                 /* not equal, break out */
-        "tstb   %3\n\t"                 /* at end of cs? */
-        "jeq    4f\n\t"                 /* yes, all done */
-        "subql  #1,%2\n\t"              /* no, adjust count */
-        "jne    1b\n\t"                 /* more to do, keep going */
-        "2:\tmoveq #0,%3\n\t"           /* strings are equal */
-        "jra    4f\n\t"
-        "3:\tsubb %1@-,%3\n\t"          /* *cs - *ct */
-        "4:"
-        : "=a" (cs), "=a" (ct), "=d" (count), "=d" (__res)
-        : "0" (cs), "1" (ct), "2" (count));
-  return __res;
+       char res;
+
+       asm ("\n"
+               "1:     move.b  (%0)+,%2\n"     /* get *cs */
+               "       cmp.b   (%1)+,%2\n"     /* compare a byte */
+               "       jne     2f\n"           /* not equal, break out */
+               "       tst.b   %2\n"           /* at end of cs? */
+               "       jne     1b\n"           /* no, keep going */
+               "       jra     3f\n"           /* strings are equal */
+               "2:     sub.b   -(%1),%2\n"     /* *cs - *ct */
+               "3:"
+               : "+a" (cs), "+a" (ct), "=d" (res));
+       return res;
 }
 
 #define __HAVE_ARCH_MEMSET
@@ -150,4 +126,6 @@ extern void *memmove(void *, const void *, __kernel_size_t);
 extern int memcmp(const void *, const void *, __kernel_size_t);
 #define memcmp(d, s, n) __builtin_memcmp(d, s, n)
 
+#endif
+
 #endif /* _M68K_STRING_H_ */
index 6c8c17d047a1a28b9533595991a75d69c92076f3..d8f17a0d8c9f6f872c513b6d5850c98e76d01465 100644 (file)
@@ -4,6 +4,7 @@
 #ifndef __SUN3_MMU_H__
 #define __SUN3_MMU_H__
 
+#include <linux/types.h>
 #include <asm/movs.h>
 #include <asm/sun3-head.h>
 
@@ -160,7 +161,7 @@ static inline void sun3_put_context(unsigned char c)
        return;
 }
 
-extern void *sun3_ioremap(unsigned long phys, unsigned long size,
+extern void __iomem *sun3_ioremap(unsigned long phys, unsigned long size,
                          unsigned long type);
 
 extern int sun3_map_test(unsigned long addr, char *val);
index ca8cc41138437960cd82aadd221fc6d263589966..32c45f84ac60d6f87b71ce76d1f04e390f026694 100644 (file)
@@ -111,8 +111,7 @@ static void sun3x_82072_fd_outb(unsigned char value, int port)
 }
 
 
-asmlinkage irqreturn_t sun3xflop_hardint(int irq, void *dev_id,
-                                        struct pt_regs * regs)
+asmlinkage irqreturn_t sun3xflop_hardint(int irq, void *dev_id)
 {
        register unsigned char st;
 
@@ -125,7 +124,7 @@ asmlinkage irqreturn_t sun3xflop_hardint(int irq, void *dev_id,
        static int dma_wait=0;
 #endif
        if(!doing_pdma) {
-               floppy_interrupt(irq, dev_id, regs);
+               floppy_interrupt(irq, dev_id);
                return IRQ_HANDLED;
        }
 
@@ -189,7 +188,7 @@ asmlinkage irqreturn_t sun3xflop_hardint(int irq, void *dev_id,
                dma_wait=0;
 #endif
 
-               floppy_interrupt(irq, dev_id, regs);
+               floppy_interrupt(irq, dev_id);
                return IRQ_HANDLED;
        }
 
index 131a0cb0f491833f8fc3413a024aecfc5c3404d1..243dd13e6bfc0895fcf0cfcd7081ac333a2f07bf 100644 (file)
@@ -78,13 +78,13 @@ static inline int irqs_disabled(void)
 #define mb()           barrier()
 #define rmb()          barrier()
 #define wmb()          barrier()
-#define read_barrier_depends() do { } while(0)
-#define set_mb(var, value)    do { xchg(&var, value); } while (0)
+#define read_barrier_depends() ((void)0)
+#define set_mb(var, value)     ({ (var) = (value); wmb(); })
 
 #define smp_mb()       barrier()
 #define smp_rmb()      barrier()
 #define smp_wmb()      barrier()
-#define smp_read_barrier_depends()     do { } while(0)
+#define smp_read_barrier_depends()     ((void)0)
 
 
 #define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
index 88b1f47400e17f8bfb4137e66c849373fef9fac2..e4c9f080ff20ad495254782cc80647bef4135aef 100644 (file)
@@ -76,7 +76,7 @@ asm volatile ("\n"                                    \
                break;                                                  \
        case 8:                                                         \
            {                                                           \
-               const void *__pu_ptr = (ptr);                           \
+               const void __user *__pu_ptr = (ptr);                    \
                asm volatile ("\n"                                      \
                        "1:     moves.l %2,(%1)+\n"                     \
                        "2:     moves.l %R2,(%1)\n"                     \
@@ -125,7 +125,7 @@ asm volatile ("\n"                                  \
                "       .previous"                              \
                : "+d" (res), "=&" #reg (__gu_val)              \
                : "m" (*(ptr)), "i" (err));                     \
-       (x) = (typeof(*(ptr)))(long)__gu_val;                   \
+       (x) = (typeof(*(ptr)))(unsigned long)__gu_val;          \
 })
 
 #define __get_user(x, ptr)                                             \
@@ -221,16 +221,16 @@ __constant_copy_from_user(void *to, const void __user *from, unsigned long n)
 
        switch (n) {
        case 1:
-               __get_user_asm(res, *(u8 *)to, (u8 *)from, u8, b, d, 1);
+               __get_user_asm(res, *(u8 *)to, (u8 __user *)from, u8, b, d, 1);
                break;
        case 2:
-               __get_user_asm(res, *(u16 *)to, (u16 *)from, u16, w, d, 2);
+               __get_user_asm(res, *(u16 *)to, (u16 __user *)from, u16, w, d, 2);
                break;
        case 3:
                __constant_copy_from_user_asm(res, to, from, tmp, 3, w, b,);
                break;
        case 4:
-               __get_user_asm(res, *(u32 *)to, (u32 *)from, u32, l, r, 4);
+               __get_user_asm(res, *(u32 *)to, (u32 __user *)from, u32, l, r, 4);
                break;
        case 5:
                __constant_copy_from_user_asm(res, to, from, tmp, 5, l, b,);
@@ -302,16 +302,16 @@ __constant_copy_to_user(void __user *to, const void *from, unsigned long n)
 
        switch (n) {
        case 1:
-               __put_user_asm(res, *(u8 *)from, (u8 *)to, b, d, 1);
+               __put_user_asm(res, *(u8 *)from, (u8 __user *)to, b, d, 1);
                break;
        case 2:
-               __put_user_asm(res, *(u16 *)from, (u16 *)to, w, d, 2);
+               __put_user_asm(res, *(u16 *)from, (u16 __user *)to, w, d, 2);
                break;
        case 3:
                __constant_copy_to_user_asm(res, to, from, tmp, 3, w, b,);
                break;
        case 4:
-               __put_user_asm(res, *(u32 *)from, (u32 *)to, l, r, 4);
+               __put_user_asm(res, *(u32 *)from, (u32 __user *)to, l, r, 4);
                break;
        case 5:
                __constant_copy_to_user_asm(res, to, from, tmp, 5, l, b,);
index 3ab716f0fc18a7870df7a1359fea9df74b16119e..ad4348058c66f18779e61b3f8a607b45cdd78f27 100644 (file)
 #define __NR_add_key           279
 #define __NR_request_key       280
 #define __NR_keyctl            281
+#define __NR_ioprio_set                282
+#define __NR_ioprio_get                283
+#define __NR_inotify_init      284
+#define __NR_inotify_add_watch 285
+#define __NR_inotify_rm_watch  286
+#define __NR_migrate_pages     287
+#define __NR_openat            288
+#define __NR_mkdirat           289
+#define __NR_mknodat           290
+#define __NR_fchownat          291
+#define __NR_futimesat         292
+#define __NR_fstatat64         293
+#define __NR_unlinkat          294
+#define __NR_renameat          295
+#define __NR_linkat            296
+#define __NR_symlinkat         297
+#define __NR_readlinkat                298
+#define __NR_fchmodat          299
+#define __NR_faccessat         300
+#define __NR_pselect6          301
+#define __NR_ppoll             302
+#define __NR_unshare           303
+#define __NR_set_robust_list   304
+#define __NR_get_robust_list   305
+#define __NR_splice            306
+#define __NR_sync_file_range   307
+#define __NR_tee               308
+#define __NR_vmsplice          309
+#define __NR_move_pages                310
 
 #ifdef __KERNEL__
 
-#define NR_syscalls            282
+#define NR_syscalls            311
 #include <linux/err.h>
 
 /* user-visible error numbers are in the range -1 - -MAX_ERRNO: see
index e8d5a64c7e798ef0486eab2109a57a8e5b060099..d7c0b109bd457c55d2baeb80132a1bad6b8f9ff6 100644 (file)
@@ -81,7 +81,7 @@ struct user{
   unsigned long magic;         /* To uniquely identify a core file */
   char u_comm[32];             /* User command that was responsible */
 };
-#define NBPG PAGE_SIZE
+#define NBPG 4096
 #define UPAGES 1
 #define HOST_TEXT_START_ADDR (u.start_code)
 #define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG)
index daafb5d43ef196c6fbc829d78ad0cdf508562c6e..ebaf03197114d0cd831a85cdddf3a11dec6db3c2 100644 (file)
 #define __NR_mq_notify         275
 #define __NR_mq_getsetattr     276
 #define __NR_waitid            277
-#define __NR_sys_setaltroot    278
+#define __NR_vserver           278
 #define __NR_add_key           279
 #define __NR_request_key       280
 #define __NR_keyctl            281
+#define __NR_ioprio_set                282
+#define __NR_ioprio_get                283
+#define __NR_inotify_init      284
+#define __NR_inotify_add_watch 285
+#define __NR_inotify_rm_watch  286
+#define __NR_migrate_pages     287
+#define __NR_openat            288
+#define __NR_mkdirat           289
+#define __NR_mknodat           290
+#define __NR_fchownat          291
+#define __NR_futimesat         292
+#define __NR_fstatat64         293
+#define __NR_unlinkat          294
+#define __NR_renameat          295
+#define __NR_linkat            296
+#define __NR_symlinkat         297
+#define __NR_readlinkat                298
+#define __NR_fchmodat          299
+#define __NR_faccessat         300
+#define __NR_pselect6          301
+#define __NR_ppoll             302
+#define __NR_unshare           303
+#define __NR_set_robust_list   304
+#define __NR_get_robust_list   305
+#define __NR_splice            306
+#define __NR_sync_file_range   307
+#define __NR_tee               308
+#define __NR_vmsplice          309
+#define __NR_move_pages                310
+
 #ifdef __KERNEL__
 
-#define NR_syscalls            282
+#define NR_syscalls            311
 #include <linux/err.h>
 
 /* user-visible error numbers are in the range -1 - -MAX_ERRNO: see
index 9ab59e2bb23368530fa67c95af0d6ab2c4f7fe8f..e3c9925876a3ce4eb80ec67937362cd7d014ad2f 100644 (file)
@@ -55,24 +55,13 @@ extern void (*flush_icache_range)(unsigned long start, unsigned long end);
 #define flush_cache_vmap(start, end)           flush_cache_all()
 #define flush_cache_vunmap(start, end)         flush_cache_all()
 
-static inline void copy_to_user_page(struct vm_area_struct *vma,
+extern void copy_to_user_page(struct vm_area_struct *vma,
        struct page *page, unsigned long vaddr, void *dst, const void *src,
-       unsigned long len)
-{
-       if (cpu_has_dc_aliases)
-               flush_cache_page(vma, vaddr, page_to_pfn(page));
-       memcpy(dst, src, len);
-       __flush_icache_page(vma, page);
-}
+       unsigned long len);
 
-static inline void copy_from_user_page(struct vm_area_struct *vma,
+extern void copy_from_user_page(struct vm_area_struct *vma,
        struct page *page, unsigned long vaddr, void *dst, const void *src,
-       unsigned long len)
-{
-       if (cpu_has_dc_aliases)
-               flush_cache_page(vma, vaddr, page_to_pfn(page));
-       memcpy(dst, src, len);
-}
+       unsigned long len);
 
 extern void (*flush_cache_sigtramp)(unsigned long addr);
 extern void (*flush_icache_all)(void);
index 19495a490e72e57aaf822ca544383bf37a1fac90..707ffdbc9add7dcec97a70da14dc5076be87fae7 100644 (file)
@@ -49,8 +49,7 @@ struct pt_regs;
 
 extern void dec_ecc_be_init(void);
 extern int dec_ecc_be_handler(struct pt_regs *regs, int is_fixup);
-extern irqreturn_t dec_ecc_be_interrupt(int irq, void *dev_id,
-                                       struct pt_regs *regs);
+extern irqreturn_t dec_ecc_be_interrupt(int irq, void *dev_id);
 #endif
 
 #endif /* __ASM_MIPS_DEC_ECC_H */
index eb522aa1e2269d60b19fe652710358e22f94987d..28fa717ac423fb169177436027843f6058a720db 100644 (file)
@@ -84,8 +84,7 @@ extern spinlock_t kn01_lock;
 
 extern void dec_kn01_be_init(void);
 extern int dec_kn01_be_handler(struct pt_regs *regs, int is_fixup);
-extern irqreturn_t dec_kn01_be_interrupt(int irq, void *dev_id,
-                                        struct pt_regs *regs);
+extern irqreturn_t dec_kn01_be_interrupt(int irq, void *dev_id);
 #endif
 
 #endif /* __ASM_MIPS_DEC_KN01_H */
index a25f3d7da7f7453463205e7ab1514eb6eeddf50d..b56b4577f6eff498af0784f553526efa46b62c52 100644 (file)
@@ -78,8 +78,7 @@ struct pt_regs;
 
 extern void dec_kn02xa_be_init(void);
 extern int dec_kn02xa_be_handler(struct pt_regs *regs, int is_fixup);
-extern irqreturn_t dec_kn02xa_be_interrupt(int irq, void *dev_id,
-                                          struct pt_regs *regs);
+extern irqreturn_t dec_kn02xa_be_interrupt(int irq, void *dev_id);
 #endif
 
 #endif /* __ASM_MIPS_DEC_KN02XA_H */
index 6959bdb59310b096ec7797e0a31c78fde5aa9afc..02c8a13fc894838b27336ae42fbb542f87132e01 100644 (file)
  * fix-mapped?
  */
 enum fixed_addresses {
+#define FIX_N_COLOURS 8
+       FIX_CMAP_BEGIN,
+#ifdef CONFIG_MIPS_MT_SMTC
+       FIX_CMAP_END = FIX_CMAP_BEGIN + (FIX_N_COLOURS * NR_CPUS),
+#else
+       FIX_CMAP_END = FIX_CMAP_BEGIN + FIX_N_COLOURS,
+#endif
 #ifdef CONFIG_HIGHMEM
-       FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */
+       /* reserved pte's for temporary kernel mappings */
+       FIX_KMAP_BEGIN = FIX_CMAP_END + 1,
        FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
 #endif
        __end_of_fixed_addresses
@@ -70,9 +78,9 @@ extern void __set_fixmap (enum fixed_addresses idx,
  * at the top of mem..
  */
 #if defined(CONFIG_CPU_TX39XX) || defined(CONFIG_CPU_TX49XX)
-#define FIXADDR_TOP    (0xff000000UL - 0x2000)
+#define FIXADDR_TOP    ((unsigned long)(long)(int)(0xff000000 - 0x20000))
 #else
-#define FIXADDR_TOP    (0xffffe000UL)
+#define FIXADDR_TOP    ((unsigned long)(long)(int)0xfffe0000)
 #endif
 #define FIXADDR_SIZE   (__end_of_fixed_addresses << PAGE_SHIFT)
 #define FIXADDR_START  (FIXADDR_TOP - FIXADDR_SIZE)
index 58c561a9ec6b74b8eaf4c48d0609c44098e96538..efef843b93f0c1694a2084f1a502523a5ac69318 100644 (file)
@@ -134,9 +134,11 @@ static inline void restore_fp(struct task_struct *tsk)
 
 static inline fpureg_t *get_fpu_regs(struct task_struct *tsk)
 {
-       if (cpu_has_fpu) {
-               if ((tsk == current) && __is_fpu_owner())
+       if (tsk == current) {
+               preempt_disable();
+               if (is_fpu_owner())
                        _save_fp(current);
+               preempt_enable();
        }
 
        return tsk->thread.fpu.fpr;
index df624e1ee6e2eb278931b6ecf56e3a5ea494dbcd..bc5f3c53155f2983b9d31b7e6cfd77e103290175 100644 (file)
@@ -172,7 +172,7 @@ extern unsigned long isa_slot_offset;
 #define page_to_phys(page)     ((dma_addr_t)page_to_pfn(page) << PAGE_SHIFT)
 
 extern void __iomem * __ioremap(phys_t offset, phys_t size, unsigned long flags);
-extern void __iounmap(volatile void __iomem *addr);
+extern void __iounmap(const volatile void __iomem *addr);
 
 static inline void __iomem * __ioremap_mode(phys_t offset, unsigned long size,
        unsigned long flags)
@@ -279,7 +279,7 @@ static inline void __iomem * __ioremap_mode(phys_t offset, unsigned long size,
 #define ioremap_uncached_accelerated(offset, size)                     \
        __ioremap_mode((offset), (size), _CACHE_UNCACHED_ACCELERATED)
 
-static inline void iounmap(volatile void __iomem *addr)
+static inline void iounmap(const volatile void __iomem *addr)
 {
 #define __IS_KSEG1(addr) (((unsigned long)(addr) & ~0x1fffffffUL) == CKSEG1)
 
@@ -561,32 +561,6 @@ extern void pci_iounmap(struct pci_dev *dev, void __iomem *);
  */
 #define eth_io_copy_and_sum(skb,src,len,unused) memcpy_fromio((skb)->data,(src),(len))
 
-/*
- *     check_signature         -       find BIOS signatures
- *     @io_addr: mmio address to check
- *     @signature:  signature block
- *     @length: length of signature
- *
- *     Perform a signature comparison with the mmio address io_addr. This
- *     address should have been obtained by ioremap.
- *     Returns 1 on a match.
- */
-static inline int check_signature(char __iomem *io_addr,
-       const unsigned char *signature, int length)
-{
-       int retval = 0;
-       do {
-               if (readb(io_addr) != *signature)
-                       goto out;
-               io_addr++;
-               signature++;
-               length--;
-       } while (length);
-       retval = 1;
-out:
-       return retval;
-}
-
 /*
  * The caches on some architectures aren't dma-coherent and have need to
  * handle this in software.  There are three types of operations that
index d35c61776a0249d5620a8a70a8033b15735f48fc..0ce2a80b689e5da23a72ed6f17bfe01458325ed5 100644 (file)
@@ -24,9 +24,7 @@ static inline int irq_canonicalize(int irq)
 #define irq_canonicalize(irq) (irq)    /* Sane hardware, sane code ... */
 #endif
 
-struct pt_regs;
-
-extern asmlinkage unsigned int do_IRQ(unsigned int irq, struct pt_regs *regs);
+extern asmlinkage unsigned int do_IRQ(unsigned int irq);
 
 #ifdef CONFIG_MIPS_MT_SMTC
 /*
@@ -55,18 +53,18 @@ do {                                                                        \
  * Ideally there should be away to get this into kernel/irq/handle.c to
  * avoid the overhead of a call for just a tiny function ...
  */
-#define do_IRQ(irq, regs)                                              \
+#define do_IRQ(irq)                                                    \
 do {                                                                   \
        irq_enter();                                                    \
        __DO_IRQ_SMTC_HOOK();                                           \
-       __do_IRQ((irq), (regs));                                        \
+       __do_IRQ((irq));                                                \
        irq_exit();                                                     \
 } while (0)
 
 #endif
 
 extern void arch_init_irq(void);
-extern void spurious_interrupt(struct pt_regs *regs);
+extern void spurious_interrupt(void);
 
 #ifdef CONFIG_MIPS_MT_SMTC
 struct irqaction;
diff --git a/include/asm-mips/irq_regs.h b/include/asm-mips/irq_regs.h
new file mode 100644 (file)
index 0000000..33bd2a0
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * 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) 2006 Ralf Baechle (ralf@linux-mips.org)
+ */
+#ifndef __ASM_IRQ_REGS_H
+#define __ASM_IRQ_REGS_H
+
+#define ARCH_HAS_OWN_IRQ_REGS
+
+#include <linux/thread_info.h>
+
+static inline struct pt_regs *get_irq_regs(void)
+{
+       return current_thread_info()->regs;
+}
+
+#endif /* __ASM_IRQ_REGS_H */
index fe551f33a74fc9cd808ef754a63cb216fa91ebbd..e3e7ed38da6c43f71b56851c26fa1d5418dad9b9 100644 (file)
@@ -45,10 +45,6 @@ extern int
 toshibaboards_setup_irq(int irq, struct irqaction * new);
 
 
-#ifdef CONFIG_TX_BRANCH_LIKELY_BUG_WORKAROUND
-extern void tx_branch_likely_bug_fixup(struct pt_regs *regs);
-#endif
-
 extern int (*toshibaboards_gen_iack)(void);
 
 #endif /* !__ASSEMBLY__ */
index 810f2fa334446e774c8bde92620ccfacc25a41bf..9f29520e8fb0a2514f79a2cf5e34f54c78d4ce7e 100644 (file)
@@ -123,8 +123,7 @@ struct dma_chan {
 extern struct dma_chan au1000_dma_table[];
 extern int request_au1000_dma(int dev_id,
                              const char *dev_str,
-                             irqreturn_t (*irqhandler)(int, void *,
-                                                struct pt_regs *),
+                             irq_handler_t irqhandler,
                              unsigned long irqflags,
                              void *irq_dev_id);
 extern void free_au1000_dma(unsigned int dmanr);
diff --git a/include/asm-mips/mach-au1x00/au1000_usbdev.h b/include/asm-mips/mach-au1x00/au1000_usbdev.h
deleted file mode 100644 (file)
index 05bc74b..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * BRIEF MODULE DESCRIPTION
- *     Au1000 USB Device-Side Driver
- *
- * Copyright 2001 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *             stevel@mvista.com or source@mvista.com
- *
- *  This program is free software; you can redistribute         it and/or modify it
- *  under  the terms of         the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the License, or (at your
- *  option) any later version.
- *
- *  THIS  SOFTWARE  IS PROVIDED          ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,          INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED          TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA, OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN         CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  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.
- */
-
-#define USBDEV_REV 0x0110 // BCD
-#define USBDEV_EP0_MAX_PACKET_SIZE 64
-
-typedef enum {
-       ATTACHED = 0,
-       POWERED,
-       DEFAULT,
-       ADDRESS,
-       CONFIGURED
-} usbdev_state_t;
-
-typedef enum {
-       CB_NEW_STATE = 0,
-       CB_PKT_COMPLETE
-} usbdev_cb_type_t;
-
-
-typedef struct usbdev_pkt {
-       int                ep_addr;    // ep addr this packet routed to
-       int                size;       // size of payload in bytes
-       unsigned           status;     // packet status
-       struct usbdev_pkt* next;       // function layer can't touch this
-       u8                 payload[0]; // the payload
-} usbdev_pkt_t;
-
-#define PKT_STATUS_ACK  (1<<0)
-#define PKT_STATUS_NAK  (1<<1)
-#define PKT_STATUS_SU   (1<<2)
-
-extern int usbdev_init(struct usb_device_descriptor* dev_desc,
-                      struct usb_config_descriptor* config_desc,
-                      struct usb_interface_descriptor* if_desc,
-                      struct usb_endpoint_descriptor* ep_desc,
-                      struct usb_string_descriptor* str_desc[],
-                      void (*cb)(usbdev_cb_type_t, unsigned long, void *),
-                      void* cb_data);
-
-extern void usbdev_exit(void);
-
-extern int usbdev_alloc_packet  (int ep_addr, int data_size,
-                                usbdev_pkt_t** pkt);
-extern int usbdev_send_packet   (int ep_addr, usbdev_pkt_t* pkt);
-extern int usbdev_receive_packet(int ep_addr, usbdev_pkt_t** pkt);
-extern int usbdev_get_byte_count(int ep_addr);
index 6bb2125bb0538b1a8d148d4df9462ae3ab8e89c9..df94955b098aa03ea7b5c8825ca65f5b64ab9ace 100644 (file)
@@ -53,6 +53,6 @@ struct mv_pci_controller {
        unsigned long   config_vreg;
 };
 
-extern void ll_mv64340_irq(struct pt_regs *regs);
+extern void ll_mv64340_irq(void);
 
 #endif /* __ASM_MIPS_MARVELL_H */
index 64f17208d6026003e5719cf935b7259fc580dc28..aa7ad9a71762e2a62ba0f44dd055f9430676bcd3 100644 (file)
@@ -145,7 +145,7 @@ typedef struct msc_irqmap {
 #define MSC01_IRQ_EDGE         1
 
 extern void __init init_msc_irqs(unsigned int base, msc_irqmap_t *imp, int nirq);
-extern void ll_msc_irq(struct pt_regs *regs);
+extern void ll_msc_irq(void);
 
 #endif /* __ASM_MIPS_BOARDS_MSC01_IC_H */
 
index 158a4cd12e460a0dfb7a4a5ee56fc25ee28008f2..1fae5dc581381cd4de2b1022023a53c1acf6647a 100644 (file)
                .endm
 
 #ifdef CONFIG_SMP
-               .macro  get_saved_sp    /* SMP variation */
-#ifdef CONFIG_32BIT
 #ifdef CONFIG_MIPS_MT_SMTC
-               .set    mips32
-               mfc0    k0, CP0_TCBIND;
-               .set    mips0
-               lui     k1, %hi(kernelsp)
-               srl     k0, k0, 19
-               /* No need to shift down and up to clear bits 0-1 */
+#define PTEBASE_SHIFT  19      /* TCBIND */
 #else
-               mfc0    k0, CP0_CONTEXT
-               lui     k1, %hi(kernelsp)
-               srl     k0, k0, 23
-#endif
-               addu    k1, k0
-               LONG_L  k1, %lo(kernelsp)(k1)
+#define PTEBASE_SHIFT  23      /* CONTEXT */
 #endif
-#ifdef CONFIG_64BIT
+               .macro  get_saved_sp    /* SMP variation */
 #ifdef CONFIG_MIPS_MT_SMTC
-               .set    mips64
-               mfc0    k0, CP0_TCBIND;
-               .set    mips0
-               lui     k0, %highest(kernelsp)
-               dsrl    k1, 19
-               /* No need to shift down and up to clear bits 0-2 */
+               mfc0    k0, CP0_TCBIND
 #else
-               MFC0    k1, CP0_CONTEXT
-               lui     k0, %highest(kernelsp)
-               dsrl    k1, 23
-               daddiu  k0, %higher(kernelsp)
-               dsll    k0, k0, 16
-               daddiu  k0, %hi(kernelsp)
-               dsll    k0, k0, 16
-#endif /* CONFIG_MIPS_MT_SMTC */
-               daddu   k1, k1, k0
+               MFC0    k0, CP0_CONTEXT
+#endif
+#if defined(CONFIG_BUILD_ELF64) || (defined(CONFIG_64BIT) && __GNUC__ < 4)
+               lui     k1, %highest(kernelsp)
+               daddiu  k1, %higher(kernelsp)
+               dsll    k1, 16
+               daddiu  k1, %hi(kernelsp)
+               dsll    k1, 16
+#else
+               lui     k1, %hi(kernelsp)
+#endif
+               LONG_SRL        k0, PTEBASE_SHIFT
+               LONG_ADDU       k1, k0
                LONG_L  k1, %lo(kernelsp)(k1)
-#endif /* CONFIG_64BIT */
                .endm
 
                .macro  set_saved_sp stackp temp temp2
-#ifdef CONFIG_32BIT
-#ifdef CONFIG_MIPS_MT_SMTC
-               mfc0    \temp, CP0_TCBIND
-               srl     \temp, 19
-#else
-               mfc0    \temp, CP0_CONTEXT
-               srl     \temp, 23
-#endif
-#endif
-#ifdef CONFIG_64BIT
 #ifdef CONFIG_MIPS_MT_SMTC
                mfc0    \temp, CP0_TCBIND
-               dsrl    \temp, 19
 #else
                MFC0    \temp, CP0_CONTEXT
-               dsrl    \temp, 23
-#endif
 #endif
+               LONG_SRL        \temp, PTEBASE_SHIFT
                LONG_S  \stackp, kernelsp(\temp)
                .endm
 #else
                .macro  get_saved_sp    /* Uniprocessor variation */
-#ifdef CONFIG_64BIT
+#if defined(CONFIG_BUILD_ELF64) || (defined(CONFIG_64BIT) && __GNUC__ < 4)
                lui     k1, %highest(kernelsp)
                daddiu  k1, %higher(kernelsp)
                dsll    k1, k1, 16
index fa6d04dac56bfc958273bbdde28a9e0bd4d28072..b62ec7c521cc3807793aa552e41fc0a20591c6ba 100644 (file)
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1995, 1996, 1999, 2001 Ralf Baechle
+ * Copyright (C) 1995, 96, 99, 2001, 06 Ralf Baechle
  * Copyright (C) 1999 Silicon Graphics, Inc.
  * Copyright (C) 2001 MIPS Technologies, Inc.
  */
 #include <linux/posix_types.h>
 
 typedef unsigned char cc_t;
-#if (_MIPS_SZLONG == 32)
-typedef unsigned long speed_t;
-typedef unsigned long tcflag_t;
-#endif
-#if (_MIPS_SZLONG == 64)
-typedef __u32 speed_t;
-typedef __u32 tcflag_t;
-#endif
+typedef unsigned int speed_t;
+typedef unsigned int tcflag_t;
 
 /*
  * The ABI says nothing about NCC but seems to use NCCS as
index ae8ada5b42a9e7bf58d8aca7071340b2058184cb..e475c45ea263e57d34409137429bb63f982d9e83 100644 (file)
@@ -34,6 +34,7 @@ struct thread_info {
                                                   0-0xFFFFFFFF for kernel-thread
                                                */
        struct restart_block    restart_block;
+       struct pt_regs          *regs;
 };
 
 /*
index 2d543735668b9b80bb29a80d5e1f3a2514739e86..28512ba2266e6f388c8db4450646de6c64dc9d29 100644 (file)
@@ -67,18 +67,18 @@ extern unsigned long (*do_gettimeoffset)(void);
 /*
  * high-level timer interrupt routines.
  */
-extern irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+extern irqreturn_t timer_interrupt(int irq, void *dev_id);
 
 /*
  * the corresponding low-level timer interrupt routine.
  */
-extern asmlinkage void ll_timer_interrupt(int irq, struct pt_regs *regs);
+extern asmlinkage void ll_timer_interrupt(int irq);
 
 /*
  * profiling and process accouting is done separately in local_timer_interrupt
  */
-extern void local_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-extern asmlinkage void ll_local_timer_interrupt(int irq, struct pt_regs *regs);
+extern void local_timer_interrupt(int irq, void *dev_id);
+extern asmlinkage void ll_local_timer_interrupt(int irq);
 
 /*
  * board specific routines required by time_init().
index 685c91467e6347527567f5aa78198226ea236514..30240a445dbbf3ff72f0d54ed6f6b1904f2eb330 100644 (file)
 #define __NR_move_pages                        (__NR_Linux + 308)
 #define __NR_set_robust_list           (__NR_Linux + 309)
 #define __NR_get_robust_list           (__NR_Linux + 310)
+#define __NR_kexec_load                        (__NR_Linux + 311)
 
 /*
  * Offset of the last Linux o32 flavoured syscall
  */
-#define __NR_Linux_syscalls            310
+#define __NR_Linux_syscalls            311
 
 #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
 
 #define __NR_O32_Linux                 4000
-#define __NR_O32_Linux_syscalls                310
+#define __NR_O32_Linux_syscalls                311
 
 #if _MIPS_SIM == _MIPS_SIM_ABI64
 
 #define __NR_move_pages                        (__NR_Linux + 267)
 #define __NR_set_robust_list           (__NR_Linux + 268)
 #define __NR_get_robust_list           (__NR_Linux + 269)
+#define __NR_kexec_load                        (__NR_Linux + 270)
 
 /*
  * Offset of the last Linux 64-bit flavoured syscall
  */
-#define __NR_Linux_syscalls            269
+#define __NR_Linux_syscalls            270
 
 #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */
 
 #define __NR_64_Linux                  5000
-#define __NR_64_Linux_syscalls         269
+#define __NR_64_Linux_syscalls         270
 
 #if _MIPS_SIM == _MIPS_SIM_NABI32
 
 #define __NR_move_pages                        (__NR_Linux + 271)
 #define __NR_set_robust_list           (__NR_Linux + 272)
 #define __NR_get_robust_list           (__NR_Linux + 273)
+#define __NR_kexec_load                        (__NR_Linux + 274)
 
 /*
  * Offset of the last N32 flavoured syscall
  */
-#define __NR_Linux_syscalls            273
+#define __NR_Linux_syscalls            274
 
 #endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */
 
 #define __NR_N32_Linux                 6000
-#define __NR_N32_Linux_syscalls                273
+#define __NR_N32_Linux_syscalls                274
 
 #ifdef __KERNEL__
 
index dd3eb3dc5886691f73376a314df85369046c9484..88b492f6ea9c4481e791bcf2c03f6f163d936e6d 100644 (file)
@@ -75,7 +75,7 @@ extern void vr41xx_mask_clock(vr41xx_clock_t clock);
  * Interrupt Control Unit
  */
 extern int vr41xx_set_intassign(unsigned int irq, unsigned char intassign);
-extern int cascade_irq(unsigned int irq, int (*get_irq)(unsigned int, struct pt_regs *));
+extern int cascade_irq(unsigned int irq, int (*get_irq)(unsigned int));
 
 #define PIUINT_COMMAND         0x0040
 #define PIUINT_DATA            0x0020
diff --git a/include/asm-parisc/irq_regs.h b/include/asm-parisc/irq_regs.h
new file mode 100644 (file)
index 0000000..3dd9c0b
--- /dev/null
@@ -0,0 +1 @@
+#include <asm-generic/irq_regs.h>
index c9b2e35326eed89eba875cd506262fdd485b21f4..423c2b84b4a02360fa49d43b5c5376fcfb46d9bd 100644 (file)
@@ -774,8 +774,6 @@ int pdc_sti_call(unsigned long func, unsigned long flags,
                  unsigned long inptr, unsigned long outputr,
                  unsigned long glob_cfg);
 
-extern void pdc_init(void);
-
 static inline char * os_id_to_string(u16 os_id) {
        switch(os_id) {
        case OS_ID_NONE:        return "No OS";
index c80e113052cd3a3da7b3f0d1f065898de6428b78..78489fb8d140f4465bd9594906efe15f47ea3ffc 100644 (file)
@@ -6,10 +6,10 @@
 
 #ifdef CONFIG_PPC_MERGE
 extern void i8259_init(struct device_node *node, unsigned long intack_addr);
-extern unsigned int i8259_irq(struct pt_regs *regs);
+extern unsigned int i8259_irq(void);
 #else
 extern void i8259_init(unsigned long intack_addr, int offset);
-extern int i8259_irq(struct pt_regs *regs);
+extern int i8259_irq(void);
 #endif
 
 #endif /* __KERNEL__ */
index 7ab195a27888535f8a4fb1edf603fb2b0af70024..3493429b70f5a577ab933cd3060f135157ad7f36 100644 (file)
@@ -65,7 +65,7 @@ void ibmebus_unregister_driver(struct ibmebus_driver *drv);
 
 int ibmebus_request_irq(struct ibmebus_dev *dev,
                        u32 ist, 
-                       irqreturn_t (*handler)(int, void*, struct pt_regs *),
+                       irq_handler_t handler,
                        unsigned long irq_flags, const char * devname,
                        void *dev_id);
 void ibmebus_free_irq(struct ibmebus_dev *dev, u32 ist, void *dev_id);
index cbbd8c648df1341120e825b29c9d33a9763d234b..3baff8b0fd5add68cb7dfde5e1324ac182a7801e 100644 (file)
@@ -404,32 +404,6 @@ static inline void __out_be64(volatile unsigned long __iomem *addr, unsigned lon
 
 #include <asm/eeh.h>
 
-/**
- *     check_signature         -       find BIOS signatures
- *     @io_addr: mmio address to check
- *     @signature:  signature block
- *     @length: length of signature
- *
- *     Perform a signature comparison with the mmio address io_addr. This
- *     address should have been obtained by ioremap.
- *     Returns 1 on a match.
- */
-static inline int check_signature(const volatile void __iomem * io_addr,
-       const unsigned char *signature, int length)
-{
-       int retval = 0;
-       do {
-               if (readb(io_addr) != *signature)
-                       goto out;
-               io_addr++;
-               signature++;
-               length--;
-       } while (length);
-       retval = 1;
-out:
-       return retval;
-}
-
 /* Nothing to do */
 
 #define dma_cache_inv(_start,_size)            do { } while (0)
index 1ce09a35906efd695a1d3cbbb07058eed915a6d1..9fbb034158608d2eb67397d1299ccd6df816f4c8 100644 (file)
@@ -79,12 +79,12 @@ extern void ipic_clear_mcp_status(u32 mask);
 
 #ifdef CONFIG_PPC_MERGE
 extern void ipic_init(struct device_node *node, unsigned int flags);
-extern unsigned int ipic_get_irq(struct pt_regs *regs);
+extern unsigned int ipic_get_irq(void);
 #else
 extern void ipic_init(phys_addr_t phys_addr, unsigned int flags,
                unsigned int irq_offset,
                unsigned char *senses, unsigned int senses_count);
-extern int ipic_get_irq(struct pt_regs *regs);
+extern int ipic_get_irq(void);
 #endif
 
 #endif /* __ASM_IPIC_H__ */
index 89ed545b446b3ff0cf24b2ac511a8fe566a816c1..f960f5346f406d717590d337de07c6a0d9cbb384 100644 (file)
@@ -825,7 +825,7 @@ extern struct thread_info *softirq_ctx[NR_CPUS];
 
 extern void irq_ctx_init(void);
 extern void call_do_softirq(struct thread_info *tp);
-extern int call_handle_irq(int irq, void *p1, void *p2,
+extern int call_handle_irq(int irq, void *p1,
                           struct thread_info *tp, void *func);
 #else
 #define irq_ctx_init()
diff --git a/include/asm-powerpc/irq_regs.h b/include/asm-powerpc/irq_regs.h
new file mode 100644 (file)
index 0000000..ba94b51
--- /dev/null
@@ -0,0 +1,2 @@
+#include <asm-generic/irq_regs.h>
+
index 4065a4de4935f8ec86e19079dab71538542f53cf..6ce2ce1e26909a0bc80bf84c772d6cc5338c4b77 100644 (file)
@@ -50,7 +50,7 @@ struct HvLpEvent {
        u64     xCorrelationToken;      /* Unique value for source/type x10-x17 */
 };
 
-typedef void (*LpEventHandler)(struct HvLpEvent *, struct pt_regs *);
+typedef void (*LpEventHandler)(struct HvLpEvent *);
 
 /* Register a handler for an event type - returns 0 on success */
 extern int HvLpEvent_registerHandler(HvLpEvent_Type eventType,
index 3f681476929594b354562d0b27aefeadf8967e5b..428278838821837929ec9764c18afefcf8499242 100644 (file)
@@ -72,7 +72,7 @@ struct hvlpevent_queue {
 extern struct hvlpevent_queue hvlpevent_queue;
 
 extern int hvlpevent_is_pending(void);
-extern void process_hvlpevents(struct pt_regs *);
+extern void process_hvlpevents(void);
 extern void setup_hvlpevent_queue(void);
 
 #endif /* _ASM_POWERPC_ISERIES_IT_LP_QUEUE_H */
index c17c1374240114bc4f0f9a211c03a9d366279bea..dac90dc341cb06cadac12c6787f86276f974f2fc 100644 (file)
@@ -97,7 +97,7 @@ struct machdep_calls {
        void            (*show_percpuinfo)(struct seq_file *m, int i);
 
        void            (*init_IRQ)(void);
-       unsigned int    (*get_irq)(struct pt_regs *);
+       unsigned int    (*get_irq)(void);
 #ifdef CONFIG_KEXEC
        void            (*kexec_cpu_down)(int crash_shutdown, int secondary);
 #endif
index a9f9604b9eff02c914405a9179832a9c61d38373..ef0a5458d2b23d959c19f70ce1aff109b2eead93 100644 (file)
@@ -409,9 +409,9 @@ extern void mpic_send_ipi(unsigned int ipi_no, unsigned int cpu_mask);
 void smp_mpic_message_pass(int target, int msg);
 
 /* Fetch interrupt from a given mpic */
-extern unsigned int mpic_get_one_irq(struct mpic *mpic, struct pt_regs *regs);
+extern unsigned int mpic_get_one_irq(struct mpic *mpic);
 /* This one gets to the primary mpic */
-extern unsigned int mpic_get_irq(struct pt_regs *regs);
+extern unsigned int mpic_get_irq(void);
 
 /* Set the EPIC clock ratio */
 void mpic_set_clk_ratio(struct mpic *mpic, u32 clock_ratio);
index 3a9fcc15811b44dff427a5b9fcbf52d48f18b4c8..8fb96811b55de74efe6ec468e619dc1e8a2a0ae4 100644 (file)
 
 /*
  * An mtfsf instruction with the L bit set. On CPUs that support this a
- * full 64bits of FPSCR is restored and on other CPUs it is ignored.
+ * full 64bits of FPSCR is restored and on other CPUs the L bit is ignored.
  *
  * Until binutils gets the new form of mtfsf, hardwire the instruction.
  */
index 068f119aa298fd7fb8d5f35f4e8ab8a2b3b34a0a..20ea7c70bc38105a77cefdf8c61c4e508f69271b 100644 (file)
@@ -34,8 +34,7 @@ extern void cpu_die(void);
 #ifdef CONFIG_SMP
 
 extern void smp_send_debugger_break(int cpu);
-struct pt_regs;
-extern void smp_message_recv(int, struct pt_regs *);
+extern void smp_message_recv(int);
 
 #ifdef CONFIG_HOTPLUG_CPU
 extern void fixup_irqs(cpumask_t map);
index b42b53c40f5dcba86568723aefa0c7a019688666..e73ea00efd8b2ea7917a9820edbd94225b695cb6 100644 (file)
@@ -138,6 +138,7 @@ struct spu {
        void (* ibox_callback)(struct spu *spu);
        void (* stop_callback)(struct spu *spu);
        void (* mfc_callback)(struct spu *spu);
+       void (* dma_callback)(struct spu *spu, int type);
 
        char irq_c0[8];
        char irq_c1[8];
@@ -147,6 +148,7 @@ struct spu {
 };
 
 struct spu *spu_alloc(void);
+struct spu *spu_alloc_node(int node);
 void spu_free(struct spu *spu);
 int spu_irq_class_0_bottom(struct spu *spu);
 int spu_irq_class_1_bottom(struct spu *spu);
@@ -168,6 +170,22 @@ extern struct spufs_calls {
        struct module *owner;
 } spufs_calls;
 
+/* return status from spu_run, same as in libspe */
+#define SPE_EVENT_DMA_ALIGNMENT                0x0008  /*A DMA alignment error */
+#define SPE_EVENT_SPE_ERROR            0x0010  /*An illegal instruction error*/
+#define SPE_EVENT_SPE_DATA_SEGMENT     0x0020  /*A DMA segmentation error    */
+#define SPE_EVENT_SPE_DATA_STORAGE     0x0040  /*A DMA storage error */
+#define SPE_EVENT_INVALID_DMA          0x0800  /* Invalid MFC DMA */
+
+/*
+ * Flags for sys_spu_create.
+ */
+#define SPU_CREATE_EVENTS_ENABLED      0x0001
+#define SPU_CREATE_GANG                        0x0002
+
+#define SPU_CREATE_FLAG_ALL            0x0003 /* mask of all valid flags */
+
+
 #ifdef CONFIG_SPU_FS_MODULE
 int register_spu_syscalls(struct spufs_calls *calls);
 void unregister_spu_syscalls(struct spufs_calls *calls);
@@ -182,6 +200,24 @@ static inline void unregister_spu_syscalls(struct spufs_calls *calls)
 #endif /* MODULE */
 
 
+/*
+ * Notifier blocks:
+ *
+ * oprofile can get notified when a context switch is performed
+ * on an spe. The notifer function that gets called is passed
+ * a pointer to the SPU structure as well as the object-id that
+ * identifies the binary running on that SPU now.
+ *
+ * For a context save, the object-id that is passed is zero,
+ * identifying that the kernel will run from that moment on.
+ *
+ * For a context restore, the object-id is the value written
+ * to object-id spufs file from user space and the notifer
+ * function can assume that spu->ctx is valid.
+ */
+int spu_switch_event_register(struct notifier_block * n);
+int spu_switch_event_unregister(struct notifier_block * n);
+
 /*
  * This defines the Local Store, Problem Area and Privlege Area of an SPU.
  */
index 3247bea5fc2b18d377953351eaedd368bb95a6cd..7b06b4e6bf30d3fe267834130a9f6ee02d9d0b01 100644 (file)
@@ -690,8 +690,7 @@ typedef struct risc_timer_pram {
 #define CICR_IEN               ((uint)0x00000080)      /* Int. enable */
 #define CICR_SPS               ((uint)0x00000001)      /* SCC Spread */
 
-extern void cpm_install_handler(int vec,
-               void (*handler)(void *, struct pt_regs *regs), void *dev_id);
+extern void cpm_install_handler(int vec, void (*handler)(void *), void *dev_id);
 extern void cpm_free_handler(int vec);
 
 #endif /* __CPM_8XX__ */
index d3963ca79ad88a76c358a86c2a13c92969a977f6..ae316e6d2ca99650cd42eb57ae9903f3c3672c4c 100644 (file)
@@ -38,14 +38,14 @@ static int virtual_dma_mode;
 static int doing_vdma;
 static struct fd_dma_ops *fd_ops;
 
-static irqreturn_t floppy_hardint(int irq, void *dev_id, struct pt_regs * regs)
+static irqreturn_t floppy_hardint(int irq, void *dev_id)
 {
        unsigned char st;
        int lcount;
        char *lptr;
 
        if (!doing_vdma)
-               return floppy_interrupt(irq, dev_id, regs);
+               return floppy_interrupt(irq, dev_id);
 
 
        st = 1;
@@ -69,7 +69,7 @@ static irqreturn_t floppy_hardint(int irq, void *dev_id, struct pt_regs * regs)
                virtual_dma_residue += virtual_dma_count;
                virtual_dma_count=0;
                doing_vdma = 0;
-               floppy_interrupt(irq, dev_id, regs);
+               floppy_interrupt(irq, dev_id);
                return IRQ_HANDLED;
        }
        return IRQ_HANDLED;
index cd0ef644943dbbe1a42cce78cc373725b2319ade..9e63b3cfffcaed093aed44293a59ec304347e24a 100644 (file)
@@ -315,7 +315,7 @@ int gt64260_get_base(u32 *base);
 int gt64260_pci_exclude_device(u8 bus, u8 devfn);
 
 void gt64260_init_irq(void);
-int gt64260_get_irq(struct pt_regs *regs);
+int gt64260_get_irq(void);
 
 void gt64260_mpsc_progress(char *s, unsigned short hex);
 
index 3d9a9e6f33217b10c63e5dacf4171703e1261562..a4c411b753efe945416a3b6e12d9725b8eb35c42 100644 (file)
@@ -439,22 +439,6 @@ extern inline void * phys_to_virt(unsigned long address)
 #define iobarrier_r()  eieio()
 #define iobarrier_w()  eieio()
 
-static inline int check_signature(volatile void __iomem * io_addr,
-       const unsigned char *signature, int length)
-{
-       int retval = 0;
-       do {
-               if (readb(io_addr) != *signature)
-                       goto out;
-               io_addr++;
-               signature++;
-               length--;
-       } while (length);
-       retval = 1;
-out:
-       return retval;
-}
-
 /*
  * Here comes the ppc implementation of the IOMAP 
  * interfaces.
index da7746738aee723ad331a7bb20b796a337894307..293a444a1d7724d057528655336f6e96a2a943cd 100644 (file)
@@ -43,7 +43,7 @@ struct machdep_calls {
        /* Optional, may be NULL. */
        unsigned int    (*irq_canonicalize)(unsigned int irq);
        void            (*init_IRQ)(void);
-       int             (*get_irq)(struct pt_regs *);
+       int             (*get_irq)(void);
        
        /* A general init function, called by ppc_init in init/main.c.
           May be NULL. DEPRECATED ! */
index 7e9842805a282628a5ec0131cfaf2d726e6889ff..64c8874618dc01c422f9edd0c0462bae3299f49b 100644 (file)
@@ -415,7 +415,7 @@ struct mpc52xx_cdm {
 #ifndef __ASSEMBLY__
 
 extern void mpc52xx_init_irq(void);
-extern int mpc52xx_get_irq(struct pt_regs *regs);
+extern int mpc52xx_get_irq(void);
 
 extern unsigned long mpc52xx_find_end_of_memory(void);
 extern void mpc52xx_set_bat(void);
index 663edbee3e910206f369383c8d339e9219a94dff..db3776f181989c65df08b11584f29a45b365ee25 100644 (file)
@@ -336,9 +336,9 @@ int mv64x60_pci_exclude_device(u8 bus, u8 devfn);
 
 
 void gt64260_init_irq(void);
-int gt64260_get_irq(struct pt_regs *regs);
+int gt64260_get_irq(void);
 void mv64360_init_irq(void);
-int mv64360_get_irq(struct pt_regs *regs);
+int mv64360_get_irq(void);
 
 u32 mv64x60_mask(u32 val, u32 num_bits);
 u32 mv64x60_shift_left(u32 val, u32 num_bits);
index a4fe962d9f7301a242393160323945d06bf38524..778d5726212cdbb061751f7ba3d2545be022d361 100644 (file)
@@ -48,12 +48,12 @@ extern void openpic_init(int linux_irq_offset);
 extern void openpic_init_nmi_irq(u_int irq);
 extern void openpic_set_irq_priority(u_int irq, u_int pri);
 extern void openpic_hookup_cascade(u_int irq, char *name,
-                                  int (*cascade_fn)(struct pt_regs *));
+                                  int (*cascade_fn)(void));
 extern u_int openpic_irq(void);
 extern void openpic_eoi(void);
 extern void openpic_request_IPIs(void);
 extern void do_openpic_setup_cpu(void);
-extern int openpic_get_irq(struct pt_regs *regs);
+extern int openpic_get_irq(void);
 extern void openpic_reset_processor_phys(u_int cpumask);
 extern void openpic_setup_ISU(int isu_num, unsigned long addr);
 extern void openpic_cause_IPI(u_int ipi, cpumask_t cpumask);
@@ -93,6 +93,6 @@ extern void openpic2_init(int linux_irq_offset);
 extern void openpic2_init_nmi_irq(u_int irq);
 extern u_int openpic2_irq(void);
 extern void openpic2_eoi(void);
-extern int openpic2_get_irq(struct pt_regs *regs);
+extern int openpic2_get_irq(void);
 extern void openpic2_setup_ISU(int isu_num, unsigned long addr);
 #endif /* _PPC_KERNEL_OPEN_PIC_H */
index 0b7fa89589df5db61bf429c2c528858eff29683c..e75791ea33a621ed96e9dbbb6bd49f664f99b2e5 100644 (file)
@@ -39,7 +39,7 @@ extern struct smp_ops_t *smp_ops;
 extern void smp_send_tlb_invalidate(int);
 extern void smp_send_xmon_break(int cpu);
 struct pt_regs;
-extern void smp_message_recv(int, struct pt_regs *);
+extern void smp_message_recv(int);
 
 extern int __cpu_disable(void);
 extern void __cpu_die(unsigned int cpu);
index da063cd5f0a006cbb5568d5d0261cbd931cdc446..81287d86329d0be4e44e491b0e059b2983422765 100644 (file)
@@ -275,6 +275,12 @@ struct ccw_dev_id {
        u16 devno;
 };
 
+static inline int ccw_dev_id_is_equal(struct ccw_dev_id *dev_id1,
+                                     struct ccw_dev_id *dev_id2)
+{
+       return !memcmp(dev_id1, dev_id2, sizeof(struct ccw_dev_id));
+}
+
 extern int diag210(struct diag210 *addr);
 
 extern void wait_cons_dev(void);
index e84b7ef54aac614d968883ca8c8c459b8f67c8ed..c2f6a8782d31b5a901b3e5e8d7dc7dc9ecbad3aa 100644 (file)
@@ -32,6 +32,6 @@ typedef struct {
 
 #define HARDIRQ_BITS   8
 
-extern void account_ticks(struct pt_regs *);
+extern void account_ticks(void);
 
 #endif /* __ASM_HARDIRQ_H */
diff --git a/include/asm-s390/irq_regs.h b/include/asm-s390/irq_regs.h
new file mode 100644 (file)
index 0000000..3dd9c0b
--- /dev/null
@@ -0,0 +1 @@
+#include <asm-generic/irq_regs.h>
index 495ad99c76351c005ed6f95977902b4c2ea4f53f..9ea7f1023e578c0ff0a4eff47e77c5028d7e171b 100644 (file)
@@ -16,7 +16,7 @@
 #if defined(__s390x__) && defined(MODULE)
 
 #define __reloc_hide(var,offset) (*({                  \
-       extern int simple_indentifier_##var(void);      \
+       extern int simple_identifier_##var(void);       \
        unsigned long *__ptr;                           \
        asm ( "larl %0,per_cpu__"#var"@GOTENT"          \
            : "=a" (__ptr) : "X" (per_cpu__##var) );    \
@@ -25,7 +25,7 @@
 #else
 
 #define __reloc_hide(var, offset) (*({                         \
-       extern int simple_indentifier_##var(void);              \
+       extern int simple_identifier_##var(void);               \
        unsigned long __ptr;                                    \
        asm ( "" : "=a" (__ptr) : "0" (&per_cpu__##var) );      \
        (typeof(&per_cpu__##var)) (__ptr + (offset)); }))
index 519f0a5ff18122ab4d4be74fbdeacb4841ab3799..36bb6dacf00840d64836adbb9405ca77a3bcad7c 100644 (file)
@@ -200,18 +200,45 @@ extern char empty_zero_page[PAGE_SIZE];
  */
 
 /* Hardware bits in the page table entry */
-#define _PAGE_RO        0x200          /* HW read-only                     */
-#define _PAGE_INVALID   0x400          /* HW invalid                       */
+#define _PAGE_RO       0x200           /* HW read-only bit  */
+#define _PAGE_INVALID  0x400           /* HW invalid bit    */
+#define _PAGE_SWT      0x001           /* SW pte type bit t */
+#define _PAGE_SWX      0x002           /* SW pte type bit x */
 
-/* Mask and six different types of pages. */
-#define _PAGE_TYPE_MASK                0x601
+/* Six different types of pages. */
 #define _PAGE_TYPE_EMPTY       0x400
 #define _PAGE_TYPE_NONE                0x401
-#define _PAGE_TYPE_SWAP                0x600
-#define _PAGE_TYPE_FILE                0x601
+#define _PAGE_TYPE_SWAP                0x403
+#define _PAGE_TYPE_FILE                0x601   /* bit 0x002 is used for offset !! */
 #define _PAGE_TYPE_RO          0x200
 #define _PAGE_TYPE_RW          0x000
 
+/*
+ * PTE type bits are rather complicated. handle_pte_fault uses pte_present,
+ * pte_none and pte_file to find out the pte type WITHOUT holding the page
+ * table lock. ptep_clear_flush on the other hand uses ptep_clear_flush to
+ * invalidate a given pte. ipte sets the hw invalid bit and clears all tlbs
+ * for the page. The page table entry is set to _PAGE_TYPE_EMPTY afterwards.
+ * This change is done while holding the lock, but the intermediate step
+ * of a previously valid pte with the hw invalid bit set can be observed by
+ * handle_pte_fault. That makes it necessary that all valid pte types with
+ * the hw invalid bit set must be distinguishable from the four pte types
+ * empty, none, swap and file.
+ *
+ *                     irxt  ipte  irxt
+ * _PAGE_TYPE_EMPTY    1000   ->   1000
+ * _PAGE_TYPE_NONE     1001   ->   1001
+ * _PAGE_TYPE_SWAP     1011   ->   1011
+ * _PAGE_TYPE_FILE     11?1   ->   11?1
+ * _PAGE_TYPE_RO       0100   ->   1100
+ * _PAGE_TYPE_RW       0000   ->   1000
+ *
+ * pte_none is true for bits combinations 1000, 1100
+ * pte_present is true for bits combinations 0000, 0010, 0100, 0110, 1001
+ * pte_file is true for bits combinations 1101, 1111
+ * swap pte is 1011 and 0001, 0011, 0101, 0111, 1010 and 1110 are invalid.
+ */
+
 #ifndef __s390x__
 
 /* Bits in the segment table entry */
@@ -365,18 +392,21 @@ static inline int pmd_bad(pmd_t pmd)
 
 static inline int pte_none(pte_t pte)
 {
-       return (pte_val(pte) & _PAGE_TYPE_MASK) == _PAGE_TYPE_EMPTY;
+       return (pte_val(pte) & _PAGE_INVALID) && !(pte_val(pte) & _PAGE_SWT);
 }
 
 static inline int pte_present(pte_t pte)
 {
-       return !(pte_val(pte) & _PAGE_INVALID) ||
-               (pte_val(pte) & _PAGE_TYPE_MASK) == _PAGE_TYPE_NONE;
+       unsigned long mask = _PAGE_RO | _PAGE_INVALID | _PAGE_SWT | _PAGE_SWX;
+       return (pte_val(pte) & mask) == _PAGE_TYPE_NONE ||
+               (!(pte_val(pte) & _PAGE_INVALID) &&
+                !(pte_val(pte) & _PAGE_SWT));
 }
 
 static inline int pte_file(pte_t pte)
 {
-       return (pte_val(pte) & _PAGE_TYPE_MASK) == _PAGE_TYPE_FILE;
+       unsigned long mask = _PAGE_RO | _PAGE_INVALID | _PAGE_SWT;
+       return (pte_val(pte) & mask) == _PAGE_TYPE_FILE;
 }
 
 #define pte_same(a,b)  (pte_val(a) == pte_val(b))
index e9a2862b230d1b9143470c7d51f1546a804bad6d..df9b1017b703a6ff9693212f3b170392ce164191 100644 (file)
@@ -10,7 +10,7 @@
  *               Martin Schwidefsky (schwidefsky@de.ibm.com)
  */
 
-typedef void (*ext_int_handler_t)(struct pt_regs *regs, __u16 code);
+typedef void (*ext_int_handler_t)(__u16 code);
 
 /*
  * Warning: if you change ext_int_info_t you have to change the
index fcd6c256a2d194aa4b1269f89cfc25fabb8c96a6..30e5cbe570f2db3d29f73e282a6ef10bd57b4063 100644 (file)
@@ -26,7 +26,7 @@ struct vtimer_list {
        spinlock_t lock;
        unsigned long magic;
 
-       void (*function)(unsigned long, struct pt_regs*);
+       void (*function)(unsigned long);
        unsigned long data;
 };
 
index a19238cbcffa7ed1aacbfcd9e06bbe141425e783..71d3c21b84f0a4169202680053c3f51cb028ec74 100644 (file)
 #define __NR_vmsplice          309
 /* Number 310 is reserved for new sys_move_pages */
 #define __NR_getcpu            311
+#define __NR_epoll_pwait       312
 
-#define NR_syscalls 312
+#define NR_syscalls 313
 
 /* 
  * There are some system calls that are not present on 64 bit, some
index 3d0943167659104ba5f8149c4dfbfa014b8805d5..c86e1705093570e0ec66d5e405b9eff29e3a7b11 100644 (file)
@@ -3,6 +3,7 @@
  *
  * Copyright (C) 1999 Niibe Yutaka
  * Copyright (C) 2003 Paul Mundt
+ * Copyright (C) 2006 Lineo Solutions Inc. support SH4A UBC
  *
  * 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
 #ifndef __ASM_CPU_SH4_UBC_H
 #define __ASM_CPU_SH4_UBC_H
 
+#if defined(CONFIG_CPU_SH4A)
+#define UBC_CBR0               0xff200000
+#define UBC_CRR0               0xff200004
+#define UBC_CAR0               0xff200008
+#define UBC_CAMR0              0xff20000c
+#define UBC_CBR1               0xff200020
+#define UBC_CRR1               0xff200024
+#define UBC_CAR1               0xff200028
+#define UBC_CAMR1              0xff20002c
+#define UBC_CDR1               0xff200030
+#define UBC_CDMR1              0xff200034
+#define UBC_CETR1              0xff200038
+#define UBC_CCMFR              0xff200600
+#define UBC_CBCR               0xff200620
+
+/* CBR */
+#define UBC_CBR_AIE            (0x01<<30)
+#define UBC_CBR_ID_INST                (0x01<<4)
+#define UBC_CBR_RW_READ                (0x01<<1)
+#define UBC_CBR_CE             (0x01)
+
+#define        UBC_CBR_AIV_MASK        (0x00FF0000)
+#define        UBC_CBR_AIV_SHIFT       (16)
+#define UBC_CBR_AIV_SET(asid)  (((asid)<<UBC_CBR_AIV_SHIFT) & UBC_CBR_AIV_MASK)
+
+#define UBC_CBR_INIT           0x20000000
+
+/* CRR */
+#define UBC_CRR_RES            (0x01<<13)
+#define UBC_CRR_PCB            (0x01<<1)
+#define UBC_CRR_BIE            (0x01)
+
+#define UBC_CRR_INIT           0x00002000
+
+#else  /* CONFIG_CPU_SH4 */
 #define UBC_BARA               0xff200000
 #define UBC_BAMRA              0xff200004
 #define UBC_BBRA               0xff200008
@@ -22,6 +58,7 @@
 #define UBC_BDRB               0xff200018
 #define UBC_BDMRB              0xff20001c
 #define UBC_BRCR               0xff200020
+#endif /* CONFIG_CPU_SH4 */
 
 #endif /* __ASM_CPU_SH4_UBC_H */
 
diff --git a/include/asm-sh/edosk7705.h b/include/asm-sh/edosk7705.h
new file mode 100644 (file)
index 0000000..a1089a6
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * include/asm-sh/edosk7705/io.h
+ *
+ * Modified version of io_se.h for the EDOSK7705 specific functions.
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.
+ *
+ * IO functions for an Hitachi EDOSK7705 development board
+ */
+
+#ifndef __ASM_SH_EDOSK7705_IO_H
+#define __ASM_SH_EDOSK7705_IO_H
+
+#include <asm/io_generic.h>
+
+extern unsigned char sh_edosk7705_inb(unsigned long port);
+extern unsigned int sh_edosk7705_inl(unsigned long port);
+
+extern void sh_edosk7705_outb(unsigned char value, unsigned long port);
+extern void sh_edosk7705_outl(unsigned int value, unsigned long port);
+
+extern void sh_edosk7705_insb(unsigned long port, void *addr, unsigned long count);
+extern void sh_edosk7705_insl(unsigned long port, void *addr, unsigned long count);
+extern void sh_edosk7705_outsb(unsigned long port, const void *addr, unsigned long count);
+extern void sh_edosk7705_outsl(unsigned long port, const void *addr, unsigned long count);
+
+extern unsigned long sh_edosk7705_isa_port2addr(unsigned long offset);
+
+#endif /* __ASM_SH_EDOSK7705_IO_H */
diff --git a/include/asm-sh/edosk7705/io.h b/include/asm-sh/edosk7705/io.h
deleted file mode 100644 (file)
index a1089a6..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * include/asm-sh/edosk7705/io.h
- *
- * Modified version of io_se.h for the EDOSK7705 specific functions.
- *
- * May be copied or modified under the terms of the GNU General Public
- * License.  See linux/COPYING for more information.
- *
- * IO functions for an Hitachi EDOSK7705 development board
- */
-
-#ifndef __ASM_SH_EDOSK7705_IO_H
-#define __ASM_SH_EDOSK7705_IO_H
-
-#include <asm/io_generic.h>
-
-extern unsigned char sh_edosk7705_inb(unsigned long port);
-extern unsigned int sh_edosk7705_inl(unsigned long port);
-
-extern void sh_edosk7705_outb(unsigned char value, unsigned long port);
-extern void sh_edosk7705_outl(unsigned int value, unsigned long port);
-
-extern void sh_edosk7705_insb(unsigned long port, void *addr, unsigned long count);
-extern void sh_edosk7705_insl(unsigned long port, void *addr, unsigned long count);
-extern void sh_edosk7705_outsb(unsigned long port, const void *addr, unsigned long count);
-extern void sh_edosk7705_outsl(unsigned long port, const void *addr, unsigned long count);
-
-extern unsigned long sh_edosk7705_isa_port2addr(unsigned long offset);
-
-#endif /* __ASM_SH_EDOSK7705_IO_H */
diff --git a/include/asm-sh/hp6xx.h b/include/asm-sh/hp6xx.h
new file mode 100644 (file)
index 0000000..f35134c
--- /dev/null
@@ -0,0 +1,80 @@
+#ifndef __ASM_SH_HP6XX_H
+#define __ASM_SH_HP6XX_H
+
+/*
+ * Copyright (C) 2003, 2004, 2005  Andriy Skulysh
+ *
+ * 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.
+ *
+ */
+
+#define HP680_BTN_IRQ          IRQ0_IRQ
+#define HP680_TS_IRQ           IRQ3_IRQ
+#define HP680_HD64461_IRQ      IRQ4_IRQ
+
+#define DAC_LCD_BRIGHTNESS     0
+#define DAC_SPEAKER_VOLUME     1
+
+#define PGDR_OPENED            0x01
+#define PGDR_MAIN_BATTERY_OUT  0x04
+#define PGDR_PLAY_BUTTON       0x08
+#define PGDR_REWIND_BUTTON     0x10
+#define PGDR_RECORD_BUTTON     0x20
+
+#define PHDR_TS_PEN_DOWN       0x08
+
+#define PJDR_LED_BLINK         0x02
+
+#define PKDR_LED_GREEN         0x10
+
+#define SCPDR_TS_SCAN_ENABLE   0x20
+#define SCPDR_TS_SCAN_Y                0x02
+#define SCPDR_TS_SCAN_X                0x01
+
+#define SCPCR_TS_ENABLE                0x405
+#define SCPCR_TS_MASK          0xc0f
+
+#define ADC_CHANNEL_TS_Y       1
+#define ADC_CHANNEL_TS_X       2
+#define ADC_CHANNEL_BATTERY    3
+#define ADC_CHANNEL_BACKUP     4
+#define ADC_CHANNEL_CHARGE     5
+
+#define HD64461_GPADR_SPEAKER  0x01
+#define HD64461_GPADR_PCMCIA0  (0x02|0x08)
+
+#define HD64461_GPBDR_LCDOFF   0x01
+#define HD64461_GPBDR_LCD_CONTRAST_MASK        0x78
+#define HD64461_GPBDR_LED_RED  0x80
+
+#include <asm/hd64461.h>
+#include <asm/io.h>
+
+#define PJDR   0xa4000130
+#define PKDR   0xa4000132
+
+static inline void hp6xx_led_red(int on)
+{
+       u16 v16;
+       v16 = ctrl_inw(CONFIG_HD64461_IOBASE + HD64461_GPBDR - 0x10000);
+       if (on)
+           ctrl_outw(v16 & (~HD64461_GPBDR_LED_RED), CONFIG_HD64461_IOBASE + HD64461_GPBDR - 0x10000);
+       else
+           ctrl_outw(v16 | HD64461_GPBDR_LED_RED, CONFIG_HD64461_IOBASE + HD64461_GPBDR - 0x10000);
+}
+
+static inline void hp6xx_led_green(int on)
+{
+       u8 v8;
+
+       v8 = ctrl_inb(PKDR);
+       if (on)
+           ctrl_outb(v8 & (~PKDR_LED_GREEN), PKDR);
+       else
+           ctrl_outb(v8 | PKDR_LED_GREEN, PKDR);
+}
+
+
+#endif /* __ASM_SH_HP6XX_H */
diff --git a/include/asm-sh/hp6xx/hp6xx.h b/include/asm-sh/hp6xx/hp6xx.h
deleted file mode 100644 (file)
index f35134c..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-#ifndef __ASM_SH_HP6XX_H
-#define __ASM_SH_HP6XX_H
-
-/*
- * Copyright (C) 2003, 2004, 2005  Andriy Skulysh
- *
- * 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.
- *
- */
-
-#define HP680_BTN_IRQ          IRQ0_IRQ
-#define HP680_TS_IRQ           IRQ3_IRQ
-#define HP680_HD64461_IRQ      IRQ4_IRQ
-
-#define DAC_LCD_BRIGHTNESS     0
-#define DAC_SPEAKER_VOLUME     1
-
-#define PGDR_OPENED            0x01
-#define PGDR_MAIN_BATTERY_OUT  0x04
-#define PGDR_PLAY_BUTTON       0x08
-#define PGDR_REWIND_BUTTON     0x10
-#define PGDR_RECORD_BUTTON     0x20
-
-#define PHDR_TS_PEN_DOWN       0x08
-
-#define PJDR_LED_BLINK         0x02
-
-#define PKDR_LED_GREEN         0x10
-
-#define SCPDR_TS_SCAN_ENABLE   0x20
-#define SCPDR_TS_SCAN_Y                0x02
-#define SCPDR_TS_SCAN_X                0x01
-
-#define SCPCR_TS_ENABLE                0x405
-#define SCPCR_TS_MASK          0xc0f
-
-#define ADC_CHANNEL_TS_Y       1
-#define ADC_CHANNEL_TS_X       2
-#define ADC_CHANNEL_BATTERY    3
-#define ADC_CHANNEL_BACKUP     4
-#define ADC_CHANNEL_CHARGE     5
-
-#define HD64461_GPADR_SPEAKER  0x01
-#define HD64461_GPADR_PCMCIA0  (0x02|0x08)
-
-#define HD64461_GPBDR_LCDOFF   0x01
-#define HD64461_GPBDR_LCD_CONTRAST_MASK        0x78
-#define HD64461_GPBDR_LED_RED  0x80
-
-#include <asm/hd64461.h>
-#include <asm/io.h>
-
-#define PJDR   0xa4000130
-#define PKDR   0xa4000132
-
-static inline void hp6xx_led_red(int on)
-{
-       u16 v16;
-       v16 = ctrl_inw(CONFIG_HD64461_IOBASE + HD64461_GPBDR - 0x10000);
-       if (on)
-           ctrl_outw(v16 & (~HD64461_GPBDR_LED_RED), CONFIG_HD64461_IOBASE + HD64461_GPBDR - 0x10000);
-       else
-           ctrl_outw(v16 | HD64461_GPBDR_LED_RED, CONFIG_HD64461_IOBASE + HD64461_GPBDR - 0x10000);
-}
-
-static inline void hp6xx_led_green(int on)
-{
-       u8 v8;
-
-       v8 = ctrl_inb(PKDR);
-       if (on)
-           ctrl_outb(v8 & (~PKDR_LED_GREEN), PKDR);
-       else
-           ctrl_outb(v8 | PKDR_LED_GREEN, PKDR);
-}
-
-
-#endif /* __ASM_SH_HP6XX_H */
diff --git a/include/asm-sh/hp6xx/ide.h b/include/asm-sh/hp6xx/ide.h
deleted file mode 100644 (file)
index 570395a..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef __ASM_SH_HP6XX_IDE_H
-#define __ASM_SH_HP6XX_IDE_H
-
-#define IRQ_CFCARD     93
-#define IRQ_PCMCIA     94
-
-#endif /* __ASM_SH_HP6XX_IDE_H */
-
diff --git a/include/asm-sh/hp6xx/io.h b/include/asm-sh/hp6xx/io.h
deleted file mode 100644 (file)
index 2044476..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef __ASM_SH_HP6XX_IO_H
-#define __ASM_SH_HP6XX_IO_H
-
-/*
- * Nothing special here.. just use the generic cchip io routines.
- */
-#include <asm/hd64461.h>
-
-#endif /* __ASM_SH_HP6XX_IO_H */
-
diff --git a/include/asm-sh/hs7751rvoip.h b/include/asm-sh/hs7751rvoip.h
new file mode 100644 (file)
index 0000000..c4cff9d
--- /dev/null
@@ -0,0 +1,54 @@
+#ifndef __ASM_SH_RENESAS_HS7751RVOIP_H
+#define __ASM_SH_RENESAS_HS7751RVOIP_H
+
+/*
+ * linux/include/asm-sh/hs7751rvoip/hs7751rvoip.h
+ *
+ * Copyright (C) 2000  Atom Create Engineering Co., Ltd.
+ *
+ * Renesas Technology Sales HS7751RVoIP support
+ */
+
+/* Box specific addresses.  */
+
+#define PA_BCR         0xa4000000      /* FPGA */
+#define PA_SLICCNTR1   0xa4000006      /* SLIC PIO Control 1 */
+#define PA_SLICCNTR2   0xa4000008      /* SLIC PIO Control 2 */
+#define PA_DMACNTR     0xa400000a      /* USB DMA Control */
+#define PA_INPORTR     0xa400000c      /* Input Port Register */
+#define PA_OUTPORTR    0xa400000e      /* Output Port Reguster */
+#define PA_VERREG      0xa4000014      /* FPGA Version Register */
+
+#define PA_IDE_OFFSET  0x1f0           /* CF IDE Offset */
+
+#define IRLCNTR1       (PA_BCR + 0)    /* Interrupt Control Register1 */
+#define IRLCNTR2       (PA_BCR + 2)    /* Interrupt Control Register2 */
+#define IRLCNTR3       (PA_BCR + 4)    /* Interrupt Control Register3 */
+#define IRLCNTR4       (PA_BCR + 16)   /* Interrupt Control Register4 */
+#define IRLCNTR5       (PA_BCR + 18)   /* Interrupt Control Register5 */
+
+#define IRQ_PCIETH     6               /* PCI Ethernet IRQ */
+#define IRQ_PCIHUB     7               /* PCI Ethernet Hub IRQ */
+#define IRQ_USBCOM     8               /* USB Comunication IRQ */
+#define IRQ_USBCON     9               /* USB Connect IRQ */
+#define IRQ_USBDMA     10              /* USB DMA IRQ */
+#define IRQ_CFCARD     11              /* CF Card IRQ */
+#define IRQ_PCMCIA     12              /* PCMCIA IRQ */
+#define IRQ_PCISLOT    13              /* PCI Slot #1 IRQ */
+#define IRQ_ONHOOK1    0               /* ON HOOK1 IRQ */
+#define IRQ_OFFHOOK1   1               /* OFF HOOK1 IRQ */
+#define IRQ_ONHOOK2    2               /* ON HOOK2 IRQ */
+#define IRQ_OFFHOOK2   3               /* OFF HOOK2 IRQ */
+#define        IRQ_RINGING     4               /* Ringing IRQ */
+#define        IRQ_CODEC       5               /* CODEC IRQ */
+
+#define __IO_PREFIX    hs7751rvoip
+#include <asm/io_generic.h>
+
+/* arch/sh/boards/renesas/hs7751rvoip/irq.c */
+void init_hs7751rvoip_IRQ(void);
+
+/* arch/sh/boards/renesas/hs7751rvoip/io.c */
+void *hs7751rvoip_ioremap(unsigned long, unsigned long);
+
+#endif  /* __ASM_SH_RENESAS_HS7751RVOIP */
diff --git a/include/asm-sh/hs7751rvoip/hs7751rvoip.h b/include/asm-sh/hs7751rvoip/hs7751rvoip.h
deleted file mode 100644 (file)
index c4cff9d..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-#ifndef __ASM_SH_RENESAS_HS7751RVOIP_H
-#define __ASM_SH_RENESAS_HS7751RVOIP_H
-
-/*
- * linux/include/asm-sh/hs7751rvoip/hs7751rvoip.h
- *
- * Copyright (C) 2000  Atom Create Engineering Co., Ltd.
- *
- * Renesas Technology Sales HS7751RVoIP support
- */
-
-/* Box specific addresses.  */
-
-#define PA_BCR         0xa4000000      /* FPGA */
-#define PA_SLICCNTR1   0xa4000006      /* SLIC PIO Control 1 */
-#define PA_SLICCNTR2   0xa4000008      /* SLIC PIO Control 2 */
-#define PA_DMACNTR     0xa400000a      /* USB DMA Control */
-#define PA_INPORTR     0xa400000c      /* Input Port Register */
-#define PA_OUTPORTR    0xa400000e      /* Output Port Reguster */
-#define PA_VERREG      0xa4000014      /* FPGA Version Register */
-
-#define PA_IDE_OFFSET  0x1f0           /* CF IDE Offset */
-
-#define IRLCNTR1       (PA_BCR + 0)    /* Interrupt Control Register1 */
-#define IRLCNTR2       (PA_BCR + 2)    /* Interrupt Control Register2 */
-#define IRLCNTR3       (PA_BCR + 4)    /* Interrupt Control Register3 */
-#define IRLCNTR4       (PA_BCR + 16)   /* Interrupt Control Register4 */
-#define IRLCNTR5       (PA_BCR + 18)   /* Interrupt Control Register5 */
-
-#define IRQ_PCIETH     6               /* PCI Ethernet IRQ */
-#define IRQ_PCIHUB     7               /* PCI Ethernet Hub IRQ */
-#define IRQ_USBCOM     8               /* USB Comunication IRQ */
-#define IRQ_USBCON     9               /* USB Connect IRQ */
-#define IRQ_USBDMA     10              /* USB DMA IRQ */
-#define IRQ_CFCARD     11              /* CF Card IRQ */
-#define IRQ_PCMCIA     12              /* PCMCIA IRQ */
-#define IRQ_PCISLOT    13              /* PCI Slot #1 IRQ */
-#define IRQ_ONHOOK1    0               /* ON HOOK1 IRQ */
-#define IRQ_OFFHOOK1   1               /* OFF HOOK1 IRQ */
-#define IRQ_ONHOOK2    2               /* ON HOOK2 IRQ */
-#define IRQ_OFFHOOK2   3               /* OFF HOOK2 IRQ */
-#define        IRQ_RINGING     4               /* Ringing IRQ */
-#define        IRQ_CODEC       5               /* CODEC IRQ */
-
-#define __IO_PREFIX    hs7751rvoip
-#include <asm/io_generic.h>
-
-/* arch/sh/boards/renesas/hs7751rvoip/irq.c */
-void init_hs7751rvoip_IRQ(void);
-
-/* arch/sh/boards/renesas/hs7751rvoip/io.c */
-void *hs7751rvoip_ioremap(unsigned long, unsigned long);
-
-#endif  /* __ASM_SH_RENESAS_HS7751RVOIP */
diff --git a/include/asm-sh/hs7751rvoip/ide.h b/include/asm-sh/hs7751rvoip/ide.h
deleted file mode 100644 (file)
index 65ad1d0..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef __ASM_SH_HS7751RVOIP_IDE_H
-#define __ASM_SH_HS7751RVOIP_IDE_H
-
-/* Nothing to see here.. */
-#include <asm/hs7751rvoip/hs7751rvoip.h>
-
-#endif /* __ASM_SH_HS7751RVOIP_IDE_H */
-
index fed26616967a03979d0d6ea6e7c14d1d6a446f97..80ee1cda7498f2383cd72588a800c66ad68178e3 100644 (file)
@@ -1,4 +1,8 @@
 #ifndef __ASM_SH_HW_IRQ_H
 #define __ASM_SH_HW_IRQ_H
 
+#include <asm/atomic.h>
+
+extern atomic_t irq_err_count;
+
 #endif /* __ASM_SH_HW_IRQ_H */
index ed12d38e8c0082dda8db85613bf578f4819e3ef9..a0e55b09e4fd773b30d9acf30e2e89ed60f72340 100644 (file)
@@ -304,22 +304,6 @@ __ioremap_mode(unsigned long offset, unsigned long size, unsigned long flags)
 #define iounmap(addr)                                  \
        __iounmap((addr))
 
-static inline int check_signature(char __iomem *io_addr,
-                       const unsigned char *signature, int length)
-{
-       int retval = 0;
-       do {
-               if (readb(io_addr) != *signature)
-                       goto out;
-               io_addr++;
-               signature++;
-               length--;
-       } while (length);
-       retval = 1;
-out:
-       return retval;
-}
-
 /*
  * The caches on some architectures aren't dma-coherent and have need to
  * handle this in software.  There are three types of operations that
index 895c5780e45473150ad02217a860e254b7fac648..19912ae6a7f720fae3d7327649b1fe0015b681f6 100644 (file)
@@ -6,16 +6,6 @@
  *
  * Copyright (C) 2004 Takashi SHUDO <shudo@hitachi-ul.co.jp>
  */
-
-#ifdef CONFIG_IDE
-# ifndef IRQ_CFCARD
-#  define IRQ_CFCARD   14
-# endif
-# ifndef IRQ_PCMCIA
-#  define IRQ_PCMCIA   15
-# endif
-#endif
-
 #define INTC_BASE      0xffd00000
 #define INTC_ICR0      (INTC_BASE+0x0)
 #define INTC_ICR1      (INTC_BASE+0x1c)
index 0e5f365aff70a63e2f2e639101e5b46e26708ce7..7596ab83e0d4dcb5136fda0483c83a1af90e846f 100644 (file)
 #include <asm/machvec.h>
 #include <asm/ptrace.h>                /* for pt_regs */
 
-#if defined(CONFIG_SH_HP6XX) || \
-    defined(CONFIG_SH_RTS7751R2D) || \
-    defined(CONFIG_SH_HS7751RVOIP) || \
-    defined(CONFIG_SH_HS7751RVOIP) || \
-    defined(CONFIG_SH_SH03) || \
-    defined(CONFIG_SH_R7780RP) || \
-    defined(CONFIG_SH_LANDISK)
-#include <asm/mach/ide.h>
-#endif
-
 #ifndef CONFIG_CPU_SUBTYPE_SH7780
 
 #define INTC_DMAC0_MSK 0
 #define INTC_IPRD      0xffd00010UL
 #endif
 
-#ifdef CONFIG_IDE
-# ifndef IRQ_CFCARD
-#  define IRQ_CFCARD   14
-# endif
-# ifndef IRQ_PCMCIA
-#  define IRQ_PCMCIA   15
-# endif
-#endif
-
 #define TIMER_IRQ      16
 #define TIMER_IPR_ADDR INTC_IPRA
 #define TIMER_IPR_POS   3
@@ -697,13 +678,15 @@ extern int ipr_irq_demux(int irq);
 
 #define INTC2_INTPRI_OFFSET    0x00
 
-void make_intc2_irq(unsigned int irq,
-                   unsigned int ipr_offset, unsigned int ipr_shift,
-                   unsigned int msk_offset, unsigned int msk_shift,
-                   unsigned int priority);
-void init_IRQ_intc2(void);
-void intc2_add_clear_irq(int irq, int (*fn)(int));
+struct intc2_data {
+       unsigned short irq;
+       unsigned char ipr_offset, ipr_shift;
+       unsigned char msk_offset, msk_shift;
+       unsigned char priority;
+};
 
+void make_intc2_irq(struct intc2_data *, unsigned int nr_irqs);
+void init_IRQ_intc2(void);
 #endif
 
 extern int shmse_irq_demux(int irq);
diff --git a/include/asm-sh/irq_regs.h b/include/asm-sh/irq_regs.h
new file mode 100644 (file)
index 0000000..3dd9c0b
--- /dev/null
@@ -0,0 +1 @@
+#include <asm-generic/irq_regs.h>
diff --git a/include/asm-sh/landisk/ide.h b/include/asm-sh/landisk/ide.h
deleted file mode 100644 (file)
index 6490e28..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * modifed by kogiidena
- * 2005.03.03
- */
-
-#ifndef __ASM_SH_LANDISK_IDE_H
-#define __ASM_SH_LANDISK_IDE_H
-
-/* Nothing to see here.. */
-#include <asm/landisk/iodata_landisk.h>
-#define IRQ_CFCARD     IRQ_FATA        /* CF Card IRQ */
-#define IRQ_PCMCIA     IRQ_ATA         /* PCMCIA IRQ */
-
-#endif /* __ASM_SH_LANDISK_IDE_H  */
index 474773853cd1a71f3184d85daf62468f3cfc2de0..45bb74e35d325acbbccc4607528ea2c4e07d0a59 100644 (file)
@@ -255,6 +255,8 @@ extern void save_fpu(struct task_struct *__tsk, struct pt_regs *regs);
  */
 #define thread_saved_pc(tsk)   (tsk->thread.pc)
 
+void show_trace(struct task_struct *tsk, unsigned long *sp,
+               struct pt_regs *regs);
 extern unsigned long get_wchan(struct task_struct *p);
 
 #define KSTK_EIP(tsk)  ((tsk)->thread.pc)
diff --git a/include/asm-sh/r7780rp.h b/include/asm-sh/r7780rp.h
new file mode 100644 (file)
index 0000000..c18f648
--- /dev/null
@@ -0,0 +1,171 @@
+#ifndef __ASM_SH_RENESAS_R7780RP_H
+#define __ASM_SH_RENESAS_R7780RP_H
+
+/*
+ * linux/include/asm-sh/r7780rp.h
+ *
+ * Copyright (C) 2000  Atom Create Engineering Co., Ltd.
+ *
+ * Renesas Solutions Highlander R7780RP support
+ */
+
+/* Box specific addresses.  */
+#if defined(CONFIG_SH_R7780MP)
+#define PA_BCR          0xa4000000      /* FPGA */
+#define PA_IRLMSK       (PA_BCR+0x0000) /* Interrupt Mask control */
+#define PA_IRLMON       (PA_BCR+0x0002) /* Interrupt Status control */
+#define PA_IRLPRI1      (PA_BCR+0x0004) /* Interrupt Priorty 1 */
+#define PA_IRLPRI2      (PA_BCR+0x0006) /* Interrupt Priorty 2 */
+#define PA_IRLPRI3      (PA_BCR+0x0008) /* Interrupt Priorty 3 */
+#define PA_IRLPRI4      (PA_BCR+0x000a) /* Interrupt Priorty 4 */
+#define PA_RSTCTL       (PA_BCR+0x000c) /* Reset Control */
+#define PA_PCIBD        (PA_BCR+0x000e) /* PCI Board detect control */
+#define PA_PCICD        (PA_BCR+0x0010) /* PCI Conector detect control */
+#define PA_EXTGIO       (PA_BCR+0x0016) /* Extension GPIO Control */
+#define PA_IVDRMON      (PA_BCR+0x0018) /* iVDR Moniter control */
+#define PA_IVDRCTL      (PA_BCR+0x001a) /* iVDR control */
+#define PA_OBLED        (PA_BCR+0x001c) /* On Board LED control */
+#define PA_OBSW         (PA_BCR+0x001e) /* On Board Switch control */
+#define PA_AUDIOSEL     (PA_BCR+0x0020) /* Sound Interface Select control */
+#define PA_EXTPLR       (PA_BCR+0x001e) /* Extention Pin Polarity control */
+#define PA_TPCTL        (PA_BCR+0x0100) /* Touch Panel Access control */
+#define PA_TPDCKCTL     (PA_BCR+0x0102) /* Touch Panel Access data control */
+#define PA_TPCTLCLR     (PA_BCR+0x0104) /* Touch Panel Access control */
+#define PA_TPXPOS       (PA_BCR+0x0106) /* Touch Panel X position control */
+#define PA_TPYPOS       (PA_BCR+0x0108) /* Touch Panel Y position control */
+#define PA_DBSW         (PA_BCR+0x0200) /* Debug Board Switch control */
+#define PA_CFCTL        (PA_BCR+0x0300) /* CF Timing control */
+#define PA_CFPOW        (PA_BCR+0x0302) /* CF Power control */
+#define PA_CFCDINTCLR   (PA_BCR+0x0304) /* CF Insert Interrupt clear */
+#define PA_SCSMR0       (PA_BCR+0x0400) /* SCIF0 Serial mode control */
+#define PA_SCBRR0       (PA_BCR+0x0404) /* SCIF0 Bit rate control */
+#define PA_SCSCR0       (PA_BCR+0x0408) /* SCIF0 Serial control */
+#define PA_SCFTDR0      (PA_BCR+0x040c) /* SCIF0 Send FIFO control */
+#define PA_SCFSR0       (PA_BCR+0x0410) /* SCIF0 Serial status control */
+#define PA_SCFRDR0      (PA_BCR+0x0414) /* SCIF0 Receive FIFO control */
+#define PA_SCFCR0       (PA_BCR+0x0418) /* SCIF0 FIFO control */
+#define PA_SCTFDR0      (PA_BCR+0x041c) /* SCIF0 Send FIFO data control */
+#define PA_SCRFDR0      (PA_BCR+0x0420) /* SCIF0 Receive FIFO data control */
+#define PA_SCSPTR0      (PA_BCR+0x0424) /* SCIF0 Serial Port control */
+#define PA_SCLSR0       (PA_BCR+0x0428) /* SCIF0 Line Status control */
+#define PA_SCRER0       (PA_BCR+0x042c) /* SCIF0 Serial Error control */
+#define PA_SCSMR1       (PA_BCR+0x0500) /* SCIF1 Serial mode control */
+#define PA_SCBRR1       (PA_BCR+0x0504) /* SCIF1 Bit rate control */
+#define PA_SCSCR1       (PA_BCR+0x0508) /* SCIF1 Serial control */
+#define PA_SCFTDR1      (PA_BCR+0x050c) /* SCIF1 Send FIFO control */
+#define PA_SCFSR1       (PA_BCR+0x0510) /* SCIF1 Serial status control */
+#define PA_SCFRDR1      (PA_BCR+0x0514) /* SCIF1 Receive FIFO control */
+#define PA_SCFCR1       (PA_BCR+0x0518) /* SCIF1 FIFO control */
+#define PA_SCTFDR1      (PA_BCR+0x051c) /* SCIF1 Send FIFO data control */
+#define PA_SCRFDR1      (PA_BCR+0x0520) /* SCIF1 Receive FIFO data control */
+#define PA_SCSPTR1      (PA_BCR+0x0524) /* SCIF1 Serial Port control */
+#define PA_SCLSR1       (PA_BCR+0x0528) /* SCIF1 Line Status control */
+#define PA_SCRER1       (PA_BCR+0x052c) /* SCIF1 Serial Error control */
+#define PA_ICCR         (PA_BCR+0x0600) /* Serial control */
+#define PA_SAR          (PA_BCR+0x0602) /* Serial Slave control */
+#define PA_MDR          (PA_BCR+0x0604) /* Serial Mode control */
+#define PA_ADR1         (PA_BCR+0x0606) /* Serial Address1 control */
+#define PA_DAR1         (PA_BCR+0x0646) /* Serial Data1 control */
+#define PA_VERREG       (PA_BCR+0x0700) /* FPGA Version Register */
+#define PA_POFF         (PA_BCR+0x0800) /* System Power Off control */
+#define PA_PMR          (PA_BCR+0x0900) /*  */
+
+#define PA_AX88796L     0xa4100400      /* AX88796L Area */
+#define PA_SC1602BSLB   0xa6000000      /* SC1602BSLB Area */
+#define PA_IDE_OFFSET   0x1f0           /* CF IDE Offset */
+#define AX88796L_IO_BASE        0x1000  /* AX88796L IO Base Address */
+
+#define IRLCNTR1        (PA_BCR + 0)    /* Interrupt Control Register1 */
+
+#define IRQ_PCISLOT1    65              /* PCI Slot #1 IRQ */
+#define IRQ_PCISLOT2    66              /* PCI Slot #2 IRQ */
+#define IRQ_PCISLOT3    67              /* PCI Slot #3 IRQ */
+#define IRQ_PCISLOT4    68              /* PCI Slot #4 IRQ */
+// #define IRQ_CFINST   0               /* CF Card Insert IRQ */
+#define IRQ_TP          2               /* Touch Panel IRQ */
+#define IRQ_SCI1        3               /* SCI1 IRQ */
+#define IRQ_SCI0        4               /* SCI0 IRQ */
+#define IRQ_2SERIAL     5               /* Serial IRQ */
+#define IRQ_RTC         6               /* RTC A / B IRQ */
+#define IRQ_EXTENTION6  7               /* EXT6n IRQ */
+#define IRQ_EXTENTION5  8               /* EXT5n IRQ */
+#define IRQ_EXTENTION4  9               /* EXT4n IRQ */
+#define IRQ_EXTENTION2  10              /* EXT2n IRQ */
+#define IRQ_EXTENTION1  11              /* EXT1n IRQ */
+#define IRQ_ONETH       13              /* On board Ethernet IRQ */
+#define IRQ_PSW         14              /* Push Switch IRQ */
+
+#else /* R7780RP */
+
+#define PA_BCR         0xa5000000      /* FPGA */
+#define        PA_IRLMSK       (PA_BCR+0x0000) /* Interrupt Mask control */
+#define PA_IRLMON      (PA_BCR+0x0002) /* Interrupt Status control */
+#define        PA_SDPOW        (PA_BCR+0x0004) /* SD Power control */
+#define        PA_RSTCTL       (PA_BCR+0x0006) /* Device Reset control */
+#define        PA_PCIBD        (PA_BCR+0x0008) /* PCI Board detect control */
+#define        PA_PCICD        (PA_BCR+0x000a) /* PCI Conector detect control */
+#define        PA_ZIGIO1       (PA_BCR+0x000c) /* Zigbee IO control 1 */
+#define        PA_ZIGIO2       (PA_BCR+0x000e) /* Zigbee IO control 2 */
+#define        PA_ZIGIO3       (PA_BCR+0x0010) /* Zigbee IO control 3 */
+#define        PA_ZIGIO4       (PA_BCR+0x0012) /* Zigbee IO control 4 */
+#define        PA_IVDRMON      (PA_BCR+0x0014) /* iVDR Moniter control */
+#define        PA_IVDRCTL      (PA_BCR+0x0016) /* iVDR control */
+#define PA_OBLED       (PA_BCR+0x0018) /* On Board LED control */
+#define PA_OBSW                (PA_BCR+0x001a) /* On Board Switch control */
+#define PA_AUDIOSEL    (PA_BCR+0x001c) /* Sound Interface Select control */
+#define PA_EXTPLR      (PA_BCR+0x001e) /* Extention Pin Polarity control */
+#define PA_TPCTL       (PA_BCR+0x0100) /* Touch Panel Access control */
+#define PA_TPDCKCTL    (PA_BCR+0x0102) /* Touch Panel Access data control */
+#define PA_TPCTLCLR    (PA_BCR+0x0104) /* Touch Panel Access control */
+#define PA_TPXPOS      (PA_BCR+0x0106) /* Touch Panel X position control */
+#define PA_TPYPOS      (PA_BCR+0x0108) /* Touch Panel Y position control */
+#define PA_DBDET       (PA_BCR+0x0200) /* Debug Board detect control */
+#define PA_DBDISPCTL   (PA_BCR+0x0202) /* Debug Board Dot timing control */
+#define PA_DBSW                (PA_BCR+0x0204) /* Debug Board Switch control */
+#define PA_CFCTL       (PA_BCR+0x0300) /* CF Timing control */
+#define PA_CFPOW       (PA_BCR+0x0302) /* CF Power control */
+#define PA_CFCDINTCLR  (PA_BCR+0x0304) /* CF Insert Interrupt clear */
+#define PA_SCSMR       (PA_BCR+0x0400) /* SCIF Serial mode control */
+#define PA_SCBRR       (PA_BCR+0x0402) /* SCIF Bit rate control */
+#define PA_SCSCR       (PA_BCR+0x0404) /* SCIF Serial control */
+#define PA_SCFDTR      (PA_BCR+0x0406) /* SCIF Send FIFO control */
+#define PA_SCFSR       (PA_BCR+0x0408) /* SCIF Serial status control */
+#define PA_SCFRDR      (PA_BCR+0x040a) /* SCIF Receive FIFO control */
+#define PA_SCFCR       (PA_BCR+0x040c) /* SCIF FIFO control */
+#define PA_SCFDR       (PA_BCR+0x040e) /* SCIF FIFO data control */
+#define PA_SCLSR       (PA_BCR+0x0412) /* SCIF Line Status control */
+#define PA_ICCR                (PA_BCR+0x0500) /* Serial control */
+#define PA_SAR         (PA_BCR+0x0502) /* Serial Slave control */
+#define PA_MDR         (PA_BCR+0x0504) /* Serial Mode control */
+#define PA_ADR1                (PA_BCR+0x0506) /* Serial Address1 control */
+#define PA_DAR1                (PA_BCR+0x0546) /* Serial Data1 control */
+#define PA_VERREG      (PA_BCR+0x0600) /* FPGA Version Register */
+
+#define PA_AX88796L    0xa5800400      /* AX88796L Area */
+#define PA_SC1602BSLB  0xa6000000      /* SC1602BSLB Area */
+#define PA_IDE_OFFSET  0x1f0           /* CF IDE Offset */
+#define AX88796L_IO_BASE       0x1000  /* AX88796L IO Base Address */
+
+#define IRLCNTR1       (PA_BCR + 0)    /* Interrupt Control Register1 */
+
+#define IRQ_PCISLOT1   0               /* PCI Slot #1 IRQ */
+#define IRQ_PCISLOT2   1               /* PCI Slot #2 IRQ */
+#define IRQ_PCISLOT3   2               /* PCI Slot #3 IRQ */
+#define IRQ_PCISLOT4   3               /* PCI Slot #4 IRQ */
+#define IRQ_CFINST     5               /* CF Card Insert IRQ */
+#define IRQ_M66596     6               /* M66596 IRQ */
+#define IRQ_SDCARD     7               /* SD Card IRQ */
+#define IRQ_TUCHPANEL  8               /* Touch Panel IRQ */
+#define IRQ_SCI                9               /* SCI IRQ */
+#define IRQ_2SERIAL    10              /* Serial IRQ */
+#define        IRQ_EXTENTION   11              /* EXTn IRQ */
+#define IRQ_ONETH      12              /* On board Ethernet IRQ */
+#define IRQ_PSW                13              /* Push Switch IRQ */
+#define IRQ_ZIGBEE     14              /* Ziggbee IO IRQ */
+
+#endif  /* CONFIG_SH_R7780MP */
+
+#define __IO_PREFIX    r7780rp
+#include <asm/io_generic.h>
+
+#endif  /* __ASM_SH_RENESAS_R7780RP */
diff --git a/include/asm-sh/r7780rp/ide.h b/include/asm-sh/r7780rp/ide.h
deleted file mode 100644 (file)
index a1ed78e..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef __ASM_SH_R7780RP_IDE_H
-#define __ASM_SH_R7780RP_IDE_H
-
-/* Nothing to see here.. */
-#include <asm/mach/r7780rp.h>
-
-#endif /* __ASM_SH_R7780RP_IDE_H */
-
diff --git a/include/asm-sh/r7780rp/r7780rp.h b/include/asm-sh/r7780rp/r7780rp.h
deleted file mode 100644 (file)
index f95d9db..0000000
+++ /dev/null
@@ -1,177 +0,0 @@
-#ifndef __ASM_SH_RENESAS_R7780RP_H
-#define __ASM_SH_RENESAS_R7780RP_H
-
-/*
- * linux/include/asm-sh/r7780rp.h
- *
- * Copyright (C) 2000  Atom Create Engineering Co., Ltd.
- *
- * Renesas Solutions Highlander R7780RP support
- */
-
-/* Box specific addresses.  */
-#if defined(CONFIG_SH_R7780MP)
-#define PA_BCR          0xa4000000      /* FPGA */
-#define PA_IRLMSK       (PA_BCR+0x0000) /* Interrupt Mask control */
-#define PA_IRLMON       (PA_BCR+0x0002) /* Interrupt Status control */
-#define PA_IRLPRI1      (PA_BCR+0x0004) /* Interrupt Priorty 1 */
-#define PA_IRLPRI2      (PA_BCR+0x0006) /* Interrupt Priorty 2 */
-#define PA_IRLPRI3      (PA_BCR+0x0008) /* Interrupt Priorty 3 */
-#define PA_IRLPRI4      (PA_BCR+0x000a) /* Interrupt Priorty 4 */
-#define PA_RSTCTL       (PA_BCR+0x000c) /* Reset Control */
-#define PA_PCIBD        (PA_BCR+0x000e) /* PCI Board detect control */
-#define PA_PCICD        (PA_BCR+0x0010) /* PCI Conector detect control */
-#define PA_EXTGIO       (PA_BCR+0x0016) /* Extension GPIO Control */
-#define PA_IVDRMON      (PA_BCR+0x0018) /* iVDR Moniter control */
-#define PA_IVDRCTL      (PA_BCR+0x001a) /* iVDR control */
-#define PA_OBLED        (PA_BCR+0x001c) /* On Board LED control */
-#define PA_OBSW         (PA_BCR+0x001e) /* On Board Switch control */
-#define PA_AUDIOSEL     (PA_BCR+0x0020) /* Sound Interface Select control */
-#define PA_EXTPLR       (PA_BCR+0x001e) /* Extention Pin Polarity control */
-#define PA_TPCTL        (PA_BCR+0x0100) /* Touch Panel Access control */
-#define PA_TPDCKCTL     (PA_BCR+0x0102) /* Touch Panel Access data control */
-#define PA_TPCTLCLR     (PA_BCR+0x0104) /* Touch Panel Access control */
-#define PA_TPXPOS       (PA_BCR+0x0106) /* Touch Panel X position control */
-#define PA_TPYPOS       (PA_BCR+0x0108) /* Touch Panel Y position control */
-#define PA_DBSW         (PA_BCR+0x0200) /* Debug Board Switch control */
-#define PA_CFCTL        (PA_BCR+0x0300) /* CF Timing control */
-#define PA_CFPOW        (PA_BCR+0x0302) /* CF Power control */
-#define PA_CFCDINTCLR   (PA_BCR+0x0304) /* CF Insert Interrupt clear */
-#define PA_SCSMR0       (PA_BCR+0x0400) /* SCIF0 Serial mode control */
-#define PA_SCBRR0       (PA_BCR+0x0404) /* SCIF0 Bit rate control */
-#define PA_SCSCR0       (PA_BCR+0x0408) /* SCIF0 Serial control */
-#define PA_SCFTDR0      (PA_BCR+0x040c) /* SCIF0 Send FIFO control */
-#define PA_SCFSR0       (PA_BCR+0x0410) /* SCIF0 Serial status control */
-#define PA_SCFRDR0      (PA_BCR+0x0414) /* SCIF0 Receive FIFO control */
-#define PA_SCFCR0       (PA_BCR+0x0418) /* SCIF0 FIFO control */
-#define PA_SCTFDR0      (PA_BCR+0x041c) /* SCIF0 Send FIFO data control */
-#define PA_SCRFDR0      (PA_BCR+0x0420) /* SCIF0 Receive FIFO data control */
-#define PA_SCSPTR0      (PA_BCR+0x0424) /* SCIF0 Serial Port control */
-#define PA_SCLSR0       (PA_BCR+0x0428) /* SCIF0 Line Status control */
-#define PA_SCRER0       (PA_BCR+0x042c) /* SCIF0 Serial Error control */
-#define PA_SCSMR1       (PA_BCR+0x0500) /* SCIF1 Serial mode control */
-#define PA_SCBRR1       (PA_BCR+0x0504) /* SCIF1 Bit rate control */
-#define PA_SCSCR1       (PA_BCR+0x0508) /* SCIF1 Serial control */
-#define PA_SCFTDR1      (PA_BCR+0x050c) /* SCIF1 Send FIFO control */
-#define PA_SCFSR1       (PA_BCR+0x0510) /* SCIF1 Serial status control */
-#define PA_SCFRDR1      (PA_BCR+0x0514) /* SCIF1 Receive FIFO control */
-#define PA_SCFCR1       (PA_BCR+0x0518) /* SCIF1 FIFO control */
-#define PA_SCTFDR1      (PA_BCR+0x051c) /* SCIF1 Send FIFO data control */
-#define PA_SCRFDR1      (PA_BCR+0x0520) /* SCIF1 Receive FIFO data control */
-#define PA_SCSPTR1      (PA_BCR+0x0524) /* SCIF1 Serial Port control */
-#define PA_SCLSR1       (PA_BCR+0x0528) /* SCIF1 Line Status control */
-#define PA_SCRER1       (PA_BCR+0x052c) /* SCIF1 Serial Error control */
-#define PA_ICCR         (PA_BCR+0x0600) /* Serial control */
-#define PA_SAR          (PA_BCR+0x0602) /* Serial Slave control */
-#define PA_MDR          (PA_BCR+0x0604) /* Serial Mode control */
-#define PA_ADR1         (PA_BCR+0x0606) /* Serial Address1 control */
-#define PA_DAR1         (PA_BCR+0x0646) /* Serial Data1 control */
-#define PA_VERREG       (PA_BCR+0x0700) /* FPGA Version Register */
-#define PA_POFF         (PA_BCR+0x0800) /* System Power Off control */
-#define PA_PMR          (PA_BCR+0x0900) /*  */
-
-#define PA_AX88796L     0xa4100400      /* AX88796L Area */
-#define PA_SC1602BSLB   0xa6000000      /* SC1602BSLB Area */
-#define PA_AREA5_IO     0xb4000000      /* Area 5 IO Memory */
-#define PA_AREA6_IO     0xb8000000      /* Area 6 IO Memory */
-#define PA_IDE_OFFSET   0x1f0           /* CF IDE Offset */
-#define AX88796L_IO_BASE        0x1000  /* AX88796L IO Base Address */
-
-#define IRLCNTR1        (PA_BCR + 0)    /* Interrupt Control Register1 */
-
-#define IRQ_PCISLOT1    65              /* PCI Slot #1 IRQ */
-#define IRQ_PCISLOT2    66              /* PCI Slot #2 IRQ */
-#define IRQ_PCISLOT3    67              /* PCI Slot #3 IRQ */
-#define IRQ_PCISLOT4    68              /* PCI Slot #4 IRQ */
-#define IRQ_CFCARD      1               /* CF Card IRQ */
-// #define IRQ_CFINST   0               /* CF Card Insert IRQ */
-#define IRQ_TP          2               /* Touch Panel IRQ */
-#define IRQ_SCI1        3               /* SCI1 IRQ */
-#define IRQ_SCI0        4               /* SCI0 IRQ */
-#define IRQ_2SERIAL     5               /* Serial IRQ */
-#define IRQ_RTC         6               /* RTC A / B IRQ */
-#define IRQ_EXTENTION6  7               /* EXT6n IRQ */
-#define IRQ_EXTENTION5  8               /* EXT5n IRQ */
-#define IRQ_EXTENTION4  9               /* EXT4n IRQ */
-#define IRQ_EXTENTION2  10              /* EXT2n IRQ */
-#define IRQ_EXTENTION1  11              /* EXT1n IRQ */
-#define IRQ_ONETH       13              /* On board Ethernet IRQ */
-#define IRQ_PSW         14              /* Push Switch IRQ */
-
-#else /* R7780RP */
-
-#define PA_BCR         0xa5000000      /* FPGA */
-#define        PA_IRLMSK       (PA_BCR+0x0000) /* Interrupt Mask control */
-#define PA_IRLMON      (PA_BCR+0x0002) /* Interrupt Status control */
-#define        PA_SDPOW        (PA_BCR+0x0004) /* SD Power control */
-#define        PA_RSTCTL       (PA_BCR+0x0006) /* Device Reset control */
-#define        PA_PCIBD        (PA_BCR+0x0008) /* PCI Board detect control */
-#define        PA_PCICD        (PA_BCR+0x000a) /* PCI Conector detect control */
-#define        PA_ZIGIO1       (PA_BCR+0x000c) /* Zigbee IO control 1 */
-#define        PA_ZIGIO2       (PA_BCR+0x000e) /* Zigbee IO control 2 */
-#define        PA_ZIGIO3       (PA_BCR+0x0010) /* Zigbee IO control 3 */
-#define        PA_ZIGIO4       (PA_BCR+0x0012) /* Zigbee IO control 4 */
-#define        PA_IVDRMON      (PA_BCR+0x0014) /* iVDR Moniter control */
-#define        PA_IVDRCTL      (PA_BCR+0x0016) /* iVDR control */
-#define PA_OBLED       (PA_BCR+0x0018) /* On Board LED control */
-#define PA_OBSW                (PA_BCR+0x001a) /* On Board Switch control */
-#define PA_AUDIOSEL    (PA_BCR+0x001c) /* Sound Interface Select control */
-#define PA_EXTPLR      (PA_BCR+0x001e) /* Extention Pin Polarity control */
-#define PA_TPCTL       (PA_BCR+0x0100) /* Touch Panel Access control */
-#define PA_TPDCKCTL    (PA_BCR+0x0102) /* Touch Panel Access data control */
-#define PA_TPCTLCLR    (PA_BCR+0x0104) /* Touch Panel Access control */
-#define PA_TPXPOS      (PA_BCR+0x0106) /* Touch Panel X position control */
-#define PA_TPYPOS      (PA_BCR+0x0108) /* Touch Panel Y position control */
-#define PA_DBDET       (PA_BCR+0x0200) /* Debug Board detect control */
-#define PA_DBDISPCTL   (PA_BCR+0x0202) /* Debug Board Dot timing control */
-#define PA_DBSW                (PA_BCR+0x0204) /* Debug Board Switch control */
-#define PA_CFCTL       (PA_BCR+0x0300) /* CF Timing control */
-#define PA_CFPOW       (PA_BCR+0x0302) /* CF Power control */
-#define PA_CFCDINTCLR  (PA_BCR+0x0304) /* CF Insert Interrupt clear */
-#define PA_SCSMR       (PA_BCR+0x0400) /* SCIF Serial mode control */
-#define PA_SCBRR       (PA_BCR+0x0402) /* SCIF Bit rate control */
-#define PA_SCSCR       (PA_BCR+0x0404) /* SCIF Serial control */
-#define PA_SCFDTR      (PA_BCR+0x0406) /* SCIF Send FIFO control */
-#define PA_SCFSR       (PA_BCR+0x0408) /* SCIF Serial status control */
-#define PA_SCFRDR      (PA_BCR+0x040a) /* SCIF Receive FIFO control */
-#define PA_SCFCR       (PA_BCR+0x040c) /* SCIF FIFO control */
-#define PA_SCFDR       (PA_BCR+0x040e) /* SCIF FIFO data control */
-#define PA_SCLSR       (PA_BCR+0x0412) /* SCIF Line Status control */
-#define PA_ICCR                (PA_BCR+0x0500) /* Serial control */
-#define PA_SAR         (PA_BCR+0x0502) /* Serial Slave control */
-#define PA_MDR         (PA_BCR+0x0504) /* Serial Mode control */
-#define PA_ADR1                (PA_BCR+0x0506) /* Serial Address1 control */
-#define PA_DAR1                (PA_BCR+0x0546) /* Serial Data1 control */
-#define PA_VERREG      (PA_BCR+0x0600) /* FPGA Version Register */
-
-#define PA_AX88796L    0xa5800400      /* AX88796L Area */
-#define PA_SC1602BSLB  0xa6000000      /* SC1602BSLB Area */
-#define PA_AREA5_IO    0xb4000000      /* Area 5 IO Memory */
-#define PA_AREA6_IO    0xb8000000      /* Area 6 IO Memory */
-#define PA_IDE_OFFSET  0x1f0           /* CF IDE Offset */
-#define AX88796L_IO_BASE       0x1000  /* AX88796L IO Base Address */
-
-#define IRLCNTR1       (PA_BCR + 0)    /* Interrupt Control Register1 */
-
-#define IRQ_PCISLOT1   0               /* PCI Slot #1 IRQ */
-#define IRQ_PCISLOT2   1               /* PCI Slot #2 IRQ */
-#define IRQ_PCISLOT3   2               /* PCI Slot #3 IRQ */
-#define IRQ_PCISLOT4   3               /* PCI Slot #4 IRQ */
-#define IRQ_CFCARD     4               /* CF Card IRQ */
-#define IRQ_CFINST     5               /* CF Card Insert IRQ */
-#define IRQ_M66596     6               /* M66596 IRQ */
-#define IRQ_SDCARD     7               /* SD Card IRQ */
-#define IRQ_TUCHPANEL  8               /* Touch Panel IRQ */
-#define IRQ_SCI                9               /* SCI IRQ */
-#define IRQ_2SERIAL    10              /* Serial IRQ */
-#define        IRQ_EXTENTION   11              /* EXTn IRQ */
-#define IRQ_ONETH      12              /* On board Ethernet IRQ */
-#define IRQ_PSW                13              /* Push Switch IRQ */
-#define IRQ_ZIGBEE     14              /* Ziggbee IO IRQ */
-
-#endif  /* CONFIG_SH_R7780MP */
-
-#define __IO_PREFIX    r7780rp
-#include <asm/io_generic.h>
-
-#endif  /* __ASM_SH_RENESAS_R7780RP */
diff --git a/include/asm-sh/rts7751r2d.h b/include/asm-sh/rts7751r2d.h
new file mode 100644 (file)
index 0000000..796b8fc
--- /dev/null
@@ -0,0 +1,74 @@
+#ifndef __ASM_SH_RENESAS_RTS7751R2D_H
+#define __ASM_SH_RENESAS_RTS7751R2D_H
+
+/*
+ * linux/include/asm-sh/renesas_rts7751r2d.h
+ *
+ * Copyright (C) 2000  Atom Create Engineering Co., Ltd.
+ *
+ * Renesas Technology Sales RTS7751R2D support
+ */
+
+/* Box specific addresses.  */
+
+#define PA_BCR         0xa4000000      /* FPGA */
+#define PA_IRLMON      0xa4000002      /* Interrupt Status control */
+#define PA_CFCTL       0xa4000004      /* CF Timing control */
+#define PA_CFPOW       0xa4000006      /* CF Power control */
+#define PA_DISPCTL     0xa4000008      /* Display Timing control */
+#define PA_SDMPOW      0xa400000a      /* SD Power control */
+#define PA_RTCCE       0xa400000c      /* RTC(9701) Enable control */
+#define PA_PCICD       0xa400000e      /* PCI Extention detect control */
+#define PA_VOYAGERRTS  0xa4000020      /* VOYAGER Reset control */
+#if defined(CONFIG_RTS7751R2D_REV11)
+#define PA_AXRST       0xa4000022      /* AX_LAN Reset control */
+#define PA_CFRST       0xa4000024      /* CF Reset control */
+#define        PA_ADMRTS       0xa4000026      /* SD Reset control */
+#define PA_EXTRST      0xa4000028      /* Extention Reset control */
+#define PA_CFCDINTCLR  0xa400002a      /* CF Insert Interrupt clear */
+#else
+#define PA_CFRST       0xa4000022      /* CF Reset control */
+#define        PA_ADMRTS       0xa4000024      /* SD Reset control */
+#define PA_EXTRST      0xa4000026      /* Extention Reset control */
+#define PA_CFCDINTCLR  0xa4000028      /* CF Insert Interrupt clear */
+#define        PA_KEYCTLCLR    0xa400002a      /* Key Interrupt clear */
+#endif
+#define PA_POWOFF      0xa4000030      /* Board Power OFF control */
+#define PA_VERREG      0xa4000032      /* FPGA Version Register */
+#define PA_INPORT      0xa4000034      /* KEY Input Port control */
+#define PA_OUTPORT     0xa4000036      /* LED control */
+#define PA_DMPORT      0xa4000038      /* DM270 Output Port control */
+
+#define PA_AX88796L    0xaa000400      /* AX88796L Area */
+#define PA_VOYAGER     0xab000000      /* VOYAGER GX Area */
+#define PA_IDE_OFFSET  0x1f0           /* CF IDE Offset */
+#define AX88796L_IO_BASE       0x1000  /* AX88796L IO Base Address */
+
+#define IRLCNTR1       (PA_BCR + 0)    /* Interrupt Control Register1 */
+
+#if defined(CONFIG_RTS7751R2D_REV11)
+#define IRQ_PCIETH     0               /* PCI Ethernet IRQ */
+#define IRQ_CFCARD     1               /* CF Card IRQ */
+#define IRQ_CFINST     2               /* CF Card Insert IRQ */
+#define IRQ_PCMCIA     3               /* PCMCIA IRQ */
+#define IRQ_VOYAGER    4               /* VOYAGER IRQ */
+#define IRQ_ONETH      5               /* On board Ethernet IRQ */
+#else
+#define IRQ_KEYIN      0               /* Key Input IRQ */
+#define IRQ_PCIETH     1               /* PCI Ethernet IRQ */
+#define IRQ_CFCARD     2               /* CF Card IRQ */
+#define IRQ_CFINST     3               /* CF Card Insert IRQ */
+#define IRQ_PCMCIA     4               /* PCMCIA IRQ */
+#define IRQ_VOYAGER    5               /* VOYAGER IRQ */
+#endif
+#define IRQ_RTCALM     6               /* RTC Alarm IRQ */
+#define IRQ_RTCTIME    7               /* RTC Timer IRQ */
+#define IRQ_SDCARD     8               /* SD Card IRQ */
+#define IRQ_PCISLOT1   9               /* PCI Slot #1 IRQ */
+#define IRQ_PCISLOT2   10              /* PCI Slot #2 IRQ */
+#define        IRQ_EXTENTION   11              /* EXTn IRQ */
+
+#define __IO_PREFIX rts7751r2d
+#include <asm/io_generic.h>
+
+#endif  /* __ASM_SH_RENESAS_RTS7751R2D */
diff --git a/include/asm-sh/rts7751r2d/ide.h b/include/asm-sh/rts7751r2d/ide.h
deleted file mode 100644 (file)
index 416f96b..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef __ASM_SH_RTS7751R2D_IDE_H
-#define __ASM_SH_RTS7751R2D_IDE_H
-
-/* Nothing to see here.. */
-#include <asm/rts7751r2d/rts7751r2d.h>
-
-#endif /* __ASM_SH_RTS7751R2D_IDE_H */
-
diff --git a/include/asm-sh/rts7751r2d/rts7751r2d.h b/include/asm-sh/rts7751r2d/rts7751r2d.h
deleted file mode 100644 (file)
index 796b8fc..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-#ifndef __ASM_SH_RENESAS_RTS7751R2D_H
-#define __ASM_SH_RENESAS_RTS7751R2D_H
-
-/*
- * linux/include/asm-sh/renesas_rts7751r2d.h
- *
- * Copyright (C) 2000  Atom Create Engineering Co., Ltd.
- *
- * Renesas Technology Sales RTS7751R2D support
- */
-
-/* Box specific addresses.  */
-
-#define PA_BCR         0xa4000000      /* FPGA */
-#define PA_IRLMON      0xa4000002      /* Interrupt Status control */
-#define PA_CFCTL       0xa4000004      /* CF Timing control */
-#define PA_CFPOW       0xa4000006      /* CF Power control */
-#define PA_DISPCTL     0xa4000008      /* Display Timing control */
-#define PA_SDMPOW      0xa400000a      /* SD Power control */
-#define PA_RTCCE       0xa400000c      /* RTC(9701) Enable control */
-#define PA_PCICD       0xa400000e      /* PCI Extention detect control */
-#define PA_VOYAGERRTS  0xa4000020      /* VOYAGER Reset control */
-#if defined(CONFIG_RTS7751R2D_REV11)
-#define PA_AXRST       0xa4000022      /* AX_LAN Reset control */
-#define PA_CFRST       0xa4000024      /* CF Reset control */
-#define        PA_ADMRTS       0xa4000026      /* SD Reset control */
-#define PA_EXTRST      0xa4000028      /* Extention Reset control */
-#define PA_CFCDINTCLR  0xa400002a      /* CF Insert Interrupt clear */
-#else
-#define PA_CFRST       0xa4000022      /* CF Reset control */
-#define        PA_ADMRTS       0xa4000024      /* SD Reset control */
-#define PA_EXTRST      0xa4000026      /* Extention Reset control */
-#define PA_CFCDINTCLR  0xa4000028      /* CF Insert Interrupt clear */
-#define        PA_KEYCTLCLR    0xa400002a      /* Key Interrupt clear */
-#endif
-#define PA_POWOFF      0xa4000030      /* Board Power OFF control */
-#define PA_VERREG      0xa4000032      /* FPGA Version Register */
-#define PA_INPORT      0xa4000034      /* KEY Input Port control */
-#define PA_OUTPORT     0xa4000036      /* LED control */
-#define PA_DMPORT      0xa4000038      /* DM270 Output Port control */
-
-#define PA_AX88796L    0xaa000400      /* AX88796L Area */
-#define PA_VOYAGER     0xab000000      /* VOYAGER GX Area */
-#define PA_IDE_OFFSET  0x1f0           /* CF IDE Offset */
-#define AX88796L_IO_BASE       0x1000  /* AX88796L IO Base Address */
-
-#define IRLCNTR1       (PA_BCR + 0)    /* Interrupt Control Register1 */
-
-#if defined(CONFIG_RTS7751R2D_REV11)
-#define IRQ_PCIETH     0               /* PCI Ethernet IRQ */
-#define IRQ_CFCARD     1               /* CF Card IRQ */
-#define IRQ_CFINST     2               /* CF Card Insert IRQ */
-#define IRQ_PCMCIA     3               /* PCMCIA IRQ */
-#define IRQ_VOYAGER    4               /* VOYAGER IRQ */
-#define IRQ_ONETH      5               /* On board Ethernet IRQ */
-#else
-#define IRQ_KEYIN      0               /* Key Input IRQ */
-#define IRQ_PCIETH     1               /* PCI Ethernet IRQ */
-#define IRQ_CFCARD     2               /* CF Card IRQ */
-#define IRQ_CFINST     3               /* CF Card Insert IRQ */
-#define IRQ_PCMCIA     4               /* PCMCIA IRQ */
-#define IRQ_VOYAGER    5               /* VOYAGER IRQ */
-#endif
-#define IRQ_RTCALM     6               /* RTC Alarm IRQ */
-#define IRQ_RTCTIME    7               /* RTC Timer IRQ */
-#define IRQ_SDCARD     8               /* SD Card IRQ */
-#define IRQ_PCISLOT1   9               /* PCI Slot #1 IRQ */
-#define IRQ_PCISLOT2   10              /* PCI Slot #2 IRQ */
-#define        IRQ_EXTENTION   11              /* EXTn IRQ */
-
-#define __IO_PREFIX rts7751r2d
-#include <asm/io_generic.h>
-
-#endif  /* __ASM_SH_RENESAS_RTS7751R2D */
diff --git a/include/asm-sh/sh03/ide.h b/include/asm-sh/sh03/ide.h
deleted file mode 100644 (file)
index 73ee92e..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef __ASM_SH_SH03_IDE_H
-#define __ASM_SH_SH03_IDE_H
-
-#define IRQ_CFCARD     8
-#define IRQ_PCMCIA     8
-
-#endif /* __ASM_SH_SH03_IDE_H */
diff --git a/include/asm-sh/shmin.h b/include/asm-sh/shmin.h
new file mode 100644 (file)
index 0000000..36ba138
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef __ASM_SH_SHMIN_H
+#define __ASM_SH_SHMIN_H
+
+#define SHMIN_IO_BASE 0xb0000000UL
+
+#define SHMIN_NE_IRQ IRQ2_IRQ
+#define SHMIN_NE_BASE 0x300
+
+#endif
diff --git a/include/asm-sh/shmin/shmin.h b/include/asm-sh/shmin/shmin.h
deleted file mode 100644 (file)
index 36ba138..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef __ASM_SH_SHMIN_H
-#define __ASM_SH_SHMIN_H
-
-#define SHMIN_IO_BASE 0xb0000000UL
-
-#define SHMIN_NE_IRQ IRQ2_IRQ
-#define SHMIN_NE_BASE 0x300
-
-#endif
index 6c1f8fde5ac4a8e6a73c6d5059491db8c7e56554..3340126f4e0fc7785cef0ed7e4c191583fdc6e35 100644 (file)
@@ -353,6 +353,13 @@ static inline unsigned long __cmpxchg(volatile void * ptr, unsigned long old,
                                    (unsigned long)_n_, sizeof(*(ptr))); \
   })
 
+extern void *set_exception_table_vec(unsigned int vec, void *handler);
+
+static inline void *set_exception_table_evt(unsigned int evt, void *handler)
+{
+       return set_exception_table_vec(evt >> 5, handler);
+}
+
 /* XXX
  * disable hlt during certain critical i/o operations
  */
index c7ab28095ba0ea4ffabe410108d57a33c9f5e56b..5df842bcf7b63d554ef6486b11e07a663514c373 100644 (file)
@@ -8,8 +8,9 @@ struct sys_timer_ops {
        int (*init)(void);
        int (*start)(void);
        int (*stop)(void);
+#ifndef CONFIG_GENERIC_TIME
        unsigned long (*get_offset)(void);
-       unsigned long (*get_frequency)(void);
+#endif
 };
 
 struct sys_timer {
@@ -24,21 +25,17 @@ struct sys_timer {
 extern struct sys_timer tmu_timer;
 extern struct sys_timer *sys_timer;
 
+#ifndef CONFIG_GENERIC_TIME
 static inline unsigned long get_timer_offset(void)
 {
        return sys_timer->ops->get_offset();
 }
-
-static inline unsigned long get_timer_frequency(void)
-{
-       return sys_timer->ops->get_frequency();
-}
+#endif
 
 /* arch/sh/kernel/timers/timer.c */
 struct sys_timer *get_sys_timer(void);
 
 /* arch/sh/kernel/time.c */
-void handle_timer_tick(struct pt_regs *);
+void handle_timer_tick(void);
 
 #endif /* __ASM_SH_TIMER_H */
-
index 252fedbb6621e4cbd5df0f815d51ef7b4414a636..14d8e7b4bf4b369254d49a0f458ec7c8b8a17c59 100644 (file)
@@ -178,22 +178,6 @@ extern void iounmap(void *addr);
 unsigned long onchip_remap(unsigned long addr, unsigned long size, const char* name);
 extern void onchip_unmap(unsigned long vaddr);
 
-static __inline__ int check_signature(volatile void __iomem *io_addr,
-                       const unsigned char *signature, int length)
-{
-       int retval = 0;
-       do {
-               if (readb(io_addr) != *signature)
-                       goto out;
-               io_addr++;
-               signature++;
-               length--;
-       } while (length);
-       retval = 1;
-out:
-       return retval;
-}
-
 /*
  * The caches on some architectures aren't dma-coherent and have need to
  * handle this in software.  There are three types of operations that
index 83a3dd15a6edffa502634290d3d3b4d910bf85de..aaf6ef40ee2fc12142794a5bd651fc1c91dd3981 100644 (file)
@@ -8,11 +8,6 @@
 
 #include <asm/ptrace.h>
 
-#ifdef __KERNEL__
-#include <asm/mbus.h>
-#include <asm/uaccess.h>
-#endif
-
 /*
  * Sparc section types
  */
@@ -77,6 +72,23 @@ typedef unsigned long elf_greg_t;
 #define ELF_NGREG 38
 typedef elf_greg_t elf_gregset_t[ELF_NGREG];
 
+typedef struct {
+       union {
+               unsigned long   pr_regs[32];
+               double          pr_dregs[16];
+       } pr_fr;
+       unsigned long __unused;
+       unsigned long   pr_fsr;
+       unsigned char   pr_qcnt;
+       unsigned char   pr_q_entrysize;
+       unsigned char   pr_en;
+       unsigned int    pr_q[64];
+} elf_fpregset_t;
+
+#ifdef __KERNEL__
+#include <asm/mbus.h>
+#include <asm/uaccess.h>
+
 /* Format is:
  *     G0 --> G7
  *     O0 --> O7
@@ -99,20 +111,7 @@ do {        unsigned long *dest = &(__elf_regs[0]);         \
        dest[34] = src->npc;                            \
        dest[35] = src->y;                              \
        dest[36] = dest[37] = 0; /* XXX */              \
-} while(0); /* Janitors: Don't touch this colon. */
-
-typedef struct {
-       union {
-               unsigned long   pr_regs[32];
-               double          pr_dregs[16];
-       } pr_fr;
-       unsigned long __unused;
-       unsigned long   pr_fsr;
-       unsigned char   pr_qcnt;
-       unsigned char   pr_q_entrysize;
-       unsigned char   pr_en;
-       unsigned int    pr_q[64];
-} elf_fpregset_t;
+} while(0); /* Janitors: Don't touch this semicolon. */
 
 #define ELF_CORE_COPY_TASK_REGS(__tsk, __elf_regs)     \
        ({ ELF_CORE_COPY_REGS((*(__elf_regs)), (__tsk)->thread.kregs); 1; })
@@ -165,8 +164,8 @@ typedef struct {
 
 #define ELF_PLATFORM   (NULL)
 
-#ifdef __KERNEL__
 #define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX)
-#endif
+
+#endif /* __KERNEL__ */
 
 #endif /* !(__ASMSPARC_ELF_H) */
index c53b332c850a696c63dcd6bb0cd71ea8a2a32ccb..9073c84218ce549204aa873d629d0275d47f1b5e 100644 (file)
@@ -262,7 +262,7 @@ static __inline__ void sun_fd_enable_dma(void)
 }
 
 /* Our low-level entry point in arch/sparc/kernel/entry.S */
-irqreturn_t floppy_hardint(int irq, void *unused, struct pt_regs *regs);
+irqreturn_t floppy_hardint(int irq, void *unused);
 
 static int sun_fd_request_irq(void)
 {
index 3141ddfea97d5ebe5e3f250a59c016d48ad0b6c8..ff520ea97473d7a4ee7e020678c0cd763b867829 100644 (file)
@@ -76,8 +76,8 @@ static inline void load_profile_irq(int cpu, int limit)
        BTFIXUP_CALL(load_profile_irq)(cpu, limit);
 }
 
-extern void (*sparc_init_timers)(irqreturn_t (*lvl10_irq)(int, void *, struct pt_regs *));
-extern void claim_ticker14(irqreturn_t (*irq_handler)(int, void *, struct pt_regs *),
+extern void (*sparc_init_timers)(irq_handler_t lvl10_irq);
+extern void claim_ticker14(irq_handler_t irq_handler,
                           int irq,
                           unsigned int timeout);
 
@@ -91,7 +91,7 @@ BTFIXUPDEF_CALL(void, set_irq_udt, int)
 #define set_irq_udt(cpu) BTFIXUP_CALL(set_irq_udt)(cpu)
 #endif
 
-extern int request_fast_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *), unsigned long flags, __const__ char *devname);
+extern int request_fast_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, __const__ char *devname);
 
 /* On the sun4m, just like the timers, we have both per-cpu and master
  * interrupt registers.
diff --git a/include/asm-sparc/irq_regs.h b/include/asm-sparc/irq_regs.h
new file mode 100644 (file)
index 0000000..3dd9c0b
--- /dev/null
@@ -0,0 +1 @@
+#include <asm-generic/irq_regs.h>
index 557d08959d2f319ce90b491672c9d4ba518ec471..de2249b267c626bd0066a986afc2d910327a3dce 100644 (file)
@@ -129,6 +129,7 @@ static inline void __raw_write_lock(raw_rwlock_t *rw)
        : /* no outputs */
        : "r" (lp)
        : "g2", "g4", "memory", "cc");
+       *(volatile __u32 *)&lp->lock = ~0U;
 }
 
 static inline int __raw_write_trylock(raw_rwlock_t *rw)
@@ -144,15 +145,40 @@ static inline int __raw_write_trylock(raw_rwlock_t *rw)
                val = rw->lock & ~0xff;
                if (val)
                        ((volatile u8*)&rw->lock)[3] = 0;
+               else
+                       *(volatile u32*)&rw->lock = ~0U;
        }
 
        return (val == 0);
 }
 
+static inline int __read_trylock(raw_rwlock_t *rw)
+{
+       register raw_rwlock_t *lp asm("g1");
+       register int res asm("o0");
+       lp = rw;
+       __asm__ __volatile__(
+       "mov    %%o7, %%g4\n\t"
+       "call   ___rw_read_try\n\t"
+       " ldstub        [%%g1 + 3], %%g2\n"
+       : "=r" (res)
+       : "r" (lp)
+       : "g2", "g4", "memory", "cc");
+       return res;
+}
+
+#define __raw_read_trylock(lock) \
+({     unsigned long flags; \
+       int res; \
+       local_irq_save(flags); \
+       res = __read_trylock(lock); \
+       local_irq_restore(flags); \
+       res; \
+})
+
 #define __raw_write_unlock(rw) do { (rw)->lock = 0; } while(0)
 
 #define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock)
-#define __raw_read_trylock(lock) generic__raw_read_trylock(lock)
 
 #define _raw_spin_relax(lock)  cpu_relax()
 #define _raw_read_relax(lock)  cpu_relax()
index c73935dc7ba11c8e800b79596d6ae27e3431fd30..36511ca514165b4307033de76e7b09db646509c1 100644 (file)
@@ -164,7 +164,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr)
        return (u32)(unsigned long)uptr;
 }
 
-static __inline__ void __user *compat_alloc_user_space(long len)
+static inline void __user *compat_alloc_user_space(long len)
 {
        struct pt_regs *regs = current_thread_info()->kregs;
        unsigned long usp = regs->u_regs[UREG_I6];
@@ -174,7 +174,10 @@ static __inline__ void __user *compat_alloc_user_space(long len)
        else
                usp &= 0xffffffffUL;
 
-       return (void __user *) (usp - len);
+       usp -= len;
+       usp &= ~0x7UL;
+
+       return (void __user *) usp;
 }
 
 struct compat_ipc64_perm {
index abf1500380192adeb427a001b63d233fbea0ab54..dbe033e494dbeabf14524c1b78b71e6659d26cd7 100644 (file)
@@ -208,7 +208,7 @@ static void sun_fd_enable_dma(void)
        pdma_areasize = pdma_size;
 }
 
-irqreturn_t sparc_floppy_irq(int irq, void *dev_cookie, struct pt_regs *regs)
+irqreturn_t sparc_floppy_irq(int irq, void *dev_cookie)
 {
        if (likely(doing_pdma)) {
                void __iomem *stat = (void __iomem *) fdc_status;
@@ -255,7 +255,7 @@ irqreturn_t sparc_floppy_irq(int irq, void *dev_cookie, struct pt_regs *regs)
        }
 
 main_interrupt:
-       return floppy_interrupt(irq, dev_cookie, regs);
+       return floppy_interrupt(irq, dev_cookie);
 }
 
 static int sun_fd_request_irq(void)
@@ -311,7 +311,7 @@ struct sun_pci_dma_op {
 static struct sun_pci_dma_op sun_pci_dma_current = { -1U, 0, 0, NULL};
 static struct sun_pci_dma_op sun_pci_dma_pending = { -1U, 0, 0, NULL};
 
-extern irqreturn_t floppy_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+extern irqreturn_t floppy_interrupt(int irq, void *dev_id);
 
 static unsigned char sun_pci_fd_inb(unsigned long port)
 {
@@ -446,7 +446,7 @@ static int sun_pci_fd_eject(int drive)
 
 void sun_pci_fd_dma_callback(struct ebus_dma_info *p, int event, void *cookie)
 {
-       floppy_interrupt(0, NULL, NULL);
+       floppy_interrupt(0, NULL);
 }
 
 /*
index 0056770e83ada176fc091dba50be956dcaf7841f..30b912d8e8bc4a0ed0a0ad6bf6e1221820950197 100644 (file)
@@ -440,21 +440,6 @@ _memcpy_toio(volatile void __iomem *dst, const void *src, __kernel_size_t n)
 
 #define memcpy_toio(d,s,sz)    _memcpy_toio(d,s,sz)
 
-static inline int check_signature(void __iomem *io_addr,
-                                 const unsigned char *signature,
-                                 int length)
-{
-       int retval = 0;
-       do {
-               if (readb(io_addr) != *signature++)
-                       goto out;
-               io_addr++;
-       } while (--length);
-       retval = 1;
-out:
-       return retval;
-}
-
 #define mmiowb()
 
 #ifdef __KERNEL__
diff --git a/include/asm-sparc64/irq_regs.h b/include/asm-sparc64/irq_regs.h
new file mode 100644 (file)
index 0000000..3dd9c0b
--- /dev/null
@@ -0,0 +1 @@
+#include <asm-generic/irq_regs.h>
index 172cd6ffacc4a28c5eceb9b40b97dc86d3019d38..4269d8a37b4f201adffc9788483458943a778091 100644 (file)
@@ -1,15 +1,6 @@
 #ifndef __UM_ARCHPARAM_PPC_H
 #define __UM_ARCHPARAM_PPC_H
 
-/********* Bits for asm-um/hw_irq.h **********/
-
-struct hw_interrupt_type;
-
-/********* Bits for asm-um/hardirq.h **********/
-
-#define irq_enter(cpu, irq) hardirq_enter(cpu)
-#define irq_exit(cpu, irq) hardirq_exit(cpu)
-
 /********* Bits for asm-um/string.h **********/
 
 #define __HAVE_ARCH_STRRCHR
diff --git a/include/asm-um/irq_regs.h b/include/asm-um/irq_regs.h
new file mode 100644 (file)
index 0000000..3dd9c0b
--- /dev/null
@@ -0,0 +1 @@
+#include <asm-generic/irq_regs.h>
index 9e66d32330c9d5a5371fb3b6e59f709cf7ac67eb..e81d0f289f0b06df8fab258197251de7caa45572 100644 (file)
@@ -77,7 +77,7 @@ extern void sync_Arb_IDs (void);
 extern void init_bsp_APIC (void);
 extern void setup_local_APIC (void);
 extern void init_apic_mappings (void);
-extern void smp_local_timer_interrupt (struct pt_regs * regs);
+extern void smp_local_timer_interrupt (void);
 extern void setup_boot_APIC_clock (void);
 extern void setup_secondary_APIC_clock (void);
 extern int APIC_init_uniprocessor (void);
index 32ff5d132714f44c5826472aa46efe16e2ee6e9f..6ea13c3806f3c70ae922731ac14c47375099d15e 100644 (file)
@@ -51,7 +51,7 @@ static char *virtual_dma_addr;
 static int virtual_dma_mode;
 static int doing_pdma;
 
-static irqreturn_t floppy_hardint(int irq, void *dev_id, struct pt_regs * regs)
+static irqreturn_t floppy_hardint(int irq, void *dev_id)
 {
        register unsigned char st;
 
@@ -63,7 +63,7 @@ static irqreturn_t floppy_hardint(int irq, void *dev_id, struct pt_regs * regs)
        static int dma_wait=0;
 #endif
        if (!doing_pdma)
-               return floppy_interrupt(irq, dev_id, regs);
+               return floppy_interrupt(irq, dev_id);
 
 #ifdef TRACE_FLPY_INT
        if(!calls)
@@ -106,7 +106,7 @@ static irqreturn_t floppy_hardint(int irq, void *dev_id, struct pt_regs * regs)
                dma_wait=0;
 #endif
                doing_pdma = 0;
-               floppy_interrupt(irq, dev_id, regs);
+               floppy_interrupt(irq, dev_id);
                return IRQ_HANDLED;
        }
 #ifdef TRACE_FLPY_INT
index 81e714665344623c9990199a5faaee15261b397b..a0e9a4b934844a96c4dced8b8cdd293e2b5decfb 100644 (file)
@@ -18,6 +18,7 @@ struct genapic {
        u32 int_dest_mode;
        int (*apic_id_registered)(void);
        cpumask_t (*target_cpus)(void);
+       cpumask_t (*vector_allocation_domain)(int cpu);
        void (*init_apic_ldr)(void);
        /* ipi */
        void (*send_IPI_mask)(cpumask_t mask, int vector);
index 53d0d9fd10d62c5986d65644a5251121f35b2c27..792dd52fcd702b0ec45a719845d6da5e46c8deed 100644 (file)
 
 
 #ifndef __ASSEMBLY__
-extern unsigned int irq_vector[NR_IRQ_VECTORS];
 typedef int vector_irq_t[NR_VECTORS];
 DECLARE_PER_CPU(vector_irq_t, vector_irq);
-#define IO_APIC_VECTOR(irq)    (irq_vector[irq])
 
 /*
  * Various low-level irq details needed by irq.c, process.c,
index 70e91fe7634485708815dda0c851c2f066064a1c..6ee9fadaaacb29a3a7cba086c37f4f7bd94e6eaf 100644 (file)
@@ -254,33 +254,6 @@ void memset_io(volatile void __iomem *a, int b, size_t c);
 
 #define eth_io_copy_and_sum(a,b,c,d)           eth_copy_and_sum((a),(void *)(b),(c),(d))
 
-/**
- *     check_signature         -       find BIOS signatures
- *     @io_addr: mmio address to check 
- *     @signature:  signature block
- *     @length: length of signature
- *
- *     Perform a signature comparison with the mmio address io_addr. This
- *     address should have been obtained by ioremap.
- *     Returns 1 on a match.
- */
-static inline int check_signature(void __iomem *io_addr,
-       const unsigned char *signature, int length)
-{
-       int retval = 0;
-       do {
-               if (readb(io_addr) != *signature)
-                       goto out;
-               io_addr++;
-               signature++;
-               length--;
-       } while (length);
-       retval = 1;
-out:
-       return retval;
-}
-
 /* Nothing to do */
 
 #define dma_cache_inv(_start,_size)            do { } while (0)
diff --git a/include/asm-x86_64/irq_regs.h b/include/asm-x86_64/irq_regs.h
new file mode 100644 (file)
index 0000000..3dd9c0b
--- /dev/null
@@ -0,0 +1 @@
+#include <asm-generic/irq_regs.h>
index d33422450c00a3bc677246c1cd561ac425e00ad5..7b7115a0c1c99f396740e0b8dcc1066a02e63e73 100644 (file)
@@ -17,6 +17,7 @@
 #define INT_DELIVERY_MODE (genapic->int_delivery_mode)
 #define INT_DEST_MODE (genapic->int_dest_mode)
 #define TARGET_CPUS      (genapic->target_cpus())
+#define vector_allocation_domain       (genapic->vector_allocation_domain)
 #define apic_id_registered (genapic->apic_id_registered)
 #define init_apic_ldr (genapic->init_apic_ldr)
 #define send_IPI_mask (genapic->send_IPI_mask)
index 285756010c517ed2dbc3a9e89e4abb2ac676f561..5ed0ef3408425cf5c10f0ed005f9894cebf1b2df 100644 (file)
 
 /* var is in discarded region: offset to particular copy we want */
 #define per_cpu(var, cpu) (*({                         \
-       extern int simple_indentifier_##var(void);      \
+       extern int simple_identifier_##var(void);       \
        RELOC_HIDE(&per_cpu__##var, __per_cpu_offset(cpu)); }))
 #define __get_cpu_var(var) (*({                                \
-       extern int simple_indentifier_##var(void);      \
+       extern int simple_identifier_##var(void);       \
        RELOC_HIDE(&per_cpu__##var, __my_cpu_offset()); }))
 #define __raw_get_cpu_var(var) (*({                    \
-       extern int simple_indentifier_##var(void);      \
+       extern int simple_identifier_##var(void);       \
        RELOC_HIDE(&per_cpu__##var, __my_cpu_offset()); }))
 
 /* A macro to avoid #include hell... */
index 6899e770b173e4a2cb75fdd5bc664359cdf0fa7b..0555c1c4d8fa9fcda13c280997c076decc85d708 100644 (file)
@@ -366,6 +366,7 @@ static inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot)
 { 
        pte_t pte;
        pte_val(pte) = physpage | pgprot_val(pgprot); 
+       pte_val(pte) &= __supported_pte_mask;
        return pte; 
 }
  
index de9c3147ee4c3dddb639210dc17a9b74b406a040..cef17e0f828cc5d0080cf967d11e80a228f4d18b 100644 (file)
@@ -475,6 +475,8 @@ static inline void __mwait(unsigned long eax, unsigned long ecx)
                : :"a" (eax), "c" (ecx));
 }
 
+extern void mwait_idle_with_hints(unsigned long eax, unsigned long ecx);
+
 #define stack_current() \
 ({                                                             \
        struct thread_info *ti;                                 \
index c28fc2db217197e30a99b956aaa523aaefe4bc9b..e72cfcdf53448d262ce0b549de267ae470f8ebe1 100644 (file)
@@ -66,7 +66,7 @@ extern void free_bootmem_generic(unsigned long phys, unsigned len);
 extern void load_gs_index(unsigned gs);
 
 extern void stop_timer_interrupt(void);
-extern void main_timer_handler(struct pt_regs *regs);
+extern void main_timer_handler(void);
 
 extern unsigned long end_pfn_map; 
 
@@ -122,9 +122,11 @@ extern int fix_aperture;
 extern int reboot_force;
 extern int notsc_setup(char *);
 
+extern int timer_over_8254;
+
 extern int gsi_irq_sharing(int gsi);
 
-extern void smp_local_timer_interrupt(struct pt_regs * regs);
+extern void smp_local_timer_interrupt(void);
 
 long do_arch_prctl(struct task_struct *task, int code, unsigned long addr);
 
index 5114ff18101daee2fa78c13efab980cfaef09326..a1155a2beb32bb46dd3fc6ce66262c53a87c17f8 100644 (file)
@@ -120,6 +120,7 @@ header-y += netrom.h
 header-y += nfs2.h
 header-y += nfs4_mount.h
 header-y += nfs_mount.h
+header-y += oom.h
 header-y += param.h
 header-y += pci_ids.h
 header-y += pci_regs.h
index 88b5dfd8ee125be2c3a025c7ea1e03183eaccbe4..2b0c955590fec1dacf875c4e0dd21d4bc0269c5e 100644 (file)
@@ -494,6 +494,9 @@ void acpi_pci_unregister_driver(struct acpi_pci_driver *driver);
 
 extern int ec_read(u8 addr, u8 *val);
 extern int ec_write(u8 addr, u8 val);
+extern int ec_transaction(u8 command,
+                          const u8 *wdata, unsigned wdata_len,
+                          u8 *rdata, unsigned rdata_len);
 
 #endif /*CONFIG_ACPI_EC*/
 
index b7305b178279316ab8ecce70dff8f3e848dc27bd..64d8878e14440656125e3b0f55024781026c244f 100644 (file)
@@ -90,10 +90,10 @@ extern struct blocking_notifier_head adb_client_list;
 int adb_request(struct adb_request *req, void (*done)(struct adb_request *),
                int flags, int nbytes, ...);
 int adb_register(int default_id,int handler_id,struct adb_ids *ids,
-                void (*handler)(unsigned char *, int, struct pt_regs *, int));
+                void (*handler)(unsigned char *, int, int));
 int adb_unregister(int index);
 void adb_poll(void);
-void adb_input(unsigned char *, int, struct pt_regs *, int);
+void adb_input(unsigned char *, int, int);
 int adb_reset_bus(void);
 
 int adb_try_handler_change(int address, int new_id);
index 231ba090ae34c0617e54f9f20cf6f2a50a7e14b2..2f85049cfb3d1ca94b1b9680bf3db2802b590acf 100644 (file)
@@ -334,7 +334,7 @@ void arcnet_dump_skb(struct net_device *dev, struct sk_buff *skb, char *desc);
 #endif
 
 void arcnet_unregister_proto(struct ArcProto *proto);
-irqreturn_t arcnet_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+irqreturn_t arcnet_interrupt(int irq, void *dev_id);
 struct net_device *alloc_arcdev(char *name);
 
 #endif                         /* __KERNEL__ */
index f7a1390d67f5b39da938c6be93c80cf0cd66fcf2..7011d6255593dda940f859ab02e89e505d1a57ae 100644 (file)
@@ -10,6 +10,8 @@
 
 #include <asm/atomic.h>
 
+struct page;
+
 /*
  * Bits in backing_dev_info.state
  */
@@ -88,6 +90,11 @@ static inline int bdi_rw_congested(struct backing_dev_info *bdi)
                                  (1 << BDI_write_congested));
 }
 
+void clear_bdi_congested(struct backing_dev_info *bdi, int rw);
+void set_bdi_congested(struct backing_dev_info *bdi, int rw);
+long congestion_wait(int rw, long timeout);
+void congestion_end(int rw);
+
 #define bdi_cap_writeback_dirty(bdi) \
        (!((bdi)->capabilities & BDI_CAP_NO_WRITEBACK))
 
index dcc5de7cc487673f786f25c2598091549121d351..64b4641904fee0415c169d3f20e3bd4cdba71f5c 100644 (file)
@@ -46,7 +46,8 @@
  * bitmap_remap(dst, src, old, new, nbits)     *dst = map(old, new)(src)
  * bitmap_bitremap(oldbit, old, new, nbits)    newbit = map(old, new)(oldbit)
  * bitmap_scnprintf(buf, len, src, nbits)      Print bitmap src to buf
- * bitmap_parse(ubuf, ulen, dst, nbits)                Parse bitmap dst from user buf
+ * bitmap_parse(buf, buflen, dst, nbits)       Parse bitmap dst from kernel buf
+ * bitmap_parse_user(ubuf, ulen, dst, nbits)   Parse bitmap dst from user buf
  * bitmap_scnlistprintf(buf, len, src, nbits)  Print bitmap src as list to buf
  * bitmap_parselist(buf, dst, nbits)           Parse bitmap dst from list
  * bitmap_find_free_region(bitmap, bits, order)        Find and allocate bit region
@@ -106,7 +107,9 @@ extern int __bitmap_weight(const unsigned long *bitmap, int bits);
 
 extern int bitmap_scnprintf(char *buf, unsigned int len,
                        const unsigned long *src, int nbits);
-extern int bitmap_parse(const char __user *ubuf, unsigned int ulen,
+extern int __bitmap_parse(const char *buf, unsigned int buflen, int is_user,
+                       unsigned long *dst, int nbits);
+extern int bitmap_parse_user(const char __user *ubuf, unsigned int ulen,
                        unsigned long *dst, int nbits);
 extern int bitmap_scnlistprintf(char *buf, unsigned int len,
                        const unsigned long *src, int nbits);
@@ -270,6 +273,12 @@ static inline void bitmap_shift_left(unsigned long *dst,
                __bitmap_shift_left(dst, src, n, nbits);
 }
 
+static inline int bitmap_parse(const char *buf, unsigned int buflen,
+                       unsigned long *maskp, int nmaskbits)
+{
+       return __bitmap_parse(buf, buflen, 0, maskp, nmaskbits);
+}
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* __LINUX_BITMAP_H */
index 26f7856ff8123e4b249ca985505fcd80d7d367d3..7bfcde2d557833935eab407e048c1763d194c4fd 100644 (file)
@@ -157,6 +157,7 @@ enum rq_cmd_type_bits {
        REQ_TYPE_ATA_CMD,
        REQ_TYPE_ATA_TASK,
        REQ_TYPE_ATA_TASKFILE,
+       REQ_TYPE_ATA_PC,
 };
 
 /*
@@ -650,6 +651,26 @@ extern void blk_recount_segments(request_queue_t *, struct bio *);
 extern int scsi_cmd_ioctl(struct file *, struct gendisk *, unsigned int, void __user *);
 extern int sg_scsi_ioctl(struct file *, struct request_queue *,
                struct gendisk *, struct scsi_ioctl_command __user *);
+
+/*
+ * A queue has just exitted congestion.  Note this in the global counter of
+ * congested queues, and wake up anyone who was waiting for requests to be
+ * put back.
+ */
+static inline void blk_clear_queue_congested(request_queue_t *q, int rw)
+{
+       clear_bdi_congested(&q->backing_dev_info, rw);
+}
+
+/*
+ * A queue has just entered congestion.  Flag that in the queue's VM-visible
+ * state flags and increment the global gounter of congested queues.
+ */
+static inline void blk_set_queue_congested(request_queue_t *q, int rw)
+{
+       set_bdi_congested(&q->backing_dev_info, rw);
+}
+
 extern void blk_start_queue(request_queue_t *q);
 extern void blk_stop_queue(request_queue_t *q);
 extern void blk_sync_queue(struct request_queue *q);
@@ -764,10 +785,8 @@ extern int blk_queue_init_tags(request_queue_t *, int, struct blk_queue_tag *);
 extern void blk_queue_free_tags(request_queue_t *);
 extern int blk_queue_resize_tags(request_queue_t *, int);
 extern void blk_queue_invalidate_tags(request_queue_t *);
-extern long blk_congestion_wait(int rw, long timeout);
 extern struct blk_queue_tag *blk_init_tags(int);
 extern void blk_free_tags(struct blk_queue_tag *);
-extern void blk_congestion_end(int rw);
 
 static inline struct request *blk_map_queue_find_tag(struct blk_queue_tag *bqt,
                                                int tag)
index 131ffd37e716fb7ac4a386eaea9ff58c26bf639d..5d9fb0e94156235eca46e199352933fc638b9596 100644 (file)
@@ -69,6 +69,8 @@ struct buffer_head {
        bh_end_io_t *b_end_io;          /* I/O completion */
        void *b_private;                /* reserved for b_end_io */
        struct list_head b_assoc_buffers; /* associated with another mapping */
+       struct address_space *b_assoc_map;      /* mapping this buffer is
+                                                  associated with */
        atomic_t b_count;               /* users using this buffer_head */
 };
 
diff --git a/include/linux/carta_random32.h b/include/linux/carta_random32.h
new file mode 100644 (file)
index 0000000..f6f3bd9
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Fast, simple, yet decent quality random number generator based on
+ * a paper by David G. Carta ("Two Fast Implementations of the
+ * `Minimal Standard' Random Number Generator," Communications of the
+ * ACM, January, 1990).
+ *
+ * Copyright (c) 2002-2006 Hewlett-Packard Development Company, L.P.
+ *     Contributed by Stephane Eranian <eranian@hpl.hp.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,
+ * 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
+ */
+#ifndef _LINUX_CARTA_RANDOM32_H_
+#define _LINUX_CARTA_RANDOM32_H_
+
+u64 carta_random32(u64 seed);
+
+#endif /* _LINUX_CARTA_RANDOM32_H_ */
index 3c9b0bc05123f1f8ceae3c2854a1a7e4b1c2a478..bbbe7b4da0bbc65c9a12f0043f280a2e6c5e1a65 100644 (file)
@@ -749,7 +749,7 @@ struct request_sense {
 #define MRW_MODE_PC                    0x03
 
 struct mrw_feature_desc {
-       __u16 feature_code;
+       __be16 feature_code;
 #if defined(__BIG_ENDIAN_BITFIELD)
        __u8 reserved1          : 2;
        __u8 feature_version    : 4;
@@ -776,7 +776,7 @@ struct mrw_feature_desc {
 
 /* cf. mmc4r02g.pdf 5.3.10 Random Writable Feature (0020h) pg 197 of 635 */
 struct rwrt_feature_desc {
-       __u16 feature_code;
+       __be16 feature_code;
 #if defined(__BIG_ENDIAN_BITFIELD)
        __u8 reserved1          : 2;
        __u8 feature_version    : 4;
@@ -803,7 +803,7 @@ struct rwrt_feature_desc {
 };
 
 typedef struct {
-       __u16 disc_information_length;
+       __be16 disc_information_length;
 #if defined(__BIG_ENDIAN_BITFIELD)
        __u8 reserved1                  : 3;
         __u8 erasable                  : 1;
@@ -849,7 +849,7 @@ typedef struct {
 } disc_information;
 
 typedef struct {
-       __u16 track_information_length;
+       __be16 track_information_length;
        __u8 track_lsb;
        __u8 session_lsb;
        __u8 reserved1;
@@ -880,12 +880,12 @@ typedef struct {
        __u8 lra_v                      : 1;
        __u8 reserved3                  : 6;
 #endif
-       __u32 track_start;
-       __u32 next_writable;
-       __u32 free_blocks;
-       __u32 fixed_packet_size;
-       __u32 track_size;
-       __u32 last_rec_address;
+       __be32 track_start;
+       __be32 next_writable;
+       __be32 free_blocks;
+       __be32 fixed_packet_size;
+       __be32 track_size;
+       __be32 last_rec_address;
 } track_information;
 
 struct feature_header {
@@ -896,12 +896,12 @@ struct feature_header {
 };
 
 struct mode_page_header {
-       __u16 mode_data_length;
+       __be16 mode_data_length;
        __u8 medium_type;
        __u8 reserved1;
        __u8 reserved2;
        __u8 reserved3;
-       __u16 desc_length;
+       __be16 desc_length;
 };
 
 #ifdef __KERNEL__
@@ -1106,7 +1106,7 @@ typedef struct {
 #endif
        __u8 session_format;
        __u8 reserved6;
-       __u32 packet_size;
+       __be32 packet_size;
        __u16 audio_pause;
        __u8 mcn[16];
        __u8 isrc[16];
@@ -1151,7 +1151,7 @@ typedef struct {
 } rpc_state_t;
 
 struct event_header {
-       __u16 data_len;
+       __be16 data_len;
 #if defined(__BIG_ENDIAN_BITFIELD)
        __u8 nea                : 1;
        __u8 reserved1          : 4;
index ef5cd192784c23bc326531660184c2098f930736..f4ebf96f5308ea0c50310bbff32745d626f69567 100644 (file)
@@ -163,7 +163,7 @@ asmlinkage long
 compat_sys_set_robust_list(struct compat_robust_list_head __user *head,
                           compat_size_t len);
 asmlinkage long
-compat_sys_get_robust_list(int pid, compat_uptr_t *head_ptr,
+compat_sys_get_robust_list(int pid, compat_uptr_t __user *head_ptr,
                           compat_size_t __user *len_ptr);
 
 long compat_sys_semctl(int first, int second, int third, void __user *uptr);
index 4e1663d7691e4a44c676a446d2c94374963656b3..c26c3adcfacff0aa9231d527daf75d0f2fc09336 100644 (file)
@@ -61,17 +61,23 @@ COMPATIBLE_IOCTL(FIGETBSZ)
  *         Some need translations, these do not.
  */
 COMPATIBLE_IOCTL(HDIO_GET_IDENTITY)
-COMPATIBLE_IOCTL(HDIO_SET_DMA)
-COMPATIBLE_IOCTL(HDIO_SET_UNMASKINTR)
-COMPATIBLE_IOCTL(HDIO_SET_NOWERR)
-COMPATIBLE_IOCTL(HDIO_SET_32BIT)
-COMPATIBLE_IOCTL(HDIO_SET_MULTCOUNT)
-COMPATIBLE_IOCTL(HDIO_DRIVE_CMD)
 COMPATIBLE_IOCTL(HDIO_DRIVE_TASK)
-COMPATIBLE_IOCTL(HDIO_SET_PIO_MODE)
-COMPATIBLE_IOCTL(HDIO_SET_NICE)
-COMPATIBLE_IOCTL(HDIO_SET_KEEPSETTINGS)
+COMPATIBLE_IOCTL(HDIO_DRIVE_CMD)
+ULONG_IOCTL(HDIO_SET_MULTCOUNT)
+ULONG_IOCTL(HDIO_SET_UNMASKINTR)
+ULONG_IOCTL(HDIO_SET_KEEPSETTINGS)
+ULONG_IOCTL(HDIO_SET_32BIT)
+ULONG_IOCTL(HDIO_SET_NOWERR)
+ULONG_IOCTL(HDIO_SET_DMA)
+ULONG_IOCTL(HDIO_SET_PIO_MODE)
+ULONG_IOCTL(HDIO_SET_NICE)
+ULONG_IOCTL(HDIO_SET_WCACHE)
+ULONG_IOCTL(HDIO_SET_ACOUSTIC)
+ULONG_IOCTL(HDIO_SET_BUSSTATE)
+ULONG_IOCTL(HDIO_SET_ADDRESS)
 COMPATIBLE_IOCTL(HDIO_SCAN_HWIF)
+/* 0x330 is reserved -- it used to be HDIO_GETGEO_BIG */
+COMPATIBLE_IOCTL(0x330)
 /* 0x02 -- Floppy ioctls */
 COMPATIBLE_IOCTL(FDMSGON)
 COMPATIBLE_IOCTL(FDMSGOFF)
@@ -125,6 +131,7 @@ COMPATIBLE_IOCTL(RUN_ARRAY)
 COMPATIBLE_IOCTL(STOP_ARRAY)
 COMPATIBLE_IOCTL(STOP_ARRAY_RO)
 COMPATIBLE_IOCTL(RESTART_ARRAY_RW)
+COMPATIBLE_IOCTL(GET_BITMAP_FILE)
 ULONG_IOCTL(SET_BITMAP_FILE)
 /* DM */
 COMPATIBLE_IOCTL(DM_VERSION_32)
diff --git a/include/linux/config.h b/include/linux/config.h
deleted file mode 100644 (file)
index 479ffb0..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef _LINUX_CONFIG_H
-#define _LINUX_CONFIG_H
-/* This file is no longer in use and kept only for backward compatibility.
- * autoconf.h is now included via -imacros on the commandline
- */
-#warning Including config.h is deprecated.
-#include <linux/autoconf.h>
-
-#endif
index b268a3c0c37628d23231754f1ad9047ac47a74b8..d0e8c8b0e34dee03a78823c81d2c7536ce88e2cc 100644 (file)
@@ -8,8 +8,8 @@
  * See detailed comments in the file linux/bitmap.h describing the
  * data type on which these cpumasks are based.
  *
- * For details of cpumask_scnprintf() and cpumask_parse(),
- * see bitmap_scnprintf() and bitmap_parse() in lib/bitmap.c.
+ * For details of cpumask_scnprintf() and cpumask_parse_user(),
+ * see bitmap_scnprintf() and bitmap_parse_user() in lib/bitmap.c.
  * For details of cpulist_scnprintf() and cpulist_parse(), see
  * bitmap_scnlistprintf() and bitmap_parselist(), also in bitmap.c.
  * For details of cpu_remap(), see bitmap_bitremap in lib/bitmap.c
@@ -49,7 +49,7 @@
  * unsigned long *cpus_addr(mask)      Array of unsigned long's in mask
  *
  * int cpumask_scnprintf(buf, len, mask) Format cpumask for printing
- * int cpumask_parse(ubuf, ulen, mask) Parse ascii string as cpumask
+ * int cpumask_parse_user(ubuf, ulen, mask)    Parse ascii string as cpumask
  * int cpulist_scnprintf(buf, len, mask) Format cpumask as list for printing
  * int cpulist_parse(buf, map)         Parse ascii string as cpulist
  * int cpu_remap(oldbit, old, new)     newbit = map(old, new)(oldbit)
@@ -273,12 +273,12 @@ static inline int __cpumask_scnprintf(char *buf, int len,
        return bitmap_scnprintf(buf, len, srcp->bits, nbits);
 }
 
-#define cpumask_parse(ubuf, ulen, dst) \
-                       __cpumask_parse((ubuf), (ulen), &(dst), NR_CPUS)
-static inline int __cpumask_parse(const char __user *buf, int len,
+#define cpumask_parse_user(ubuf, ulen, dst) \
+                       __cpumask_parse_user((ubuf), (ulen), &(dst), NR_CPUS)
+static inline int __cpumask_parse_user(const char __user *buf, int len,
                                        cpumask_t *dstp, int nbits)
 {
-       return bitmap_parse(buf, len, dstp->bits, nbits);
+       return bitmap_parse_user(buf, len, dstp->bits, nbits);
 }
 
 #define cpulist_scnprintf(buf, len, src) \
index 44605be5940902caac298dc796d0d8376ff89686..63f64a9a5bf7b207b674be433d1c3b218ff39813 100644 (file)
@@ -230,6 +230,7 @@ extern struct dentry * d_alloc_anon(struct inode *);
 extern struct dentry * d_splice_alias(struct inode *, struct dentry *);
 extern void shrink_dcache_sb(struct super_block *);
 extern void shrink_dcache_parent(struct dentry *);
+extern void shrink_dcache_for_umount(struct super_block *);
 extern int d_invalidate(struct dentry *);
 
 /* only used at mount-time */
index d6f4ec467a4bb9f273c7fdea7d7a04b08fbcee7a..53553c99cad636c888900bd0b63698b2f4a81b43 100644 (file)
@@ -191,7 +191,7 @@ enum {
 /* this structure is argument to DCCP_SOCKOPT_CHANGE_X */
 struct dccp_so_feat {
        __u8 dccpsf_feat;
-       __u8 *dccpsf_val;
+       __u8 __user *dccpsf_val;
        __u8 dccpsf_len;
 };
 
index 662e6a10144e5b453b2ad11b02fc7314bd33816e..9d4f6a9639365bd6e2483ed911ea336a9e83caa0 100644 (file)
@@ -393,7 +393,7 @@ extern void device_unregister(struct device * dev);
 extern void device_initialize(struct device * dev);
 extern int __must_check device_add(struct device * dev);
 extern void device_del(struct device * dev);
-extern int __must_check device_for_each_child(struct device *, void *,
+extern int device_for_each_child(struct device *, void *,
                     int (*fn)(struct device *, void *));
 extern int device_rename(struct device *dev, char *new_name);
 
index 38dc403be70b5bc4f49aee4132ba7ea85ca61399..904bf3d2d90bb068bc3837dfc40bf45e65cdddb6 100644 (file)
@@ -69,6 +69,7 @@ extern struct dmi_device * dmi_find_device(int type, const char *name,
        struct dmi_device *from);
 extern void dmi_scan_machine(void);
 extern int dmi_get_year(int field);
+extern int dmi_name_in_vendors(char *str);
 
 #else
 
@@ -77,6 +78,7 @@ static inline char * dmi_get_system_info(int field) { return NULL; }
 static inline struct dmi_device * dmi_find_device(int type, const char *name,
        struct dmi_device *from) { return NULL; }
 static inline int dmi_get_year(int year) { return 0; }
+static inline int dmi_name_in_vendors(char *s) { return 0; }
 
 #endif
 
index b3370ef5164d0589d3300e91162c0b5599045de1..2fa9f1144228e7270ab626b2daf887ff0eb1b1b9 100644 (file)
@@ -70,7 +70,6 @@ struct elevator_type
 {
        struct list_head list;
        struct elevator_ops ops;
-       struct elevator_type *elevator_type;
        struct elv_fs_entry *elevator_attrs;
        char elevator_name[ELV_NAME_MAX];
        struct module *elevator_owner;
diff --git a/include/linux/ext4_fs.h b/include/linux/ext4_fs.h
new file mode 100644 (file)
index 0000000..498503e
--- /dev/null
@@ -0,0 +1,994 @@
+/*
+ *  linux/include/linux/ext4_fs.h
+ *
+ * Copyright (C) 1992, 1993, 1994, 1995
+ * Remy Card (card@masi.ibp.fr)
+ * Laboratoire MASI - Institut Blaise Pascal
+ * Universite Pierre et Marie Curie (Paris VI)
+ *
+ *  from
+ *
+ *  linux/include/linux/minix_fs.h
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ */
+
+#ifndef _LINUX_EXT4_FS_H
+#define _LINUX_EXT4_FS_H
+
+#include <linux/types.h>
+#include <linux/blkdev.h>
+#include <linux/magic.h>
+
+/*
+ * The second extended filesystem constants/structures
+ */
+
+/*
+ * Define EXT4FS_DEBUG to produce debug messages
+ */
+#undef EXT4FS_DEBUG
+
+/*
+ * Define EXT4_RESERVATION to reserve data blocks for expanding files
+ */
+#define EXT4_DEFAULT_RESERVE_BLOCKS     8
+/*max window size: 1024(direct blocks) + 3([t,d]indirect blocks) */
+#define EXT4_MAX_RESERVE_BLOCKS         1027
+#define EXT4_RESERVE_WINDOW_NOT_ALLOCATED 0
+/*
+ * Always enable hashed directories
+ */
+#define CONFIG_EXT4_INDEX
+
+/*
+ * Debug code
+ */
+#ifdef EXT4FS_DEBUG
+#define ext4_debug(f, a...)                                            \
+       do {                                                            \
+               printk (KERN_DEBUG "EXT4-fs DEBUG (%s, %d): %s:",       \
+                       __FILE__, __LINE__, __FUNCTION__);              \
+               printk (KERN_DEBUG f, ## a);                            \
+       } while (0)
+#else
+#define ext4_debug(f, a...)    do {} while (0)
+#endif
+
+/*
+ * Special inodes numbers
+ */
+#define        EXT4_BAD_INO             1      /* Bad blocks inode */
+#define EXT4_ROOT_INO           2      /* Root inode */
+#define EXT4_BOOT_LOADER_INO    5      /* Boot loader inode */
+#define EXT4_UNDEL_DIR_INO      6      /* Undelete directory inode */
+#define EXT4_RESIZE_INO                 7      /* Reserved group descriptors inode */
+#define EXT4_JOURNAL_INO        8      /* Journal inode */
+
+/* First non-reserved inode for old ext4 filesystems */
+#define EXT4_GOOD_OLD_FIRST_INO        11
+
+/*
+ * Maximal count of links to a file
+ */
+#define EXT4_LINK_MAX          32000
+
+/*
+ * Macro-instructions used to manage several block sizes
+ */
+#define EXT4_MIN_BLOCK_SIZE            1024
+#define        EXT4_MAX_BLOCK_SIZE             4096
+#define EXT4_MIN_BLOCK_LOG_SIZE                  10
+#ifdef __KERNEL__
+# define EXT4_BLOCK_SIZE(s)            ((s)->s_blocksize)
+#else
+# define EXT4_BLOCK_SIZE(s)            (EXT4_MIN_BLOCK_SIZE << (s)->s_log_block_size)
+#endif
+#define        EXT4_ADDR_PER_BLOCK(s)          (EXT4_BLOCK_SIZE(s) / sizeof (__u32))
+#ifdef __KERNEL__
+# define EXT4_BLOCK_SIZE_BITS(s)       ((s)->s_blocksize_bits)
+#else
+# define EXT4_BLOCK_SIZE_BITS(s)       ((s)->s_log_block_size + 10)
+#endif
+#ifdef __KERNEL__
+#define        EXT4_ADDR_PER_BLOCK_BITS(s)     (EXT4_SB(s)->s_addr_per_block_bits)
+#define EXT4_INODE_SIZE(s)             (EXT4_SB(s)->s_inode_size)
+#define EXT4_FIRST_INO(s)              (EXT4_SB(s)->s_first_ino)
+#else
+#define EXT4_INODE_SIZE(s)     (((s)->s_rev_level == EXT4_GOOD_OLD_REV) ? \
+                                EXT4_GOOD_OLD_INODE_SIZE : \
+                                (s)->s_inode_size)
+#define EXT4_FIRST_INO(s)      (((s)->s_rev_level == EXT4_GOOD_OLD_REV) ? \
+                                EXT4_GOOD_OLD_FIRST_INO : \
+                                (s)->s_first_ino)
+#endif
+
+/*
+ * Macro-instructions used to manage fragments
+ */
+#define EXT4_MIN_FRAG_SIZE             1024
+#define        EXT4_MAX_FRAG_SIZE              4096
+#define EXT4_MIN_FRAG_LOG_SIZE           10
+#ifdef __KERNEL__
+# define EXT4_FRAG_SIZE(s)             (EXT4_SB(s)->s_frag_size)
+# define EXT4_FRAGS_PER_BLOCK(s)       (EXT4_SB(s)->s_frags_per_block)
+#else
+# define EXT4_FRAG_SIZE(s)             (EXT4_MIN_FRAG_SIZE << (s)->s_log_frag_size)
+# define EXT4_FRAGS_PER_BLOCK(s)       (EXT4_BLOCK_SIZE(s) / EXT4_FRAG_SIZE(s))
+#endif
+
+/*
+ * Structure of a blocks group descriptor
+ */
+struct ext4_group_desc
+{
+       __le32  bg_block_bitmap;                /* Blocks bitmap block */
+       __le32  bg_inode_bitmap;                /* Inodes bitmap block */
+       __le32  bg_inode_table;         /* Inodes table block */
+       __le16  bg_free_blocks_count;   /* Free blocks count */
+       __le16  bg_free_inodes_count;   /* Free inodes count */
+       __le16  bg_used_dirs_count;     /* Directories count */
+       __u16   bg_flags;
+       __u32   bg_reserved[3];
+       __le32  bg_block_bitmap_hi;     /* Blocks bitmap block MSB */
+       __le32  bg_inode_bitmap_hi;     /* Inodes bitmap block MSB */
+       __le32  bg_inode_table_hi;      /* Inodes table block MSB */
+};
+
+#ifdef __KERNEL__
+#include <linux/ext4_fs_i.h>
+#include <linux/ext4_fs_sb.h>
+#endif
+/*
+ * Macro-instructions used to manage group descriptors
+ */
+#define EXT4_MIN_DESC_SIZE             32
+#define EXT4_MIN_DESC_SIZE_64BIT       64
+#define        EXT4_MAX_DESC_SIZE              EXT4_MIN_BLOCK_SIZE
+#define EXT4_DESC_SIZE(s)              (EXT4_SB(s)->s_desc_size)
+#ifdef __KERNEL__
+# define EXT4_BLOCKS_PER_GROUP(s)      (EXT4_SB(s)->s_blocks_per_group)
+# define EXT4_DESC_PER_BLOCK(s)                (EXT4_SB(s)->s_desc_per_block)
+# define EXT4_INODES_PER_GROUP(s)      (EXT4_SB(s)->s_inodes_per_group)
+# define EXT4_DESC_PER_BLOCK_BITS(s)   (EXT4_SB(s)->s_desc_per_block_bits)
+#else
+# define EXT4_BLOCKS_PER_GROUP(s)      ((s)->s_blocks_per_group)
+# define EXT4_DESC_PER_BLOCK(s)                (EXT4_BLOCK_SIZE(s) / EXT4_DESC_SIZE(s))
+# define EXT4_INODES_PER_GROUP(s)      ((s)->s_inodes_per_group)
+#endif
+
+/*
+ * Constants relative to the data blocks
+ */
+#define        EXT4_NDIR_BLOCKS                12
+#define        EXT4_IND_BLOCK                  EXT4_NDIR_BLOCKS
+#define        EXT4_DIND_BLOCK                 (EXT4_IND_BLOCK + 1)
+#define        EXT4_TIND_BLOCK                 (EXT4_DIND_BLOCK + 1)
+#define        EXT4_N_BLOCKS                   (EXT4_TIND_BLOCK + 1)
+
+/*
+ * Inode flags
+ */
+#define        EXT4_SECRM_FL                   0x00000001 /* Secure deletion */
+#define        EXT4_UNRM_FL                    0x00000002 /* Undelete */
+#define        EXT4_COMPR_FL                   0x00000004 /* Compress file */
+#define EXT4_SYNC_FL                   0x00000008 /* Synchronous updates */
+#define EXT4_IMMUTABLE_FL              0x00000010 /* Immutable file */
+#define EXT4_APPEND_FL                 0x00000020 /* writes to file may only append */
+#define EXT4_NODUMP_FL                 0x00000040 /* do not dump file */
+#define EXT4_NOATIME_FL                        0x00000080 /* do not update atime */
+/* Reserved for compression usage... */
+#define EXT4_DIRTY_FL                  0x00000100
+#define EXT4_COMPRBLK_FL               0x00000200 /* One or more compressed clusters */
+#define EXT4_NOCOMPR_FL                        0x00000400 /* Don't compress */
+#define EXT4_ECOMPR_FL                 0x00000800 /* Compression error */
+/* End compression flags --- maybe not all used */
+#define EXT4_INDEX_FL                  0x00001000 /* hash-indexed directory */
+#define EXT4_IMAGIC_FL                 0x00002000 /* AFS directory */
+#define EXT4_JOURNAL_DATA_FL           0x00004000 /* file data should be journaled */
+#define EXT4_NOTAIL_FL                 0x00008000 /* file tail should not be merged */
+#define EXT4_DIRSYNC_FL                        0x00010000 /* dirsync behaviour (directories only) */
+#define EXT4_TOPDIR_FL                 0x00020000 /* Top of directory hierarchies*/
+#define EXT4_RESERVED_FL               0x80000000 /* reserved for ext4 lib */
+#define EXT4_EXTENTS_FL                        0x00080000 /* Inode uses extents */
+
+#define EXT4_FL_USER_VISIBLE           0x000BDFFF /* User visible flags */
+#define EXT4_FL_USER_MODIFIABLE                0x000380FF /* User modifiable flags */
+
+/*
+ * Inode dynamic state flags
+ */
+#define EXT4_STATE_JDATA               0x00000001 /* journaled data exists */
+#define EXT4_STATE_NEW                 0x00000002 /* inode is newly created */
+#define EXT4_STATE_XATTR               0x00000004 /* has in-inode xattrs */
+
+/* Used to pass group descriptor data when online resize is done */
+struct ext4_new_group_input {
+       __u32 group;            /* Group number for this data */
+       __u64 block_bitmap;     /* Absolute block number of block bitmap */
+       __u64 inode_bitmap;     /* Absolute block number of inode bitmap */
+       __u64 inode_table;      /* Absolute block number of inode table start */
+       __u32 blocks_count;     /* Total number of blocks in this group */
+       __u16 reserved_blocks;  /* Number of reserved blocks in this group */
+       __u16 unused;
+};
+
+/* The struct ext4_new_group_input in kernel space, with free_blocks_count */
+struct ext4_new_group_data {
+       __u32 group;
+       __u64 block_bitmap;
+       __u64 inode_bitmap;
+       __u64 inode_table;
+       __u32 blocks_count;
+       __u16 reserved_blocks;
+       __u16 unused;
+       __u32 free_blocks_count;
+};
+
+
+/*
+ * ioctl commands
+ */
+#define        EXT4_IOC_GETFLAGS               FS_IOC_GETFLAGS
+#define        EXT4_IOC_SETFLAGS               FS_IOC_SETFLAGS
+#define        EXT4_IOC_GETVERSION             _IOR('f', 3, long)
+#define        EXT4_IOC_SETVERSION             _IOW('f', 4, long)
+#define EXT4_IOC_GROUP_EXTEND          _IOW('f', 7, unsigned long)
+#define EXT4_IOC_GROUP_ADD             _IOW('f', 8,struct ext4_new_group_input)
+#define        EXT4_IOC_GETVERSION_OLD         FS_IOC_GETVERSION
+#define        EXT4_IOC_SETVERSION_OLD         FS_IOC_SETVERSION
+#ifdef CONFIG_JBD_DEBUG
+#define EXT4_IOC_WAIT_FOR_READONLY     _IOR('f', 99, long)
+#endif
+#define EXT4_IOC_GETRSVSZ              _IOR('f', 5, long)
+#define EXT4_IOC_SETRSVSZ              _IOW('f', 6, long)
+
+/*
+ * ioctl commands in 32 bit emulation
+ */
+#define EXT4_IOC32_GETFLAGS            FS_IOC32_GETFLAGS
+#define EXT4_IOC32_SETFLAGS            FS_IOC32_SETFLAGS
+#define EXT4_IOC32_GETVERSION          _IOR('f', 3, int)
+#define EXT4_IOC32_SETVERSION          _IOW('f', 4, int)
+#define EXT4_IOC32_GETRSVSZ            _IOR('f', 5, int)
+#define EXT4_IOC32_SETRSVSZ            _IOW('f', 6, int)
+#define EXT4_IOC32_GROUP_EXTEND                _IOW('f', 7, unsigned int)
+#ifdef CONFIG_JBD_DEBUG
+#define EXT4_IOC32_WAIT_FOR_READONLY   _IOR('f', 99, int)
+#endif
+#define EXT4_IOC32_GETVERSION_OLD      FS_IOC32_GETVERSION
+#define EXT4_IOC32_SETVERSION_OLD      FS_IOC32_SETVERSION
+
+
+/*
+ *  Mount options
+ */
+struct ext4_mount_options {
+       unsigned long s_mount_opt;
+       uid_t s_resuid;
+       gid_t s_resgid;
+       unsigned long s_commit_interval;
+#ifdef CONFIG_QUOTA
+       int s_jquota_fmt;
+       char *s_qf_names[MAXQUOTAS];
+#endif
+};
+
+/*
+ * Structure of an inode on the disk
+ */
+struct ext4_inode {
+       __le16  i_mode;         /* File mode */
+       __le16  i_uid;          /* Low 16 bits of Owner Uid */
+       __le32  i_size;         /* Size in bytes */
+       __le32  i_atime;        /* Access time */
+       __le32  i_ctime;        /* Creation time */
+       __le32  i_mtime;        /* Modification time */
+       __le32  i_dtime;        /* Deletion Time */
+       __le16  i_gid;          /* Low 16 bits of Group Id */
+       __le16  i_links_count;  /* Links count */
+       __le32  i_blocks;       /* Blocks count */
+       __le32  i_flags;        /* File flags */
+       union {
+               struct {
+                       __u32  l_i_reserved1;
+               } linux1;
+               struct {
+                       __u32  h_i_translator;
+               } hurd1;
+               struct {
+                       __u32  m_i_reserved1;
+               } masix1;
+       } osd1;                         /* OS dependent 1 */
+       __le32  i_block[EXT4_N_BLOCKS];/* Pointers to blocks */
+       __le32  i_generation;   /* File version (for NFS) */
+       __le32  i_file_acl;     /* File ACL */
+       __le32  i_dir_acl;      /* Directory ACL */
+       __le32  i_faddr;        /* Fragment address */
+       union {
+               struct {
+                       __u8    l_i_frag;       /* Fragment number */
+                       __u8    l_i_fsize;      /* Fragment size */
+                       __le16  l_i_file_acl_high;
+                       __le16  l_i_uid_high;   /* these 2 fields    */
+                       __le16  l_i_gid_high;   /* were reserved2[0] */
+                       __u32   l_i_reserved2;
+               } linux2;
+               struct {
+                       __u8    h_i_frag;       /* Fragment number */
+                       __u8    h_i_fsize;      /* Fragment size */
+                       __u16   h_i_mode_high;
+                       __u16   h_i_uid_high;
+                       __u16   h_i_gid_high;
+                       __u32   h_i_author;
+               } hurd2;
+               struct {
+                       __u8    m_i_frag;       /* Fragment number */
+                       __u8    m_i_fsize;      /* Fragment size */
+                       __le16  m_i_file_acl_high;
+                       __u32   m_i_reserved2[2];
+               } masix2;
+       } osd2;                         /* OS dependent 2 */
+       __le16  i_extra_isize;
+       __le16  i_pad1;
+};
+
+#define i_size_high    i_dir_acl
+
+#if defined(__KERNEL__) || defined(__linux__)
+#define i_reserved1    osd1.linux1.l_i_reserved1
+#define i_frag         osd2.linux2.l_i_frag
+#define i_fsize                osd2.linux2.l_i_fsize
+#define i_file_acl_high        osd2.linux2.l_i_file_acl_high
+#define i_uid_low      i_uid
+#define i_gid_low      i_gid
+#define i_uid_high     osd2.linux2.l_i_uid_high
+#define i_gid_high     osd2.linux2.l_i_gid_high
+#define i_reserved2    osd2.linux2.l_i_reserved2
+
+#elif defined(__GNU__)
+
+#define i_translator   osd1.hurd1.h_i_translator
+#define i_frag         osd2.hurd2.h_i_frag;
+#define i_fsize                osd2.hurd2.h_i_fsize;
+#define i_uid_high     osd2.hurd2.h_i_uid_high
+#define i_gid_high     osd2.hurd2.h_i_gid_high
+#define i_author       osd2.hurd2.h_i_author
+
+#elif defined(__masix__)
+
+#define i_reserved1    osd1.masix1.m_i_reserved1
+#define i_frag         osd2.masix2.m_i_frag
+#define i_fsize                osd2.masix2.m_i_fsize
+#define i_file_acl_high        osd2.masix2.m_i_file_acl_high
+#define i_reserved2    osd2.masix2.m_i_reserved2
+
+#endif /* defined(__KERNEL__) || defined(__linux__) */
+
+/*
+ * File system states
+ */
+#define        EXT4_VALID_FS                   0x0001  /* Unmounted cleanly */
+#define        EXT4_ERROR_FS                   0x0002  /* Errors detected */
+#define        EXT4_ORPHAN_FS                  0x0004  /* Orphans being recovered */
+
+/*
+ * Mount flags
+ */
+#define EXT4_MOUNT_CHECK               0x00001 /* Do mount-time checks */
+#define EXT4_MOUNT_OLDALLOC            0x00002  /* Don't use the new Orlov allocator */
+#define EXT4_MOUNT_GRPID               0x00004 /* Create files with directory's group */
+#define EXT4_MOUNT_DEBUG               0x00008 /* Some debugging messages */
+#define EXT4_MOUNT_ERRORS_CONT         0x00010 /* Continue on errors */
+#define EXT4_MOUNT_ERRORS_RO           0x00020 /* Remount fs ro on errors */
+#define EXT4_MOUNT_ERRORS_PANIC                0x00040 /* Panic on errors */
+#define EXT4_MOUNT_MINIX_DF            0x00080 /* Mimics the Minix statfs */
+#define EXT4_MOUNT_NOLOAD              0x00100 /* Don't use existing journal*/
+#define EXT4_MOUNT_ABORT               0x00200 /* Fatal error detected */
+#define EXT4_MOUNT_DATA_FLAGS          0x00C00 /* Mode for data writes: */
+#define EXT4_MOUNT_JOURNAL_DATA                0x00400 /* Write data to journal */
+#define EXT4_MOUNT_ORDERED_DATA                0x00800 /* Flush data before commit */
+#define EXT4_MOUNT_WRITEBACK_DATA      0x00C00 /* No data ordering */
+#define EXT4_MOUNT_UPDATE_JOURNAL      0x01000 /* Update the journal format */
+#define EXT4_MOUNT_NO_UID32            0x02000  /* Disable 32-bit UIDs */
+#define EXT4_MOUNT_XATTR_USER          0x04000 /* Extended user attributes */
+#define EXT4_MOUNT_POSIX_ACL           0x08000 /* POSIX Access Control Lists */
+#define EXT4_MOUNT_RESERVATION         0x10000 /* Preallocation */
+#define EXT4_MOUNT_BARRIER             0x20000 /* Use block barriers */
+#define EXT4_MOUNT_NOBH                        0x40000 /* No bufferheads */
+#define EXT4_MOUNT_QUOTA               0x80000 /* Some quota option set */
+#define EXT4_MOUNT_USRQUOTA            0x100000 /* "old" user quota */
+#define EXT4_MOUNT_GRPQUOTA            0x200000 /* "old" group quota */
+#define EXT4_MOUNT_EXTENTS             0x400000 /* Extents support */
+
+/* Compatibility, for having both ext2_fs.h and ext4_fs.h included at once */
+#ifndef _LINUX_EXT2_FS_H
+#define clear_opt(o, opt)              o &= ~EXT4_MOUNT_##opt
+#define set_opt(o, opt)                        o |= EXT4_MOUNT_##opt
+#define test_opt(sb, opt)              (EXT4_SB(sb)->s_mount_opt & \
+                                        EXT4_MOUNT_##opt)
+#else
+#define EXT2_MOUNT_NOLOAD              EXT4_MOUNT_NOLOAD
+#define EXT2_MOUNT_ABORT               EXT4_MOUNT_ABORT
+#define EXT2_MOUNT_DATA_FLAGS          EXT4_MOUNT_DATA_FLAGS
+#endif
+
+#define ext4_set_bit                   ext2_set_bit
+#define ext4_set_bit_atomic            ext2_set_bit_atomic
+#define ext4_clear_bit                 ext2_clear_bit
+#define ext4_clear_bit_atomic          ext2_clear_bit_atomic
+#define ext4_test_bit                  ext2_test_bit
+#define ext4_find_first_zero_bit       ext2_find_first_zero_bit
+#define ext4_find_next_zero_bit                ext2_find_next_zero_bit
+
+/*
+ * Maximal mount counts between two filesystem checks
+ */
+#define EXT4_DFL_MAX_MNT_COUNT         20      /* Allow 20 mounts */
+#define EXT4_DFL_CHECKINTERVAL         0       /* Don't use interval check */
+
+/*
+ * Behaviour when detecting errors
+ */
+#define EXT4_ERRORS_CONTINUE           1       /* Continue execution */
+#define EXT4_ERRORS_RO                 2       /* Remount fs read-only */
+#define EXT4_ERRORS_PANIC              3       /* Panic */
+#define EXT4_ERRORS_DEFAULT            EXT4_ERRORS_CONTINUE
+
+/*
+ * Structure of the super block
+ */
+struct ext4_super_block {
+/*00*/ __le32  s_inodes_count;         /* Inodes count */
+       __le32  s_blocks_count;         /* Blocks count */
+       __le32  s_r_blocks_count;       /* Reserved blocks count */
+       __le32  s_free_blocks_count;    /* Free blocks count */
+/*10*/ __le32  s_free_inodes_count;    /* Free inodes count */
+       __le32  s_first_data_block;     /* First Data Block */
+       __le32  s_log_block_size;       /* Block size */
+       __le32  s_log_frag_size;        /* Fragment size */
+/*20*/ __le32  s_blocks_per_group;     /* # Blocks per group */
+       __le32  s_frags_per_group;      /* # Fragments per group */
+       __le32  s_inodes_per_group;     /* # Inodes per group */
+       __le32  s_mtime;                /* Mount time */
+/*30*/ __le32  s_wtime;                /* Write time */
+       __le16  s_mnt_count;            /* Mount count */
+       __le16  s_max_mnt_count;        /* Maximal mount count */
+       __le16  s_magic;                /* Magic signature */
+       __le16  s_state;                /* File system state */
+       __le16  s_errors;               /* Behaviour when detecting errors */
+       __le16  s_minor_rev_level;      /* minor revision level */
+/*40*/ __le32  s_lastcheck;            /* time of last check */
+       __le32  s_checkinterval;        /* max. time between checks */
+       __le32  s_creator_os;           /* OS */
+       __le32  s_rev_level;            /* Revision level */
+/*50*/ __le16  s_def_resuid;           /* Default uid for reserved blocks */
+       __le16  s_def_resgid;           /* Default gid for reserved blocks */
+       /*
+        * These fields are for EXT4_DYNAMIC_REV superblocks only.
+        *
+        * Note: the difference between the compatible feature set and
+        * the incompatible feature set is that if there is a bit set
+        * in the incompatible feature set that the kernel doesn't
+        * know about, it should refuse to mount the filesystem.
+        *
+        * e2fsck's requirements are more strict; if it doesn't know
+        * about a feature in either the compatible or incompatible
+        * feature set, it must abort and not try to meddle with
+        * things it doesn't understand...
+        */
+       __le32  s_first_ino;            /* First non-reserved inode */
+       __le16  s_inode_size;           /* size of inode structure */
+       __le16  s_block_group_nr;       /* block group # of this superblock */
+       __le32  s_feature_compat;       /* compatible feature set */
+/*60*/ __le32  s_feature_incompat;     /* incompatible feature set */
+       __le32  s_feature_ro_compat;    /* readonly-compatible feature set */
+/*68*/ __u8    s_uuid[16];             /* 128-bit uuid for volume */
+/*78*/ char    s_volume_name[16];      /* volume name */
+/*88*/ char    s_last_mounted[64];     /* directory where last mounted */
+/*C8*/ __le32  s_algorithm_usage_bitmap; /* For compression */
+       /*
+        * Performance hints.  Directory preallocation should only
+        * happen if the EXT4_FEATURE_COMPAT_DIR_PREALLOC flag is on.
+        */
+       __u8    s_prealloc_blocks;      /* Nr of blocks to try to preallocate*/
+       __u8    s_prealloc_dir_blocks;  /* Nr to preallocate for dirs */
+       __le16  s_reserved_gdt_blocks;  /* Per group desc for online growth */
+       /*
+        * Journaling support valid if EXT4_FEATURE_COMPAT_HAS_JOURNAL set.
+        */
+/*D0*/ __u8    s_journal_uuid[16];     /* uuid of journal superblock */
+/*E0*/ __le32  s_journal_inum;         /* inode number of journal file */
+       __le32  s_journal_dev;          /* device number of journal file */
+       __le32  s_last_orphan;          /* start of list of inodes to delete */
+       __le32  s_hash_seed[4];         /* HTREE hash seed */
+       __u8    s_def_hash_version;     /* Default hash version to use */
+       __u8    s_reserved_char_pad;
+       __le16  s_desc_size;            /* size of group descriptor */
+/*100*/        __le32  s_default_mount_opts;
+       __le32  s_first_meta_bg;        /* First metablock block group */
+       __le32  s_mkfs_time;            /* When the filesystem was created */
+       __le32  s_jnl_blocks[17];       /* Backup of the journal inode */
+       /* 64bit support valid if EXT4_FEATURE_COMPAT_64BIT */
+/*150*/        __le32  s_blocks_count_hi;      /* Blocks count */
+       __le32  s_r_blocks_count_hi;    /* Reserved blocks count */
+       __le32  s_free_blocks_count_hi; /* Free blocks count */
+       __u32   s_reserved[169];        /* Padding to the end of the block */
+};
+
+#ifdef __KERNEL__
+static inline struct ext4_sb_info * EXT4_SB(struct super_block *sb)
+{
+       return sb->s_fs_info;
+}
+static inline struct ext4_inode_info *EXT4_I(struct inode *inode)
+{
+       return container_of(inode, struct ext4_inode_info, vfs_inode);
+}
+
+static inline int ext4_valid_inum(struct super_block *sb, unsigned long ino)
+{
+       return ino == EXT4_ROOT_INO ||
+               ino == EXT4_JOURNAL_INO ||
+               ino == EXT4_RESIZE_INO ||
+               (ino >= EXT4_FIRST_INO(sb) &&
+                ino <= le32_to_cpu(EXT4_SB(sb)->s_es->s_inodes_count));
+}
+#else
+/* Assume that user mode programs are passing in an ext4fs superblock, not
+ * a kernel struct super_block.  This will allow us to call the feature-test
+ * macros from user land. */
+#define EXT4_SB(sb)    (sb)
+#endif
+
+#define NEXT_ORPHAN(inode) EXT4_I(inode)->i_dtime
+
+/*
+ * Codes for operating systems
+ */
+#define EXT4_OS_LINUX          0
+#define EXT4_OS_HURD           1
+#define EXT4_OS_MASIX          2
+#define EXT4_OS_FREEBSD                3
+#define EXT4_OS_LITES          4
+
+/*
+ * Revision levels
+ */
+#define EXT4_GOOD_OLD_REV      0       /* The good old (original) format */
+#define EXT4_DYNAMIC_REV       1       /* V2 format w/ dynamic inode sizes */
+
+#define EXT4_CURRENT_REV       EXT4_GOOD_OLD_REV
+#define EXT4_MAX_SUPP_REV      EXT4_DYNAMIC_REV
+
+#define EXT4_GOOD_OLD_INODE_SIZE 128
+
+/*
+ * Feature set definitions
+ */
+
+#define EXT4_HAS_COMPAT_FEATURE(sb,mask)                       \
+       ( EXT4_SB(sb)->s_es->s_feature_compat & cpu_to_le32(mask) )
+#define EXT4_HAS_RO_COMPAT_FEATURE(sb,mask)                    \
+       ( EXT4_SB(sb)->s_es->s_feature_ro_compat & cpu_to_le32(mask) )
+#define EXT4_HAS_INCOMPAT_FEATURE(sb,mask)                     \
+       ( EXT4_SB(sb)->s_es->s_feature_incompat & cpu_to_le32(mask) )
+#define EXT4_SET_COMPAT_FEATURE(sb,mask)                       \
+       EXT4_SB(sb)->s_es->s_feature_compat |= cpu_to_le32(mask)
+#define EXT4_SET_RO_COMPAT_FEATURE(sb,mask)                    \
+       EXT4_SB(sb)->s_es->s_feature_ro_compat |= cpu_to_le32(mask)
+#define EXT4_SET_INCOMPAT_FEATURE(sb,mask)                     \
+       EXT4_SB(sb)->s_es->s_feature_incompat |= cpu_to_le32(mask)
+#define EXT4_CLEAR_COMPAT_FEATURE(sb,mask)                     \
+       EXT4_SB(sb)->s_es->s_feature_compat &= ~cpu_to_le32(mask)
+#define EXT4_CLEAR_RO_COMPAT_FEATURE(sb,mask)                  \
+       EXT4_SB(sb)->s_es->s_feature_ro_compat &= ~cpu_to_le32(mask)
+#define EXT4_CLEAR_INCOMPAT_FEATURE(sb,mask)                   \
+       EXT4_SB(sb)->s_es->s_feature_incompat &= ~cpu_to_le32(mask)
+
+#define EXT4_FEATURE_COMPAT_DIR_PREALLOC       0x0001
+#define EXT4_FEATURE_COMPAT_IMAGIC_INODES      0x0002
+#define EXT4_FEATURE_COMPAT_HAS_JOURNAL                0x0004
+#define EXT4_FEATURE_COMPAT_EXT_ATTR           0x0008
+#define EXT4_FEATURE_COMPAT_RESIZE_INODE       0x0010
+#define EXT4_FEATURE_COMPAT_DIR_INDEX          0x0020
+
+#define EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER    0x0001
+#define EXT4_FEATURE_RO_COMPAT_LARGE_FILE      0x0002
+#define EXT4_FEATURE_RO_COMPAT_BTREE_DIR       0x0004
+
+#define EXT4_FEATURE_INCOMPAT_COMPRESSION      0x0001
+#define EXT4_FEATURE_INCOMPAT_FILETYPE         0x0002
+#define EXT4_FEATURE_INCOMPAT_RECOVER          0x0004 /* Needs recovery */
+#define EXT4_FEATURE_INCOMPAT_JOURNAL_DEV      0x0008 /* Journal device */
+#define EXT4_FEATURE_INCOMPAT_META_BG          0x0010
+#define EXT4_FEATURE_INCOMPAT_EXTENTS          0x0040 /* extents support */
+#define EXT4_FEATURE_INCOMPAT_64BIT            0x0080
+
+#define EXT4_FEATURE_COMPAT_SUPP       EXT2_FEATURE_COMPAT_EXT_ATTR
+#define EXT4_FEATURE_INCOMPAT_SUPP     (EXT4_FEATURE_INCOMPAT_FILETYPE| \
+                                        EXT4_FEATURE_INCOMPAT_RECOVER| \
+                                        EXT4_FEATURE_INCOMPAT_META_BG| \
+                                        EXT4_FEATURE_INCOMPAT_EXTENTS| \
+                                        EXT4_FEATURE_INCOMPAT_64BIT)
+#define EXT4_FEATURE_RO_COMPAT_SUPP    (EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER| \
+                                        EXT4_FEATURE_RO_COMPAT_LARGE_FILE| \
+                                        EXT4_FEATURE_RO_COMPAT_BTREE_DIR)
+
+/*
+ * Default values for user and/or group using reserved blocks
+ */
+#define        EXT4_DEF_RESUID         0
+#define        EXT4_DEF_RESGID         0
+
+/*
+ * Default mount options
+ */
+#define EXT4_DEFM_DEBUG                0x0001
+#define EXT4_DEFM_BSDGROUPS    0x0002
+#define EXT4_DEFM_XATTR_USER   0x0004
+#define EXT4_DEFM_ACL          0x0008
+#define EXT4_DEFM_UID16                0x0010
+#define EXT4_DEFM_JMODE                0x0060
+#define EXT4_DEFM_JMODE_DATA   0x0020
+#define EXT4_DEFM_JMODE_ORDERED        0x0040
+#define EXT4_DEFM_JMODE_WBACK  0x0060
+
+/*
+ * Structure of a directory entry
+ */
+#define EXT4_NAME_LEN 255
+
+struct ext4_dir_entry {
+       __le32  inode;                  /* Inode number */
+       __le16  rec_len;                /* Directory entry length */
+       __le16  name_len;               /* Name length */
+       char    name[EXT4_NAME_LEN];    /* File name */
+};
+
+/*
+ * The new version of the directory entry.  Since EXT4 structures are
+ * stored in intel byte order, and the name_len field could never be
+ * bigger than 255 chars, it's safe to reclaim the extra byte for the
+ * file_type field.
+ */
+struct ext4_dir_entry_2 {
+       __le32  inode;                  /* Inode number */
+       __le16  rec_len;                /* Directory entry length */
+       __u8    name_len;               /* Name length */
+       __u8    file_type;
+       char    name[EXT4_NAME_LEN];    /* File name */
+};
+
+/*
+ * Ext4 directory file types.  Only the low 3 bits are used.  The
+ * other bits are reserved for now.
+ */
+#define EXT4_FT_UNKNOWN                0
+#define EXT4_FT_REG_FILE       1
+#define EXT4_FT_DIR            2
+#define EXT4_FT_CHRDEV         3
+#define EXT4_FT_BLKDEV         4
+#define EXT4_FT_FIFO           5
+#define EXT4_FT_SOCK           6
+#define EXT4_FT_SYMLINK                7
+
+#define EXT4_FT_MAX            8
+
+/*
+ * EXT4_DIR_PAD defines the directory entries boundaries
+ *
+ * NOTE: It must be a multiple of 4
+ */
+#define EXT4_DIR_PAD                   4
+#define EXT4_DIR_ROUND                 (EXT4_DIR_PAD - 1)
+#define EXT4_DIR_REC_LEN(name_len)     (((name_len) + 8 + EXT4_DIR_ROUND) & \
+                                        ~EXT4_DIR_ROUND)
+/*
+ * Hash Tree Directory indexing
+ * (c) Daniel Phillips, 2001
+ */
+
+#ifdef CONFIG_EXT4_INDEX
+  #define is_dx(dir) (EXT4_HAS_COMPAT_FEATURE(dir->i_sb, \
+                                             EXT4_FEATURE_COMPAT_DIR_INDEX) && \
+                     (EXT4_I(dir)->i_flags & EXT4_INDEX_FL))
+#define EXT4_DIR_LINK_MAX(dir) (!is_dx(dir) && (dir)->i_nlink >= EXT4_LINK_MAX)
+#define EXT4_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2 || (dir)->i_nlink == 1)
+#else
+  #define is_dx(dir) 0
+#define EXT4_DIR_LINK_MAX(dir) ((dir)->i_nlink >= EXT4_LINK_MAX)
+#define EXT4_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2)
+#endif
+
+/* Legal values for the dx_root hash_version field: */
+
+#define DX_HASH_LEGACY         0
+#define DX_HASH_HALF_MD4       1
+#define DX_HASH_TEA            2
+
+#ifdef __KERNEL__
+
+/* hash info structure used by the directory hash */
+struct dx_hash_info
+{
+       u32             hash;
+       u32             minor_hash;
+       int             hash_version;
+       u32             *seed;
+};
+
+#define EXT4_HTREE_EOF 0x7fffffff
+
+/*
+ * Control parameters used by ext4_htree_next_block
+ */
+#define HASH_NB_ALWAYS         1
+
+
+/*
+ * Describe an inode's exact location on disk and in memory
+ */
+struct ext4_iloc
+{
+       struct buffer_head *bh;
+       unsigned long offset;
+       unsigned long block_group;
+};
+
+static inline struct ext4_inode *ext4_raw_inode(struct ext4_iloc *iloc)
+{
+       return (struct ext4_inode *) (iloc->bh->b_data + iloc->offset);
+}
+
+/*
+ * This structure is stuffed into the struct file's private_data field
+ * for directories.  It is where we put information so that we can do
+ * readdir operations in hash tree order.
+ */
+struct dir_private_info {
+       struct rb_root  root;
+       struct rb_node  *curr_node;
+       struct fname    *extra_fname;
+       loff_t          last_pos;
+       __u32           curr_hash;
+       __u32           curr_minor_hash;
+       __u32           next_hash;
+};
+
+/* calculate the first block number of the group */
+static inline ext4_fsblk_t
+ext4_group_first_block_no(struct super_block *sb, unsigned long group_no)
+{
+       return group_no * (ext4_fsblk_t)EXT4_BLOCKS_PER_GROUP(sb) +
+               le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block);
+}
+
+/*
+ * Special error return code only used by dx_probe() and its callers.
+ */
+#define ERR_BAD_DX_DIR -75000
+
+void ext4_get_group_no_and_offset(struct super_block *sb, ext4_fsblk_t blocknr,
+                       unsigned long *blockgrpp, ext4_grpblk_t *offsetp);
+
+/*
+ * Function prototypes
+ */
+
+/*
+ * Ok, these declarations are also in <linux/kernel.h> but none of the
+ * ext4 source programs needs to include it so they are duplicated here.
+ */
+# define NORET_TYPE    /**/
+# define ATTRIB_NORET  __attribute__((noreturn))
+# define NORET_AND     noreturn,
+
+/* balloc.c */
+extern unsigned int ext4_block_group(struct super_block *sb,
+                       ext4_fsblk_t blocknr);
+extern ext4_grpblk_t ext4_block_group_offset(struct super_block *sb,
+                       ext4_fsblk_t blocknr);
+extern int ext4_bg_has_super(struct super_block *sb, int group);
+extern unsigned long ext4_bg_num_gdb(struct super_block *sb, int group);
+extern ext4_fsblk_t ext4_new_block (handle_t *handle, struct inode *inode,
+                       ext4_fsblk_t goal, int *errp);
+extern ext4_fsblk_t ext4_new_blocks (handle_t *handle, struct inode *inode,
+                       ext4_fsblk_t goal, unsigned long *count, int *errp);
+extern void ext4_free_blocks (handle_t *handle, struct inode *inode,
+                       ext4_fsblk_t block, unsigned long count);
+extern void ext4_free_blocks_sb (handle_t *handle, struct super_block *sb,
+                                ext4_fsblk_t block, unsigned long count,
+                               unsigned long *pdquot_freed_blocks);
+extern ext4_fsblk_t ext4_count_free_blocks (struct super_block *);
+extern void ext4_check_blocks_bitmap (struct super_block *);
+extern struct ext4_group_desc * ext4_get_group_desc(struct super_block * sb,
+                                                   unsigned int block_group,
+                                                   struct buffer_head ** bh);
+extern int ext4_should_retry_alloc(struct super_block *sb, int *retries);
+extern void ext4_init_block_alloc_info(struct inode *);
+extern void ext4_rsv_window_add(struct super_block *sb, struct ext4_reserve_window_node *rsv);
+
+/* dir.c */
+extern int ext4_check_dir_entry(const char *, struct inode *,
+                               struct ext4_dir_entry_2 *,
+                               struct buffer_head *, unsigned long);
+extern int ext4_htree_store_dirent(struct file *dir_file, __u32 hash,
+                                   __u32 minor_hash,
+                                   struct ext4_dir_entry_2 *dirent);
+extern void ext4_htree_free_dir_info(struct dir_private_info *p);
+
+/* fsync.c */
+extern int ext4_sync_file (struct file *, struct dentry *, int);
+
+/* hash.c */
+extern int ext4fs_dirhash(const char *name, int len, struct
+                         dx_hash_info *hinfo);
+
+/* ialloc.c */
+extern struct inode * ext4_new_inode (handle_t *, struct inode *, int);
+extern void ext4_free_inode (handle_t *, struct inode *);
+extern struct inode * ext4_orphan_get (struct super_block *, unsigned long);
+extern unsigned long ext4_count_free_inodes (struct super_block *);
+extern unsigned long ext4_count_dirs (struct super_block *);
+extern void ext4_check_inodes_bitmap (struct super_block *);
+extern unsigned long ext4_count_free (struct buffer_head *, unsigned);
+
+
+/* inode.c */
+int ext4_forget(handle_t *handle, int is_metadata, struct inode *inode,
+               struct buffer_head *bh, ext4_fsblk_t blocknr);
+struct buffer_head * ext4_getblk (handle_t *, struct inode *, long, int, int *);
+struct buffer_head * ext4_bread (handle_t *, struct inode *, int, int, int *);
+int ext4_get_blocks_handle(handle_t *handle, struct inode *inode,
+       sector_t iblock, unsigned long maxblocks, struct buffer_head *bh_result,
+       int create, int extend_disksize);
+
+extern void ext4_read_inode (struct inode *);
+extern int  ext4_write_inode (struct inode *, int);
+extern int  ext4_setattr (struct dentry *, struct iattr *);
+extern void ext4_delete_inode (struct inode *);
+extern int  ext4_sync_inode (handle_t *, struct inode *);
+extern void ext4_discard_reservation (struct inode *);
+extern void ext4_dirty_inode(struct inode *);
+extern int ext4_change_inode_journal_flag(struct inode *, int);
+extern int ext4_get_inode_loc(struct inode *, struct ext4_iloc *);
+extern void ext4_truncate (struct inode *);
+extern void ext4_set_inode_flags(struct inode *);
+extern void ext4_set_aops(struct inode *inode);
+extern int ext4_writepage_trans_blocks(struct inode *);
+extern int ext4_block_truncate_page(handle_t *handle, struct page *page,
+               struct address_space *mapping, loff_t from);
+
+/* ioctl.c */
+extern int ext4_ioctl (struct inode *, struct file *, unsigned int,
+                      unsigned long);
+extern long ext4_compat_ioctl (struct file *, unsigned int, unsigned long);
+
+/* namei.c */
+extern int ext4_orphan_add(handle_t *, struct inode *);
+extern int ext4_orphan_del(handle_t *, struct inode *);
+extern int ext4_htree_fill_tree(struct file *dir_file, __u32 start_hash,
+                               __u32 start_minor_hash, __u32 *next_hash);
+
+/* resize.c */
+extern int ext4_group_add(struct super_block *sb,
+                               struct ext4_new_group_data *input);
+extern int ext4_group_extend(struct super_block *sb,
+                               struct ext4_super_block *es,
+                               ext4_fsblk_t n_blocks_count);
+
+/* super.c */
+extern void ext4_error (struct super_block *, const char *, const char *, ...)
+       __attribute__ ((format (printf, 3, 4)));
+extern void __ext4_std_error (struct super_block *, const char *, int);
+extern void ext4_abort (struct super_block *, const char *, const char *, ...)
+       __attribute__ ((format (printf, 3, 4)));
+extern void ext4_warning (struct super_block *, const char *, const char *, ...)
+       __attribute__ ((format (printf, 3, 4)));
+extern void ext4_update_dynamic_rev (struct super_block *sb);
+extern ext4_fsblk_t ext4_block_bitmap(struct super_block *sb,
+                                     struct ext4_group_desc *bg);
+extern ext4_fsblk_t ext4_inode_bitmap(struct super_block *sb,
+                                     struct ext4_group_desc *bg);
+extern ext4_fsblk_t ext4_inode_table(struct super_block *sb,
+                                    struct ext4_group_desc *bg);
+extern void ext4_block_bitmap_set(struct super_block *sb,
+                                 struct ext4_group_desc *bg, ext4_fsblk_t blk);
+extern void ext4_inode_bitmap_set(struct super_block *sb,
+                                 struct ext4_group_desc *bg, ext4_fsblk_t blk);
+extern void ext4_inode_table_set(struct super_block *sb,
+                                struct ext4_group_desc *bg, ext4_fsblk_t blk);
+
+static inline ext4_fsblk_t ext4_blocks_count(struct ext4_super_block *es)
+{
+       return ((ext4_fsblk_t)le32_to_cpu(es->s_blocks_count_hi) << 32) |
+               le32_to_cpu(es->s_blocks_count);
+}
+
+static inline ext4_fsblk_t ext4_r_blocks_count(struct ext4_super_block *es)
+{
+       return ((ext4_fsblk_t)le32_to_cpu(es->s_r_blocks_count_hi) << 32) |
+               le32_to_cpu(es->s_r_blocks_count);
+}
+
+static inline ext4_fsblk_t ext4_free_blocks_count(struct ext4_super_block *es)
+{
+       return ((ext4_fsblk_t)le32_to_cpu(es->s_free_blocks_count_hi) << 32) |
+               le32_to_cpu(es->s_free_blocks_count);
+}
+
+static inline void ext4_blocks_count_set(struct ext4_super_block *es,
+                                        ext4_fsblk_t blk)
+{
+       es->s_blocks_count = cpu_to_le32((u32)blk);
+       es->s_blocks_count_hi = cpu_to_le32(blk >> 32);
+}
+
+static inline void ext4_free_blocks_count_set(struct ext4_super_block *es,
+                                             ext4_fsblk_t blk)
+{
+       es->s_free_blocks_count = cpu_to_le32((u32)blk);
+       es->s_free_blocks_count_hi = cpu_to_le32(blk >> 32);
+}
+
+static inline void ext4_r_blocks_count_set(struct ext4_super_block *es,
+                                          ext4_fsblk_t blk)
+{
+       es->s_r_blocks_count = cpu_to_le32((u32)blk);
+       es->s_r_blocks_count_hi = cpu_to_le32(blk >> 32);
+}
+
+
+
+#define ext4_std_error(sb, errno)                              \
+do {                                                           \
+       if ((errno))                                            \
+               __ext4_std_error((sb), __FUNCTION__, (errno));  \
+} while (0)
+
+/*
+ * Inodes and files operations
+ */
+
+/* dir.c */
+extern const struct file_operations ext4_dir_operations;
+
+/* file.c */
+extern struct inode_operations ext4_file_inode_operations;
+extern const struct file_operations ext4_file_operations;
+
+/* namei.c */
+extern struct inode_operations ext4_dir_inode_operations;
+extern struct inode_operations ext4_special_inode_operations;
+
+/* symlink.c */
+extern struct inode_operations ext4_symlink_inode_operations;
+extern struct inode_operations ext4_fast_symlink_inode_operations;
+
+/* extents.c */
+extern int ext4_ext_tree_init(handle_t *handle, struct inode *);
+extern int ext4_ext_writepage_trans_blocks(struct inode *, int);
+extern int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
+                       ext4_fsblk_t iblock,
+                       unsigned long max_blocks, struct buffer_head *bh_result,
+                       int create, int extend_disksize);
+extern void ext4_ext_truncate(struct inode *, struct page *);
+extern void ext4_ext_init(struct super_block *);
+extern void ext4_ext_release(struct super_block *);
+static inline int
+ext4_get_blocks_wrap(handle_t *handle, struct inode *inode, sector_t block,
+                       unsigned long max_blocks, struct buffer_head *bh,
+                       int create, int extend_disksize)
+{
+       if (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL)
+               return ext4_ext_get_blocks(handle, inode, block, max_blocks,
+                                       bh, create, extend_disksize);
+       return ext4_get_blocks_handle(handle, inode, block, max_blocks, bh,
+                                       create, extend_disksize);
+}
+
+
+#endif /* __KERNEL__ */
+
+#endif /* _LINUX_EXT4_FS_H */
diff --git a/include/linux/ext4_fs_extents.h b/include/linux/ext4_fs_extents.h
new file mode 100644 (file)
index 0000000..a41cc24
--- /dev/null
@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) 2003-2006, Cluster File Systems, Inc, info@clusterfs.com
+ * Written by Alex Tomas <alex@clusterfs.com>
+ *
+ * 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 Licens
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-
+ */
+
+#ifndef _LINUX_EXT4_EXTENTS
+#define _LINUX_EXT4_EXTENTS
+
+#include <linux/ext4_fs.h>
+
+/*
+ * With AGRESSIVE_TEST defined, the capacity of index/leaf blocks
+ * becomes very small, so index split, in-depth growing and
+ * other hard changes happen much more often.
+ * This is for debug purposes only.
+ */
+#define AGRESSIVE_TEST_
+
+/*
+ * With EXTENTS_STATS defined, the number of blocks and extents
+ * are collected in the truncate path. They'll be shown at
+ * umount time.
+ */
+#define EXTENTS_STATS__
+
+/*
+ * If CHECK_BINSEARCH is defined, then the results of the binary search
+ * will also be checked by linear search.
+ */
+#define CHECK_BINSEARCH__
+
+/*
+ * If EXT_DEBUG is defined you can use the 'extdebug' mount option
+ * to get lots of info about what's going on.
+ */
+#define EXT_DEBUG__
+#ifdef EXT_DEBUG
+#define ext_debug(a...)                printk(a)
+#else
+#define ext_debug(a...)
+#endif
+
+/*
+ * If EXT_STATS is defined then stats numbers are collected.
+ * These number will be displayed at umount time.
+ */
+#define EXT_STATS_
+
+
+/*
+ * ext4_inode has i_block array (60 bytes total).
+ * The first 12 bytes store ext4_extent_header;
+ * the remainder stores an array of ext4_extent.
+ */
+
+/*
+ * This is the extent on-disk structure.
+ * It's used at the bottom of the tree.
+ */
+struct ext4_extent {
+       __le32  ee_block;       /* first logical block extent covers */
+       __le16  ee_len;         /* number of blocks covered by extent */
+       __le16  ee_start_hi;    /* high 16 bits of physical block */
+       __le32  ee_start;       /* low 32 bits of physical block */
+};
+
+/*
+ * This is index on-disk structure.
+ * It's used at all the levels except the bottom.
+ */
+struct ext4_extent_idx {
+       __le32  ei_block;       /* index covers logical blocks from 'block' */
+       __le32  ei_leaf;        /* pointer to the physical block of the next *
+                                * level. leaf or next index could be there */
+       __le16  ei_leaf_hi;     /* high 16 bits of physical block */
+       __u16   ei_unused;
+};
+
+/*
+ * Each block (leaves and indexes), even inode-stored has header.
+ */
+struct ext4_extent_header {
+       __le16  eh_magic;       /* probably will support different formats */
+       __le16  eh_entries;     /* number of valid entries */
+       __le16  eh_max;         /* capacity of store in entries */
+       __le16  eh_depth;       /* has tree real underlying blocks? */
+       __le32  eh_generation;  /* generation of the tree */
+};
+
+#define EXT4_EXT_MAGIC         cpu_to_le16(0xf30a)
+
+/*
+ * Array of ext4_ext_path contains path to some extent.
+ * Creation/lookup routines use it for traversal/splitting/etc.
+ * Truncate uses it to simulate recursive walking.
+ */
+struct ext4_ext_path {
+       ext4_fsblk_t                    p_block;
+       __u16                           p_depth;
+       struct ext4_extent              *p_ext;
+       struct ext4_extent_idx          *p_idx;
+       struct ext4_extent_header       *p_hdr;
+       struct buffer_head              *p_bh;
+};
+
+/*
+ * structure for external API
+ */
+
+#define EXT4_EXT_CACHE_NO      0
+#define EXT4_EXT_CACHE_GAP     1
+#define EXT4_EXT_CACHE_EXTENT  2
+
+/*
+ * to be called by ext4_ext_walk_space()
+ * negative retcode - error
+ * positive retcode - signal for ext4_ext_walk_space(), see below
+ * callback must return valid extent (passed or newly created)
+ */
+typedef int (*ext_prepare_callback)(struct inode *, struct ext4_ext_path *,
+                                       struct ext4_ext_cache *,
+                                       void *);
+
+#define EXT_CONTINUE   0
+#define EXT_BREAK      1
+#define EXT_REPEAT     2
+
+
+#define EXT_MAX_BLOCK  0xffffffff
+
+#define EXT_MAX_LEN    ((1UL << 15) - 1)
+
+
+#define EXT_FIRST_EXTENT(__hdr__) \
+       ((struct ext4_extent *) (((char *) (__hdr__)) +         \
+                                sizeof(struct ext4_extent_header)))
+#define EXT_FIRST_INDEX(__hdr__) \
+       ((struct ext4_extent_idx *) (((char *) (__hdr__)) +     \
+                                    sizeof(struct ext4_extent_header)))
+#define EXT_HAS_FREE_INDEX(__path__) \
+        (le16_to_cpu((__path__)->p_hdr->eh_entries) \
+                                    < le16_to_cpu((__path__)->p_hdr->eh_max))
+#define EXT_LAST_EXTENT(__hdr__) \
+       (EXT_FIRST_EXTENT((__hdr__)) + le16_to_cpu((__hdr__)->eh_entries) - 1)
+#define EXT_LAST_INDEX(__hdr__) \
+       (EXT_FIRST_INDEX((__hdr__)) + le16_to_cpu((__hdr__)->eh_entries) - 1)
+#define EXT_MAX_EXTENT(__hdr__) \
+       (EXT_FIRST_EXTENT((__hdr__)) + le16_to_cpu((__hdr__)->eh_max) - 1)
+#define EXT_MAX_INDEX(__hdr__) \
+       (EXT_FIRST_INDEX((__hdr__)) + le16_to_cpu((__hdr__)->eh_max) - 1)
+
+static inline struct ext4_extent_header *ext_inode_hdr(struct inode *inode)
+{
+       return (struct ext4_extent_header *) EXT4_I(inode)->i_data;
+}
+
+static inline struct ext4_extent_header *ext_block_hdr(struct buffer_head *bh)
+{
+       return (struct ext4_extent_header *) bh->b_data;
+}
+
+static inline unsigned short ext_depth(struct inode *inode)
+{
+       return le16_to_cpu(ext_inode_hdr(inode)->eh_depth);
+}
+
+static inline void ext4_ext_tree_changed(struct inode *inode)
+{
+       EXT4_I(inode)->i_ext_generation++;
+}
+
+static inline void
+ext4_ext_invalidate_cache(struct inode *inode)
+{
+       EXT4_I(inode)->i_cached_extent.ec_type = EXT4_EXT_CACHE_NO;
+}
+
+extern int ext4_extent_tree_init(handle_t *, struct inode *);
+extern int ext4_ext_calc_credits_for_insert(struct inode *, struct ext4_ext_path *);
+extern int ext4_ext_insert_extent(handle_t *, struct inode *, struct ext4_ext_path *, struct ext4_extent *);
+extern int ext4_ext_walk_space(struct inode *, unsigned long, unsigned long, ext_prepare_callback, void *);
+extern struct ext4_ext_path * ext4_ext_find_extent(struct inode *, int, struct ext4_ext_path *);
+
+#endif /* _LINUX_EXT4_EXTENTS */
+
diff --git a/include/linux/ext4_fs_i.h b/include/linux/ext4_fs_i.h
new file mode 100644 (file)
index 0000000..bb42379
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+ *  linux/include/linux/ext4_fs_i.h
+ *
+ * Copyright (C) 1992, 1993, 1994, 1995
+ * Remy Card (card@masi.ibp.fr)
+ * Laboratoire MASI - Institut Blaise Pascal
+ * Universite Pierre et Marie Curie (Paris VI)
+ *
+ *  from
+ *
+ *  linux/include/linux/minix_fs_i.h
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ */
+
+#ifndef _LINUX_EXT4_FS_I
+#define _LINUX_EXT4_FS_I
+
+#include <linux/rwsem.h>
+#include <linux/rbtree.h>
+#include <linux/seqlock.h>
+#include <linux/mutex.h>
+
+/* data type for block offset of block group */
+typedef int ext4_grpblk_t;
+
+/* data type for filesystem-wide blocks number */
+typedef unsigned long long ext4_fsblk_t;
+
+struct ext4_reserve_window {
+       ext4_fsblk_t    _rsv_start;     /* First byte reserved */
+       ext4_fsblk_t    _rsv_end;       /* Last byte reserved or 0 */
+};
+
+struct ext4_reserve_window_node {
+       struct rb_node          rsv_node;
+       __u32                   rsv_goal_size;
+       __u32                   rsv_alloc_hit;
+       struct ext4_reserve_window      rsv_window;
+};
+
+struct ext4_block_alloc_info {
+       /* information about reservation window */
+       struct ext4_reserve_window_node rsv_window_node;
+       /*
+        * was i_next_alloc_block in ext4_inode_info
+        * is the logical (file-relative) number of the
+        * most-recently-allocated block in this file.
+        * We use this for detecting linearly ascending allocation requests.
+        */
+       __u32                   last_alloc_logical_block;
+       /*
+        * Was i_next_alloc_goal in ext4_inode_info
+        * is the *physical* companion to i_next_alloc_block.
+        * it the the physical block number of the block which was most-recentl
+        * allocated to this file.  This give us the goal (target) for the next
+        * allocation when we detect linearly ascending requests.
+        */
+       ext4_fsblk_t            last_alloc_physical_block;
+};
+
+#define rsv_start rsv_window._rsv_start
+#define rsv_end rsv_window._rsv_end
+
+/*
+ * storage for cached extent
+ */
+struct ext4_ext_cache {
+       ext4_fsblk_t    ec_start;
+       __u32           ec_block;
+       __u32           ec_len; /* must be 32bit to return holes */
+       __u32           ec_type;
+};
+
+/*
+ * third extended file system inode data in memory
+ */
+struct ext4_inode_info {
+       __le32  i_data[15];     /* unconverted */
+       __u32   i_flags;
+#ifdef EXT4_FRAGMENTS
+       __u32   i_faddr;
+       __u8    i_frag_no;
+       __u8    i_frag_size;
+#endif
+       ext4_fsblk_t    i_file_acl;
+       __u32   i_dir_acl;
+       __u32   i_dtime;
+
+       /*
+        * i_block_group is the number of the block group which contains
+        * this file's inode.  Constant across the lifetime of the inode,
+        * it is ued for making block allocation decisions - we try to
+        * place a file's data blocks near its inode block, and new inodes
+        * near to their parent directory's inode.
+        */
+       __u32   i_block_group;
+       __u32   i_state;                /* Dynamic state flags for ext4 */
+
+       /* block reservation info */
+       struct ext4_block_alloc_info *i_block_alloc_info;
+
+       __u32   i_dir_start_lookup;
+#ifdef CONFIG_EXT4DEV_FS_XATTR
+       /*
+        * Extended attributes can be read independently of the main file
+        * data. Taking i_mutex even when reading would cause contention
+        * between readers of EAs and writers of regular file data, so
+        * instead we synchronize on xattr_sem when reading or changing
+        * EAs.
+        */
+       struct rw_semaphore xattr_sem;
+#endif
+#ifdef CONFIG_EXT4DEV_FS_POSIX_ACL
+       struct posix_acl        *i_acl;
+       struct posix_acl        *i_default_acl;
+#endif
+
+       struct list_head i_orphan;      /* unlinked but open inodes */
+
+       /*
+        * i_disksize keeps track of what the inode size is ON DISK, not
+        * in memory.  During truncate, i_size is set to the new size by
+        * the VFS prior to calling ext4_truncate(), but the filesystem won't
+        * set i_disksize to 0 until the truncate is actually under way.
+        *
+        * The intent is that i_disksize always represents the blocks which
+        * are used by this file.  This allows recovery to restart truncate
+        * on orphans if we crash during truncate.  We actually write i_disksize
+        * into the on-disk inode when writing inodes out, instead of i_size.
+        *
+        * The only time when i_disksize and i_size may be different is when
+        * a truncate is in progress.  The only things which change i_disksize
+        * are ext4_get_block (growth) and ext4_truncate (shrinkth).
+        */
+       loff_t  i_disksize;
+
+       /* on-disk additional length */
+       __u16 i_extra_isize;
+
+       /*
+        * truncate_mutex is for serialising ext4_truncate() against
+        * ext4_getblock().  In the 2.4 ext2 design, great chunks of inode's
+        * data tree are chopped off during truncate. We can't do that in
+        * ext4 because whenever we perform intermediate commits during
+        * truncate, the inode and all the metadata blocks *must* be in a
+        * consistent state which allows truncation of the orphans to restart
+        * during recovery.  Hence we must fix the get_block-vs-truncate race
+        * by other means, so we have truncate_mutex.
+        */
+       struct mutex truncate_mutex;
+       struct inode vfs_inode;
+
+       unsigned long i_ext_generation;
+       struct ext4_ext_cache i_cached_extent;
+};
+
+#endif /* _LINUX_EXT4_FS_I */
diff --git a/include/linux/ext4_fs_sb.h b/include/linux/ext4_fs_sb.h
new file mode 100644 (file)
index 0000000..691a713
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ *  linux/include/linux/ext4_fs_sb.h
+ *
+ * Copyright (C) 1992, 1993, 1994, 1995
+ * Remy Card (card@masi.ibp.fr)
+ * Laboratoire MASI - Institut Blaise Pascal
+ * Universite Pierre et Marie Curie (Paris VI)
+ *
+ *  from
+ *
+ *  linux/include/linux/minix_fs_sb.h
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ */
+
+#ifndef _LINUX_EXT4_FS_SB
+#define _LINUX_EXT4_FS_SB
+
+#ifdef __KERNEL__
+#include <linux/timer.h>
+#include <linux/wait.h>
+#include <linux/blockgroup_lock.h>
+#include <linux/percpu_counter.h>
+#endif
+#include <linux/rbtree.h>
+
+/*
+ * third extended-fs super-block data in memory
+ */
+struct ext4_sb_info {
+       unsigned long s_frag_size;      /* Size of a fragment in bytes */
+       unsigned long s_desc_size;      /* Size of a group descriptor in bytes */
+       unsigned long s_frags_per_block;/* Number of fragments per block */
+       unsigned long s_inodes_per_block;/* Number of inodes per block */
+       unsigned long s_frags_per_group;/* Number of fragments in a group */
+       unsigned long s_blocks_per_group;/* Number of blocks in a group */
+       unsigned long s_inodes_per_group;/* Number of inodes in a group */
+       unsigned long s_itb_per_group;  /* Number of inode table blocks per group */
+       unsigned long s_gdb_count;      /* Number of group descriptor blocks */
+       unsigned long s_desc_per_block; /* Number of group descriptors per block */
+       unsigned long s_groups_count;   /* Number of groups in the fs */
+       struct buffer_head * s_sbh;     /* Buffer containing the super block */
+       struct ext4_super_block * s_es; /* Pointer to the super block in the buffer */
+       struct buffer_head ** s_group_desc;
+       unsigned long  s_mount_opt;
+       uid_t s_resuid;
+       gid_t s_resgid;
+       unsigned short s_mount_state;
+       unsigned short s_pad;
+       int s_addr_per_block_bits;
+       int s_desc_per_block_bits;
+       int s_inode_size;
+       int s_first_ino;
+       spinlock_t s_next_gen_lock;
+       u32 s_next_generation;
+       u32 s_hash_seed[4];
+       int s_def_hash_version;
+       struct percpu_counter s_freeblocks_counter;
+       struct percpu_counter s_freeinodes_counter;
+       struct percpu_counter s_dirs_counter;
+       struct blockgroup_lock s_blockgroup_lock;
+
+       /* root of the per fs reservation window tree */
+       spinlock_t s_rsv_window_lock;
+       struct rb_root s_rsv_window_root;
+       struct ext4_reserve_window_node s_rsv_window_head;
+
+       /* Journaling */
+       struct inode * s_journal_inode;
+       struct journal_s * s_journal;
+       struct list_head s_orphan;
+       unsigned long s_commit_interval;
+       struct block_device *journal_bdev;
+#ifdef CONFIG_JBD_DEBUG
+       struct timer_list turn_ro_timer;        /* For turning read-only (crash simulation) */
+       wait_queue_head_t ro_wait_queue;        /* For people waiting for the fs to go read-only */
+#endif
+#ifdef CONFIG_QUOTA
+       char *s_qf_names[MAXQUOTAS];            /* Names of quota files with journalled quota */
+       int s_jquota_fmt;                       /* Format of quota to use */
+#endif
+
+#ifdef EXTENTS_STATS
+       /* ext4 extents stats */
+       unsigned long s_ext_min;
+       unsigned long s_ext_max;
+       unsigned long s_depth_max;
+       spinlock_t s_ext_stats_lock;
+       unsigned long s_ext_blocks;
+       unsigned long s_ext_extents;
+#endif
+};
+
+#endif /* _LINUX_EXT4_FS_SB */
diff --git a/include/linux/ext4_jbd2.h b/include/linux/ext4_jbd2.h
new file mode 100644 (file)
index 0000000..72dd631
--- /dev/null
@@ -0,0 +1,273 @@
+/*
+ * linux/include/linux/ext4_jbd2.h
+ *
+ * Written by Stephen C. Tweedie <sct@redhat.com>, 1999
+ *
+ * Copyright 1998--1999 Red Hat corp --- All Rights Reserved
+ *
+ * This file is part of the Linux kernel and is made available under
+ * the terms of the GNU General Public License, version 2, or at your
+ * option, any later version, incorporated herein by reference.
+ *
+ * Ext4-specific journaling extensions.
+ */
+
+#ifndef _LINUX_EXT4_JBD_H
+#define _LINUX_EXT4_JBD_H
+
+#include <linux/fs.h>
+#include <linux/jbd2.h>
+#include <linux/ext4_fs.h>
+
+#define EXT4_JOURNAL(inode)    (EXT4_SB((inode)->i_sb)->s_journal)
+
+/* Define the number of blocks we need to account to a transaction to
+ * modify one block of data.
+ *
+ * We may have to touch one inode, one bitmap buffer, up to three
+ * indirection blocks, the group and superblock summaries, and the data
+ * block to complete the transaction.
+ *
+ * For extents-enabled fs we may have to allocate and modify up to
+ * 5 levels of tree + root which are stored in the inode. */
+
+#define EXT4_SINGLEDATA_TRANS_BLOCKS(sb)                               \
+       (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_EXTENTS)   \
+               || test_opt(sb, EXTENTS) ? 27U : 8U)
+
+/* Extended attribute operations touch at most two data buffers,
+ * two bitmap buffers, and two group summaries, in addition to the inode
+ * and the superblock, which are already accounted for. */
+
+#define EXT4_XATTR_TRANS_BLOCKS                6U
+
+/* Define the minimum size for a transaction which modifies data.  This
+ * needs to take into account the fact that we may end up modifying two
+ * quota files too (one for the group, one for the user quota).  The
+ * superblock only gets updated once, of course, so don't bother
+ * counting that again for the quota updates. */
+
+#define EXT4_DATA_TRANS_BLOCKS(sb)     (EXT4_SINGLEDATA_TRANS_BLOCKS(sb) + \
+                                        EXT4_XATTR_TRANS_BLOCKS - 2 + \
+                                        2*EXT4_QUOTA_TRANS_BLOCKS(sb))
+
+/* Delete operations potentially hit one directory's namespace plus an
+ * entire inode, plus arbitrary amounts of bitmap/indirection data.  Be
+ * generous.  We can grow the delete transaction later if necessary. */
+
+#define EXT4_DELETE_TRANS_BLOCKS(sb)   (2 * EXT4_DATA_TRANS_BLOCKS(sb) + 64)
+
+/* Define an arbitrary limit for the amount of data we will anticipate
+ * writing to any given transaction.  For unbounded transactions such as
+ * write(2) and truncate(2) we can write more than this, but we always
+ * start off at the maximum transaction size and grow the transaction
+ * optimistically as we go. */
+
+#define EXT4_MAX_TRANS_DATA            64U
+
+/* We break up a large truncate or write transaction once the handle's
+ * buffer credits gets this low, we need either to extend the
+ * transaction or to start a new one.  Reserve enough space here for
+ * inode, bitmap, superblock, group and indirection updates for at least
+ * one block, plus two quota updates.  Quota allocations are not
+ * needed. */
+
+#define EXT4_RESERVE_TRANS_BLOCKS      12U
+
+#define EXT4_INDEX_EXTRA_TRANS_BLOCKS  8
+
+#ifdef CONFIG_QUOTA
+/* Amount of blocks needed for quota update - we know that the structure was
+ * allocated so we need to update only inode+data */
+#define EXT4_QUOTA_TRANS_BLOCKS(sb) (test_opt(sb, QUOTA) ? 2 : 0)
+/* Amount of blocks needed for quota insert/delete - we do some block writes
+ * but inode, sb and group updates are done only once */
+#define EXT4_QUOTA_INIT_BLOCKS(sb) (test_opt(sb, QUOTA) ? (DQUOT_INIT_ALLOC*\
+               (EXT4_SINGLEDATA_TRANS_BLOCKS(sb)-3)+3+DQUOT_INIT_REWRITE) : 0)
+#define EXT4_QUOTA_DEL_BLOCKS(sb) (test_opt(sb, QUOTA) ? (DQUOT_DEL_ALLOC*\
+               (EXT4_SINGLEDATA_TRANS_BLOCKS(sb)-3)+3+DQUOT_DEL_REWRITE) : 0)
+#else
+#define EXT4_QUOTA_TRANS_BLOCKS(sb) 0
+#define EXT4_QUOTA_INIT_BLOCKS(sb) 0
+#define EXT4_QUOTA_DEL_BLOCKS(sb) 0
+#endif
+
+int
+ext4_mark_iloc_dirty(handle_t *handle,
+                    struct inode *inode,
+                    struct ext4_iloc *iloc);
+
+/*
+ * On success, We end up with an outstanding reference count against
+ * iloc->bh.  This _must_ be cleaned up later.
+ */
+
+int ext4_reserve_inode_write(handle_t *handle, struct inode *inode,
+                       struct ext4_iloc *iloc);
+
+int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode);
+
+/*
+ * Wrapper functions with which ext4 calls into JBD.  The intent here is
+ * to allow these to be turned into appropriate stubs so ext4 can control
+ * ext2 filesystems, so ext2+ext4 systems only nee one fs.  This work hasn't
+ * been done yet.
+ */
+
+void ext4_journal_abort_handle(const char *caller, const char *err_fn,
+               struct buffer_head *bh, handle_t *handle, int err);
+
+static inline int
+__ext4_journal_get_undo_access(const char *where, handle_t *handle,
+                               struct buffer_head *bh)
+{
+       int err = jbd2_journal_get_undo_access(handle, bh);
+       if (err)
+               ext4_journal_abort_handle(where, __FUNCTION__, bh, handle,err);
+       return err;
+}
+
+static inline int
+__ext4_journal_get_write_access(const char *where, handle_t *handle,
+                               struct buffer_head *bh)
+{
+       int err = jbd2_journal_get_write_access(handle, bh);
+       if (err)
+               ext4_journal_abort_handle(where, __FUNCTION__, bh, handle,err);
+       return err;
+}
+
+static inline void
+ext4_journal_release_buffer(handle_t *handle, struct buffer_head *bh)
+{
+       jbd2_journal_release_buffer(handle, bh);
+}
+
+static inline int
+__ext4_journal_forget(const char *where, handle_t *handle, struct buffer_head *bh)
+{
+       int err = jbd2_journal_forget(handle, bh);
+       if (err)
+               ext4_journal_abort_handle(where, __FUNCTION__, bh, handle,err);
+       return err;
+}
+
+static inline int
+__ext4_journal_revoke(const char *where, handle_t *handle,
+                     ext4_fsblk_t blocknr, struct buffer_head *bh)
+{
+       int err = jbd2_journal_revoke(handle, blocknr, bh);
+       if (err)
+               ext4_journal_abort_handle(where, __FUNCTION__, bh, handle,err);
+       return err;
+}
+
+static inline int
+__ext4_journal_get_create_access(const char *where,
+                                handle_t *handle, struct buffer_head *bh)
+{
+       int err = jbd2_journal_get_create_access(handle, bh);
+       if (err)
+               ext4_journal_abort_handle(where, __FUNCTION__, bh, handle,err);
+       return err;
+}
+
+static inline int
+__ext4_journal_dirty_metadata(const char *where,
+                             handle_t *handle, struct buffer_head *bh)
+{
+       int err = jbd2_journal_dirty_metadata(handle, bh);
+       if (err)
+               ext4_journal_abort_handle(where, __FUNCTION__, bh, handle,err);
+       return err;
+}
+
+
+#define ext4_journal_get_undo_access(handle, bh) \
+       __ext4_journal_get_undo_access(__FUNCTION__, (handle), (bh))
+#define ext4_journal_get_write_access(handle, bh) \
+       __ext4_journal_get_write_access(__FUNCTION__, (handle), (bh))
+#define ext4_journal_revoke(handle, blocknr, bh) \
+       __ext4_journal_revoke(__FUNCTION__, (handle), (blocknr), (bh))
+#define ext4_journal_get_create_access(handle, bh) \
+       __ext4_journal_get_create_access(__FUNCTION__, (handle), (bh))
+#define ext4_journal_dirty_metadata(handle, bh) \
+       __ext4_journal_dirty_metadata(__FUNCTION__, (handle), (bh))
+#define ext4_journal_forget(handle, bh) \
+       __ext4_journal_forget(__FUNCTION__, (handle), (bh))
+
+int ext4_journal_dirty_data(handle_t *handle, struct buffer_head *bh);
+
+handle_t *ext4_journal_start_sb(struct super_block *sb, int nblocks);
+int __ext4_journal_stop(const char *where, handle_t *handle);
+
+static inline handle_t *ext4_journal_start(struct inode *inode, int nblocks)
+{
+       return ext4_journal_start_sb(inode->i_sb, nblocks);
+}
+
+#define ext4_journal_stop(handle) \
+       __ext4_journal_stop(__FUNCTION__, (handle))
+
+static inline handle_t *ext4_journal_current_handle(void)
+{
+       return journal_current_handle();
+}
+
+static inline int ext4_journal_extend(handle_t *handle, int nblocks)
+{
+       return jbd2_journal_extend(handle, nblocks);
+}
+
+static inline int ext4_journal_restart(handle_t *handle, int nblocks)
+{
+       return jbd2_journal_restart(handle, nblocks);
+}
+
+static inline int ext4_journal_blocks_per_page(struct inode *inode)
+{
+       return jbd2_journal_blocks_per_page(inode);
+}
+
+static inline int ext4_journal_force_commit(journal_t *journal)
+{
+       return jbd2_journal_force_commit(journal);
+}
+
+/* super.c */
+int ext4_force_commit(struct super_block *sb);
+
+static inline int ext4_should_journal_data(struct inode *inode)
+{
+       if (!S_ISREG(inode->i_mode))
+               return 1;
+       if (test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA)
+               return 1;
+       if (EXT4_I(inode)->i_flags & EXT4_JOURNAL_DATA_FL)
+               return 1;
+       return 0;
+}
+
+static inline int ext4_should_order_data(struct inode *inode)
+{
+       if (!S_ISREG(inode->i_mode))
+               return 0;
+       if (EXT4_I(inode)->i_flags & EXT4_JOURNAL_DATA_FL)
+               return 0;
+       if (test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_ORDERED_DATA)
+               return 1;
+       return 0;
+}
+
+static inline int ext4_should_writeback_data(struct inode *inode)
+{
+       if (!S_ISREG(inode->i_mode))
+               return 0;
+       if (EXT4_I(inode)->i_flags & EXT4_JOURNAL_DATA_FL)
+               return 0;
+       if (test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_WRITEBACK_DATA)
+               return 1;
+       return 0;
+}
+
+#endif /* _LINUX_EXT4_JBD_H */
index 34406ed467c352c4ac4ad67b490c0729107c967d..2fe6e3f900ba5fd06a64754c809f9e724382f39e 100644 (file)
@@ -623,6 +623,9 @@ enum inode_i_mutex_lock_class
        I_MUTEX_QUOTA
 };
 
+extern void inode_double_lock(struct inode *inode1, struct inode *inode2);
+extern void inode_double_unlock(struct inode *inode1, struct inode *inode2);
+
 /*
  * NOTE: in a 32bit arch with a preemptable kernel and
  * an UP compile the i_size_read/write must be atomic
@@ -656,7 +659,11 @@ static inline loff_t i_size_read(struct inode *inode)
 #endif
 }
 
-
+/*
+ * NOTE: unlike i_size_read(), i_size_write() does need locking around it
+ * (normally i_mutex), otherwise on 32bit/SMP an update of i_size_seqcount
+ * can be lost, resulting in subsequent i_size_read() calls spinning forever.
+ */
 static inline void i_size_write(struct inode *inode, loff_t i_size)
 {
 #if BITS_PER_LONG==32 && defined(CONFIG_SMP)
@@ -1705,6 +1712,8 @@ extern void __iget(struct inode * inode);
 extern void clear_inode(struct inode *);
 extern void destroy_inode(struct inode *);
 extern struct inode *new_inode(struct super_block *);
+extern int __remove_suid(struct dentry *, int);
+extern int should_remove_suid(struct dentry *);
 extern int remove_suid(struct dentry *);
 extern void remove_dquot_ref(struct super_block *, int, struct list_head *);
 
@@ -1751,6 +1760,8 @@ extern ssize_t generic_file_splice_read(struct file *, loff_t *,
                struct pipe_inode_info *, size_t, unsigned int);
 extern ssize_t generic_file_splice_write(struct pipe_inode_info *,
                struct file *, loff_t *, size_t, unsigned int);
+extern ssize_t generic_file_splice_write_nolock(struct pipe_inode_info *,
+               struct file *, loff_t *, size_t, unsigned int);
 extern ssize_t generic_splice_sendpage(struct pipe_inode_info *pipe,
                struct file *out, loff_t *, size_t len, unsigned int flags);
 extern long do_splice_direct(struct file *in, loff_t *ppos, struct file *out,
index 945ba1ad14acd61212c7c81d60c87c4824c619a1..acbdae6d7ae1c323ebcc98ebfd955ece2a29f74f 100644 (file)
@@ -222,7 +222,7 @@ struct hid_report;
 int hiddev_connect(struct hid_device *);
 void hiddev_disconnect(struct hid_device *);
 void hiddev_hid_event(struct hid_device *hid, struct hid_field *field,
-                     struct hid_usage *usage, __s32 value, struct pt_regs *regs);
+                     struct hid_usage *usage, __s32 value);
 void hiddev_report_event(struct hid_device *hid, struct hid_report *report);
 int __init hiddev_init(void);
 void hiddev_exit(void);
@@ -230,7 +230,7 @@ void hiddev_exit(void);
 static inline int hiddev_connect(struct hid_device *hid) { return -1; }
 static inline void hiddev_disconnect(struct hid_device *hid) { }
 static inline void hiddev_hid_event(struct hid_device *hid, struct hid_field *field,
-                     struct hid_usage *usage, __s32 value, struct pt_regs *regs) { }
+                     struct hid_usage *usage, __s32 value) { }
 static inline void hiddev_report_event(struct hid_device *hid, struct hid_report *report) { }
 static inline int hiddev_init(void) { return 0; }
 static inline void hiddev_exit(void) { }
index c25a38d8f600df00e8f852572d20b266c8cc7a40..5081d27bfa27ac22979dd4a2ad7a865b81701893 100644 (file)
@@ -17,6 +17,7 @@ int hugetlb_sysctl_handler(struct ctl_table *, int, struct file *, void __user *
 int copy_hugetlb_page_range(struct mm_struct *, struct mm_struct *, struct vm_area_struct *);
 int follow_hugetlb_page(struct mm_struct *, struct vm_area_struct *, struct page **, struct vm_area_struct **, unsigned long *, int *, int);
 void unmap_hugepage_range(struct vm_area_struct *, unsigned long, unsigned long);
+void __unmap_hugepage_range(struct vm_area_struct *, unsigned long, unsigned long);
 int hugetlb_prefault(struct address_space *, struct vm_area_struct *);
 int hugetlb_report_meminfo(char *);
 int hugetlb_report_node_meminfo(int, char *);
index 07d8d725541fa5c9b26d312671fcd8b974329190..9c2050293f17c81727d70ffc44eea24a95e7e9f1 100644 (file)
@@ -1185,7 +1185,7 @@ extern void ide_stall_queue(ide_drive_t *drive, unsigned long timeout);
 
 extern int ide_spin_wait_hwgroup(ide_drive_t *);
 extern void ide_timer_expiry(unsigned long);
-extern irqreturn_t ide_intr(int irq, void *dev_id, struct pt_regs *regs);
+extern irqreturn_t ide_intr(int irq, void *dev_id);
 extern void do_ide_request(request_queue_t *);
 
 void ide_init_disk(struct gendisk *, ide_drive_t *);
index ab2740832742e85c6a6870384aa47bbe70c8a201..35cb385735837a2e5b0eca166770bcc647c41fd9 100644 (file)
@@ -44,7 +44,7 @@ struct vlan_ethhdr {
    unsigned char       h_source[ETH_ALEN];        /* source ether addr */
    __be16               h_vlan_proto;              /* Should always be 0x8100 */
    __be16               h_vlan_TCI;                /* Encapsulates priority and VLAN ID */
-   unsigned short      h_vlan_encapsulated_proto; /* packet type ID field (or len) */
+   __be16              h_vlan_encapsulated_proto; /* packet type ID field (or len) */
 };
 
 #include <linux/skbuff.h>
index 5770105471dd359eb2e2b46c70f510e4c2eac35b..c38507ba38b51bab3e48c0a4cb75758c930b145a 100644 (file)
@@ -953,7 +953,6 @@ struct input_dev {
        unsigned int repeat_key;
        struct timer_list timer;
 
-       struct pt_regs *regs;
        int state;
 
        int sync;
@@ -1149,15 +1148,9 @@ static inline void input_report_switch(struct input_dev *dev, unsigned int code,
        input_event(dev, EV_SW, code, !!value);
 }
 
-static inline void input_regs(struct input_dev *dev, struct pt_regs *regs)
-{
-       dev->regs = regs;
-}
-
 static inline void input_sync(struct input_dev *dev)
 {
        input_event(dev, EV_SYN, SYN_REPORT, 0);
-       dev->regs = NULL;
 }
 
 static inline void input_set_abs_params(struct input_dev *dev, int axis, int min, int max, int fuzz, int flat)
index 1f97e3d92639e75aaed86a8066518e2526fa1dee..5b83e7b59621e22e365da7cd923921846e1d987f 100644 (file)
 #define SA_TRIGGER_RISING      IRQF_TRIGGER_RISING
 #define SA_TRIGGER_MASK                IRQF_TRIGGER_MASK
 
+typedef irqreturn_t (*irq_handler_t)(int, void *);
+
 struct irqaction {
-       irqreturn_t (*handler)(int, void *, struct pt_regs *);
+       irq_handler_t handler;
        unsigned long flags;
        cpumask_t mask;
        const char *name;
@@ -75,9 +77,8 @@ struct irqaction {
        struct proc_dir_entry *dir;
 };
 
-extern irqreturn_t no_action(int cpl, void *dev_id, struct pt_regs *regs);
-extern int request_irq(unsigned int,
-                      irqreturn_t (*handler)(int, void *, struct pt_regs *),
+extern irqreturn_t no_action(int cpl, void *dev_id);
+extern int request_irq(unsigned int, irq_handler_t handler,
                       unsigned long, const char *, void *);
 extern void free_irq(unsigned int, void *);
 
index aa3f5af670b579bc9de78a9d1a4075daa6c039c2..81877ea39309aea73cef4a63a3212c69ab5c9131 100644 (file)
@@ -18,6 +18,7 @@
 #ifndef _LINUX_IO_H
 #define _LINUX_IO_H
 
+#include <linux/types.h>
 #include <asm/io.h>
 #include <asm/page.h>
 
@@ -27,4 +28,31 @@ void __iowrite64_copy(void __iomem *to, const void *from, size_t count);
 int ioremap_page_range(unsigned long addr, unsigned long end,
                       unsigned long phys_addr, pgprot_t prot);
 
+/**
+ *     check_signature         -       find BIOS signatures
+ *     @io_addr: mmio address to check
+ *     @signature:  signature block
+ *     @length: length of signature
+ *
+ *     Perform a signature comparison with the mmio address io_addr. This
+ *     address should have been obtained by ioremap.
+ *     Returns 1 on a match.
+ */
+
+static inline int check_signature(const volatile void __iomem *io_addr,
+       const unsigned char *signature, int length)
+{
+       int retval = 0;
+       do {
+               if (readb(io_addr) != *signature)
+                       goto out;
+               io_addr++;
+               signature++;
+               length--;
+       } while (length);
+       retval = 1;
+out:
+       return retval;
+}
+
 #endif /* _LINUX_IO_H */
index da7c09e4ede6e83198bf1ab5f16c571b0cc214ee..38b286e9a46c3f11ddf13ac2f76f4371f21468b5 100644 (file)
@@ -63,7 +63,7 @@ struct ioc3_submodule {
        /* IRQ stuff */
        unsigned int irq_mask;  /* IOC3 IRQ mask, leave clear for Ethernet */
        int reset_mask;         /* non-zero if you want the ioc3.c module to reset interrupts */
-       int (*intr) (struct ioc3_submodule *, struct ioc3_driver_data *, unsigned int, struct pt_regs *);
+       int (*intr) (struct ioc3_submodule *, struct ioc3_driver_data *, unsigned int);
        /* private submodule data */
        void *data;             /* assigned by submodule */
 };
index de73a3289cc2b6e04efcc887d88794a12dfd7cef..51e2b9fb6372f84b5694daa67dd2614c90012a55 100644 (file)
@@ -157,7 +157,7 @@ struct ioc4_driver_data {
        unsigned long idd_bar0;
        struct pci_dev *idd_pdev;
        const struct pci_device_id *idd_pci_id;
-       struct __iomem ioc4_misc_regs *idd_misc_regs;
+       struct ioc4_misc_regs __iomem *idd_misc_regs;
        unsigned long count_period;
        void *idd_serial_data;
        unsigned int idd_variant;
index 6f463606c318ed46bbfdc0427f219023b1da3860..52fc4052a0ae62d113fe1a7eef6692d8d93bf645 100644 (file)
 
 #include <asm/irq.h>
 #include <asm/ptrace.h>
+#include <asm/irq_regs.h>
+
+struct irq_desc;
+typedef        void fastcall (*irq_flow_handler_t)(unsigned int irq,
+                                           struct irq_desc *desc);
+
 
 /*
  * IRQ line status.
@@ -135,13 +141,12 @@ struct irq_chip {
  * @pending_mask:      pending rebalanced interrupts
  * @dir:               /proc/irq/ procfs entry
  * @affinity_entry:    /proc/irq/smp_affinity procfs entry on SMP
+ * @name:              flow handler name for /proc/interrupts output
  *
  * Pad this out to 32 bytes for cache and indexing reasons.
  */
 struct irq_desc {
-       void fastcall           (*handle_irq)(unsigned int irq,
-                                             struct irq_desc *desc,
-                                             struct pt_regs *regs);
+       irq_flow_handler_t      handle_irq;
        struct irq_chip         *chip;
        void                    *handler_data;
        void                    *chip_data;
@@ -161,8 +166,9 @@ struct irq_desc {
        cpumask_t               pending_mask;
 #endif
 #ifdef CONFIG_PROC_FS
-       struct proc_dir_entry *dir;
+       struct proc_dir_entry   *dir;
 #endif
+       const char              *name;
 } ____cacheline_aligned;
 
 extern struct irq_desc irq_desc[NR_IRQS];
@@ -254,43 +260,25 @@ static inline int select_smp_affinity(unsigned int irq)
 extern int no_irq_affinity;
 
 /* Handle irq action chains: */
-extern int handle_IRQ_event(unsigned int irq, struct pt_regs *regs,
-                           struct irqaction *action);
+extern int handle_IRQ_event(unsigned int irq, struct irqaction *action);
 
 /*
  * Built-in IRQ handlers for various IRQ types,
  * callable via desc->chip->handle_irq()
  */
-extern void fastcall
-handle_level_irq(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs);
-extern void fastcall
-handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc,
-                        struct pt_regs *regs);
-extern void fastcall
-handle_edge_irq(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs);
-extern void fastcall
-handle_simple_irq(unsigned int irq, struct irq_desc *desc,
-                 struct pt_regs *regs);
-extern void fastcall
-handle_percpu_irq(unsigned int irq, struct irq_desc *desc,
-                 struct pt_regs *regs);
-extern void fastcall
-handle_bad_irq(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs);
-
-/*
- * Get a descriptive string for the highlevel handler, for
- * /proc/interrupts output:
- */
-extern const char *
-handle_irq_name(void fastcall (*handle)(unsigned int, struct irq_desc *,
-                                       struct pt_regs *));
+extern void fastcall handle_level_irq(unsigned int irq, struct irq_desc *desc);
+extern void fastcall handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc);
+extern void fastcall handle_edge_irq(unsigned int irq, struct irq_desc *desc);
+extern void fastcall handle_simple_irq(unsigned int irq, struct irq_desc *desc);
+extern void fastcall handle_percpu_irq(unsigned int irq, struct irq_desc *desc);
+extern void fastcall handle_bad_irq(unsigned int irq, struct irq_desc *desc);
 
 /*
  * Monolithic do_IRQ implementation.
  * (is an explicit fastcall, because i386 4KSTACKS calls it from assembly)
  */
 #ifndef CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ
-extern fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs);
+extern fastcall unsigned int __do_IRQ(unsigned int irq);
 #endif
 
 /*
@@ -299,23 +287,23 @@ extern fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs);
  * irqchip-style controller then we call the ->handle_irq() handler,
  * and it calls __do_IRQ() if it's attached to an irqtype-style controller.
  */
-static inline void generic_handle_irq(unsigned int irq, struct pt_regs *regs)
+static inline void generic_handle_irq(unsigned int irq)
 {
        struct irq_desc *desc = irq_desc + irq;
 
 #ifdef CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ
-       desc->handle_irq(irq, desc, regs);
+       desc->handle_irq(irq, desc);
 #else
        if (likely(desc->handle_irq))
-               desc->handle_irq(irq, desc, regs);
+               desc->handle_irq(irq, desc);
        else
-               __do_IRQ(irq, regs);
+               __do_IRQ(irq);
 #endif
 }
 
 /* Handling of unhandled and spurious interrupts: */
 extern void note_interrupt(unsigned int irq, struct irq_desc *desc,
-                          int action_ret, struct pt_regs *regs);
+                          int action_ret);
 
 /* Resending of interrupts :*/
 void check_irq_resend(struct irq_desc *desc, unsigned int irq);
@@ -335,24 +323,22 @@ extern struct irq_chip dummy_irq_chip;
 
 extern void
 set_irq_chip_and_handler(unsigned int irq, struct irq_chip *chip,
-                        void fastcall (*handle)(unsigned int,
-                                                struct irq_desc *,
-                                                struct pt_regs *));
+                        irq_flow_handler_t handle);
+extern void
+set_irq_chip_and_handler_name(unsigned int irq, struct irq_chip *chip,
+                             irq_flow_handler_t handle, const char *name);
+
 extern void
-__set_irq_handler(unsigned int irq,
-                 void fastcall (*handle)(unsigned int, struct irq_desc *,
-                                         struct pt_regs *),
-                 int is_chained);
+__set_irq_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
+                 const char *name);
 
 /*
  * Set a highlevel flow handler for a given IRQ:
  */
 static inline void
-set_irq_handler(unsigned int irq,
-               void fastcall (*handle)(unsigned int, struct irq_desc *,
-                                       struct pt_regs *))
+set_irq_handler(unsigned int irq, irq_flow_handler_t handle)
 {
-       __set_irq_handler(irq, handle, 0);
+       __set_irq_handler(irq, handle, 0, NULL);
 }
 
 /*
@@ -362,10 +348,9 @@ set_irq_handler(unsigned int irq,
  */
 static inline void
 set_irq_chained_handler(unsigned int irq,
-                       void fastcall (*handle)(unsigned int, struct irq_desc *,
-                                               struct pt_regs *))
+                       irq_flow_handler_t handle)
 {
-       __set_irq_handler(irq, handle, 1);
+       __set_irq_handler(irq, handle, 1, NULL);
 }
 
 /* Handle dynamic irq creation and destruction */
index 1f996621bc9c9cf67a85f71ef665e0eda7615466..b55e2a035605af23dfec9040f9102b5cdebc2892 100644 (file)
@@ -100,7 +100,7 @@ typedef struct stlibrd {
        unsigned int    iobase;
        int             iosize;
        unsigned long   memaddr;
-       void            *membase;
+       void            __iomem *membase;
        int             memsize;
        int             pagesize;
        int             hostoffset;
@@ -113,7 +113,7 @@ typedef struct stlibrd {
        void            (*enable)(struct stlibrd *brdp);
        void            (*reenable)(struct stlibrd *brdp);
        void            (*disable)(struct stlibrd *brdp);
-       char            *(*getmemptr)(struct stlibrd *brdp, unsigned long offset, int line);
+       void            __iomem *(*getmemptr)(struct stlibrd *brdp, unsigned long offset, int line);
        void            (*intr)(struct stlibrd *brdp);
        void            (*reset)(struct stlibrd *brdp);
        stliport_t      *ports[STL_MAXPORTS];
diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h
new file mode 100644 (file)
index 0000000..ddb1287
--- /dev/null
@@ -0,0 +1,1107 @@
+/*
+ * linux/include/linux/jbd2.h
+ *
+ * Written by Stephen C. Tweedie <sct@redhat.com>
+ *
+ * Copyright 1998-2000 Red Hat, Inc --- All Rights Reserved
+ *
+ * This file is part of the Linux kernel and is made available under
+ * the terms of the GNU General Public License, version 2, or at your
+ * option, any later version, incorporated herein by reference.
+ *
+ * Definitions for transaction data structures for the buffer cache
+ * filesystem journaling support.
+ */
+
+#ifndef _LINUX_JBD_H
+#define _LINUX_JBD_H
+
+/* Allow this file to be included directly into e2fsprogs */
+#ifndef __KERNEL__
+#include "jfs_compat.h"
+#define JBD2_DEBUG
+#define jfs_debug jbd_debug
+#else
+
+#include <linux/types.h>
+#include <linux/buffer_head.h>
+#include <linux/journal-head.h>
+#include <linux/stddef.h>
+#include <linux/bit_spinlock.h>
+#include <linux/mutex.h>
+#include <linux/timer.h>
+
+#include <asm/semaphore.h>
+#endif
+
+#define journal_oom_retry 1
+
+/*
+ * Define JBD_PARANIOD_IOFAIL to cause a kernel BUG() if ext3 finds
+ * certain classes of error which can occur due to failed IOs.  Under
+ * normal use we want ext3 to continue after such errors, because
+ * hardware _can_ fail, but for debugging purposes when running tests on
+ * known-good hardware we may want to trap these errors.
+ */
+#undef JBD_PARANOID_IOFAIL
+
+/*
+ * The default maximum commit age, in seconds.
+ */
+#define JBD_DEFAULT_MAX_COMMIT_AGE 5
+
+#ifdef CONFIG_JBD_DEBUG
+/*
+ * Define JBD_EXPENSIVE_CHECKING to enable more expensive internal
+ * consistency checks.  By default we don't do this unless
+ * CONFIG_JBD_DEBUG is on.
+ */
+#define JBD_EXPENSIVE_CHECKING
+extern int jbd2_journal_enable_debug;
+
+#define jbd_debug(n, f, a...)                                          \
+       do {                                                            \
+               if ((n) <= jbd2_journal_enable_debug) {                 \
+                       printk (KERN_DEBUG "(%s, %d): %s: ",            \
+                               __FILE__, __LINE__, __FUNCTION__);      \
+                       printk (f, ## a);                               \
+               }                                                       \
+       } while (0)
+#else
+#define jbd_debug(f, a...)     /**/
+#endif
+
+extern void * __jbd2_kmalloc (const char *where, size_t size, gfp_t flags, int retry);
+extern void * jbd2_slab_alloc(size_t size, gfp_t flags);
+extern void jbd2_slab_free(void *ptr, size_t size);
+
+#define jbd_kmalloc(size, flags) \
+       __jbd2_kmalloc(__FUNCTION__, (size), (flags), journal_oom_retry)
+#define jbd_rep_kmalloc(size, flags) \
+       __jbd2_kmalloc(__FUNCTION__, (size), (flags), 1)
+
+#define JBD2_MIN_JOURNAL_BLOCKS 1024
+
+#ifdef __KERNEL__
+
+/**
+ * typedef handle_t - The handle_t type represents a single atomic update being performed by some process.
+ *
+ * All filesystem modifications made by the process go
+ * through this handle.  Recursive operations (such as quota operations)
+ * are gathered into a single update.
+ *
+ * The buffer credits field is used to account for journaled buffers
+ * being modified by the running process.  To ensure that there is
+ * enough log space for all outstanding operations, we need to limit the
+ * number of outstanding buffers possible at any time.  When the
+ * operation completes, any buffer credits not used are credited back to
+ * the transaction, so that at all times we know how many buffers the
+ * outstanding updates on a transaction might possibly touch.
+ *
+ * This is an opaque datatype.
+ **/
+typedef struct handle_s                handle_t;       /* Atomic operation type */
+
+
+/**
+ * typedef journal_t - The journal_t maintains all of the journaling state information for a single filesystem.
+ *
+ * journal_t is linked to from the fs superblock structure.
+ *
+ * We use the journal_t to keep track of all outstanding transaction
+ * activity on the filesystem, and to manage the state of the log
+ * writing process.
+ *
+ * This is an opaque datatype.
+ **/
+typedef struct journal_s       journal_t;      /* Journal control structure */
+#endif
+
+/*
+ * Internal structures used by the logging mechanism:
+ */
+
+#define JBD2_MAGIC_NUMBER 0xc03b3998U /* The first 4 bytes of /dev/random! */
+
+/*
+ * On-disk structures
+ */
+
+/*
+ * Descriptor block types:
+ */
+
+#define JBD2_DESCRIPTOR_BLOCK  1
+#define JBD2_COMMIT_BLOCK      2
+#define JBD2_SUPERBLOCK_V1     3
+#define JBD2_SUPERBLOCK_V2     4
+#define JBD2_REVOKE_BLOCK      5
+
+/*
+ * Standard header for all descriptor blocks:
+ */
+typedef struct journal_header_s
+{
+       __be32          h_magic;
+       __be32          h_blocktype;
+       __be32          h_sequence;
+} journal_header_t;
+
+
+/*
+ * The block tag: used to describe a single buffer in the journal.
+ * t_blocknr_high is only used if INCOMPAT_64BIT is set, so this
+ * raw struct shouldn't be used for pointer math or sizeof() - use
+ * journal_tag_bytes(journal) instead to compute this.
+ */
+typedef struct journal_block_tag_s
+{
+       __be32          t_blocknr;      /* The on-disk block number */
+       __be32          t_flags;        /* See below */
+       __be32          t_blocknr_high; /* most-significant high 32bits. */
+} journal_block_tag_t;
+
+#define JBD_TAG_SIZE32 (offsetof(journal_block_tag_t, t_blocknr_high))
+#define JBD_TAG_SIZE64 (sizeof(journal_block_tag_t))
+
+/*
+ * The revoke descriptor: used on disk to describe a series of blocks to
+ * be revoked from the log
+ */
+typedef struct jbd2_journal_revoke_header_s
+{
+       journal_header_t r_header;
+       __be32           r_count;       /* Count of bytes used in the block */
+} jbd2_journal_revoke_header_t;
+
+
+/* Definitions for the journal tag flags word: */
+#define JBD2_FLAG_ESCAPE               1       /* on-disk block is escaped */
+#define JBD2_FLAG_SAME_UUID    2       /* block has same uuid as previous */
+#define JBD2_FLAG_DELETED      4       /* block deleted by this transaction */
+#define JBD2_FLAG_LAST_TAG     8       /* last tag in this descriptor block */
+
+
+/*
+ * The journal superblock.  All fields are in big-endian byte order.
+ */
+typedef struct journal_superblock_s
+{
+/* 0x0000 */
+       journal_header_t s_header;
+
+/* 0x000C */
+       /* Static information describing the journal */
+       __be32  s_blocksize;            /* journal device blocksize */
+       __be32  s_maxlen;               /* total blocks in journal file */
+       __be32  s_first;                /* first block of log information */
+
+/* 0x0018 */
+       /* Dynamic information describing the current state of the log */
+       __be32  s_sequence;             /* first commit ID expected in log */
+       __be32  s_start;                /* blocknr of start of log */
+
+/* 0x0020 */
+       /* Error value, as set by jbd2_journal_abort(). */
+       __be32  s_errno;
+
+/* 0x0024 */
+       /* Remaining fields are only valid in a version-2 superblock */
+       __be32  s_feature_compat;       /* compatible feature set */
+       __be32  s_feature_incompat;     /* incompatible feature set */
+       __be32  s_feature_ro_compat;    /* readonly-compatible feature set */
+/* 0x0030 */
+       __u8    s_uuid[16];             /* 128-bit uuid for journal */
+
+/* 0x0040 */
+       __be32  s_nr_users;             /* Nr of filesystems sharing log */
+
+       __be32  s_dynsuper;             /* Blocknr of dynamic superblock copy*/
+
+/* 0x0048 */
+       __be32  s_max_transaction;      /* Limit of journal blocks per trans.*/
+       __be32  s_max_trans_data;       /* Limit of data blocks per trans. */
+
+/* 0x0050 */
+       __u32   s_padding[44];
+
+/* 0x0100 */
+       __u8    s_users[16*48];         /* ids of all fs'es sharing the log */
+/* 0x0400 */
+} journal_superblock_t;
+
+#define JBD2_HAS_COMPAT_FEATURE(j,mask)                                        \
+       ((j)->j_format_version >= 2 &&                                  \
+        ((j)->j_superblock->s_feature_compat & cpu_to_be32((mask))))
+#define JBD2_HAS_RO_COMPAT_FEATURE(j,mask)                             \
+       ((j)->j_format_version >= 2 &&                                  \
+        ((j)->j_superblock->s_feature_ro_compat & cpu_to_be32((mask))))
+#define JBD2_HAS_INCOMPAT_FEATURE(j,mask)                              \
+       ((j)->j_format_version >= 2 &&                                  \
+        ((j)->j_superblock->s_feature_incompat & cpu_to_be32((mask))))
+
+#define JBD2_FEATURE_INCOMPAT_REVOKE   0x00000001
+#define JBD2_FEATURE_INCOMPAT_64BIT    0x00000002
+
+/* Features known to this kernel version: */
+#define JBD2_KNOWN_COMPAT_FEATURES     0
+#define JBD2_KNOWN_ROCOMPAT_FEATURES   0
+#define JBD2_KNOWN_INCOMPAT_FEATURES   (JBD2_FEATURE_INCOMPAT_REVOKE | \
+                                        JBD2_FEATURE_INCOMPAT_64BIT)
+
+#ifdef __KERNEL__
+
+#include <linux/fs.h>
+#include <linux/sched.h>
+
+#define JBD_ASSERTIONS
+#ifdef JBD_ASSERTIONS
+#define J_ASSERT(assert)                                               \
+do {                                                                   \
+       if (!(assert)) {                                                \
+               printk (KERN_EMERG                                      \
+                       "Assertion failure in %s() at %s:%d: \"%s\"\n", \
+                       __FUNCTION__, __FILE__, __LINE__, # assert);    \
+               BUG();                                                  \
+       }                                                               \
+} while (0)
+
+#if defined(CONFIG_BUFFER_DEBUG)
+void buffer_assertion_failure(struct buffer_head *bh);
+#define J_ASSERT_BH(bh, expr)                                          \
+       do {                                                            \
+               if (!(expr))                                            \
+                       buffer_assertion_failure(bh);                   \
+               J_ASSERT(expr);                                         \
+       } while (0)
+#define J_ASSERT_JH(jh, expr)  J_ASSERT_BH(jh2bh(jh), expr)
+#else
+#define J_ASSERT_BH(bh, expr)  J_ASSERT(expr)
+#define J_ASSERT_JH(jh, expr)  J_ASSERT(expr)
+#endif
+
+#else
+#define J_ASSERT(assert)       do { } while (0)
+#endif         /* JBD_ASSERTIONS */
+
+#if defined(JBD_PARANOID_IOFAIL)
+#define J_EXPECT(expr, why...)         J_ASSERT(expr)
+#define J_EXPECT_BH(bh, expr, why...)  J_ASSERT_BH(bh, expr)
+#define J_EXPECT_JH(jh, expr, why...)  J_ASSERT_JH(jh, expr)
+#else
+#define __journal_expect(expr, why...)                                      \
+       ({                                                                   \
+               int val = (expr);                                            \
+               if (!val) {                                                  \
+                       printk(KERN_ERR                                      \
+                               "EXT3-fs unexpected failure: %s;\n",# expr); \
+                       printk(KERN_ERR why "\n");                           \
+               }                                                            \
+               val;                                                         \
+       })
+#define J_EXPECT(expr, why...)         __journal_expect(expr, ## why)
+#define J_EXPECT_BH(bh, expr, why...)  __journal_expect(expr, ## why)
+#define J_EXPECT_JH(jh, expr, why...)  __journal_expect(expr, ## why)
+#endif
+
+enum jbd_state_bits {
+       BH_JBD                  /* Has an attached ext3 journal_head */
+         = BH_PrivateStart,
+       BH_JWrite,              /* Being written to log (@@@ DEBUGGING) */
+       BH_Freed,               /* Has been freed (truncated) */
+       BH_Revoked,             /* Has been revoked from the log */
+       BH_RevokeValid,         /* Revoked flag is valid */
+       BH_JBDDirty,            /* Is dirty but journaled */
+       BH_State,               /* Pins most journal_head state */
+       BH_JournalHead,         /* Pins bh->b_private and jh->b_bh */
+       BH_Unshadow,            /* Dummy bit, for BJ_Shadow wakeup filtering */
+};
+
+BUFFER_FNS(JBD, jbd)
+BUFFER_FNS(JWrite, jwrite)
+BUFFER_FNS(JBDDirty, jbddirty)
+TAS_BUFFER_FNS(JBDDirty, jbddirty)
+BUFFER_FNS(Revoked, revoked)
+TAS_BUFFER_FNS(Revoked, revoked)
+BUFFER_FNS(RevokeValid, revokevalid)
+TAS_BUFFER_FNS(RevokeValid, revokevalid)
+BUFFER_FNS(Freed, freed)
+
+static inline struct buffer_head *jh2bh(struct journal_head *jh)
+{
+       return jh->b_bh;
+}
+
+static inline struct journal_head *bh2jh(struct buffer_head *bh)
+{
+       return bh->b_private;
+}
+
+static inline void jbd_lock_bh_state(struct buffer_head *bh)
+{
+       bit_spin_lock(BH_State, &bh->b_state);
+}
+
+static inline int jbd_trylock_bh_state(struct buffer_head *bh)
+{
+       return bit_spin_trylock(BH_State, &bh->b_state);
+}
+
+static inline int jbd_is_locked_bh_state(struct buffer_head *bh)
+{
+       return bit_spin_is_locked(BH_State, &bh->b_state);
+}
+
+static inline void jbd_unlock_bh_state(struct buffer_head *bh)
+{
+       bit_spin_unlock(BH_State, &bh->b_state);
+}
+
+static inline void jbd_lock_bh_journal_head(struct buffer_head *bh)
+{
+       bit_spin_lock(BH_JournalHead, &bh->b_state);
+}
+
+static inline void jbd_unlock_bh_journal_head(struct buffer_head *bh)
+{
+       bit_spin_unlock(BH_JournalHead, &bh->b_state);
+}
+
+struct jbd2_revoke_table_s;
+
+/**
+ * struct handle_s - The handle_s type is the concrete type associated with
+ *     handle_t.
+ * @h_transaction: Which compound transaction is this update a part of?
+ * @h_buffer_credits: Number of remaining buffers we are allowed to dirty.
+ * @h_ref: Reference count on this handle
+ * @h_err: Field for caller's use to track errors through large fs operations
+ * @h_sync: flag for sync-on-close
+ * @h_jdata: flag to force data journaling
+ * @h_aborted: flag indicating fatal error on handle
+ **/
+
+/* Docbook can't yet cope with the bit fields, but will leave the documentation
+ * in so it can be fixed later.
+ */
+
+struct handle_s
+{
+       /* Which compound transaction is this update a part of? */
+       transaction_t           *h_transaction;
+
+       /* Number of remaining buffers we are allowed to dirty: */
+       int                     h_buffer_credits;
+
+       /* Reference count on this handle */
+       int                     h_ref;
+
+       /* Field for caller's use to track errors through large fs */
+       /* operations */
+       int                     h_err;
+
+       /* Flags [no locking] */
+       unsigned int    h_sync:         1;      /* sync-on-close */
+       unsigned int    h_jdata:        1;      /* force data journaling */
+       unsigned int    h_aborted:      1;      /* fatal error on handle */
+};
+
+
+/* The transaction_t type is the guts of the journaling mechanism.  It
+ * tracks a compound transaction through its various states:
+ *
+ * RUNNING:    accepting new updates
+ * LOCKED:     Updates still running but we don't accept new ones
+ * RUNDOWN:    Updates are tidying up but have finished requesting
+ *             new buffers to modify (state not used for now)
+ * FLUSH:       All updates complete, but we are still writing to disk
+ * COMMIT:      All data on disk, writing commit record
+ * FINISHED:   We still have to keep the transaction for checkpointing.
+ *
+ * The transaction keeps track of all of the buffers modified by a
+ * running transaction, and all of the buffers committed but not yet
+ * flushed to home for finished transactions.
+ */
+
+/*
+ * Lock ranking:
+ *
+ *    j_list_lock
+ *      ->jbd_lock_bh_journal_head()   (This is "innermost")
+ *
+ *    j_state_lock
+ *    ->jbd_lock_bh_state()
+ *
+ *    jbd_lock_bh_state()
+ *    ->j_list_lock
+ *
+ *    j_state_lock
+ *    ->t_handle_lock
+ *
+ *    j_state_lock
+ *    ->j_list_lock                    (journal_unmap_buffer)
+ *
+ */
+
+struct transaction_s
+{
+       /* Pointer to the journal for this transaction. [no locking] */
+       journal_t               *t_journal;
+
+       /* Sequence number for this transaction [no locking] */
+       tid_t                   t_tid;
+
+       /*
+        * Transaction's current state
+        * [no locking - only kjournald2 alters this]
+        * FIXME: needs barriers
+        * KLUDGE: [use j_state_lock]
+        */
+       enum {
+               T_RUNNING,
+               T_LOCKED,
+               T_RUNDOWN,
+               T_FLUSH,
+               T_COMMIT,
+               T_FINISHED
+       }                       t_state;
+
+       /*
+        * Where in the log does this transaction's commit start? [no locking]
+        */
+       unsigned long           t_log_start;
+
+       /* Number of buffers on the t_buffers list [j_list_lock] */
+       int                     t_nr_buffers;
+
+       /*
+        * Doubly-linked circular list of all buffers reserved but not yet
+        * modified by this transaction [j_list_lock]
+        */
+       struct journal_head     *t_reserved_list;
+
+       /*
+        * Doubly-linked circular list of all buffers under writeout during
+        * commit [j_list_lock]
+        */
+       struct journal_head     *t_locked_list;
+
+       /*
+        * Doubly-linked circular list of all metadata buffers owned by this
+        * transaction [j_list_lock]
+        */
+       struct journal_head     *t_buffers;
+
+       /*
+        * Doubly-linked circular list of all data buffers still to be
+        * flushed before this transaction can be committed [j_list_lock]
+        */
+       struct journal_head     *t_sync_datalist;
+
+       /*
+        * Doubly-linked circular list of all forget buffers (superseded
+        * buffers which we can un-checkpoint once this transaction commits)
+        * [j_list_lock]
+        */
+       struct journal_head     *t_forget;
+
+       /*
+        * Doubly-linked circular list of all buffers still to be flushed before
+        * this transaction can be checkpointed. [j_list_lock]
+        */
+       struct journal_head     *t_checkpoint_list;
+
+       /*
+        * Doubly-linked circular list of all buffers submitted for IO while
+        * checkpointing. [j_list_lock]
+        */
+       struct journal_head     *t_checkpoint_io_list;
+
+       /*
+        * Doubly-linked circular list of temporary buffers currently undergoing
+        * IO in the log [j_list_lock]
+        */
+       struct journal_head     *t_iobuf_list;
+
+       /*
+        * Doubly-linked circular list of metadata buffers being shadowed by log
+        * IO.  The IO buffers on the iobuf list and the shadow buffers on this
+        * list match each other one for one at all times. [j_list_lock]
+        */
+       struct journal_head     *t_shadow_list;
+
+       /*
+        * Doubly-linked circular list of control buffers being written to the
+        * log. [j_list_lock]
+        */
+       struct journal_head     *t_log_list;
+
+       /*
+        * Protects info related to handles
+        */
+       spinlock_t              t_handle_lock;
+
+       /*
+        * Number of outstanding updates running on this transaction
+        * [t_handle_lock]
+        */
+       int                     t_updates;
+
+       /*
+        * Number of buffers reserved for use by all handles in this transaction
+        * handle but not yet modified. [t_handle_lock]
+        */
+       int                     t_outstanding_credits;
+
+       /*
+        * Forward and backward links for the circular list of all transactions
+        * awaiting checkpoint. [j_list_lock]
+        */
+       transaction_t           *t_cpnext, *t_cpprev;
+
+       /*
+        * When will the transaction expire (become due for commit), in jiffies?
+        * [no locking]
+        */
+       unsigned long           t_expires;
+
+       /*
+        * How many handles used this transaction? [t_handle_lock]
+        */
+       int t_handle_count;
+
+};
+
+/**
+ * struct journal_s - The journal_s type is the concrete type associated with
+ *     journal_t.
+ * @j_flags:  General journaling state flags
+ * @j_errno:  Is there an outstanding uncleared error on the journal (from a
+ *     prior abort)?
+ * @j_sb_buffer: First part of superblock buffer
+ * @j_superblock: Second part of superblock buffer
+ * @j_format_version: Version of the superblock format
+ * @j_state_lock: Protect the various scalars in the journal
+ * @j_barrier_count:  Number of processes waiting to create a barrier lock
+ * @j_barrier: The barrier lock itself
+ * @j_running_transaction: The current running transaction..
+ * @j_committing_transaction: the transaction we are pushing to disk
+ * @j_checkpoint_transactions: a linked circular list of all transactions
+ *  waiting for checkpointing
+ * @j_wait_transaction_locked: Wait queue for waiting for a locked transaction
+ *  to start committing, or for a barrier lock to be released
+ * @j_wait_logspace: Wait queue for waiting for checkpointing to complete
+ * @j_wait_done_commit: Wait queue for waiting for commit to complete
+ * @j_wait_checkpoint:  Wait queue to trigger checkpointing
+ * @j_wait_commit: Wait queue to trigger commit
+ * @j_wait_updates: Wait queue to wait for updates to complete
+ * @j_checkpoint_mutex: Mutex for locking against concurrent checkpoints
+ * @j_head: Journal head - identifies the first unused block in the journal
+ * @j_tail: Journal tail - identifies the oldest still-used block in the
+ *  journal.
+ * @j_free: Journal free - how many free blocks are there in the journal?
+ * @j_first: The block number of the first usable block
+ * @j_last: The block number one beyond the last usable block
+ * @j_dev: Device where we store the journal
+ * @j_blocksize: blocksize for the location where we store the journal.
+ * @j_blk_offset: starting block offset for into the device where we store the
+ *     journal
+ * @j_fs_dev: Device which holds the client fs.  For internal journal this will
+ *     be equal to j_dev
+ * @j_maxlen: Total maximum capacity of the journal region on disk.
+ * @j_list_lock: Protects the buffer lists and internal buffer state.
+ * @j_inode: Optional inode where we store the journal.  If present, all journal
+ *     block numbers are mapped into this inode via bmap().
+ * @j_tail_sequence:  Sequence number of the oldest transaction in the log
+ * @j_transaction_sequence: Sequence number of the next transaction to grant
+ * @j_commit_sequence: Sequence number of the most recently committed
+ *  transaction
+ * @j_commit_request: Sequence number of the most recent transaction wanting
+ *     commit
+ * @j_uuid: Uuid of client object.
+ * @j_task: Pointer to the current commit thread for this journal
+ * @j_max_transaction_buffers:  Maximum number of metadata buffers to allow in a
+ *     single compound commit transaction
+ * @j_commit_interval: What is the maximum transaction lifetime before we begin
+ *  a commit?
+ * @j_commit_timer:  The timer used to wakeup the commit thread
+ * @j_revoke_lock: Protect the revoke table
+ * @j_revoke: The revoke table - maintains the list of revoked blocks in the
+ *     current transaction.
+ * @j_revoke_table: alternate revoke tables for j_revoke
+ * @j_wbuf: array of buffer_heads for jbd2_journal_commit_transaction
+ * @j_wbufsize: maximum number of buffer_heads allowed in j_wbuf, the
+ *     number that will fit in j_blocksize
+ * @j_last_sync_writer: most recent pid which did a synchronous write
+ * @j_private: An opaque pointer to fs-private information.
+ */
+
+struct journal_s
+{
+       /* General journaling state flags [j_state_lock] */
+       unsigned long           j_flags;
+
+       /*
+        * Is there an outstanding uncleared error on the journal (from a prior
+        * abort)? [j_state_lock]
+        */
+       int                     j_errno;
+
+       /* The superblock buffer */
+       struct buffer_head      *j_sb_buffer;
+       journal_superblock_t    *j_superblock;
+
+       /* Version of the superblock format */
+       int                     j_format_version;
+
+       /*
+        * Protect the various scalars in the journal
+        */
+       spinlock_t              j_state_lock;
+
+       /*
+        * Number of processes waiting to create a barrier lock [j_state_lock]
+        */
+       int                     j_barrier_count;
+
+       /* The barrier lock itself */
+       struct mutex            j_barrier;
+
+       /*
+        * Transactions: The current running transaction...
+        * [j_state_lock] [caller holding open handle]
+        */
+       transaction_t           *j_running_transaction;
+
+       /*
+        * the transaction we are pushing to disk
+        * [j_state_lock] [caller holding open handle]
+        */
+       transaction_t           *j_committing_transaction;
+
+       /*
+        * ... and a linked circular list of all transactions waiting for
+        * checkpointing. [j_list_lock]
+        */
+       transaction_t           *j_checkpoint_transactions;
+
+       /*
+        * Wait queue for waiting for a locked transaction to start committing,
+        * or for a barrier lock to be released
+        */
+       wait_queue_head_t       j_wait_transaction_locked;
+
+       /* Wait queue for waiting for checkpointing to complete */
+       wait_queue_head_t       j_wait_logspace;
+
+       /* Wait queue for waiting for commit to complete */
+       wait_queue_head_t       j_wait_done_commit;
+
+       /* Wait queue to trigger checkpointing */
+       wait_queue_head_t       j_wait_checkpoint;
+
+       /* Wait queue to trigger commit */
+       wait_queue_head_t       j_wait_commit;
+
+       /* Wait queue to wait for updates to complete */
+       wait_queue_head_t       j_wait_updates;
+
+       /* Semaphore for locking against concurrent checkpoints */
+       struct mutex            j_checkpoint_mutex;
+
+       /*
+        * Journal head: identifies the first unused block in the journal.
+        * [j_state_lock]
+        */
+       unsigned long           j_head;
+
+       /*
+        * Journal tail: identifies the oldest still-used block in the journal.
+        * [j_state_lock]
+        */
+       unsigned long           j_tail;
+
+       /*
+        * Journal free: how many free blocks are there in the journal?
+        * [j_state_lock]
+        */
+       unsigned long           j_free;
+
+       /*
+        * Journal start and end: the block numbers of the first usable block
+        * and one beyond the last usable block in the journal. [j_state_lock]
+        */
+       unsigned long           j_first;
+       unsigned long           j_last;
+
+       /*
+        * Device, blocksize and starting block offset for the location where we
+        * store the journal.
+        */
+       struct block_device     *j_dev;
+       int                     j_blocksize;
+       unsigned long long              j_blk_offset;
+
+       /*
+        * Device which holds the client fs.  For internal journal this will be
+        * equal to j_dev.
+        */
+       struct block_device     *j_fs_dev;
+
+       /* Total maximum capacity of the journal region on disk. */
+       unsigned int            j_maxlen;
+
+       /*
+        * Protects the buffer lists and internal buffer state.
+        */
+       spinlock_t              j_list_lock;
+
+       /* Optional inode where we store the journal.  If present, all */
+       /* journal block numbers are mapped into this inode via */
+       /* bmap(). */
+       struct inode            *j_inode;
+
+       /*
+        * Sequence number of the oldest transaction in the log [j_state_lock]
+        */
+       tid_t                   j_tail_sequence;
+
+       /*
+        * Sequence number of the next transaction to grant [j_state_lock]
+        */
+       tid_t                   j_transaction_sequence;
+
+       /*
+        * Sequence number of the most recently committed transaction
+        * [j_state_lock].
+        */
+       tid_t                   j_commit_sequence;
+
+       /*
+        * Sequence number of the most recent transaction wanting commit
+        * [j_state_lock]
+        */
+       tid_t                   j_commit_request;
+
+       /*
+        * Journal uuid: identifies the object (filesystem, LVM volume etc)
+        * backed by this journal.  This will eventually be replaced by an array
+        * of uuids, allowing us to index multiple devices within a single
+        * journal and to perform atomic updates across them.
+        */
+       __u8                    j_uuid[16];
+
+       /* Pointer to the current commit thread for this journal */
+       struct task_struct      *j_task;
+
+       /*
+        * Maximum number of metadata buffers to allow in a single compound
+        * commit transaction
+        */
+       int                     j_max_transaction_buffers;
+
+       /*
+        * What is the maximum transaction lifetime before we begin a commit?
+        */
+       unsigned long           j_commit_interval;
+
+       /* The timer used to wakeup the commit thread: */
+       struct timer_list       j_commit_timer;
+
+       /*
+        * The revoke table: maintains the list of revoked blocks in the
+        * current transaction.  [j_revoke_lock]
+        */
+       spinlock_t              j_revoke_lock;
+       struct jbd2_revoke_table_s *j_revoke;
+       struct jbd2_revoke_table_s *j_revoke_table[2];
+
+       /*
+        * array of bhs for jbd2_journal_commit_transaction
+        */
+       struct buffer_head      **j_wbuf;
+       int                     j_wbufsize;
+
+       pid_t                   j_last_sync_writer;
+
+       /*
+        * An opaque pointer to fs-private information.  ext3 puts its
+        * superblock pointer here
+        */
+       void *j_private;
+};
+
+/*
+ * Journal flag definitions
+ */
+#define JBD2_UNMOUNT   0x001   /* Journal thread is being destroyed */
+#define JBD2_ABORT     0x002   /* Journaling has been aborted for errors. */
+#define JBD2_ACK_ERR   0x004   /* The errno in the sb has been acked */
+#define JBD2_FLUSHED   0x008   /* The journal superblock has been flushed */
+#define JBD2_LOADED    0x010   /* The journal superblock has been loaded */
+#define JBD2_BARRIER   0x020   /* Use IDE barriers */
+
+/*
+ * Function declarations for the journaling transaction and buffer
+ * management
+ */
+
+/* Filing buffers */
+extern void __jbd2_journal_temp_unlink_buffer(struct journal_head *jh);
+extern void jbd2_journal_unfile_buffer(journal_t *, struct journal_head *);
+extern void __jbd2_journal_unfile_buffer(struct journal_head *);
+extern void __jbd2_journal_refile_buffer(struct journal_head *);
+extern void jbd2_journal_refile_buffer(journal_t *, struct journal_head *);
+extern void __jbd2_journal_file_buffer(struct journal_head *, transaction_t *, int);
+extern void __journal_free_buffer(struct journal_head *bh);
+extern void jbd2_journal_file_buffer(struct journal_head *, transaction_t *, int);
+extern void __journal_clean_data_list(transaction_t *transaction);
+
+/* Log buffer allocation */
+extern struct journal_head * jbd2_journal_get_descriptor_buffer(journal_t *);
+int jbd2_journal_next_log_block(journal_t *, unsigned long long *);
+
+/* Commit management */
+extern void jbd2_journal_commit_transaction(journal_t *);
+
+/* Checkpoint list management */
+int __jbd2_journal_clean_checkpoint_list(journal_t *journal);
+int __jbd2_journal_remove_checkpoint(struct journal_head *);
+void __jbd2_journal_insert_checkpoint(struct journal_head *, transaction_t *);
+
+/* Buffer IO */
+extern int
+jbd2_journal_write_metadata_buffer(transaction_t         *transaction,
+                             struct journal_head  *jh_in,
+                             struct journal_head **jh_out,
+                             unsigned long long   blocknr);
+
+/* Transaction locking */
+extern void            __wait_on_journal (journal_t *);
+
+/*
+ * Journal locking.
+ *
+ * We need to lock the journal during transaction state changes so that nobody
+ * ever tries to take a handle on the running transaction while we are in the
+ * middle of moving it to the commit phase.  j_state_lock does this.
+ *
+ * Note that the locking is completely interrupt unsafe.  We never touch
+ * journal structures from interrupts.
+ */
+
+static inline handle_t *journal_current_handle(void)
+{
+       return current->journal_info;
+}
+
+/* The journaling code user interface:
+ *
+ * Create and destroy handles
+ * Register buffer modifications against the current transaction.
+ */
+
+extern handle_t *jbd2_journal_start(journal_t *, int nblocks);
+extern int      jbd2_journal_restart (handle_t *, int nblocks);
+extern int      jbd2_journal_extend (handle_t *, int nblocks);
+extern int      jbd2_journal_get_write_access(handle_t *, struct buffer_head *);
+extern int      jbd2_journal_get_create_access (handle_t *, struct buffer_head *);
+extern int      jbd2_journal_get_undo_access(handle_t *, struct buffer_head *);
+extern int      jbd2_journal_dirty_data (handle_t *, struct buffer_head *);
+extern int      jbd2_journal_dirty_metadata (handle_t *, struct buffer_head *);
+extern void     jbd2_journal_release_buffer (handle_t *, struct buffer_head *);
+extern int      jbd2_journal_forget (handle_t *, struct buffer_head *);
+extern void     journal_sync_buffer (struct buffer_head *);
+extern void     jbd2_journal_invalidatepage(journal_t *,
+                               struct page *, unsigned long);
+extern int      jbd2_journal_try_to_free_buffers(journal_t *, struct page *, gfp_t);
+extern int      jbd2_journal_stop(handle_t *);
+extern int      jbd2_journal_flush (journal_t *);
+extern void     jbd2_journal_lock_updates (journal_t *);
+extern void     jbd2_journal_unlock_updates (journal_t *);
+
+extern journal_t * jbd2_journal_init_dev(struct block_device *bdev,
+                               struct block_device *fs_dev,
+                               unsigned long long start, int len, int bsize);
+extern journal_t * jbd2_journal_init_inode (struct inode *);
+extern int        jbd2_journal_update_format (journal_t *);
+extern int        jbd2_journal_check_used_features
+                  (journal_t *, unsigned long, unsigned long, unsigned long);
+extern int        jbd2_journal_check_available_features
+                  (journal_t *, unsigned long, unsigned long, unsigned long);
+extern int        jbd2_journal_set_features
+                  (journal_t *, unsigned long, unsigned long, unsigned long);
+extern int        jbd2_journal_create     (journal_t *);
+extern int        jbd2_journal_load       (journal_t *journal);
+extern void       jbd2_journal_destroy    (journal_t *);
+extern int        jbd2_journal_recover    (journal_t *journal);
+extern int        jbd2_journal_wipe       (journal_t *, int);
+extern int        jbd2_journal_skip_recovery   (journal_t *);
+extern void       jbd2_journal_update_superblock       (journal_t *, int);
+extern void       __jbd2_journal_abort_hard    (journal_t *);
+extern void       jbd2_journal_abort      (journal_t *, int);
+extern int        jbd2_journal_errno      (journal_t *);
+extern void       jbd2_journal_ack_err    (journal_t *);
+extern int        jbd2_journal_clear_err  (journal_t *);
+extern int        jbd2_journal_bmap(journal_t *, unsigned long, unsigned long long *);
+extern int        jbd2_journal_force_commit(journal_t *);
+
+/*
+ * journal_head management
+ */
+struct journal_head *jbd2_journal_add_journal_head(struct buffer_head *bh);
+struct journal_head *jbd2_journal_grab_journal_head(struct buffer_head *bh);
+void jbd2_journal_remove_journal_head(struct buffer_head *bh);
+void jbd2_journal_put_journal_head(struct journal_head *jh);
+
+/*
+ * handle management
+ */
+extern kmem_cache_t *jbd2_handle_cache;
+
+static inline handle_t *jbd_alloc_handle(gfp_t gfp_flags)
+{
+       return kmem_cache_alloc(jbd2_handle_cache, gfp_flags);
+}
+
+static inline void jbd_free_handle(handle_t *handle)
+{
+       kmem_cache_free(jbd2_handle_cache, handle);
+}
+
+/* Primary revoke support */
+#define JOURNAL_REVOKE_DEFAULT_HASH 256
+extern int        jbd2_journal_init_revoke(journal_t *, int);
+extern void       jbd2_journal_destroy_revoke_caches(void);
+extern int        jbd2_journal_init_revoke_caches(void);
+
+extern void       jbd2_journal_destroy_revoke(journal_t *);
+extern int        jbd2_journal_revoke (handle_t *, unsigned long long, struct buffer_head *);
+extern int        jbd2_journal_cancel_revoke(handle_t *, struct journal_head *);
+extern void       jbd2_journal_write_revoke_records(journal_t *, transaction_t *);
+
+/* Recovery revoke support */
+extern int     jbd2_journal_set_revoke(journal_t *, unsigned long long, tid_t);
+extern int     jbd2_journal_test_revoke(journal_t *, unsigned long long, tid_t);
+extern void    jbd2_journal_clear_revoke(journal_t *);
+extern void    jbd2_journal_switch_revoke_table(journal_t *journal);
+
+/*
+ * The log thread user interface:
+ *
+ * Request space in the current transaction, and force transaction commit
+ * transitions on demand.
+ */
+
+int __jbd2_log_space_left(journal_t *); /* Called with journal locked */
+int jbd2_log_start_commit(journal_t *journal, tid_t tid);
+int __jbd2_log_start_commit(journal_t *journal, tid_t tid);
+int jbd2_journal_start_commit(journal_t *journal, tid_t *tid);
+int jbd2_journal_force_commit_nested(journal_t *journal);
+int jbd2_log_wait_commit(journal_t *journal, tid_t tid);
+int jbd2_log_do_checkpoint(journal_t *journal);
+
+void __jbd2_log_wait_for_space(journal_t *journal);
+extern void    __jbd2_journal_drop_transaction(journal_t *, transaction_t *);
+extern int     jbd2_cleanup_journal_tail(journal_t *);
+
+/* Debugging code only: */
+
+#define jbd_ENOSYS() \
+do {                                                                      \
+       printk (KERN_ERR "JBD unimplemented function %s\n", __FUNCTION__); \
+       current->state = TASK_UNINTERRUPTIBLE;                             \
+       schedule();                                                        \
+} while (1)
+
+/*
+ * is_journal_abort
+ *
+ * Simple test wrapper function to test the JBD2_ABORT state flag.  This
+ * bit, when set, indicates that we have had a fatal error somewhere,
+ * either inside the journaling layer or indicated to us by the client
+ * (eg. ext3), and that we and should not commit any further
+ * transactions.
+ */
+
+static inline int is_journal_aborted(journal_t *journal)
+{
+       return journal->j_flags & JBD2_ABORT;
+}
+
+static inline int is_handle_aborted(handle_t *handle)
+{
+       if (handle->h_aborted)
+               return 1;
+       return is_journal_aborted(handle->h_transaction->t_journal);
+}
+
+static inline void jbd2_journal_abort_handle(handle_t *handle)
+{
+       handle->h_aborted = 1;
+}
+
+#endif /* __KERNEL__   */
+
+/* Comparison functions for transaction IDs: perform comparisons using
+ * modulo arithmetic so that they work over sequence number wraps. */
+
+static inline int tid_gt(tid_t x, tid_t y)
+{
+       int difference = (x - y);
+       return (difference > 0);
+}
+
+static inline int tid_geq(tid_t x, tid_t y)
+{
+       int difference = (x - y);
+       return (difference >= 0);
+}
+
+extern int jbd2_journal_blocks_per_page(struct inode *inode);
+extern size_t journal_tag_bytes(journal_t *journal);
+
+/*
+ * Return the minimum number of blocks which must be free in the journal
+ * before a new transaction may be started.  Must be called under j_state_lock.
+ */
+static inline int jbd_space_needed(journal_t *journal)
+{
+       int nblocks = journal->j_max_transaction_buffers;
+       if (journal->j_committing_transaction)
+               nblocks += journal->j_committing_transaction->
+                                       t_outstanding_credits;
+       return nblocks;
+}
+
+/*
+ * Definitions which augment the buffer_head layer
+ */
+
+/* journaling buffer types */
+#define BJ_None                0       /* Not journaled */
+#define BJ_SyncData    1       /* Normal data: flush before commit */
+#define BJ_Metadata    2       /* Normal journaled metadata */
+#define BJ_Forget      3       /* Buffer superseded by this transaction */
+#define BJ_IO          4       /* Buffer is for temporary IO use */
+#define BJ_Shadow      5       /* Buffer contents being shadowed to the log */
+#define BJ_LogCtl      6       /* Buffer contains log descriptors */
+#define BJ_Reserved    7       /* Buffer is reserved for access by journal */
+#define BJ_Locked      8       /* Locked for I/O during commit */
+#define BJ_Types       9
+
+extern int jbd_blocks_per_page(struct inode *inode);
+
+#ifdef __KERNEL__
+
+#define buffer_trace_init(bh)  do {} while (0)
+#define print_buffer_fields(bh)        do {} while (0)
+#define print_buffer_trace(bh) do {} while (0)
+#define BUFFER_TRACE(bh, info) do {} while (0)
+#define BUFFER_TRACE2(bh, bh2, info)   do {} while (0)
+#define JBUFFER_TRACE(jh, info)        do {} while (0)
+
+#endif /* __KERNEL__ */
+
+#endif /* _LINUX_JBD_H */
index d1af1dbeaeb4af7c0422943928e88dfdc42e824d..b03d5a340dc810723368d1cc4fbf73b703e9628d 100644 (file)
@@ -143,7 +143,7 @@ enum {
        ATA_DFLAG_CFG_MASK      = (1 << 8) - 1,
 
        ATA_DFLAG_PIO           = (1 << 8), /* device limited to PIO mode */
-       ATA_DFLAG_NCQ_OFF       = (1 << 9), /* devied limited to non-NCQ mode */
+       ATA_DFLAG_NCQ_OFF       = (1 << 9), /* device limited to non-NCQ mode */
        ATA_DFLAG_SUSPENDED     = (1 << 10), /* device suspended */
        ATA_DFLAG_INIT_MASK     = (1 << 16) - 1,
 
@@ -628,7 +628,7 @@ struct ata_port_operations {
        void (*error_handler) (struct ata_port *ap);
        void (*post_internal_cmd) (struct ata_queued_cmd *qc);
 
-       irqreturn_t (*irq_handler)(int, void *, struct pt_regs *);
+       irq_handler_t irq_handler;
        void (*irq_clear) (struct ata_port *);
 
        u32 (*scr_read) (struct ata_port *ap, unsigned int sc_reg);
@@ -769,7 +769,7 @@ extern void ata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf)
 extern int ata_port_start (struct ata_port *ap);
 extern void ata_port_stop (struct ata_port *ap);
 extern void ata_host_stop (struct ata_host *host);
-extern irqreturn_t ata_interrupt (int irq, void *dev_instance, struct pt_regs *regs);
+extern irqreturn_t ata_interrupt (int irq, void *dev_instance);
 extern void ata_mmio_data_xfer(struct ata_device *adev, unsigned char *buf,
                               unsigned int buflen, int write_data);
 extern void ata_pio_data_xfer(struct ata_device *adev, unsigned char *buf,
index 81e3a185f9515ada07ef16bef6b94a619e9196f6..aa50d89eacd77abb748ad7a892f20575b7c4b1bb 100644 (file)
 #define LINUX_LOCKD_BIND_H
 
 #include <linux/lockd/nlm.h>
+/* need xdr-encoded error codes too, so... */
+#include <linux/lockd/xdr.h>
+#ifdef CONFIG_LOCKD_V4
+#include <linux/lockd/xdr4.h>
+#endif
 
 /* Dummy declarations */
 struct svc_rqst;
index 2909619c029589b5f74d86e236f12682cc4946f0..862d9730a60dd4e4b4de43d60363c4434b11f94a 100644 (file)
@@ -154,7 +154,7 @@ int           nlm_async_reply(struct nlm_rqst *, u32, const struct rpc_call_ops *);
 struct nlm_wait * nlmclnt_prepare_block(struct nlm_host *host, struct file_lock *fl);
 void             nlmclnt_finish_block(struct nlm_wait *block);
 int              nlmclnt_block(struct nlm_wait *block, struct nlm_rqst *req, long timeout);
-u32              nlmclnt_grant(const struct sockaddr_in *addr, const struct nlm_lock *);
+__be32           nlmclnt_grant(const struct sockaddr_in *addr, const struct nlm_lock *);
 void             nlmclnt_recovery(struct nlm_host *);
 int              nlmclnt_reclaim(struct nlm_host *, struct file_lock *);
 void             nlmclnt_next_cookie(struct nlm_cookie *);
@@ -184,12 +184,12 @@ typedef int         (*nlm_host_match_fn_t)(struct nlm_host *cur, struct nlm_host *ref)
 /*
  * Server-side lock handling
  */
-u32              nlmsvc_lock(struct svc_rqst *, struct nlm_file *,
+__be32           nlmsvc_lock(struct svc_rqst *, struct nlm_file *,
                                        struct nlm_lock *, int, struct nlm_cookie *);
-u32              nlmsvc_unlock(struct nlm_file *, struct nlm_lock *);
-u32              nlmsvc_testlock(struct nlm_file *, struct nlm_lock *,
+__be32           nlmsvc_unlock(struct nlm_file *, struct nlm_lock *);
+__be32           nlmsvc_testlock(struct nlm_file *, struct nlm_lock *,
                                        struct nlm_lock *);
-u32              nlmsvc_cancel_blocked(struct nlm_file *, struct nlm_lock *);
+__be32           nlmsvc_cancel_blocked(struct nlm_file *, struct nlm_lock *);
 unsigned long    nlmsvc_retry_blocked(void);
 void             nlmsvc_traverse_blocks(struct nlm_host *, struct nlm_file *,
                                        nlm_host_match_fn_t match);
@@ -198,7 +198,7 @@ void                  nlmsvc_grant_reply(struct nlm_cookie *, u32);
 /*
  * File handling for the server personality
  */
-u32              nlm_lookup_file(struct svc_rqst *, struct nlm_file **,
+__be32           nlm_lookup_file(struct svc_rqst *, struct nlm_file **,
                                        struct nfs_fh *);
 void             nlm_release_file(struct nlm_file *);
 void             nlmsvc_mark_resources(void);
index cd7816e74c0536f71faf01e8cd909900efe48c5a..630c5bf69b0786046bf420481e0894c56e3a4562 100644 (file)
@@ -21,9 +21,9 @@ struct nlm_share {
        u32                     s_mode;         /* deny mode */
 };
 
-u32    nlmsvc_share_file(struct nlm_host *, struct nlm_file *,
+__be32 nlmsvc_share_file(struct nlm_host *, struct nlm_file *,
                                               struct nlm_args *);
-u32    nlmsvc_unshare_file(struct nlm_host *, struct nlm_file *,
+__be32 nlmsvc_unshare_file(struct nlm_host *, struct nlm_file *,
                                               struct nlm_args *);
 void   nlmsvc_traverse_shares(struct nlm_host *, struct nlm_file *,
                                               nlm_host_match_fn_t);
index bb0a0f1caa91e9bc521686fe6dfed54d7b85c17a..29e7d9fc9dad68c163c38a6908659540869d0bb4 100644 (file)
@@ -13,6 +13,8 @@
 #include <linux/nfs.h>
 #include <linux/sunrpc/xdr.h>
 
+struct svc_rqst;
+
 #define NLM_MAXCOOKIELEN       32
 #define NLM_MAXSTRLEN          1024
 
@@ -22,6 +24,8 @@
 #define        nlm_lck_blocked         __constant_htonl(NLM_LCK_BLOCKED)
 #define        nlm_lck_denied_grace_period     __constant_htonl(NLM_LCK_DENIED_GRACE_PERIOD)
 
+#define nlm_drop_reply         __constant_htonl(30000)
+
 /* Lock info passed via NLM */
 struct nlm_lock {
        char *                  caller;
@@ -86,19 +90,19 @@ struct nlm_reboot {
  */
 #define NLMSVC_XDRSIZE         sizeof(struct nlm_args)
 
-int    nlmsvc_decode_testargs(struct svc_rqst *, u32 *, struct nlm_args *);
-int    nlmsvc_encode_testres(struct svc_rqst *, u32 *, struct nlm_res *);
-int    nlmsvc_decode_lockargs(struct svc_rqst *, u32 *, struct nlm_args *);
-int    nlmsvc_decode_cancargs(struct svc_rqst *, u32 *, struct nlm_args *);
-int    nlmsvc_decode_unlockargs(struct svc_rqst *, u32 *, struct nlm_args *);
-int    nlmsvc_encode_res(struct svc_rqst *, u32 *, struct nlm_res *);
-int    nlmsvc_decode_res(struct svc_rqst *, u32 *, struct nlm_res *);
-int    nlmsvc_encode_void(struct svc_rqst *, u32 *, void *);
-int    nlmsvc_decode_void(struct svc_rqst *, u32 *, void *);
-int    nlmsvc_decode_shareargs(struct svc_rqst *, u32 *, struct nlm_args *);
-int    nlmsvc_encode_shareres(struct svc_rqst *, u32 *, struct nlm_res *);
-int    nlmsvc_decode_notify(struct svc_rqst *, u32 *, struct nlm_args *);
-int    nlmsvc_decode_reboot(struct svc_rqst *, u32 *, struct nlm_reboot *);
+int    nlmsvc_decode_testargs(struct svc_rqst *, __be32 *, struct nlm_args *);
+int    nlmsvc_encode_testres(struct svc_rqst *, __be32 *, struct nlm_res *);
+int    nlmsvc_decode_lockargs(struct svc_rqst *, __be32 *, struct nlm_args *);
+int    nlmsvc_decode_cancargs(struct svc_rqst *, __be32 *, struct nlm_args *);
+int    nlmsvc_decode_unlockargs(struct svc_rqst *, __be32 *, struct nlm_args *);
+int    nlmsvc_encode_res(struct svc_rqst *, __be32 *, struct nlm_res *);
+int    nlmsvc_decode_res(struct svc_rqst *, __be32 *, struct nlm_res *);
+int    nlmsvc_encode_void(struct svc_rqst *, __be32 *, void *);
+int    nlmsvc_decode_void(struct svc_rqst *, __be32 *, void *);
+int    nlmsvc_decode_shareargs(struct svc_rqst *, __be32 *, struct nlm_args *);
+int    nlmsvc_encode_shareres(struct svc_rqst *, __be32 *, struct nlm_res *);
+int    nlmsvc_decode_notify(struct svc_rqst *, __be32 *, struct nlm_args *);
+int    nlmsvc_decode_reboot(struct svc_rqst *, __be32 *, struct nlm_reboot *);
 /*
 int    nlmclt_encode_testargs(struct rpc_rqst *, u32 *, struct nlm_args *);
 int    nlmclt_encode_lockargs(struct rpc_rqst *, u32 *, struct nlm_args *);
index 3cc1ae25009b7e63d7f973311b94a600062b8e62..dd12b4c9e613eab54d82c6eb2b7deb139b774cbe 100644 (file)
 
 
 
-int    nlm4svc_decode_testargs(struct svc_rqst *, u32 *, struct nlm_args *);
-int    nlm4svc_encode_testres(struct svc_rqst *, u32 *, struct nlm_res *);
-int    nlm4svc_decode_lockargs(struct svc_rqst *, u32 *, struct nlm_args *);
-int    nlm4svc_decode_cancargs(struct svc_rqst *, u32 *, struct nlm_args *);
-int    nlm4svc_decode_unlockargs(struct svc_rqst *, u32 *, struct nlm_args *);
-int    nlm4svc_encode_res(struct svc_rqst *, u32 *, struct nlm_res *);
-int    nlm4svc_decode_res(struct svc_rqst *, u32 *, struct nlm_res *);
-int    nlm4svc_encode_void(struct svc_rqst *, u32 *, void *);
-int    nlm4svc_decode_void(struct svc_rqst *, u32 *, void *);
-int    nlm4svc_decode_shareargs(struct svc_rqst *, u32 *, struct nlm_args *);
-int    nlm4svc_encode_shareres(struct svc_rqst *, u32 *, struct nlm_res *);
-int    nlm4svc_decode_notify(struct svc_rqst *, u32 *, struct nlm_args *);
-int    nlm4svc_decode_reboot(struct svc_rqst *, u32 *, struct nlm_reboot *);
+int    nlm4svc_decode_testargs(struct svc_rqst *, __be32 *, struct nlm_args *);
+int    nlm4svc_encode_testres(struct svc_rqst *, __be32 *, struct nlm_res *);
+int    nlm4svc_decode_lockargs(struct svc_rqst *, __be32 *, struct nlm_args *);
+int    nlm4svc_decode_cancargs(struct svc_rqst *, __be32 *, struct nlm_args *);
+int    nlm4svc_decode_unlockargs(struct svc_rqst *, __be32 *, struct nlm_args *);
+int    nlm4svc_encode_res(struct svc_rqst *, __be32 *, struct nlm_res *);
+int    nlm4svc_decode_res(struct svc_rqst *, __be32 *, struct nlm_res *);
+int    nlm4svc_encode_void(struct svc_rqst *, __be32 *, void *);
+int    nlm4svc_decode_void(struct svc_rqst *, __be32 *, void *);
+int    nlm4svc_decode_shareargs(struct svc_rqst *, __be32 *, struct nlm_args *);
+int    nlm4svc_encode_shareres(struct svc_rqst *, __be32 *, struct nlm_res *);
+int    nlm4svc_decode_notify(struct svc_rqst *, __be32 *, struct nlm_args *);
+int    nlm4svc_decode_reboot(struct svc_rqst *, __be32 *, struct nlm_reboot *);
 /*
 int    nlmclt_encode_testargs(struct rpc_rqst *, u32 *, struct nlm_args *);
 int    nlmclt_encode_lockargs(struct rpc_rqst *, u32 *, struct nlm_args *);
index 1314ca0f29be78f637f027614d09d5a062e091a2..819f08f1310db878f753e7656da2ce32590a5a69 100644 (file)
@@ -202,7 +202,7 @@ extern int lockdep_internal(void);
  */
 
 extern void lockdep_init_map(struct lockdep_map *lock, const char *name,
-                            struct lock_class_key *key);
+                            struct lock_class_key *key, int subclass);
 
 /*
  * Reinitialize a lock key - for cases where there is special locking or
@@ -211,9 +211,14 @@ extern void lockdep_init_map(struct lockdep_map *lock, const char *name,
  * or they are too narrow (they suffer from a false class-split):
  */
 #define lockdep_set_class(lock, key) \
-               lockdep_init_map(&(lock)->dep_map, #key, key)
+               lockdep_init_map(&(lock)->dep_map, #key, key, 0)
 #define lockdep_set_class_and_name(lock, key, name) \
-               lockdep_init_map(&(lock)->dep_map, name, key)
+               lockdep_init_map(&(lock)->dep_map, name, key, 0)
+#define lockdep_set_class_and_subclass(lock, key, sub) \
+               lockdep_init_map(&(lock)->dep_map, #key, key, sub)
+#define lockdep_set_subclass(lock, sub)        \
+               lockdep_init_map(&(lock)->dep_map, #lock, \
+                                (lock)->dep_map.key, sub)
 
 /*
  * Acquire a lock.
@@ -257,10 +262,14 @@ static inline int lockdep_internal(void)
 # define lock_release(l, n, i)                 do { } while (0)
 # define lockdep_init()                                do { } while (0)
 # define lockdep_info()                                do { } while (0)
-# define lockdep_init_map(lock, name, key)     do { (void)(key); } while (0)
+# define lockdep_init_map(lock, name, key, sub)        do { (void)(key); } while (0)
 # define lockdep_set_class(lock, key)          do { (void)(key); } while (0)
 # define lockdep_set_class_and_name(lock, key, name) \
                do { (void)(key); } while (0)
+#define lockdep_set_class_and_subclass(lock, key, sub) \
+               do { (void)(key); } while (0)
+#define lockdep_set_subclass(lock, sub)                do { } while (0)
+
 # define INIT_LOCKDEP
 # define lockdep_reset()               do { debug_locks = 1; } while (0)
 # define lockdep_free_key_range(start, size)   do { } while (0)
index 22036dd2ba362dee7b4b48e90416f65b9f2871aa..156c40fc664e26420f07cd6985efbc8dfa62113c 100644 (file)
@@ -8,6 +8,7 @@
 #define EFS_SUPER_MAGIC                0x414A53
 #define EXT2_SUPER_MAGIC       0xEF53
 #define EXT3_SUPER_MAGIC       0xEF53
+#define EXT4_SUPER_MAGIC       0xEF53
 #define HPFS_SUPER_MAGIC       0xf995e849
 #define ISOFS_SUPER_MAGIC      0x9660
 #define JFFS2_SUPER_MAGIC      0x72b6
index 09f0f575ddff947b32ac9cdef5e8f2b07b4dff87..daabb3aa1ec6b96b5078f6236d2df87fbfe710f6 100644 (file)
@@ -150,7 +150,7 @@ extern void mpol_rebind_mm(struct mm_struct *mm, nodemask_t *new);
 extern void mpol_fix_fork_child_flag(struct task_struct *p);
 #define set_cpuset_being_rebound(x) (cpuset_being_rebound = (x))
 
-#ifdef CONFIG_CPUSET
+#ifdef CONFIG_CPUSETS
 #define current_cpuset_is_being_rebound() \
                                (cpuset_being_rebound == current->cpuset)
 #else
index b7966ab8cb6ac42ebd864c62542e01427d5b99eb..d538de9019652c851fc6afc281cc1eaa0969268e 100644 (file)
@@ -593,6 +593,7 @@ static inline int page_mapped(struct page *page)
  */
 #define NOPAGE_SIGBUS  (NULL)
 #define NOPAGE_OOM     ((struct page *) (-1))
+#define NOPAGE_REFAULT ((struct page *) (-2))  /* Return to userspace, rerun */
 
 /*
  * Error return values for the *_nopfn functions
@@ -1102,12 +1103,7 @@ static inline void vm_stat_account(struct mm_struct *mm,
 
 #ifndef CONFIG_DEBUG_PAGEALLOC
 static inline void
-kernel_map_pages(struct page *page, int numpages, int enable)
-{
-       if (!PageHighMem(page) && !enable)
-               debug_check_no_locks_freed(page_address(page),
-                                          numpages * PAGE_SIZE);
-}
+kernel_map_pages(struct page *page, int numpages, int enable) {}
 #endif
 
 extern struct vm_area_struct *get_gate_vma(struct task_struct *tsk);
@@ -1119,9 +1115,6 @@ int in_gate_area_no_task(unsigned long addr);
 #define in_gate_area(task, addr) ({(void)task; in_gate_area_no_task(addr);})
 #endif /* __HAVE_ARCH_GATE_AREA */
 
-/* /proc/<pid>/oom_adj set to -17 protects from the oom-killer */
-#define OOM_DISABLE -17
-
 int drop_caches_sysctl_handler(struct ctl_table *, int, struct file *,
                                        void __user *, size_t *, loff_t *);
 unsigned long shrink_slab(unsigned long scanned, gfp_t gfp_mask,
index 81c3f77f652c95f6ec9ba8efee8450dc4e501a8f..08dec8d9e7038a09fbeb1fbe64973a16f590ab94 100644 (file)
@@ -83,6 +83,7 @@
 
   /* Application commands */
 #define SD_APP_SET_BUS_WIDTH      6   /* ac   [1:0] bus width    R1  */
+#define SD_APP_SEND_NUM_WR_BLKS  22   /* adtc                    R1  */
 #define SD_APP_OP_COND           41   /* bcr  [31:0] OCR         R3  */
 #define SD_APP_SEND_SCR          51   /* adtc                    R1  */
 
index 59855b8718a0a4b993a39cb825034ad081dd09cd..ed0762b283a9fd725b08a10fd2e194f89fcba3c0 100644 (file)
@@ -674,6 +674,12 @@ void sparse_init(void);
 #define sparse_index_init(_sec, _nid)  do {} while (0)
 #endif /* CONFIG_SPARSEMEM */
 
+#ifdef CONFIG_NODES_SPAN_OTHER_NODES
+#define early_pfn_in_nid(pfn, nid)     (early_pfn_to_nid(pfn) == (nid))
+#else
+#define early_pfn_in_nid(pfn, nid)     (1)
+#endif
+
 #ifndef early_pfn_valid
 #define early_pfn_valid(pfn)   (1)
 #endif
index 4b2d8091a4104a0cd603d64a9240d6dbdf9b5396..d1d00ce8f4ed5c53ecd09b8d6f38a0ddcb503089 100644 (file)
@@ -317,9 +317,6 @@ struct module
        /* Am I unsafe to unload? */
        int unsafe;
 
-       /* Am I GPL-compatible */
-       int license_gplok;
-
        unsigned int taints;    /* same bits as kernel:tainted */
 
 #ifdef CONFIG_MODULE_UNLOAD
index e712e7d47cc22a6c0f6e3071bbabbf6770506b16..d6b6dc09ad972d9f844da2e64d765d254ee8f87f 100644 (file)
@@ -15,6 +15,8 @@
 #ifndef LINUX_NBD_H
 #define LINUX_NBD_H
 
+#include <linux/types.h>
+
 #define NBD_SET_SOCK   _IO( 0xab, 0 )
 #define NBD_SET_BLKSIZE        _IO( 0xab, 1 )
 #define NBD_SET_SIZE   _IO( 0xab, 2 )
index c257f716e00f0b1698fb4154d67f6792e3b6fd50..15c733b816f0820afcef4d615ed11cfa7b43cd76 100644 (file)
@@ -19,6 +19,7 @@
 #define _LINUX_NET_H
 
 #include <linux/wait.h>
+#include <linux/random.h>
 #include <asm/socket.h>
 
 struct poll_table_struct;
@@ -193,9 +194,9 @@ extern int       sock_map_fd(struct socket *sock);
 extern struct socket *sockfd_lookup(int fd, int *err);
 #define                     sockfd_put(sock) fput(sock->file)
 extern int          net_ratelimit(void);
-extern unsigned long net_random(void);
-extern void         net_srandom(unsigned long);
-extern void         net_random_init(void);
+
+#define net_random()           random32()
+#define net_srandom(seed)      srandom32(seed)
 
 extern int          kernel_sendmsg(struct socket *sock, struct msghdr *msg,
                                    struct kvec *vec, size_t num, size_t len);
index 76ff54846ada1e07cab6ca2fa8e0de019a906e85..45228c1a119527daa656cc1334d13c2fba8d9690 100644 (file)
@@ -157,7 +157,7 @@ struct nfs_inode {
         * This is the cookie verifier used for NFSv3 readdir
         * operations
         */
-       __u32                   cookieverf[2];
+       __be32                  cookieverf[2];
 
        /*
         * This is the list of dirty unwritten pages.
@@ -290,6 +290,7 @@ static inline int nfs_verify_change_attribute(struct inode *inode, unsigned long
  * linux/fs/nfs/inode.c
  */
 extern int nfs_sync_mapping(struct address_space *mapping);
+extern void nfs_zap_mapping(struct inode *inode, struct address_space *mapping);
 extern void nfs_zap_caches(struct inode *);
 extern struct inode *nfs_fhget(struct super_block *, struct nfs_fh *,
                                struct nfs_fattr *);
index dc5397d9d23cf1e325f55eb06efe0b0f4be769ac..768c1ad5ff6f93e1859ca7771fb20fbf36c4faf2 100644 (file)
@@ -266,7 +266,7 @@ struct nfs_writeargs {
 
 struct nfs_writeverf {
        enum nfs3_stable_how    committed;
-       __u32                   verifier[2];
+       __be32                  verifier[2];
 };
 
 struct nfs_writeres {
@@ -420,7 +420,7 @@ struct nfs3_createargs {
        unsigned int            len;
        struct iattr *          sattr;
        enum nfs3_createmode    createmode;
-       __u32                   verifier[2];
+       __be32                  verifier[2];
 };
 
 struct nfs3_mkdirargs {
@@ -467,7 +467,7 @@ struct nfs3_linkargs {
 struct nfs3_readdirargs {
        struct nfs_fh *         fh;
        __u64                   cookie;
-       __u32                   verf[2];
+       __be32                  verf[2];
        int                     plus;
        unsigned int            count;
        struct page **          pages;
@@ -503,7 +503,7 @@ struct nfs3_linkres {
 
 struct nfs3_readdirres {
        struct nfs_fattr *      dir_attr;
-       __u32 *                 verf;
+       __be32 *                verf;
        int                     plus;
 };
 
@@ -811,7 +811,7 @@ struct nfs_rpc_ops {
        int     (*pathconf) (struct nfs_server *, struct nfs_fh *,
                             struct nfs_pathconf *);
        int     (*set_capabilities)(struct nfs_server *, struct nfs_fh *);
-       u32 *   (*decode_dirent)(u32 *, struct nfs_entry *, int plus);
+       __be32 *(*decode_dirent)(__be32 *, struct nfs_entry *, int plus);
        void    (*read_setup)   (struct nfs_read_data *);
        int     (*read_done)  (struct rpc_task *, struct nfs_read_data *);
        void    (*write_setup)  (struct nfs_write_data *, int how);
index c3a3557c2a5b49ac994d3aa87c3a651603e4b361..007480cd6a601fbec62c5d5ac41ed50e2a2d882d 100644 (file)
@@ -26,14 +26,14 @@ struct svc_cacherep {
                                c_type,         /* status, buffer */
                                c_secure : 1;   /* req came from port < 1024 */
        struct sockaddr_in      c_addr;
-       u32                     c_xid;
+       __be32                  c_xid;
        u32                     c_prot;
        u32                     c_proc;
        u32                     c_vers;
        unsigned long           c_timestamp;
        union {
                struct kvec     u_vec;
-               u32             u_status;
+               __be32          u_status;
        }                       c_u;
 };
 
@@ -75,7 +75,7 @@ enum {
 void   nfsd_cache_init(void);
 void   nfsd_cache_shutdown(void);
 int    nfsd_cache_lookup(struct svc_rqst *, int);
-void   nfsd_cache_update(struct svc_rqst *, int, u32 *);
+void   nfsd_cache_update(struct svc_rqst *, int, __be32 *);
 
 #endif /* __KERNEL__ */
 #endif /* NFSCACHE_H */
index 6e78ea969f4935977559495a1a0f139bc2423735..045e38cdbe646f966abf370cddb8d573b4770d62 100644 (file)
@@ -117,8 +117,8 @@ struct svc_export * exp_parent(struct auth_domain *clp,
                                   struct cache_req *reqp);
 int                    exp_rootfh(struct auth_domain *, 
                                        char *path, struct knfsd_fh *, int maxsize);
-int                    exp_pseudoroot(struct auth_domain *, struct svc_fh *fhp, struct cache_req *creq);
-int                    nfserrno(int errno);
+__be32                 exp_pseudoroot(struct auth_domain *, struct svc_fh *fhp, struct cache_req *creq);
+__be32                 nfserrno(int errno);
 
 extern struct cache_detail svc_export_cache;
 
index d0d4aae7085fd5fea09de2831132ee3d0e80b734..eb231143d5794fa4783e235e7a0d28032470a254 100644 (file)
@@ -50,7 +50,7 @@
  * Callback function for readdir
  */
 struct readdir_cd {
-       int                     err;    /* 0, nfserr, or nfserr_eof */
+       __be32                  err;    /* 0, nfserr, or nfserr_eof */
 };
 typedef int            (*encode_dent_fn)(struct readdir_cd *, const char *,
                                                int, loff_t, ino_t, unsigned int);
@@ -64,7 +64,7 @@ extern struct svc_serv                *nfsd_serv;
  * Function prototypes.
  */
 int            nfsd_svc(unsigned short port, int nrservs);
-int            nfsd_dispatch(struct svc_rqst *rqstp, u32 *statp);
+int            nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp);
 
 /* nfsd/vfs.c */
 int            fh_lock_parent(struct svc_fh *, struct dentry *);
@@ -72,57 +72,57 @@ int         nfsd_racache_init(int);
 void           nfsd_racache_shutdown(void);
 int            nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry **dpp,
                                struct svc_export **expp);
-int            nfsd_lookup(struct svc_rqst *, struct svc_fh *,
+__be32         nfsd_lookup(struct svc_rqst *, struct svc_fh *,
                                const char *, int, struct svc_fh *);
-int            nfsd_setattr(struct svc_rqst *, struct svc_fh *,
+__be32         nfsd_setattr(struct svc_rqst *, struct svc_fh *,
                                struct iattr *, int, time_t);
 #ifdef CONFIG_NFSD_V4
-int             nfsd4_set_nfs4_acl(struct svc_rqst *, struct svc_fh *,
+__be32          nfsd4_set_nfs4_acl(struct svc_rqst *, struct svc_fh *,
                     struct nfs4_acl *);
 int             nfsd4_get_nfs4_acl(struct svc_rqst *, struct dentry *, struct nfs4_acl **);
 #endif /* CONFIG_NFSD_V4 */
-int            nfsd_create(struct svc_rqst *, struct svc_fh *,
+__be32         nfsd_create(struct svc_rqst *, struct svc_fh *,
                                char *name, int len, struct iattr *attrs,
                                int type, dev_t rdev, struct svc_fh *res);
 #ifdef CONFIG_NFSD_V3
-int            nfsd_access(struct svc_rqst *, struct svc_fh *, u32 *, u32 *);
-int            nfsd_create_v3(struct svc_rqst *, struct svc_fh *,
+__be32         nfsd_access(struct svc_rqst *, struct svc_fh *, u32 *, u32 *);
+__be32         nfsd_create_v3(struct svc_rqst *, struct svc_fh *,
                                char *name, int len, struct iattr *attrs,
                                struct svc_fh *res, int createmode,
                                u32 *verifier, int *truncp);
-int            nfsd_commit(struct svc_rqst *, struct svc_fh *,
+__be32         nfsd_commit(struct svc_rqst *, struct svc_fh *,
                                loff_t, unsigned long);
 #endif /* CONFIG_NFSD_V3 */
-int            nfsd_open(struct svc_rqst *, struct svc_fh *, int,
+__be32         nfsd_open(struct svc_rqst *, struct svc_fh *, int,
                                int, struct file **);
 void           nfsd_close(struct file *);
-int            nfsd_read(struct svc_rqst *, struct svc_fh *, struct file *,
+__be32                 nfsd_read(struct svc_rqst *, struct svc_fh *, struct file *,
                                loff_t, struct kvec *, int, unsigned long *);
-int            nfsd_write(struct svc_rqst *, struct svc_fh *,struct file *,
+__be32                 nfsd_write(struct svc_rqst *, struct svc_fh *,struct file *,
                                loff_t, struct kvec *,int, unsigned long, int *);
-int            nfsd_readlink(struct svc_rqst *, struct svc_fh *,
+__be32         nfsd_readlink(struct svc_rqst *, struct svc_fh *,
                                char *, int *);
-int            nfsd_symlink(struct svc_rqst *, struct svc_fh *,
+__be32         nfsd_symlink(struct svc_rqst *, struct svc_fh *,
                                char *name, int len, char *path, int plen,
                                struct svc_fh *res, struct iattr *);
-int            nfsd_link(struct svc_rqst *, struct svc_fh *,
+__be32         nfsd_link(struct svc_rqst *, struct svc_fh *,
                                char *, int, struct svc_fh *);
-int            nfsd_rename(struct svc_rqst *,
+__be32         nfsd_rename(struct svc_rqst *,
                                struct svc_fh *, char *, int,
                                struct svc_fh *, char *, int);
-int            nfsd_remove(struct svc_rqst *,
+__be32         nfsd_remove(struct svc_rqst *,
                                struct svc_fh *, char *, int);
-int            nfsd_unlink(struct svc_rqst *, struct svc_fh *, int type,
+__be32         nfsd_unlink(struct svc_rqst *, struct svc_fh *, int type,
                                char *name, int len);
 int            nfsd_truncate(struct svc_rqst *, struct svc_fh *,
                                unsigned long size);
-int            nfsd_readdir(struct svc_rqst *, struct svc_fh *,
+__be32         nfsd_readdir(struct svc_rqst *, struct svc_fh *,
                             loff_t *, struct readdir_cd *, encode_dent_fn);
-int            nfsd_statfs(struct svc_rqst *, struct svc_fh *,
+__be32         nfsd_statfs(struct svc_rqst *, struct svc_fh *,
                                struct kstatfs *);
 
 int            nfsd_notify_change(struct inode *, struct iattr *);
-int            nfsd_permission(struct svc_export *, struct dentry *, int);
+__be32         nfsd_permission(struct svc_export *, struct dentry *, int);
 int            nfsd_sync_dir(struct dentry *dp);
 
 #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
@@ -238,6 +238,7 @@ void                nfsd_lockd_shutdown(void);
 #define        nfserr_badname          __constant_htonl(NFSERR_BADNAME)
 #define        nfserr_cb_path_down     __constant_htonl(NFSERR_CB_PATH_DOWN)
 #define        nfserr_locked           __constant_htonl(NFSERR_LOCKED)
+#define        nfserr_replay_me        __constant_htonl(NFSERR_REPLAY_ME)
 
 /* error codes for internal use */
 /* if a request fails due to kmalloc failure, it gets dropped.
index 069257ea99a0fe4c92de7ccc4a993d88b35774ea..f3b51d62ec7dc4eb9f01deb4f4de4eedc42281b2 100644 (file)
@@ -157,7 +157,7 @@ typedef struct svc_fh {
        __u64                   fh_post_size;   /* i_size */
        unsigned long           fh_post_blocks; /* i_blocks */
        unsigned long           fh_post_blksize;/* i_blksize */
-       __u32                   fh_post_rdev[2];/* i_rdev */
+       __be32                  fh_post_rdev[2];/* i_rdev */
        struct timespec         fh_post_atime;  /* i_atime */
        struct timespec         fh_post_mtime;  /* i_mtime */
        struct timespec         fh_post_ctime;  /* i_ctime */
@@ -209,9 +209,9 @@ extern char * SVCFH_fmt(struct svc_fh *fhp);
 /*
  * Function prototypes
  */
-u32    fh_verify(struct svc_rqst *, struct svc_fh *, int, int);
-int    fh_compose(struct svc_fh *, struct svc_export *, struct dentry *, struct svc_fh *);
-int    fh_update(struct svc_fh *);
+__be32 fh_verify(struct svc_rqst *, struct svc_fh *, int, int);
+__be32 fh_compose(struct svc_fh *, struct svc_export *, struct dentry *, struct svc_fh *);
+__be32 fh_update(struct svc_fh *);
 void   fh_put(struct svc_fh *);
 
 static __inline__ struct svc_fh *
index 8bf23cf8b6035d0a849bd02c1016f23d53522552..c3673f487e841984169419c33d5663cf0db868b3 100644 (file)
@@ -125,7 +125,7 @@ struct nfs4_client {
        char                    cl_recdir[HEXDIR_LEN]; /* recovery dir */
        nfs4_verifier           cl_verifier;    /* generated by client */
        time_t                  cl_time;        /* time of last lease renewal */
-       u32                     cl_addr;        /* client ipaddress */
+       __be32                  cl_addr;        /* client ipaddress */
        struct svc_cred         cl_cred;        /* setclientid principal */
        clientid_t              cl_clientid;    /* generated by server */
        nfs4_verifier           cl_confirm;     /* generated by server */
@@ -164,7 +164,7 @@ update_stateid(stateid_t *stateid)
  * is cached. 
  */
 struct nfs4_replay {
-       u32                     rp_status;
+       __be32                  rp_status;
        unsigned int            rp_buflen;
        char                    *rp_buf;
        unsigned                intrp_allocated;
@@ -273,19 +273,19 @@ struct nfs4_stateid {
        ((err) != nfserr_stale_stateid) &&      \
        ((err) != nfserr_bad_stateid))
 
-extern int nfsd4_renew(clientid_t *clid);
-extern int nfs4_preprocess_stateid_op(struct svc_fh *current_fh, 
+extern __be32 nfsd4_renew(clientid_t *clid);
+extern __be32 nfs4_preprocess_stateid_op(struct svc_fh *current_fh,
                stateid_t *stateid, int flags, struct file **filp);
 extern void nfs4_lock_state(void);
 extern void nfs4_unlock_state(void);
 extern int nfs4_in_grace(void);
-extern int nfs4_check_open_reclaim(clientid_t *clid);
+extern __be32 nfs4_check_open_reclaim(clientid_t *clid);
 extern void put_nfs4_client(struct nfs4_client *clp);
 extern void nfs4_free_stateowner(struct kref *kref);
 extern void nfsd4_probe_callback(struct nfs4_client *clp);
 extern void nfsd4_cb_recall(struct nfs4_delegation *dp);
 extern void nfs4_put_delegation(struct nfs4_delegation *dp);
-extern int nfs4_make_rec_clidname(char *clidname, struct xdr_netobj *clname);
+extern __be32 nfs4_make_rec_clidname(char *clidname, struct xdr_netobj *clname);
 extern void nfsd4_init_recdir(char *recdir_name);
 extern int nfsd4_recdir_load(void);
 extern void nfsd4_shutdown_recdir(void);
index 0e53de87d886216f4f9478ce8bfde9c581b9c881..877192d3ae79605ed941b2737c0f983f27c7fffc 100644 (file)
@@ -81,7 +81,7 @@ struct nfsd_readdirargs {
        struct svc_fh           fh;
        __u32                   cookie;
        __u32                   count;
-       u32 *                   buffer;
+       __be32 *                buffer;
 };
 
 struct nfsd_attrstat {
@@ -108,9 +108,9 @@ struct nfsd_readdirres {
        int                     count;
 
        struct readdir_cd       common;
-       u32 *                   buffer;
+       __be32 *                buffer;
        int                     buflen;
-       u32 *                   offset;
+       __be32 *                offset;
 };
 
 struct nfsd_statfsres {
@@ -135,43 +135,43 @@ union nfsd_xdrstore {
 #define NFS2_SVC_XDRSIZE       sizeof(union nfsd_xdrstore)
 
 
-int nfssvc_decode_void(struct svc_rqst *, u32 *, void *);
-int nfssvc_decode_fhandle(struct svc_rqst *, u32 *, struct nfsd_fhandle *);
-int nfssvc_decode_sattrargs(struct svc_rqst *, u32 *,
+int nfssvc_decode_void(struct svc_rqst *, __be32 *, void *);
+int nfssvc_decode_fhandle(struct svc_rqst *, __be32 *, struct nfsd_fhandle *);
+int nfssvc_decode_sattrargs(struct svc_rqst *, __be32 *,
                                struct nfsd_sattrargs *);
-int nfssvc_decode_diropargs(struct svc_rqst *, u32 *,
+int nfssvc_decode_diropargs(struct svc_rqst *, __be32 *,
                                struct nfsd_diropargs *);
-int nfssvc_decode_readargs(struct svc_rqst *, u32 *,
+int nfssvc_decode_readargs(struct svc_rqst *, __be32 *,
                                struct nfsd_readargs *);
-int nfssvc_decode_writeargs(struct svc_rqst *, u32 *,
+int nfssvc_decode_writeargs(struct svc_rqst *, __be32 *,
                                struct nfsd_writeargs *);
-int nfssvc_decode_createargs(struct svc_rqst *, u32 *,
+int nfssvc_decode_createargs(struct svc_rqst *, __be32 *,
                                struct nfsd_createargs *);
-int nfssvc_decode_renameargs(struct svc_rqst *, u32 *,
+int nfssvc_decode_renameargs(struct svc_rqst *, __be32 *,
                                struct nfsd_renameargs *);
-int nfssvc_decode_readlinkargs(struct svc_rqst *, u32 *,
+int nfssvc_decode_readlinkargs(struct svc_rqst *, __be32 *,
                                struct nfsd_readlinkargs *);
-int nfssvc_decode_linkargs(struct svc_rqst *, u32 *,
+int nfssvc_decode_linkargs(struct svc_rqst *, __be32 *,
                                struct nfsd_linkargs *);
-int nfssvc_decode_symlinkargs(struct svc_rqst *, u32 *,
+int nfssvc_decode_symlinkargs(struct svc_rqst *, __be32 *,
                                struct nfsd_symlinkargs *);
-int nfssvc_decode_readdirargs(struct svc_rqst *, u32 *,
+int nfssvc_decode_readdirargs(struct svc_rqst *, __be32 *,
                                struct nfsd_readdirargs *);
-int nfssvc_encode_void(struct svc_rqst *, u32 *, void *);
-int nfssvc_encode_attrstat(struct svc_rqst *, u32 *, struct nfsd_attrstat *);
-int nfssvc_encode_diropres(struct svc_rqst *, u32 *, struct nfsd_diropres *);
-int nfssvc_encode_readlinkres(struct svc_rqst *, u32 *, struct nfsd_readlinkres *);
-int nfssvc_encode_readres(struct svc_rqst *, u32 *, struct nfsd_readres *);
-int nfssvc_encode_statfsres(struct svc_rqst *, u32 *, struct nfsd_statfsres *);
-int nfssvc_encode_readdirres(struct svc_rqst *, u32 *, struct nfsd_readdirres *);
+int nfssvc_encode_void(struct svc_rqst *, __be32 *, void *);
+int nfssvc_encode_attrstat(struct svc_rqst *, __be32 *, struct nfsd_attrstat *);
+int nfssvc_encode_diropres(struct svc_rqst *, __be32 *, struct nfsd_diropres *);
+int nfssvc_encode_readlinkres(struct svc_rqst *, __be32 *, struct nfsd_readlinkres *);
+int nfssvc_encode_readres(struct svc_rqst *, __be32 *, struct nfsd_readres *);
+int nfssvc_encode_statfsres(struct svc_rqst *, __be32 *, struct nfsd_statfsres *);
+int nfssvc_encode_readdirres(struct svc_rqst *, __be32 *, struct nfsd_readdirres *);
 
 int nfssvc_encode_entry(struct readdir_cd *, const char *name,
                                int namlen, loff_t offset, ino_t ino, unsigned int);
 
-int nfssvc_release_fhandle(struct svc_rqst *, u32 *, struct nfsd_fhandle *);
+int nfssvc_release_fhandle(struct svc_rqst *, __be32 *, struct nfsd_fhandle *);
 
 /* Helper functions for NFSv2 ACL code */
-u32 *nfs2svc_encode_fattr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp);
-u32 *nfs2svc_decode_fh(u32 *p, struct svc_fh *fhp);
+__be32 *nfs2svc_encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp);
+__be32 *nfs2svc_decode_fh(__be32 *p, struct svc_fh *fhp);
 
 #endif /* LINUX_NFSD_H */
index 474d882dc2f385839a7b1cf869591a2f807a22f7..79963867b0d774cb2258d5a6ba18ae160aab6d65 100644 (file)
@@ -51,7 +51,7 @@ struct nfsd3_createargs {
        int                     len;
        int                     createmode;
        struct iattr            attrs;
-       __u32 *                 verf;
+       __be32 *                verf;
 };
 
 struct nfsd3_mknodargs {
@@ -98,8 +98,8 @@ struct nfsd3_readdirargs {
        __u64                   cookie;
        __u32                   dircount;
        __u32                   count;
-       __u32 *                 verf;
-       u32 *                   buffer;
+       __be32 *                verf;
+       __be32 *                buffer;
 };
 
 struct nfsd3_commitargs {
@@ -122,79 +122,79 @@ struct nfsd3_setaclargs {
 };
 
 struct nfsd3_attrstat {
-       __u32                   status;
+       __be32                  status;
        struct svc_fh           fh;
        struct kstat            stat;
 };
 
 /* LOOKUP, CREATE, MKDIR, SYMLINK, MKNOD */
 struct nfsd3_diropres  {
-       __u32                   status;
+       __be32                  status;
        struct svc_fh           dirfh;
        struct svc_fh           fh;
 };
 
 struct nfsd3_accessres {
-       __u32                   status;
+       __be32                  status;
        struct svc_fh           fh;
        __u32                   access;
 };
 
 struct nfsd3_readlinkres {
-       __u32                   status;
+       __be32                  status;
        struct svc_fh           fh;
        __u32                   len;
 };
 
 struct nfsd3_readres {
-       __u32                   status;
+       __be32                  status;
        struct svc_fh           fh;
        unsigned long           count;
        int                     eof;
 };
 
 struct nfsd3_writeres {
-       __u32                   status;
+       __be32                  status;
        struct svc_fh           fh;
        unsigned long           count;
        int                     committed;
 };
 
 struct nfsd3_renameres {
-       __u32                   status;
+       __be32                  status;
        struct svc_fh           ffh;
        struct svc_fh           tfh;
 };
 
 struct nfsd3_linkres {
-       __u32                   status;
+       __be32                  status;
        struct svc_fh           tfh;
        struct svc_fh           fh;
 };
 
 struct nfsd3_readdirres {
-       __u32                   status;
+       __be32                  status;
        struct svc_fh           fh;
        int                     count;
-       __u32                   verf[2];
+       __be32                  verf[2];
 
        struct readdir_cd       common;
-       u32 *                   buffer;
+       __be32 *                buffer;
        int                     buflen;
-       u32 *                   offset;
-       u32 *                   offset1;
+       __be32 *                offset;
+       __be32 *                offset1;
        struct svc_rqst *       rqstp;
 
 };
 
 struct nfsd3_fsstatres {
-       __u32                   status;
+       __be32                  status;
        struct kstatfs          stats;
        __u32                   invarsec;
 };
 
 struct nfsd3_fsinfores {
-       __u32                   status;
+       __be32                  status;
        __u32                   f_rtmax;
        __u32                   f_rtpref;
        __u32                   f_rtmult;
@@ -207,7 +207,7 @@ struct nfsd3_fsinfores {
 };
 
 struct nfsd3_pathconfres {
-       __u32                   status;
+       __be32                  status;
        __u32                   p_link_max;
        __u32                   p_name_max;
        __u32                   p_no_trunc;
@@ -217,12 +217,12 @@ struct nfsd3_pathconfres {
 };
 
 struct nfsd3_commitres {
-       __u32                   status;
+       __be32                  status;
        struct svc_fh           fh;
 };
 
 struct nfsd3_getaclres {
-       __u32                   status;
+       __be32                  status;
        struct svc_fh           fh;
        int                     mask;
        struct posix_acl        *acl_access;
@@ -266,70 +266,70 @@ union nfsd3_xdrstore {
 
 #define NFS3_SVC_XDRSIZE               sizeof(union nfsd3_xdrstore)
 
-int nfs3svc_decode_fhandle(struct svc_rqst *, u32 *, struct nfsd_fhandle *);
-int nfs3svc_decode_sattrargs(struct svc_rqst *, u32 *,
+int nfs3svc_decode_fhandle(struct svc_rqst *, __be32 *, struct nfsd_fhandle *);
+int nfs3svc_decode_sattrargs(struct svc_rqst *, __be32 *,
                                struct nfsd3_sattrargs *);
-int nfs3svc_decode_diropargs(struct svc_rqst *, u32 *,
+int nfs3svc_decode_diropargs(struct svc_rqst *, __be32 *,
                                struct nfsd3_diropargs *);
-int nfs3svc_decode_accessargs(struct svc_rqst *, u32 *,
+int nfs3svc_decode_accessargs(struct svc_rqst *, __be32 *,
                                struct nfsd3_accessargs *);
-int nfs3svc_decode_readargs(struct svc_rqst *, u32 *,
+int nfs3svc_decode_readargs(struct svc_rqst *, __be32 *,
                                struct nfsd3_readargs *);
-int nfs3svc_decode_writeargs(struct svc_rqst *, u32 *,
+int nfs3svc_decode_writeargs(struct svc_rqst *, __be32 *,
                                struct nfsd3_writeargs *);
-int nfs3svc_decode_createargs(struct svc_rqst *, u32 *,
+int nfs3svc_decode_createargs(struct svc_rqst *, __be32 *,
                                struct nfsd3_createargs *);
-int nfs3svc_decode_mkdirargs(struct svc_rqst *, u32 *,
+int nfs3svc_decode_mkdirargs(struct svc_rqst *, __be32 *,
                                struct nfsd3_createargs *);
-int nfs3svc_decode_mknodargs(struct svc_rqst *, u32 *,
+int nfs3svc_decode_mknodargs(struct svc_rqst *, __be32 *,
                                struct nfsd3_mknodargs *);
-int nfs3svc_decode_renameargs(struct svc_rqst *, u32 *,
+int nfs3svc_decode_renameargs(struct svc_rqst *, __be32 *,
                                struct nfsd3_renameargs *);
-int nfs3svc_decode_readlinkargs(struct svc_rqst *, u32 *,
+int nfs3svc_decode_readlinkargs(struct svc_rqst *, __be32 *,
                                struct nfsd3_readlinkargs *);
-int nfs3svc_decode_linkargs(struct svc_rqst *, u32 *,
+int nfs3svc_decode_linkargs(struct svc_rqst *, __be32 *,
                                struct nfsd3_linkargs *);
-int nfs3svc_decode_symlinkargs(struct svc_rqst *, u32 *,
+int nfs3svc_decode_symlinkargs(struct svc_rqst *, __be32 *,
                                struct nfsd3_symlinkargs *);
-int nfs3svc_decode_readdirargs(struct svc_rqst *, u32 *,
+int nfs3svc_decode_readdirargs(struct svc_rqst *, __be32 *,
                                struct nfsd3_readdirargs *);
-int nfs3svc_decode_readdirplusargs(struct svc_rqst *, u32 *,
+int nfs3svc_decode_readdirplusargs(struct svc_rqst *, __be32 *,
                                struct nfsd3_readdirargs *);
-int nfs3svc_decode_commitargs(struct svc_rqst *, u32 *,
+int nfs3svc_decode_commitargs(struct svc_rqst *, __be32 *,
                                struct nfsd3_commitargs *);
-int nfs3svc_encode_voidres(struct svc_rqst *, u32 *, void *);
-int nfs3svc_encode_attrstat(struct svc_rqst *, u32 *,
+int nfs3svc_encode_voidres(struct svc_rqst *, __be32 *, void *);
+int nfs3svc_encode_attrstat(struct svc_rqst *, __be32 *,
                                struct nfsd3_attrstat *);
-int nfs3svc_encode_wccstat(struct svc_rqst *, u32 *,
+int nfs3svc_encode_wccstat(struct svc_rqst *, __be32 *,
                                struct nfsd3_attrstat *);
-int nfs3svc_encode_diropres(struct svc_rqst *, u32 *,
+int nfs3svc_encode_diropres(struct svc_rqst *, __be32 *,
                                struct nfsd3_diropres *);
-int nfs3svc_encode_accessres(struct svc_rqst *, u32 *,
+int nfs3svc_encode_accessres(struct svc_rqst *, __be32 *,
                                struct nfsd3_accessres *);
-int nfs3svc_encode_readlinkres(struct svc_rqst *, u32 *,
+int nfs3svc_encode_readlinkres(struct svc_rqst *, __be32 *,
                                struct nfsd3_readlinkres *);
-int nfs3svc_encode_readres(struct svc_rqst *, u32 *, struct nfsd3_readres *);
-int nfs3svc_encode_writeres(struct svc_rqst *, u32 *, struct nfsd3_writeres *);
-int nfs3svc_encode_createres(struct svc_rqst *, u32 *,
+int nfs3svc_encode_readres(struct svc_rqst *, __be32 *, struct nfsd3_readres *);
+int nfs3svc_encode_writeres(struct svc_rqst *, __be32 *, struct nfsd3_writeres *);
+int nfs3svc_encode_createres(struct svc_rqst *, __be32 *,
                                struct nfsd3_diropres *);
-int nfs3svc_encode_renameres(struct svc_rqst *, u32 *,
+int nfs3svc_encode_renameres(struct svc_rqst *, __be32 *,
                                struct nfsd3_renameres *);
-int nfs3svc_encode_linkres(struct svc_rqst *, u32 *,
+int nfs3svc_encode_linkres(struct svc_rqst *, __be32 *,
                                struct nfsd3_linkres *);
-int nfs3svc_encode_readdirres(struct svc_rqst *, u32 *,
+int nfs3svc_encode_readdirres(struct svc_rqst *, __be32 *,
                                struct nfsd3_readdirres *);
-int nfs3svc_encode_fsstatres(struct svc_rqst *, u32 *,
+int nfs3svc_encode_fsstatres(struct svc_rqst *, __be32 *,
                                struct nfsd3_fsstatres *);
-int nfs3svc_encode_fsinfores(struct svc_rqst *, u32 *,
+int nfs3svc_encode_fsinfores(struct svc_rqst *, __be32 *,
                                struct nfsd3_fsinfores *);
-int nfs3svc_encode_pathconfres(struct svc_rqst *, u32 *,
+int nfs3svc_encode_pathconfres(struct svc_rqst *, __be32 *,
                                struct nfsd3_pathconfres *);
-int nfs3svc_encode_commitres(struct svc_rqst *, u32 *,
+int nfs3svc_encode_commitres(struct svc_rqst *, __be32 *,
                                struct nfsd3_commitres *);
 
-int nfs3svc_release_fhandle(struct svc_rqst *, u32 *,
+int nfs3svc_release_fhandle(struct svc_rqst *, __be32 *,
                                struct nfsd3_attrstat *);
-int nfs3svc_release_fhandle2(struct svc_rqst *, u32 *,
+int nfs3svc_release_fhandle2(struct svc_rqst *, __be32 *,
                                struct nfsd3_fhandle_pair *);
 int nfs3svc_encode_entry(struct readdir_cd *, const char *name,
                                int namlen, loff_t offset, ino_t ino,
@@ -338,9 +338,9 @@ int nfs3svc_encode_entry_plus(struct readdir_cd *, const char *name,
                                int namlen, loff_t offset, ino_t ino,
                                unsigned int);
 /* Helper functions for NFSv3 ACL code */
-u32 *nfs3svc_encode_post_op_attr(struct svc_rqst *rqstp, u32 *p,
+__be32 *nfs3svc_encode_post_op_attr(struct svc_rqst *rqstp, __be32 *p,
                                struct svc_fh *fhp);
-u32 *nfs3svc_decode_fh(u32 *p, struct svc_fh *fhp);
+__be32 *nfs3svc_decode_fh(__be32 *p, struct svc_fh *fhp);
 
 
 #endif /* _LINUX_NFSD_XDR3_H */
index 66e642762a0720e609ef0dcc09a648c511de7c43..45ca01b5f844ffaa68b8902be92bd47cf4f65ae1 100644 (file)
@@ -258,9 +258,9 @@ struct nfsd4_readdir {
        struct svc_fh * rd_fhp;             /* response */
 
        struct readdir_cd       common;
-       u32 *                   buffer;
+       __be32 *                buffer;
        int                     buflen;
-       u32 *                   offset;
+       __be32 *                offset;
 };
 
 struct nfsd4_release_lockowner {
@@ -334,7 +334,7 @@ struct nfsd4_write {
 
 struct nfsd4_op {
        int                                     opnum;
-       int                                     status;
+       __be32                                  status;
        union {
                struct nfsd4_access             access;
                struct nfsd4_close              close;
@@ -371,12 +371,12 @@ struct nfsd4_op {
 
 struct nfsd4_compoundargs {
        /* scratch variables for XDR decode */
-       u32 *                           p;
-       u32 *                           end;
+       __be32 *                        p;
+       __be32 *                        end;
        struct page **                  pagelist;
        int                             pagelen;
-       u32                             tmp[8];
-       u32 *                           tmpp;
+       __be32                          tmp[8];
+       __be32 *                        tmpp;
        struct tmpbuf {
                struct tmpbuf *next;
                void (*release)(const void *);
@@ -395,15 +395,15 @@ struct nfsd4_compoundargs {
 
 struct nfsd4_compoundres {
        /* scratch variables for XDR encode */
-       u32 *                           p;
-       u32 *                           end;
+       __be32 *                        p;
+       __be32 *                        end;
        struct xdr_buf *                xbuf;
        struct svc_rqst *               rqstp;
 
        u32                             taglen;
        char *                          tag;
        u32                             opcnt;
-       u32 *                           tagp; /* where to encode tag and  opcount */
+       __be32 *                        tagp; /* where to encode tag and  opcount */
 };
 
 #define NFS4_SVC_XDRSIZE               sizeof(struct nfsd4_compoundargs)
@@ -419,45 +419,45 @@ set_change_info(struct nfsd4_change_info *cinfo, struct svc_fh *fhp)
        cinfo->after_ctime_nsec = fhp->fh_post_ctime.tv_nsec;
 }
 
-int nfs4svc_encode_voidres(struct svc_rqst *, u32 *, void *);
-int nfs4svc_decode_compoundargs(struct svc_rqst *, u32 *, 
+int nfs4svc_encode_voidres(struct svc_rqst *, __be32 *, void *);
+int nfs4svc_decode_compoundargs(struct svc_rqst *, __be32 *,
                struct nfsd4_compoundargs *);
-int nfs4svc_encode_compoundres(struct svc_rqst *, u32 *, 
+int nfs4svc_encode_compoundres(struct svc_rqst *, __be32 *,
                struct nfsd4_compoundres *);
 void nfsd4_encode_operation(struct nfsd4_compoundres *, struct nfsd4_op *);
 void nfsd4_encode_replay(struct nfsd4_compoundres *resp, struct nfsd4_op *op);
-int nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
-                      struct dentry *dentry, u32 *buffer, int *countp, 
+__be32 nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
+                      struct dentry *dentry, __be32 *buffer, int *countp,
                       u32 *bmval, struct svc_rqst *);
-extern int nfsd4_setclientid(struct svc_rqst *rqstp, 
+extern __be32 nfsd4_setclientid(struct svc_rqst *rqstp,
                struct nfsd4_setclientid *setclid);
-extern int nfsd4_setclientid_confirm(struct svc_rqst *rqstp, 
+extern __be32 nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
                struct nfsd4_setclientid_confirm *setclientid_confirm);
-extern int nfsd4_process_open1(struct nfsd4_open *open);
-extern int nfsd4_process_open2(struct svc_rqst *rqstp, 
+extern __be32 nfsd4_process_open1(struct nfsd4_open *open);
+extern __be32 nfsd4_process_open2(struct svc_rqst *rqstp,
                struct svc_fh *current_fh, struct nfsd4_open *open);
-extern int nfsd4_open_confirm(struct svc_rqst *rqstp, 
+extern __be32 nfsd4_open_confirm(struct svc_rqst *rqstp,
                struct svc_fh *current_fh, struct nfsd4_open_confirm *oc,
                struct nfs4_stateowner **);
-extern  int nfsd4_close(struct svc_rqst *rqstp, struct svc_fh *current_fh, 
+extern __be32 nfsd4_close(struct svc_rqst *rqstp, struct svc_fh *current_fh,
                struct nfsd4_close *close,
                struct nfs4_stateowner **replay_owner);
-extern int nfsd4_open_downgrade(struct svc_rqst *rqstp, 
+extern __be32 nfsd4_open_downgrade(struct svc_rqst *rqstp,
                struct svc_fh *current_fh, struct nfsd4_open_downgrade *od,
                struct nfs4_stateowner **replay_owner);
-extern int nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, 
+extern __be32 nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh,
                struct nfsd4_lock *lock,
                struct nfs4_stateowner **replay_owner);
-extern int nfsd4_lockt(struct svc_rqst *rqstp, struct svc_fh *current_fh, 
+extern __be32 nfsd4_lockt(struct svc_rqst *rqstp, struct svc_fh *current_fh,
                struct nfsd4_lockt *lockt);
-extern int nfsd4_locku(struct svc_rqst *rqstp, struct svc_fh *current_fh, 
+extern __be32 nfsd4_locku(struct svc_rqst *rqstp, struct svc_fh *current_fh,
                struct nfsd4_locku *locku,
                struct nfs4_stateowner **replay_owner);
-extern int
+extern __be32
 nfsd4_release_lockowner(struct svc_rqst *rqstp,
                struct nfsd4_release_lockowner *rlockowner);
 extern void nfsd4_release_compoundargs(struct nfsd4_compoundargs *);
-extern int nfsd4_delegreturn(struct svc_rqst *rqstp,
+extern __be32 nfsd4_delegreturn(struct svc_rqst *rqstp,
                struct svc_fh *current_fh, struct nfsd4_delegreturn *dr);
 #endif
 
index 5dce5c21822ca12bc6b3c6423352b50fcbe75b44..b1063e9cdb1b77c35f3b8d2ec72656138ff93b5a 100644 (file)
@@ -8,8 +8,8 @@
  * See detailed comments in the file linux/bitmap.h describing the
  * data type on which these nodemasks are based.
  *
- * For details of nodemask_scnprintf() and nodemask_parse(),
- * see bitmap_scnprintf() and bitmap_parse() in lib/bitmap.c.
+ * For details of nodemask_scnprintf() and nodemask_parse_user(),
+ * see bitmap_scnprintf() and bitmap_parse_user() in lib/bitmap.c.
  * For details of nodelist_scnprintf() and nodelist_parse(), see
  * bitmap_scnlistprintf() and bitmap_parselist(), also in bitmap.c.
  * For details of node_remap(), see bitmap_bitremap in lib/bitmap.c.
@@ -51,7 +51,7 @@
  * unsigned long *nodes_addr(mask)     Array of unsigned long's in mask
  *
  * int nodemask_scnprintf(buf, len, mask) Format nodemask for printing
- * int nodemask_parse(ubuf, ulen, mask)        Parse ascii string as nodemask
+ * int nodemask_parse_user(ubuf, ulen, mask)   Parse ascii string as nodemask
  * int nodelist_scnprintf(buf, len, mask) Format nodemask as list for printing
  * int nodelist_parse(buf, map)                Parse ascii string as nodelist
  * int node_remap(oldbit, old, new)    newbit = map(old, new)(oldbit)
@@ -288,12 +288,12 @@ static inline int __nodemask_scnprintf(char *buf, int len,
        return bitmap_scnprintf(buf, len, srcp->bits, nbits);
 }
 
-#define nodemask_parse(ubuf, ulen, dst) \
-                       __nodemask_parse((ubuf), (ulen), &(dst), MAX_NUMNODES)
-static inline int __nodemask_parse(const char __user *buf, int len,
+#define nodemask_parse_user(ubuf, ulen, dst) \
+               __nodemask_parse_user((ubuf), (ulen), &(dst), MAX_NUMNODES)
+static inline int __nodemask_parse_user(const char __user *buf, int len,
                                        nodemask_t *dstp, int nbits)
 {
-       return bitmap_parse(buf, len, dstp->bits, nbits);
+       return bitmap_parse_user(buf, len, dstp->bits, nbits);
 }
 
 #define nodelist_scnprintf(buf, len, src) \
diff --git a/include/linux/oom.h b/include/linux/oom.h
new file mode 100644 (file)
index 0000000..ad76463
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef __INCLUDE_LINUX_OOM_H
+#define __INCLUDE_LINUX_OOM_H
+
+/* /proc/<pid>/oom_adj set to -17 protects from the oom-killer */
+#define OOM_DISABLE (-17)
+/* inclusive */
+#define OOM_ADJUST_MIN (-16)
+#define OOM_ADJUST_MAX 15
+
+#endif
index 5bf321e82c998ed78c37ed87179cbb0e65597b19..80682aaa8f183c741aa0d079eb44ec3de3aa84d7 100644 (file)
@@ -229,7 +229,7 @@ struct pardevice {
        int (*preempt)(void *);
        void (*wakeup)(void *);
        void *private;
-       void (*irq_func)(int, void *, struct pt_regs *);
+       void (*irq_func)(int, void *);
        unsigned int flags;
        struct pardevice *next;
        struct pardevice *prev;
@@ -375,7 +375,7 @@ extern void parport_put_port (struct parport *);
 struct pardevice *parport_register_device(struct parport *port, 
                          const char *name,
                          int (*pf)(void *), void (*kf)(void *),
-                         void (*irq_func)(int, void *, struct pt_regs *), 
+                         void (*irq_func)(int, void *), 
                          int flags, void *handle);
 
 /* parport_unregister unlinks a device from the chain. */
@@ -457,7 +457,7 @@ static __inline__ int parport_yield_blocking(struct pardevice *dev)
 #define PARPORT_FLAG_EXCL              (1<<1)  /* EXCL driver registered. */
 
 /* IEEE1284 functions */
-extern void parport_ieee1284_interrupt (int, void *, struct pt_regs *);
+extern void parport_ieee1284_interrupt (int, void *);
 extern int parport_negotiate (struct parport *, int mode);
 extern ssize_t parport_write (struct parport *, const void *buf, size_t len);
 extern ssize_t parport_read (struct parport *, void *buf, size_t len);
@@ -502,8 +502,7 @@ extern void parport_daisy_fini (struct parport *port);
 extern struct pardevice *parport_open (int devnum, const char *name,
                                       int (*pf) (void *),
                                       void (*kf) (void *),
-                                      void (*irqf) (int, void *,
-                                                    struct pt_regs *),
+                                      void (*irqf) (int, void *),
                                       int flags, void *handle);
 extern void parport_close (struct pardevice *dev);
 extern ssize_t parport_device_id (int devnum, char *buffer, size_t len);
@@ -512,13 +511,12 @@ extern void parport_daisy_deselect_all (struct parport *port);
 extern int parport_daisy_select (struct parport *port, int daisy, int mode);
 
 /* Lowlevel drivers _can_ call this support function to handle irqs.  */
-static __inline__ void parport_generic_irq(int irq, struct parport *port,
-                                          struct pt_regs *regs)
+static __inline__ void parport_generic_irq(int irq, struct parport *port)
 {
-       parport_ieee1284_interrupt (irq, port, regs);
+       parport_ieee1284_interrupt (irq, port);
        read_lock(&port->cad_lock);
        if (port->cad && port->cad->irq_func)
-               port->cad->irq_func(irq, port->cad->private, regs);
+               port->cad->irq_func(irq, port->cad->private);
        read_unlock(&port->cad_lock);
 }
 
index 5c604f5fad67d94c31ba6feb193eb49c0f42d0c8..09be0f81b27ba37d4125f4dfa7fa2de601858b37 100644 (file)
@@ -443,6 +443,7 @@ extern void pci_remove_bus(struct pci_bus *b);
 extern void pci_remove_bus_device(struct pci_dev *dev);
 extern void pci_stop_bus_device(struct pci_dev *dev);
 void pci_setup_cardbus(struct pci_bus *bus);
+extern void pci_sort_breadthfirst(void);
 
 /* Generic PCI functions exported to card drivers */
 
@@ -452,13 +453,18 @@ struct pci_dev *pci_find_slot (unsigned int bus, unsigned int devfn);
 int pci_find_capability (struct pci_dev *dev, int cap);
 int pci_find_next_capability (struct pci_dev *dev, u8 pos, int cap);
 int pci_find_ext_capability (struct pci_dev *dev, int cap);
-struct pci_bus * pci_find_next_bus(const struct pci_bus *from);
+struct pci_bus *pci_find_next_bus(const struct pci_bus *from);
+
+struct pci_dev *pci_get_device(unsigned int vendor, unsigned int device,
+                               struct pci_dev *from);
+struct pci_dev *pci_get_device_reverse(unsigned int vendor, unsigned int device,
+                               struct pci_dev *from);
 
-struct pci_dev *pci_get_device (unsigned int vendor, unsigned int device, struct pci_dev *from);
 struct pci_dev *pci_get_subsys (unsigned int vendor, unsigned int device,
                                unsigned int ss_vendor, unsigned int ss_device,
                                struct pci_dev *from);
 struct pci_dev *pci_get_slot (struct pci_bus *bus, unsigned int devfn);
+struct pci_dev *pci_get_bus_and_slot (unsigned int bus, unsigned int devfn);
 struct pci_dev *pci_get_class (unsigned int class, struct pci_dev *from);
 int pci_dev_present(const struct pci_device_id *ids);
 
@@ -658,7 +664,12 @@ static inline struct pci_dev *pci_find_device(unsigned int vendor, unsigned int
 static inline struct pci_dev *pci_find_slot(unsigned int bus, unsigned int devfn)
 { return NULL; }
 
-static inline struct pci_dev *pci_get_device (unsigned int vendor, unsigned int device, struct pci_dev *from)
+static inline struct pci_dev *pci_get_device(unsigned int vendor,
+                               unsigned int device, struct pci_dev *from)
+{ return NULL; }
+
+static inline struct pci_dev *pci_get_device_reverse(unsigned int vendor,
+                               unsigned int device, struct pci_dev *from)
 { return NULL; }
 
 static inline struct pci_dev *pci_get_subsys (unsigned int vendor, unsigned int device,
diff --git a/include/linux/pci_hotplug.h b/include/linux/pci_hotplug.h
new file mode 100644 (file)
index 0000000..a675a05
--- /dev/null
@@ -0,0 +1,236 @@
+/*
+ * PCI HotPlug Core Functions
+ *
+ * Copyright (C) 1995,2001 Compaq Computer Corporation
+ * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
+ * Copyright (C) 2001 IBM Corp.
+ *
+ * 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; 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, GOOD TITLE or
+ * NON INFRINGEMENT.  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.
+ *
+ * Send feedback to <kristen.c.accardi@intel.com>
+ *
+ */
+#ifndef _PCI_HOTPLUG_H
+#define _PCI_HOTPLUG_H
+
+
+/* These values come from the PCI Hotplug Spec */
+enum pci_bus_speed {
+       PCI_SPEED_33MHz                 = 0x00,
+       PCI_SPEED_66MHz                 = 0x01,
+       PCI_SPEED_66MHz_PCIX            = 0x02,
+       PCI_SPEED_100MHz_PCIX           = 0x03,
+       PCI_SPEED_133MHz_PCIX           = 0x04,
+       PCI_SPEED_66MHz_PCIX_ECC        = 0x05,
+       PCI_SPEED_100MHz_PCIX_ECC       = 0x06,
+       PCI_SPEED_133MHz_PCIX_ECC       = 0x07,
+       PCI_SPEED_66MHz_PCIX_266        = 0x09,
+       PCI_SPEED_100MHz_PCIX_266       = 0x0a,
+       PCI_SPEED_133MHz_PCIX_266       = 0x0b,
+       PCI_SPEED_66MHz_PCIX_533        = 0x11,
+       PCI_SPEED_100MHz_PCIX_533       = 0x12,
+       PCI_SPEED_133MHz_PCIX_533       = 0x13,
+       PCI_SPEED_UNKNOWN               = 0xff,
+};
+
+/* These values come from the PCI Express Spec */
+enum pcie_link_width {
+       PCIE_LNK_WIDTH_RESRV    = 0x00,
+       PCIE_LNK_X1             = 0x01,
+       PCIE_LNK_X2             = 0x02,
+       PCIE_LNK_X4             = 0x04,
+       PCIE_LNK_X8             = 0x08,
+       PCIE_LNK_X12            = 0x0C,
+       PCIE_LNK_X16            = 0x10,
+       PCIE_LNK_X32            = 0x20,
+       PCIE_LNK_WIDTH_UNKNOWN  = 0xFF,
+};
+
+enum pcie_link_speed {
+       PCIE_2PT5GB             = 0x14,
+       PCIE_LNK_SPEED_UNKNOWN  = 0xFF,
+};
+
+struct hotplug_slot;
+struct hotplug_slot_attribute {
+       struct attribute attr;
+       ssize_t (*show)(struct hotplug_slot *, char *);
+       ssize_t (*store)(struct hotplug_slot *, const char *, size_t);
+};
+#define to_hotplug_attr(n) container_of(n, struct hotplug_slot_attribute, attr);
+
+/**
+ * struct hotplug_slot_ops -the callbacks that the hotplug pci core can use
+ * @owner: The module owner of this structure
+ * @enable_slot: Called when the user wants to enable a specific pci slot
+ * @disable_slot: Called when the user wants to disable a specific pci slot
+ * @set_attention_status: Called to set the specific slot's attention LED to
+ * the specified value
+ * @hardware_test: Called to run a specified hardware test on the specified
+ * slot.
+ * @get_power_status: Called to get the current power status of a slot.
+ *     If this field is NULL, the value passed in the struct hotplug_slot_info
+ *     will be used when this value is requested by a user.
+ * @get_attention_status: Called to get the current attention status of a slot.
+ *     If this field is NULL, the value passed in the struct hotplug_slot_info
+ *     will be used when this value is requested by a user.
+ * @get_latch_status: Called to get the current latch status of a slot.
+ *     If this field is NULL, the value passed in the struct hotplug_slot_info
+ *     will be used when this value is requested by a user.
+ * @get_adapter_status: Called to get see if an adapter is present in the slot or not.
+ *     If this field is NULL, the value passed in the struct hotplug_slot_info
+ *     will be used when this value is requested by a user.
+ * @get_address: Called to get pci address of a slot.
+ *     If this field is NULL, the value passed in the struct hotplug_slot_info
+ *     will be used when this value is requested by a user.
+ * @get_max_bus_speed: Called to get the max bus speed for a slot.
+ *     If this field is NULL, the value passed in the struct hotplug_slot_info
+ *     will be used when this value is requested by a user.
+ * @get_cur_bus_speed: Called to get the current bus speed for a slot.
+ *     If this field is NULL, the value passed in the struct hotplug_slot_info
+ *     will be used when this value is requested by a user.
+ *
+ * The table of function pointers that is passed to the hotplug pci core by a
+ * hotplug pci driver.  These functions are called by the hotplug pci core when
+ * the user wants to do something to a specific slot (query it for information,
+ * set an LED, enable / disable power, etc.)
+ */
+struct hotplug_slot_ops {
+       struct module *owner;
+       int (*enable_slot)              (struct hotplug_slot *slot);
+       int (*disable_slot)             (struct hotplug_slot *slot);
+       int (*set_attention_status)     (struct hotplug_slot *slot, u8 value);
+       int (*hardware_test)            (struct hotplug_slot *slot, u32 value);
+       int (*get_power_status)         (struct hotplug_slot *slot, u8 *value);
+       int (*get_attention_status)     (struct hotplug_slot *slot, u8 *value);
+       int (*get_latch_status)         (struct hotplug_slot *slot, u8 *value);
+       int (*get_adapter_status)       (struct hotplug_slot *slot, u8 *value);
+       int (*get_address)              (struct hotplug_slot *slot, u32 *value);
+       int (*get_max_bus_speed)        (struct hotplug_slot *slot, enum pci_bus_speed *value);
+       int (*get_cur_bus_speed)        (struct hotplug_slot *slot, enum pci_bus_speed *value);
+};
+
+/**
+ * struct hotplug_slot_info - used to notify the hotplug pci core of the state of the slot
+ * @power: if power is enabled or not (1/0)
+ * @attention_status: if the attention light is enabled or not (1/0)
+ * @latch_status: if the latch (if any) is open or closed (1/0)
+ * @adapter_present: if there is a pci board present in the slot or not (1/0)
+ * @address: (domain << 16 | bus << 8 | dev)
+ *
+ * Used to notify the hotplug pci core of the status of a specific slot.
+ */
+struct hotplug_slot_info {
+       u8      power_status;
+       u8      attention_status;
+       u8      latch_status;
+       u8      adapter_status;
+       u32     address;
+       enum pci_bus_speed      max_bus_speed;
+       enum pci_bus_speed      cur_bus_speed;
+};
+
+/**
+ * struct hotplug_slot - used to register a physical slot with the hotplug pci core
+ * @name: the name of the slot being registered.  This string must
+ * be unique amoung slots registered on this system.
+ * @ops: pointer to the &struct hotplug_slot_ops to be used for this slot
+ * @info: pointer to the &struct hotplug_slot_info for the initial values for
+ * this slot.
+ * @release: called during pci_hp_deregister to free memory allocated in a
+ * hotplug_slot structure.
+ * @private: used by the hotplug pci controller driver to store whatever it
+ * needs.
+ */
+struct hotplug_slot {
+       char                            *name;
+       struct hotplug_slot_ops         *ops;
+       struct hotplug_slot_info        *info;
+       void (*release) (struct hotplug_slot *slot);
+       void                            *private;
+
+       /* Variables below this are for use only by the hotplug pci core. */
+       struct list_head                slot_list;
+       struct kobject                  kobj;
+};
+#define to_hotplug_slot(n) container_of(n, struct hotplug_slot, kobj)
+
+extern int pci_hp_register             (struct hotplug_slot *slot);
+extern int pci_hp_deregister           (struct hotplug_slot *slot);
+extern int __must_check pci_hp_change_slot_info        (struct hotplug_slot *slot,
+                                                struct hotplug_slot_info *info);
+extern struct subsystem pci_hotplug_slots_subsys;
+
+/* PCI Setting Record (Type 0) */
+struct hpp_type0 {
+       u32 revision;
+       u8  cache_line_size;
+       u8  latency_timer;
+       u8  enable_serr;
+       u8  enable_perr;
+};
+
+/* PCI-X Setting Record (Type 1) */
+struct hpp_type1 {
+       u32 revision;
+       u8  max_mem_read;
+       u8  avg_max_split;
+       u16 tot_max_split;
+};
+
+/* PCI Express Setting Record (Type 2) */
+struct hpp_type2 {
+       u32 revision;
+       u32 unc_err_mask_and;
+       u32 unc_err_mask_or;
+       u32 unc_err_sever_and;
+       u32 unc_err_sever_or;
+       u32 cor_err_mask_and;
+       u32 cor_err_mask_or;
+       u32 adv_err_cap_and;
+       u32 adv_err_cap_or;
+       u16 pci_exp_devctl_and;
+       u16 pci_exp_devctl_or;
+       u16 pci_exp_lnkctl_and;
+       u16 pci_exp_lnkctl_or;
+       u32 sec_unc_err_sever_and;
+       u32 sec_unc_err_sever_or;
+       u32 sec_unc_err_mask_and;
+       u32 sec_unc_err_mask_or;
+};
+
+struct hotplug_params {
+       struct hpp_type0 *t0;           /* Type0: NULL if not available */
+       struct hpp_type1 *t1;           /* Type1: NULL if not available */
+       struct hpp_type2 *t2;           /* Type2: NULL if not available */
+       struct hpp_type0 type0_data;
+       struct hpp_type1 type1_data;
+       struct hpp_type2 type2_data;
+};
+
+#ifdef CONFIG_ACPI
+#include <acpi/acpi.h>
+#include <acpi/acpi_bus.h>
+#include <acpi/actypes.h>
+extern acpi_status acpi_run_oshp(acpi_handle handle);
+extern acpi_status acpi_get_hp_params_from_firmware(struct pci_bus *bus,
+                               struct hotplug_params *hpp);
+int acpi_root_bridge(acpi_handle handle);
+#endif
+#endif
+
index f069df2454699b408fa311d619cd9d3f780663da..f3a168f3c9df826e90e5af03955710e4a386027b 100644 (file)
 #define PCI_DEVICE_ID_RME_DIGI32_PRO   0x9897
 #define PCI_DEVICE_ID_RME_DIGI32_8     0x9898
 
+#define PCI_VENDOR_ID_QUICKNET         0x15E2
+#define PCI_DEVICE_ID_QUICKNET_XJ      0x0500
index 46ec72fa2c8435db3e9d8bd17605916aff3b5e54..600e3d387ffc9b2f5445cc3f2c92e6512524a996 100644 (file)
@@ -19,7 +19,7 @@
  * we force a syntax error here if it isn't.
  */
 #define get_cpu_var(var) (*({                          \
-       extern int simple_indentifier_##var(void);      \
+       extern int simple_identifier_##var(void);       \
        preempt_disable();                              \
        &__get_cpu_var(var); }))
 #define put_cpu_var(var) preempt_enable()
index 80d780e5a8f5ae501ee8e12b2d0977c257df385f..bf4cf2080e5cb1c0ba57abf88b7a85951fd0d7fb 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef _LINUX_PERSONALITY_H
 #define _LINUX_PERSONALITY_H
 
+#ifdef __KERNEL__
+
 /*
  * Handling of different ABIs (personalities).
  */
@@ -12,6 +14,8 @@ extern int            register_exec_domain(struct exec_domain *);
 extern int             unregister_exec_domain(struct exec_domain *);
 extern int             __set_personality(unsigned long);
 
+#endif /* __KERNEL__ */
+
 /*
  * Flags for bug emulation.
  *
@@ -71,6 +75,7 @@ enum {
        PER_MASK =              0x00ff,
 };
 
+#ifdef __KERNEL__
 
 /*
  * Description of an execution domain.
@@ -111,4 +116,6 @@ struct exec_domain {
 #define set_personality(pers) \
        ((current->personality == pers) ? 0 : __set_personality(pers))
 
+#endif /* __KERNEL__ */
+
 #endif /* _LINUX_PERSONALITY_H */
index e633004ae052876eb9c4415a1f2f32d49611c8a4..acce53fd38b6484416ddc855996c0974bada2e81 100644 (file)
@@ -17,7 +17,7 @@ struct notifier_block;
 
 /* init basic kernel profiler */
 void __init profile_init(void);
-void profile_tick(int, struct pt_regs *);
+void profile_tick(int);
 void profile_hit(int, void *);
 #ifdef CONFIG_PROC_FS
 void create_prof_cpu_mask(struct proc_dir_entry *);
index 84d88775185556e4d2a8a6b0560bcfc9c202038a..ebd42a3710b4eefc44bec8a9880bd88af6472bcb 100644 (file)
@@ -146,16 +146,16 @@ enum bitmap_state {
 
 /* the superblock at the front of the bitmap file -- little endian */
 typedef struct bitmap_super_s {
-       __u32 magic;        /*  0  BITMAP_MAGIC */
-       __u32 version;      /*  4  the bitmap major for now, could change... */
-       __u8  uuid[16];     /*  8  128 bit uuid - must match md device uuid */
-       __u64 events;       /* 24  event counter for the bitmap (1)*/
-       __u64 events_cleared;/*32  event counter when last bit cleared (2) */
-       __u64 sync_size;    /* 40  the size of the md device's sync range(3) */
-       __u32 state;        /* 48  bitmap state information */
-       __u32 chunksize;    /* 52  the bitmap chunk size in bytes */
-       __u32 daemon_sleep; /* 56  seconds between disk flushes */
-       __u32 write_behind; /* 60  number of outstanding write-behind writes */
+       __le32 magic;        /*  0  BITMAP_MAGIC */
+       __le32 version;      /*  4  the bitmap major for now, could change... */
+       __u8  uuid[16];      /*  8  128 bit uuid - must match md device uuid */
+       __le64 events;       /* 24  event counter for the bitmap (1)*/
+       __le64 events_cleared;/*32  event counter when last bit cleared (2) */
+       __le64 sync_size;    /* 40  the size of the md device's sync range(3) */
+       __le32 state;        /* 48  bitmap state information */
+       __le32 chunksize;    /* 52  the bitmap chunk size in bytes */
+       __le32 daemon_sleep; /* 56  seconds between disk flushes */
+       __le32 write_behind; /* 60  number of outstanding write-behind writes */
 
        __u8  pad[256 - 64]; /* set to zero */
 } bitmap_super_t;
index b6ebc69bae54d7b22402732355279d474701f699..3f2cd98c508bfdff781b361b1b86886bd65ddda8 100644 (file)
@@ -206,52 +206,52 @@ static inline __u64 md_event(mdp_super_t *sb) {
  */
 struct mdp_superblock_1 {
        /* constant array information - 128 bytes */
-       __u32   magic;          /* MD_SB_MAGIC: 0xa92b4efc - little endian */
-       __u32   major_version;  /* 1 */
-       __u32   feature_map;    /* bit 0 set if 'bitmap_offset' is meaningful */
-       __u32   pad0;           /* always set to 0 when writing */
+       __le32  magic;          /* MD_SB_MAGIC: 0xa92b4efc - little endian */
+       __le32  major_version;  /* 1 */
+       __le32  feature_map;    /* bit 0 set if 'bitmap_offset' is meaningful */
+       __le32  pad0;           /* always set to 0 when writing */
 
        __u8    set_uuid[16];   /* user-space generated. */
        char    set_name[32];   /* set and interpreted by user-space */
 
-       __u64   ctime;          /* lo 40 bits are seconds, top 24 are microseconds or 0*/
-       __u32   level;          /* -4 (multipath), -1 (linear), 0,1,4,5 */
-       __u32   layout;         /* only for raid5 and raid10 currently */
-       __u64   size;           /* used size of component devices, in 512byte sectors */
+       __le64  ctime;          /* lo 40 bits are seconds, top 24 are microseconds or 0*/
+       __le32  level;          /* -4 (multipath), -1 (linear), 0,1,4,5 */
+       __le32  layout;         /* only for raid5 and raid10 currently */
+       __le64  size;           /* used size of component devices, in 512byte sectors */
 
-       __u32   chunksize;      /* in 512byte sectors */
-       __u32   raid_disks;
-       __u32   bitmap_offset;  /* sectors after start of superblock that bitmap starts
+       __le32  chunksize;      /* in 512byte sectors */
+       __le32  raid_disks;
+       __le32  bitmap_offset;  /* sectors after start of superblock that bitmap starts
                                 * NOTE: signed, so bitmap can be before superblock
                                 * only meaningful of feature_map[0] is set.
                                 */
 
        /* These are only valid with feature bit '4' */
-       __u32   new_level;      /* new level we are reshaping to                */
-       __u64   reshape_position;       /* next address in array-space for reshape */
-       __u32   delta_disks;    /* change in number of raid_disks               */
-       __u32   new_layout;     /* new layout                                   */
-       __u32   new_chunk;      /* new chunk size (bytes)                       */
+       __le32  new_level;      /* new level we are reshaping to                */
+       __le64  reshape_position;       /* next address in array-space for reshape */
+       __le32  delta_disks;    /* change in number of raid_disks               */
+       __le32  new_layout;     /* new layout                                   */
+       __le32  new_chunk;      /* new chunk size (bytes)                       */
        __u8    pad1[128-124];  /* set to 0 when written */
 
        /* constant this-device information - 64 bytes */
-       __u64   data_offset;    /* sector start of data, often 0 */
-       __u64   data_size;      /* sectors in this device that can be used for data */
-       __u64   super_offset;   /* sector start of this superblock */
-       __u64   recovery_offset;/* sectors before this offset (from data_offset) have been recovered */
-       __u32   dev_number;     /* permanent identifier of this  device - not role in raid */
-       __u32   cnt_corrected_read; /* number of read errors that were corrected by re-writing */
+       __le64  data_offset;    /* sector start of data, often 0 */
+       __le64  data_size;      /* sectors in this device that can be used for data */
+       __le64  super_offset;   /* sector start of this superblock */
+       __le64  recovery_offset;/* sectors before this offset (from data_offset) have been recovered */
+       __le32  dev_number;     /* permanent identifier of this  device - not role in raid */
+       __le32  cnt_corrected_read; /* number of read errors that were corrected by re-writing */
        __u8    device_uuid[16]; /* user-space setable, ignored by kernel */
        __u8    devflags;       /* per-device flags.  Only one defined...*/
 #define        WriteMostly1    1       /* mask for writemostly flag in above */
        __u8    pad2[64-57];    /* set to 0 when writing */
 
        /* array state information - 64 bytes */
-       __u64   utime;          /* 40 bits second, 24 btes microseconds */
-       __u64   events;         /* incremented when superblock updated */
-       __u64   resync_offset;  /* data before this offset (from data_offset) known to be in sync */
-       __u32   sb_csum;        /* checksum upto devs[max_dev] */
-       __u32   max_dev;        /* size of devs[] array to consider */
+       __le64  utime;          /* 40 bits second, 24 btes microseconds */
+       __le64  events;         /* incremented when superblock updated */
+       __le64  resync_offset;  /* data before this offset (from data_offset) known to be in sync */
+       __le32  sb_csum;        /* checksum upto devs[max_dev] */
+       __le32  max_dev;        /* size of devs[] array to consider */
        __u8    pad3[64-32];    /* set to 0 when writing */
 
        /* device state information. Indexed by dev_number.
@@ -260,7 +260,7 @@ struct mdp_superblock_1 {
         * into the 'roles' value.  If a device is spare or faulty, then it doesn't
         * have a meaningful role.
         */
-       __u16   dev_roles[0];   /* role in array, or 0xffff for a spare, or 0xfffe for faulty */
+       __le16  dev_roles[0];   /* role in array, or 0xffff for a spare, or 0xfffe for faulty */
 };
 
 /* feature_map bits */
index d0dd38b3a2fd8b0c14ea47d540eb4de9361080b5..d22ad392242ac811bf1c432c89b4c18592dbd987 100644 (file)
@@ -77,5 +77,6 @@ DEFINE_RAID_ATTRIBUTE(enum raid_state, state)
 struct raid_template *raid_class_attach(struct raid_function_template *);
 void raid_class_release(struct raid_template *);
 
-void raid_component_add(struct raid_template *, struct device *,
-                       struct device *);
+int __must_check raid_component_add(struct raid_template *, struct device *,
+                                   struct device *);
+
index 5d6456bcdebac8e4099809369407583bf04b8d69..0248b30e306d3a5b747201f008a550c46cc4aa0e 100644 (file)
@@ -69,6 +69,9 @@ extern struct file_operations random_fops, urandom_fops;
 unsigned int get_random_int(void);
 unsigned long randomize_range(unsigned long start, unsigned long end, unsigned long len);
 
+u32 random32(void);
+void srandom32(u32 seed);
+
 #endif /* __KERNEL___ */
 
 #endif /* _LINUX_RANDOM_H */
index b89f09357054ff13414eade0f14dc0748e98f925..09ff4c3e2713e3184eea072787f96c6fba918def 100644 (file)
@@ -208,7 +208,7 @@ int rtc_register(rtc_task_t *task);
 int rtc_unregister(rtc_task_t *task);
 int rtc_control(rtc_task_t *t, unsigned int cmd, unsigned long arg);
 void rtc_get_rtc_time(struct rtc_time *rtc_tm);
-irqreturn_t rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+irqreturn_t rtc_interrupt(int irq, void *dev_id);
 
 #endif /* __KERNEL__ */
 
index 331f4502e92bb6540f407d2c1d735c693a28edd9..6735c1cf334caba982d9a8dee39a9e70c8fe50de 100644 (file)
@@ -1065,9 +1065,10 @@ static inline int pid_alive(struct task_struct *p)
 }
 
 /**
- * is_init - check if a task structure is the first user space
- *          task the kernel created.
- * @p: Task structure to be checked.
+ * is_init - check if a task structure is init
+ * @tsk: Task structure to be checked.
+ *
+ * Check if a task structure is the first user space task the kernel created.
  */
 static inline int is_init(struct task_struct *tsk)
 {
index 9b5fea81f55e4e96dfdca7fb83a3ecd0834c2137..b200b9856f32f2f585f6953994bd4ec54a524e9e 100644 (file)
@@ -882,7 +882,8 @@ struct request_sock;
  *     Check permission when a flow selects a xfrm_policy for processing
  *     XFRMs on a packet.  The hook is called when selecting either a
  *     per-socket policy or a generic xfrm policy.
- *     Return 0 if permission is granted.
+ *     Return 0 if permission is granted, -ESRCH otherwise, or -errno
+ *     on other errors.
  * @xfrm_state_pol_flow_match:
  *     @x contains the state to match.
  *     @xp contains the policy to check for a match.
@@ -891,6 +892,7 @@ struct request_sock;
  * @xfrm_flow_state_match:
  *     @fl contains the flow key to match.
  *     @xfrm points to the xfrm_state to match.
+ *     @xp points to the xfrm_policy to match.
  *     Return 1 if there is a match.
  * @xfrm_decode_session:
  *     @skb points to skb to decode.
@@ -1388,7 +1390,8 @@ struct security_operations {
        int (*xfrm_policy_lookup)(struct xfrm_policy *xp, u32 fl_secid, u8 dir);
        int (*xfrm_state_pol_flow_match)(struct xfrm_state *x,
                        struct xfrm_policy *xp, struct flowi *fl);
-       int (*xfrm_flow_state_match)(struct flowi *fl, struct xfrm_state *xfrm);
+       int (*xfrm_flow_state_match)(struct flowi *fl, struct xfrm_state *xfrm,
+                       struct xfrm_policy *xp);
        int (*xfrm_decode_session)(struct sk_buff *skb, u32 *secid, int ckall);
 #endif /* CONFIG_SECURITY_NETWORK_XFRM */
 
@@ -3120,11 +3123,6 @@ static inline int security_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm
        return security_ops->xfrm_policy_alloc_security(xp, sec_ctx, NULL);
 }
 
-static inline int security_xfrm_sock_policy_alloc(struct xfrm_policy *xp, struct sock *sk)
-{
-       return security_ops->xfrm_policy_alloc_security(xp, NULL, sk);
-}
-
 static inline int security_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new)
 {
        return security_ops->xfrm_policy_clone_security(old, new);
@@ -3175,9 +3173,10 @@ static inline int security_xfrm_state_pol_flow_match(struct xfrm_state *x,
        return security_ops->xfrm_state_pol_flow_match(x, xp, fl);
 }
 
-static inline int security_xfrm_flow_state_match(struct flowi *fl, struct xfrm_state *xfrm)
+static inline int security_xfrm_flow_state_match(struct flowi *fl,
+                       struct xfrm_state *xfrm, struct xfrm_policy *xp)
 {
-       return security_ops->xfrm_flow_state_match(fl, xfrm);
+       return security_ops->xfrm_flow_state_match(fl, xfrm, xp);
 }
 
 static inline int security_xfrm_decode_session(struct sk_buff *skb, u32 *secid)
@@ -3197,11 +3196,6 @@ static inline int security_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm
        return 0;
 }
 
-static inline int security_xfrm_sock_policy_alloc(struct xfrm_policy *xp, struct sock *sk)
-{
-       return 0;
-}
-
 static inline int security_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new)
 {
        return 0;
@@ -3249,7 +3243,7 @@ static inline int security_xfrm_state_pol_flow_match(struct xfrm_state *x,
 }
 
 static inline int security_xfrm_flow_state_match(struct flowi *fl,
-                                struct xfrm_state *xfrm)
+                       struct xfrm_state *xfrm, struct xfrm_policy *xp)
 {
        return 1;
 }
index b661c19f3f728263f799ad8f0ee156b6ff31ae13..463ab953b0925f2607b52e20d70bc06f4fdced38 100644 (file)
@@ -409,13 +409,12 @@ int uart_resume_port(struct uart_driver *reg, struct uart_port *port);
  * The following are helper functions for the low level drivers.
  */
 static inline int
-uart_handle_sysrq_char(struct uart_port *port, unsigned int ch,
-                      struct pt_regs *regs)
+uart_handle_sysrq_char(struct uart_port *port, unsigned int ch)
 {
 #ifdef SUPPORT_SYSRQ
        if (port->sysrq) {
                if (ch && time_before(jiffies, port->sysrq)) {
-                       handle_sysrq(ch, regs, port->info->tty);
+                       handle_sysrq(ch, port->info->tty);
                        port->sysrq = 0;
                        return 1;
                }
@@ -425,7 +424,7 @@ uart_handle_sysrq_char(struct uart_port *port, unsigned int ch,
        return 0;
 }
 #ifndef SUPPORT_SYSRQ
-#define uart_handle_sysrq_char(port,ch,regs) uart_handle_sysrq_char(port, 0, NULL)
+#define uart_handle_sysrq_char(port,ch) uart_handle_sysrq_char(port, 0)
 #endif
 
 /*
index c9069310b6acc531242a64210743b471639fea77..b99c5ca9708d42b7aa03e8c016cb03d1a1c6bbfc 100644 (file)
@@ -41,6 +41,7 @@ struct serio {
        void (*stop)(struct serio *);
 
        struct serio *parent, *child;
+       unsigned int depth;             /* level of nesting in serio hierarchy */
 
        struct serio_driver *drv;       /* accessed from interrupt, must be protected by serio->lock and serio->sem */
        struct mutex drv_mutex;         /* protects serio->drv so attributes can pin driver */
@@ -60,8 +61,7 @@ struct serio_driver {
        unsigned int manual_bind;
 
        void (*write_wakeup)(struct serio *);
-       irqreturn_t (*interrupt)(struct serio *, unsigned char,
-                       unsigned int, struct pt_regs *);
+       irqreturn_t (*interrupt)(struct serio *, unsigned char, unsigned int);
        int  (*connect)(struct serio *, struct serio_driver *drv);
        int  (*reconnect)(struct serio *);
        void (*disconnect)(struct serio *);
@@ -75,7 +75,7 @@ int serio_open(struct serio *serio, struct serio_driver *drv);
 void serio_close(struct serio *serio);
 void serio_rescan(struct serio *serio);
 void serio_reconnect(struct serio *serio);
-irqreturn_t serio_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs);
+irqreturn_t serio_interrupt(struct serio *serio, unsigned char data, unsigned int flags);
 
 void __serio_register_port(struct serio *serio, struct module *owner);
 static inline void serio_register_port(struct serio *serio)
index 367d6c3e8ed4d51e939bbe07e86f9fbc8cca0a1b..13b3af5478646b021696388ae5fc36978922161f 100644 (file)
@@ -43,17 +43,17 @@ static inline struct smb_inode_info *SMB_I(struct inode *inode)
 
 /* macro names are short for word, double-word, long value (?) */
 #define WVAL(buf,pos) \
-       (le16_to_cpu(get_unaligned((u16 *)((u8 *)(buf) + (pos)))))
+       (le16_to_cpu(get_unaligned((__le16 *)((u8 *)(buf) + (pos)))))
 #define DVAL(buf,pos) \
-       (le32_to_cpu(get_unaligned((u32 *)((u8 *)(buf) + (pos)))))
+       (le32_to_cpu(get_unaligned((__le32 *)((u8 *)(buf) + (pos)))))
 #define LVAL(buf,pos) \
-       (le64_to_cpu(get_unaligned((u64 *)((u8 *)(buf) + (pos)))))
+       (le64_to_cpu(get_unaligned((__le64 *)((u8 *)(buf) + (pos)))))
 #define WSET(buf,pos,val) \
-       put_unaligned(cpu_to_le16((u16)(val)), (u16 *)((u8 *)(buf) + (pos)))
+       put_unaligned(cpu_to_le16((u16)(val)), (__le16 *)((u8 *)(buf) + (pos)))
 #define DSET(buf,pos,val) \
-       put_unaligned(cpu_to_le32((u32)(val)), (u32 *)((u8 *)(buf) + (pos)))
+       put_unaligned(cpu_to_le32((u32)(val)), (__le32 *)((u8 *)(buf) + (pos)))
 #define LSET(buf,pos,val) \
-       put_unaligned(cpu_to_le64((u64)(val)), (u64 *)((u8 *)(buf) + (pos)))
+       put_unaligned(cpu_to_le64((u64)(val)), (__le64 *)((u8 *)(buf) + (pos)))
 
 /* where to find the base of the SMB packet proper */
 #define smb_base(buf) ((u8 *)(((u8 *)(buf))+4))
index 1e65f2dd80e5d5aa4bbd8f5a7885862cccfe5c4f..606cb21652322d33ed1d389e44b6c304d4fb6b8f 100644 (file)
@@ -56,7 +56,9 @@ enum rpc_accept_stat {
        RPC_PROG_MISMATCH = 2,
        RPC_PROC_UNAVAIL = 3,
        RPC_GARBAGE_ARGS = 4,
-       RPC_SYSTEM_ERR = 5
+       RPC_SYSTEM_ERR = 5,
+       /* internal use only */
+       RPC_DROP_REPLY = 60000,
 };
 
 enum rpc_reject_stat {
index d6288e89fd9d64308113cc0035afd29ea1f71528..965d6c20086ee2980ddee1f30e7d842df019a1df 100644 (file)
@@ -57,7 +57,8 @@ struct svc_serv {
        struct svc_stat *       sv_stats;       /* RPC statistics */
        spinlock_t              sv_lock;
        unsigned int            sv_nrthreads;   /* # of server threads */
-       unsigned int            sv_bufsz;       /* datagram buffer size */
+       unsigned int            sv_max_payload; /* datagram payload size */
+       unsigned int            sv_max_mesg;    /* max_payload + 1 page for overheads */
        unsigned int            sv_xdrsize;     /* XDR buffer size */
 
        struct list_head        sv_permsocks;   /* all permanent sockets */
@@ -334,7 +335,7 @@ struct svc_version {
 /*
  * RPC procedure info
  */
-typedef int    (*svc_procfunc)(struct svc_rqst *, void *argp, void *resp);
+typedef __be32 (*svc_procfunc)(struct svc_rqst *, void *argp, void *resp);
 struct svc_procedure {
        svc_procfunc            pc_func;        /* process the request */
        kxdrproc_t              pc_decode;      /* XDR decode args */
index 953723b09bc6d73cd5ad97bd0143bdf1fbd162f9..ac69e55116060be1d29fb783a812d861011ac548 100644 (file)
@@ -74,6 +74,7 @@ struct xdr_buf {
 #define        rpc_proc_unavail        __constant_htonl(RPC_PROC_UNAVAIL)
 #define        rpc_garbage_args        __constant_htonl(RPC_GARBAGE_ARGS)
 #define        rpc_system_err          __constant_htonl(RPC_SYSTEM_ERR)
+#define        rpc_drop_reply          __constant_htonl(RPC_DROP_REPLY)
 
 #define        rpc_auth_ok             __constant_htonl(RPC_AUTH_OK)
 #define        rpc_autherr_badcred     __constant_htonl(RPC_AUTH_BADCRED)
index 3efcfc7e9c6c705a7e9c42f93c1ed0369fddb3cf..1912c6cbef553cd1d05795c223df8f8e4425af16 100644 (file)
@@ -431,6 +431,10 @@ asmlinkage long sys_epoll_ctl(int epfd, int op, int fd,
                                struct epoll_event __user *event);
 asmlinkage long sys_epoll_wait(int epfd, struct epoll_event __user *events,
                                int maxevents, int timeout);
+asmlinkage long sys_epoll_pwait(int epfd, struct epoll_event __user *events,
+                               int maxevents, int timeout,
+                               const sigset_t __user *sigmask,
+                               size_t sigsetsize);
 asmlinkage long sys_gethostname(char __user *name, int len);
 asmlinkage long sys_sethostname(char __user *name, int len);
 asmlinkage long sys_setdomainname(char __user *name, int len);
@@ -593,7 +597,7 @@ asmlinkage long sys_tee(int fdin, int fdout, size_t len, unsigned int flags);
 asmlinkage long sys_sync_file_range(int fd, loff_t offset, loff_t nbytes,
                                        unsigned int flags);
 asmlinkage long sys_get_robust_list(int pid,
-                                   struct robust_list_head __user **head_ptr,
+                                   struct robust_list_head __user * __user *head_ptr,
                                    size_t __user *len_ptr);
 asmlinkage long sys_set_robust_list(struct robust_list_head __user *head,
                                    size_t len);
index e657e523b9bf62b7a6f0d51850e3b9d3292c64fc..9df8833670cbc9b4f01b3b622bc1074f40020d8e 100644 (file)
@@ -29,7 +29,7 @@ struct tty_struct;
 #define SYSRQ_ENABLE_RTNICE    0x0100
 
 struct sysrq_key_op {
-       void (*handler)(int, struct pt_regs *, struct tty_struct *);
+       void (*handler)(int, struct tty_struct *);
        char *help_msg;
        char *action_msg;
        int enable_mask;
@@ -42,8 +42,8 @@ struct sysrq_key_op {
  * are available -- else NULL's).
  */
 
-void handle_sysrq(int, struct pt_regs *, struct tty_struct *);
-void __handle_sysrq(int, struct pt_regs *, struct tty_struct *, int check_mask);
+void handle_sysrq(int, struct tty_struct *);
+void __handle_sysrq(int, struct tty_struct *, int check_mask);
 int register_sysrq_key(int, struct sysrq_key_op *);
 int unregister_sysrq_key(int, struct sysrq_key_op *);
 struct sysrq_key_op *__sysrq_get_key_op(int key);
index 0e058a2d1c6d72a62ddcef1e733830bff6323269..2d36f6db37067b84e1343979079395c3e8127a11 100644 (file)
@@ -342,6 +342,8 @@ struct tcp_sock {
 
        unsigned long last_synq_overflow; 
 
+       __u32   tso_deferred;
+
 /* Receiver side RTT estimation */
        struct {
                __u32   rtt;
index 203dd5e11ecbbdc1c763d3afd0db8ff4b62bf2e2..dfb8052eee5eb730938ae32a70ed579aed37cf86 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/wait.h>
 #include <linux/delay.h>
 #include <linux/pci.h>
+#include <linux/scatterlist.h>
 
 /* Host registers (relative to pci base address): */
 enum {
index 049dfe4a11f2a520399314b50bf3664044b01c46..db501dc23c299e52af3ac357cd7af05478465d23 100644 (file)
@@ -293,6 +293,9 @@ extern void second_overflow(void);
 extern void update_ntp_one_tick(void);
 extern int do_adjtimex(struct timex *);
 
+/* Don't use! Compatibility define for existing users. */
+#define tickadj        (500/HZ ? : 1)
+
 #endif /* KERNEL */
 
 #endif /* LINUX_TIMEX_H */
index 243a15f54002445f5b8b4938981ec90430b73ec6..bea469455a0c8bf6cdd0668d4f54fdb4ad0e4457 100644 (file)
@@ -129,6 +129,7 @@ static inline unsigned int tipc_node(__u32 addr)
 
 #define TIPC_SUB_PORTS         0x01    /* filter for port availability */
 #define TIPC_SUB_SERVICE       0x02    /* filter for service availability */
+#define TIPC_SUB_CANCEL         0x04    /* cancel a subscription */
 #if 0
 /* The following filter options are not currently implemented */
 #define TIPC_SUB_NO_BIND_EVTS  0x04    /* filter out "publish" events */
index fc62887c5206628d78279a1480628e6448c154a1..61eef508b041559203d89ca7a5f4ae3cee3d68ec 100644 (file)
@@ -351,6 +351,14 @@ struct ufs2_csum_total {
        __fs64   cs_spare[3];   /* future expansion */
 };
 
+struct ufs_csum_core {
+       __u64   cs_ndir;        /* number of directories */
+       __u64   cs_nbfree;      /* number of free blocks */
+       __u64   cs_nifree;      /* number of free inodes */
+       __u64   cs_nffree;      /* number of free frags */
+       __u64   cs_numclusters; /* number of free clusters */
+};
+
 /*
  * File system flags
  */
@@ -715,7 +723,7 @@ struct ufs_cg_private_info {
 
 struct ufs_sb_private_info {
        struct ufs_buffer_head s_ubh; /* buffer containing super block */
-       struct ufs2_csum_total cs_total;
+       struct ufs_csum_core cs_total;
        __u32   s_sblkno;       /* offset of super-blocks in filesys */
        __u32   s_cblkno;       /* offset of cg-block in filesys */
        __u32   s_iblkno;       /* offset of inode-blocks in filesys */
index 73e1751d03dd18e2806d4a018c05f9cf05eaf942..749928c161fb24a6fbdcc95fc703c18d900f9494 100644 (file)
@@ -26,6 +26,7 @@ struct module;
  * Initialize unwind support.
  */
 extern void unwind_init(void);
+extern void unwind_setup(void);
 
 #ifdef CONFIG_MODULES
 
@@ -73,6 +74,7 @@ extern int unwind_to_user(struct unwind_frame_info *);
 struct unwind_frame_info {};
 
 static inline void unwind_init(void) {}
+static inline void unwind_setup(void) {}
 
 #ifdef CONFIG_MODULES
 
index 190cc1b78fe2a29a071b01bb9ff8dbc4bc5490cc..5482bfb3303dc36ff70b371171030ca99e3db7c4 100644 (file)
@@ -764,9 +764,8 @@ struct usb_iso_packet_descriptor {
 };
 
 struct urb;
-struct pt_regs;
 
-typedef void (*usb_complete_t)(struct urb *, struct pt_regs *);
+typedef void (*usb_complete_t)(struct urb *);
 
 /**
  * struct urb - USB Request Block
index 91c983eef899a6cbd78242b93da9b0923cdbbf88..91b3ea2bbb149fbbf283cc8b297abddb8cca08ae 100644 (file)
@@ -226,10 +226,10 @@ struct usb_serial_driver {
        int  (*tiocmget)        (struct usb_serial_port *port, struct file *file);
        int  (*tiocmset)        (struct usb_serial_port *port, struct file *file, unsigned int set, unsigned int clear);
 
-       void (*read_int_callback)(struct urb *urb, struct pt_regs *regs);
-       void (*write_int_callback)(struct urb *urb, struct pt_regs *regs);
-       void (*read_bulk_callback)(struct urb *urb, struct pt_regs *regs);
-       void (*write_bulk_callback)(struct urb *urb, struct pt_regs *regs);
+       void (*read_int_callback)(struct urb *urb);
+       void (*write_int_callback)(struct urb *urb);
+       void (*read_bulk_callback)(struct urb *urb);
+       void (*write_bulk_callback)(struct urb *urb);
 };
 #define to_usb_serial_driver(d) container_of(d, struct usb_serial_driver, driver)
 
@@ -262,8 +262,8 @@ extern int usb_serial_generic_write (struct usb_serial_port *port, const unsigne
 extern void usb_serial_generic_close (struct usb_serial_port *port, struct file *filp);
 extern int usb_serial_generic_write_room (struct usb_serial_port *port);
 extern int usb_serial_generic_chars_in_buffer (struct usb_serial_port *port);
-extern void usb_serial_generic_read_bulk_callback (struct urb *urb, struct pt_regs *regs);
-extern void usb_serial_generic_write_bulk_callback (struct urb *urb, struct pt_regs *regs);
+extern void usb_serial_generic_read_bulk_callback (struct urb *urb);
+extern void usb_serial_generic_write_bulk_callback (struct urb *urb);
 extern void usb_serial_generic_shutdown (struct usb_serial *serial);
 extern int usb_serial_generic_register (int debug);
 extern void usb_serial_generic_deregister (void);
index c5fdf62595483430ea42dec5d483a6503e11c312..df5c4654360d029ba95f222d22b3a74042556944 100644 (file)
@@ -243,7 +243,7 @@ struct v4l2_pix_format
 #define V4L2_PIX_FMT_YUV420  v4l2_fourcc('Y','U','1','2') /* 12  YUV 4:2:0     */
 #define V4L2_PIX_FMT_YYUV    v4l2_fourcc('Y','Y','U','V') /* 16  YUV 4:2:2     */
 #define V4L2_PIX_FMT_HI240   v4l2_fourcc('H','I','2','4') /*  8  8-bit color   */
-#define V4L2_PIX_FMT_HM12    v4l2_fourcc('H','M','1','2') /*  8  YUV 4:1:1 16x16 macroblocks */
+#define V4L2_PIX_FMT_HM12    v4l2_fourcc('H','M','1','2') /*  8  YUV 4:2:0 16x16 macroblocks */
 
 /* see http://www.siliconimaging.com/RGB%20Bayer.htm */
 #define V4L2_PIX_FMT_SBGGR8  v4l2_fourcc('B','A','8','1') /*  8  BGBG.. GRGR.. */
index a341c803286617d570fac7cda0ad11ced9d67536..fc35e6bdfb93e4bf4d5cac5b50c983e97e846c5a 100644 (file)
@@ -85,7 +85,6 @@ int wakeup_pdflush(long nr_pages);
 void laptop_io_completion(void);
 void laptop_sync_completion(void);
 void throttle_vm_writeout(void);
-void writeback_congestion_end(void);
 
 /* These are exported to sysctl. */
 extern int dirty_background_ratio;
index cda8a96e2fa039f6e43c92b973f34eac9d5d8e6d..0e7f1e20ea45345d24a3d383256ddb798ec4fced 100644 (file)
@@ -41,6 +41,7 @@ struct xattr_handler {
 };
 
 ssize_t vfs_getxattr(struct dentry *, char *, void *, size_t);
+ssize_t vfs_listxattr(struct dentry *d, char *list, size_t size);
 int vfs_setxattr(struct dentry *, char *, void *, size_t, int);
 int vfs_removexattr(struct dentry *, char *);
 
index df22efcfcc0b7deceb77ee1094a05d24f00c22d2..c0fc39620f3643c4393ba2b1d99c8181498b0da0 100644 (file)
@@ -153,6 +153,7 @@ struct hci_conn {
        __u8             mode;
        __u8             type;
        __u8             out;
+       __u8             attempt;
        __u8             dev_class[3];
        __u8             features[8];
        __u16            interval;
@@ -289,6 +290,22 @@ static inline struct hci_conn *hci_conn_hash_lookup_ba(struct hci_dev *hdev,
        return NULL;
 }
 
+static inline struct hci_conn *hci_conn_hash_lookup_state(struct hci_dev *hdev,
+                                       __u8 type, __u16 state)
+{
+       struct hci_conn_hash *h = &hdev->conn_hash;
+       struct list_head *p;
+       struct hci_conn  *c;
+
+       list_for_each(p, &h->list) {
+               c = list_entry(p, struct hci_conn, list);
+               if (c->type == type && c->state == state)
+                       return c;
+       }
+       return NULL;
+}
+
+void hci_acl_connect(struct hci_conn *conn);
 void hci_acl_disconn(struct hci_conn *conn, __u8 reason);
 void hci_add_sco(struct hci_conn *conn, __u16 handle);
 
index 465b7830278209fee5a1454d634739c9e17a3a50..ac4ce9091747cd6660c5d77a7bce868e8e7a1747 100644 (file)
@@ -199,11 +199,6 @@ static inline void dn_sk_ports_copy(struct flowi *fl, struct dn_scp *scp)
 {
        fl->uli_u.dnports.sport = scp->addrloc;
        fl->uli_u.dnports.dport = scp->addrrem;
-       fl->uli_u.dnports.objnum = scp->addr.sdn_objnum;
-       if (fl->uli_u.dnports.objnum == 0) {
-               fl->uli_u.dnports.objnamel = (__u8)dn_ntohs(scp->addr.sdn_objnamel);
-               memcpy(fl->uli_u.dnports.objname, scp->addr.sdn_objname, 16);
-       }
 }
 
 extern unsigned dn_mss_from_pmtu(struct net_device *dev, int mtu);
index ddf5f3ca1720154be67aca197f628f1e7a83fd08..5cda27cd9debdbaa59afd05ec151b61badf9e4e5 100644 (file)
@@ -68,9 +68,6 @@ struct flowi {
                struct {
                        __le16  sport;
                        __le16  dport;
-                       __u8    objnum;
-                       __u8    objnamel; /* Not 16 bits since max val is 16 */
-                       __u8    objname[16]; /* Not zero terminated */
                } dnports;
 
                __be32          spi;
@@ -97,7 +94,7 @@ struct flowi {
 #define FLOW_DIR_FWD   2
 
 struct sock;
-typedef void (*flow_resolve_t)(struct flowi *key, u16 family, u8 dir,
+typedef int (*flow_resolve_t)(struct flowi *key, u16 family, u8 dir,
                               void **objp, atomic_t **obj_refp);
 
 extern void *flow_cache_lookup(struct flowi *key, u16 family, u8 dir,
index 425b3a57ac74a01d12f8f3d714b66cd9d7dbcb04..617b672b1132e7fa3ff5f9c940b1692520dc8483 100644 (file)
@@ -63,13 +63,11 @@ struct ieee80211softmac_wpa {
 
 /*
  * Information about association
- *
- * Do we need a lock for this?
- * We only ever use this structure inlined
- * into our global struct. I've used its lock,
- * but maybe we need a local one here?
  */
 struct ieee80211softmac_assoc_info {
+
+       struct mutex mutex;
+
        /*
         * This is the requested ESSID. It is written
         * only by the WX handlers.
@@ -99,12 +97,13 @@ struct ieee80211softmac_assoc_info {
         *
         * bssfixed is used for SIOCSIWAP.
         */
-       u8 static_essid:1,
-          short_preamble_available:1,
-          associating:1,
-          assoc_wait:1,
-          bssvalid:1,
-          bssfixed:1;
+       u8 static_essid;
+       u8 short_preamble_available;
+       u8 associating;
+       u8 associated;
+       u8 assoc_wait;
+       u8 bssvalid;
+       u8 bssfixed;
 
        /* Scan retries remaining */
        int scan_retry;
@@ -229,12 +228,10 @@ struct ieee80211softmac_device {
        /* private stuff follows */
        /* this lock protects this structure */
        spinlock_t lock;
-       
-       /* couple of flags */
-       u8 scanning:1, /* protects scanning from being done multiple times at once */
-          associated:1,
-          running:1;
-       
+
+       u8 running; /* SoftMAC started? */
+       u8 scanning;
+
        struct ieee80211softmac_scaninfo *scaninfo;
        struct ieee80211softmac_assoc_info associnfo;
        struct ieee80211softmac_bss_info bssinfo;
@@ -250,7 +247,7 @@ struct ieee80211softmac_device {
 
        /* we need to keep a list of network structs we copied */
        struct list_head network_list;
-       
+
        /* This must be the last item so that it points to the data
         * allocated beyond this structure by alloc_ieee80211 */
        u8 priv[0];
@@ -295,7 +292,7 @@ static inline u8 ieee80211softmac_suggest_txrate(struct ieee80211softmac_device
 {
        struct ieee80211softmac_txrates *txrates = &mac->txrates;
 
-       if (!mac->associated)
+       if (!mac->associnfo.associated)
                return txrates->mgt_mcast_rate;
 
        /* We are associated, sending unicast frame */
index 6d14c22a00c5e3e9ab750fb0c68434edba86c853..5f48748fe017557e0ec61f1d0a5bce47800387c8 100644 (file)
@@ -196,6 +196,7 @@ static inline void inet_twsk_put(struct inet_timewait_sock *tw)
 {
        if (atomic_dec_and_test(&tw->tw_refcnt)) {
                struct module *owner = tw->tw_prot->owner;
+               twsk_destructor((struct sock *)tw);
 #ifdef SOCK_REFCNT_DEBUG
                printk(KERN_DEBUG "%s timewait_sock %p released\n",
                       tw->tw_prot->name, tw);
index 925573fd2aed04a91e41c0de1b84bf09f68e06c5..aa10a8178e7011532d63e66ef0d0d08dfc583634 100644 (file)
 
 struct inet_peer
 {
+       /* group together avl_left,avl_right,v4daddr to speedup lookups */
        struct inet_peer        *avl_left, *avl_right;
-       struct inet_peer        *unused_next, **unused_prevp;
-       unsigned long           dtime;          /* the time of last use of not
-                                                * referenced entries */
-       atomic_t                refcnt;
        __be32                  v4daddr;        /* peer's address */
        __u16                   avl_height;
        __u16                   ip_id_count;    /* IP ID for the next packet */
+       struct inet_peer        *unused_next, **unused_prevp;
+       __u32                   dtime;          /* the time of last use of not
+                                                * referenced entries */
+       atomic_t                refcnt;
        atomic_t                rid;            /* Frag reception counter */
        __u32                   tcp_ts;
        unsigned long           tcp_ts_stamp;
@@ -35,21 +36,8 @@ void                 inet_initpeers(void) __init;
 /* can be called with or without local BH being disabled */
 struct inet_peer       *inet_getpeer(__be32 daddr, int create);
 
-extern spinlock_t inet_peer_unused_lock;
-extern struct inet_peer **inet_peer_unused_tailp;
 /* can be called from BH context or outside */
-static inline void     inet_putpeer(struct inet_peer *p)
-{
-       spin_lock_bh(&inet_peer_unused_lock);
-       if (atomic_dec_and_test(&p->refcnt)) {
-               p->unused_prevp = inet_peer_unused_tailp;
-               p->unused_next = NULL;
-               *inet_peer_unused_tailp = p;
-               inet_peer_unused_tailp = &p->unused_next;
-               p->dtime = jiffies;
-       }
-       spin_unlock_bh(&inet_peer_unused_lock);
-}
+extern void inet_putpeer(struct inet_peer *p);
 
 extern spinlock_t inet_peer_idlock;
 /* can be called with or without local BH being disabled */
index 6ca6b71dfe0f07406f9222092da64559358df696..c14b70ed4c57b247f8fd0a31b8a8329b5e222016 100644 (file)
@@ -36,13 +36,6 @@ struct route_info {
 #define RT6_LOOKUP_F_REACHABLE 0x2
 #define RT6_LOOKUP_F_HAS_SADDR 0x4
 
-struct pol_chain {
-       int                     type;
-       int                     priority;
-       struct fib6_node        *rules;
-       struct pol_chain        *next;
-};
-
 extern struct rt6_info ip6_null_entry;
 
 #ifdef CONFIG_IPV6_MULTIPLE_TABLES
index 82229146bac7f127156050880edc5c150f0de882..949b932d2f08c8f72017f8d61ce1f773192f55e0 100644 (file)
 #include <net/fib_rules.h>
 
 struct fib_config {
-       u8                      fc_family;
        u8                      fc_dst_len;
-       u8                      fc_src_len;
        u8                      fc_tos;
        u8                      fc_protocol;
        u8                      fc_scope;
        u8                      fc_type;
-       /* 1 byte unused */
+       /* 3 bytes unused */
        u32                     fc_table;
        __be32                  fc_dst;
-       __be32                  fc_src;
        __be32                  fc_gw;
        int                     fc_oif;
        u32                     fc_flags;
index c63a58058e2170b811e01c446b8781b5f1faa93e..12c214b9eadf8b8d7da0f7c0eb12c08512193049 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/net.h>
 #include <linux/skbuff.h>
 #include <net/netlink.h>
+#include <asm/atomic.h>
 
 /*
  * NetLabel - A management interface for maintaining network packet label
@@ -106,6 +107,7 @@ int netlbl_domhsh_remove(const char *domain, struct netlbl_audit *audit_info);
 
 /* LSM security attributes */
 struct netlbl_lsm_cache {
+       atomic_t refcount;
        void (*free) (const void *data);
        void *data;
 };
@@ -117,7 +119,7 @@ struct netlbl_lsm_secattr {
        unsigned char *mls_cat;
        size_t mls_cat_len;
 
-       struct netlbl_lsm_cache cache;
+       struct netlbl_lsm_cache *cache;
 };
 
 /*
@@ -125,6 +127,43 @@ struct netlbl_lsm_secattr {
  */
 
 
+/**
+ * netlbl_secattr_cache_alloc - Allocate and initialize a secattr cache
+ * @flags: the memory allocation flags
+ *
+ * Description:
+ * Allocate and initialize a netlbl_lsm_cache structure.  Returns a pointer
+ * on success, NULL on failure.
+ *
+ */
+static inline struct netlbl_lsm_cache *netlbl_secattr_cache_alloc(gfp_t flags)
+{
+       struct netlbl_lsm_cache *cache;
+
+       cache = kzalloc(sizeof(*cache), flags);
+       if (cache)
+               atomic_set(&cache->refcount, 1);
+       return cache;
+}
+
+/**
+ * netlbl_secattr_cache_free - Frees a netlbl_lsm_cache struct
+ * @cache: the struct to free
+ *
+ * Description:
+ * Frees @secattr including all of the internal buffers.
+ *
+ */
+static inline void netlbl_secattr_cache_free(struct netlbl_lsm_cache *cache)
+{
+       if (!atomic_dec_and_test(&cache->refcount))
+               return;
+
+       if (cache->free)
+               cache->free(cache->data);
+       kfree(cache);
+}
+
 /**
  * netlbl_secattr_init - Initialize a netlbl_lsm_secattr struct
  * @secattr: the struct to initialize
@@ -143,20 +182,16 @@ static inline int netlbl_secattr_init(struct netlbl_lsm_secattr *secattr)
 /**
  * netlbl_secattr_destroy - Clears a netlbl_lsm_secattr struct
  * @secattr: the struct to clear
- * @clear_cache: cache clear flag
  *
  * Description:
  * Destroys the @secattr struct, including freeing all of the internal buffers.
- * If @clear_cache is true then free the cache fields, otherwise leave them
- * intact.  The struct must be reset with a call to netlbl_secattr_init()
- * before reuse.
+ * The struct must be reset with a call to netlbl_secattr_init() before reuse.
  *
  */
-static inline void netlbl_secattr_destroy(struct netlbl_lsm_secattr *secattr,
-                                         u32 clear_cache)
+static inline void netlbl_secattr_destroy(struct netlbl_lsm_secattr *secattr)
 {
-       if (clear_cache && secattr->cache.data != NULL && secattr->cache.free)
-               secattr->cache.free(secattr->cache.data);
+       if (secattr->cache)
+               netlbl_secattr_cache_free(secattr->cache);
        kfree(secattr->domain);
        kfree(secattr->mls_cat);
 }
@@ -178,17 +213,14 @@ static inline struct netlbl_lsm_secattr *netlbl_secattr_alloc(int flags)
 /**
  * netlbl_secattr_free - Frees a netlbl_lsm_secattr struct
  * @secattr: the struct to free
- * @clear_cache: cache clear flag
  *
  * Description:
- * Frees @secattr including all of the internal buffers.  If @clear_cache is
- * true then free the cache fields, otherwise leave them intact.
+ * Frees @secattr including all of the internal buffers.
  *
  */
-static inline void netlbl_secattr_free(struct netlbl_lsm_secattr *secattr,
-                                      u32 clear_cache)
+static inline void netlbl_secattr_free(struct netlbl_lsm_secattr *secattr)
 {
-       netlbl_secattr_destroy(secattr, clear_cache);
+       netlbl_secattr_destroy(secattr);
        kfree(secattr);
 }
 
index ee68a3124076554d08d3dcc45cf96fc801834253..764e3af5be9340c04b303b82416d29c6bbbc5e8e 100644 (file)
@@ -139,6 +139,7 @@ int sctp_inet_listen(struct socket *sock, int backlog);
 void sctp_write_space(struct sock *sk);
 unsigned int sctp_poll(struct file *file, struct socket *sock,
                poll_table *wait);
+void sctp_sock_rfree(struct sk_buff *skb);
 
 /*
  * sctp/primitive.c
@@ -444,6 +445,19 @@ static inline struct list_head *sctp_list_dequeue(struct list_head *list)
        return result;
 }
 
+/* SCTP version of skb_set_owner_r.  We need this one because
+ * of the way we have to do receive buffer accounting on bundled
+ * chunks.
+ */
+static inline void sctp_skb_set_owner_r(struct sk_buff *skb, struct sock *sk)
+{
+       struct sctp_ulpevent *event = sctp_skb2event(skb);
+
+       skb->sk = sk;
+       skb->destructor = sctp_sock_rfree;
+       atomic_add(event->rmem_len, &sk->sk_rmem_alloc);
+}
+
 /* Tests if the list has one and only one entry. */
 static inline int sctp_list_single_entry(struct list_head *head)
 {
index 6c40cfc4832d4a8beb136b8944fb05a7fad9cd68..1a4ddc1ec7d24cfd9a6b5acfe090c430a40a1502 100644 (file)
@@ -63,6 +63,7 @@ struct sctp_ulpevent {
        __u32 cumtsn;
        int msg_flags;
        int iif;
+       unsigned int rmem_len;
 };
 
 /* Retrieve the skb this event sits inside of. */
index 40bb90ebb2d1b24e11134b08c21ab47f59f68e75..ac286a35303288eddbf2171bced23f79cd11da7c 100644 (file)
@@ -884,8 +884,7 @@ static inline int sk_filter(struct sock *sk, struct sk_buff *skb)
 
 /**
  *     sk_filter_release: Release a socket filter
- *     @sk: socket
- *     @fp: filter to remove
+ *     @rcu: rcu_head that contains the sk_filter info to remove
  *
  *     Remove a filter from a socket and release its resources.
  */
index 2544281e1d5e60f3e8b60ff1006327135c452576..be293d795e385396cf2e3e7f7761e1e1efd223c7 100644 (file)
@@ -19,6 +19,7 @@ struct timewait_sock_ops {
        unsigned int    twsk_obj_size;
        int             (*twsk_unique)(struct sock *sk,
                                       struct sock *sktw, void *twp);
+       void            (*twsk_destructor)(struct sock *sk);
 };
 
 static inline int twsk_unique(struct sock *sk, struct sock *sktw, void *twp)
@@ -28,4 +29,10 @@ static inline int twsk_unique(struct sock *sk, struct sock *sktw, void *twp)
        return 0;
 }
 
+static inline void twsk_destructor(struct sock *sk)
+{
+       if (sk->sk_prot->twsk_prot->twsk_destructor != NULL)
+               sk->sk_prot->twsk_prot->twsk_destructor(sk);
+}
+
 #endif /* _TIMEWAIT_SOCK_H */
index 1e2a4ddec96e3c7cfdf8e5ef2010d234c0673821..737fdb2ee8a45bb230c87e3303d52f098d74f53a 100644 (file)
@@ -995,7 +995,8 @@ struct xfrm_state * xfrm_find_acq(u8 mode, u32 reqid, u8 proto,
                                  int create, unsigned short family);
 extern void xfrm_policy_flush(u8 type);
 extern int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol);
-extern int xfrm_bundle_ok(struct xfrm_dst *xdst, struct flowi *fl, int family, int strict);
+extern int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *xdst,
+                         struct flowi *fl, int family, int strict);
 extern void xfrm_init_pmtu(struct dst_entry *dst);
 
 extern wait_queue_head_t km_waitq;
index 0a487fe26d4fe1c8ba4c07f0c3a538327abcf6b0..519c49a0fc11decf664e6d676f1dab8580169236 100644 (file)
 Original driver (sg.h):
 *       Copyright (C) 1992 Lawrence Foard
 Version 2 and 3 extensions to driver:
-*       Copyright (C) 1998 - 2003 Douglas Gilbert
-
-    Version: 3.5.29 (20030529)
-    This version is for 2.5 series kernels.
-
-    Changes since 3.5.28 (20030308)
-       - fix bug introduced in version 3.1.24 (last segment of sgat list)
-    Changes since 3.5.27 (20020812)
-       - remove procfs entries: hosts, host_hdr + host_strs (now in sysfs)
-       - add sysfs sg driver params: def_reserved_size, allow_dio, version
-       - new boot option: "sg_allow_dio" and module parameter: "allow_dio"
-        - multiple internal changes due to scsi subsystem rework       
-    Changes since 3.5.26 (20020708)
-       - re-add direct IO using Kai Makisara's work
-       - re-tab to 8, start using C99-isms
-       - simplify memory management
-    Changes since 3.5.25 (20020504)
-       - driverfs additions
-       - copy_to/from_user() fixes [William Stinson]
-       - disable kiobufs support
+*       Copyright (C) 1998 - 2006 Douglas Gilbert
+
+    Version: 3.5.34 (20060920)
+    This version is for 2.6 series kernels.
 
     For a full changelog see http://www.torque.net/sg
 
@@ -40,7 +24,7 @@ Map of SG verions to the Linux kernels in which they appear:
        2.1.40            2.2.20
        3.0.x             optional version 3 sg driver for 2.2 series
        3.1.17++          2.4.0++
-       3.5.23++          2.5.0++
+       3.5.30++          2.6.0++
 
 Major new features in SG 3.x driver (cf SG 2.x drivers)
        - SG_IO ioctl() combines function if write() and read()
@@ -51,14 +35,15 @@ Major new features in SG 3.x driver (cf SG 2.x drivers)
  data into kernel buffers and then use the CPU to copy the data into the 
  user space (vice versa for writes). That is called "indirect" IO due to 
  the double handling of data. There are two methods offered to remove the
- redundant copy: 1) direct IO which uses the kernel kiobuf mechanism and 
- 2) using the mmap() system call to map the reserve buffer (this driver has 
one reserve buffer per fd) into the user space. Both have their advantages.
+ redundant copy: 1) direct IO and 2) using the mmap() system call to map
+ the reserve buffer (this driver has one reserve buffer per fd) into the
+ user space. Both have their advantages.
  In terms of absolute speed mmap() is faster. If speed is not a concern, 
  indirect IO should be fine. Read the documentation for more information.
 
- ** N.B. To use direct IO 'echo 1 > /proc/scsi/sg/allow_dio' may be
-         needed. That pseudo file's content is defaulted to 0. **
+ ** N.B. To use direct IO 'echo 1 > /proc/scsi/sg/allow_dio' or
+         'echo 1 > /sys/module/sg/parameters/allow_dio' is needed.
+         That attribute is 0 by default. **
  
  Historical note: this SCSI pass-through driver has been known as "sg" for 
  a decade. In broader kernel discussions "sg" is used to refer to scatter
@@ -72,20 +57,17 @@ Major new features in SG 3.x driver (cf SG 2.x drivers)
        http://www.torque.net/sg/p/sg_v3_ho.html
  This is a rendering from DocBook source [change the extension to "sgml"
  or "xml"]. There are renderings in "ps", "pdf", "rtf" and "txt" (soon).
+ The SG_IO ioctl is now found in other parts kernel (e.g. the block layer).
+ For more information see http://www.torque.net/sg/sg_io.html
 
  The older, version 2 documents discuss the original sg interface in detail:
        http://www.torque.net/sg/p/scsi-generic.txt
        http://www.torque.net/sg/p/scsi-generic_long.txt
- A version of this document (potentially out of date) may also be found in
- the kernel source tree, probably at:
-        Documentation/scsi/scsi-generic.txt .
+ Also available: <kernel_source>/Documentation/scsi/scsi-generic.txt
 
  Utility and test programs are available at the sg web site. They are 
- bundled as sg_utils (for the lk 2.2 series) and sg3_utils (for the
- lk 2.4 series).
-
- There is a HOWTO on the Linux SCSI subsystem in the lk 2.4 series at:
-       http://www.linuxdoc.org/HOWTO/SCSI-2.4-HOWTO
+ packaged as sg3_utils (for the lk 2.4 and 2.6 series) and sg_utils
+ (for the lk 2.2 series).
 */
 
 
@@ -238,13 +220,12 @@ typedef struct sg_req_info { /* used by SG_GET_REQUEST_TABLE ioctl() */
 #define SG_GET_ACCESS_COUNT 0x2289  
 
 
-#define SG_SCATTER_SZ (8 * 4096)  /* PAGE_SIZE not available to user */
+#define SG_SCATTER_SZ (8 * 4096)
 /* Largest size (in bytes) a single scatter-gather list element can have.
-   The value must be a power of 2 and <= (PAGE_SIZE * 32) [131072 bytes on
-   i386]. The minimum value is PAGE_SIZE. If scatter-gather not supported
-   by adapter then this value is the largest data block that can be
-   read/written by a single scsi command. The user can find the value of
-   PAGE_SIZE by calling getpagesize() defined in unistd.h . */
+   The value used by the driver is 'max(SG_SCATTER_SZ, PAGE_SIZE)'.
+   This value should be a power of 2 (and may be rounded up internally).
+   If scatter-gather is not supported by adapter then this value is the
+   largest data block that can be read/written by a single scsi command. */
 
 #define SG_DEFAULT_RETRIES 0
 
index b056ea925ecf33c7e06bf6e3d7c4d27d8f66a9b1..fa1ca0127babe1731fca854e5b4aa3e26ed30cef 100644 (file)
@@ -89,10 +89,10 @@ struct snd_device {
 struct snd_monitor_file {
        struct file *file;
        struct snd_monitor_file *next;
+       const struct file_operations *disconnected_f_op;
+       struct list_head shutdown_list;
 };
 
-struct snd_shutdown_f_ops;     /* define it later in init.c */
-
 /* main structure for soundcard */
 
 struct snd_card {
index 60b5b92a131985a6a62da67ee07afc3491665f53..ab51ce1ba9a5484acef339bd72b3688c8dbb1470 100644 (file)
@@ -273,7 +273,7 @@ unsigned char snd_cs4236_ext_in(struct snd_cs4231 *chip, unsigned char reg);
 void snd_cs4231_mce_up(struct snd_cs4231 *chip);
 void snd_cs4231_mce_down(struct snd_cs4231 *chip);
 
-irqreturn_t snd_cs4231_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+irqreturn_t snd_cs4231_interrupt(int irq, void *dev_id);
 
 const char *snd_cs4231_chip_id(struct snd_cs4231 *chip);
 
index 892e310c504d61b38b5f43562ea6a1840ec6b3d4..3d3c1514cf71308de5bdc36d4e5a6cdb69208342 100644 (file)
@@ -1194,7 +1194,7 @@ int snd_emu10k1_mixer(struct snd_emu10k1 * emu, int pcm_device, int multi_device
 int snd_emu10k1_timer(struct snd_emu10k1 * emu, int device);
 int snd_emu10k1_fx8010_new(struct snd_emu10k1 *emu, int device, struct snd_hwdep ** rhwdep);
 
-irqreturn_t snd_emu10k1_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+irqreturn_t snd_emu10k1_interrupt(int irq, void *dev_id);
 
 void snd_emu10k1_voice_init(struct snd_emu10k1 * emu, int voice);
 int snd_emu10k1_init_efx(struct snd_emu10k1 *emu);
index 68a664ab97f391e18eb55922952c31993cf51ecc..c49ea57db8cc38a6fb4e071e310cf53204a21495 100644 (file)
@@ -638,7 +638,7 @@ int snd_gus_initialize(struct snd_gus_card * gus);
 
 /* gus_irq.c */
 
-irqreturn_t snd_gus_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+irqreturn_t snd_gus_interrupt(int irq, void *dev_id);
 #ifdef CONFIG_SND_DEBUG
 void snd_gus_irq_profile_init(struct snd_gus_card *gus);
 #endif
index 2ae76efc696fef63fe3d8b51d8c30dd9b528b774..e85b90750a597514b0195c7efc781f3f0de8dc01 100644 (file)
@@ -53,7 +53,7 @@
 #ifdef SNDRV_LEGACY_FIND_FREE_IRQ
 #include <linux/interrupt.h>
 
-static irqreturn_t snd_legacy_empty_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t snd_legacy_empty_irq_handler(int irq, void *dev_id)
 {
        return IRQ_HANDLED;
 }
index ac504321ea5625775698a3735f9b5bbf252c418f..8c88267e9beaaa7aa5f95e843703c4a3ad7fcc67 100644 (file)
@@ -106,10 +106,8 @@ struct snd_mpu401 {
 
  */
 
-irqreturn_t snd_mpu401_uart_interrupt(int irq, void *dev_id,
-                                     struct pt_regs *regs);
-irqreturn_t snd_mpu401_uart_interrupt_tx(int irq, void *dev_id,
-                                        struct pt_regs *regs);
+irqreturn_t snd_mpu401_uart_interrupt(int irq, void *dev_id);
+irqreturn_t snd_mpu401_uart_interrupt_tx(int irq, void *dev_id);
 
 int snd_mpu401_uart_new(struct snd_card *card,
                        int device,
index 431d06675e36b9a848104d78c373d2e40852e1fc..2dd5c8e5b4feabc027a48dfed2320421c26d4c26 100644 (file)
@@ -100,7 +100,7 @@ struct snd_sb {
        struct snd_rawmidi *rmidi;
        struct snd_rawmidi_substream *midi_substream_input;
        struct snd_rawmidi_substream *midi_substream_output;
-       irqreturn_t (*rmidi_callback)(int irq, void *dev_id, struct pt_regs *regs);
+       irq_handler_t rmidi_callback;
 
        spinlock_t reg_lock;
        spinlock_t open_lock;
@@ -286,7 +286,7 @@ int snd_sbdsp_reset(struct snd_sb *chip);
 int snd_sbdsp_create(struct snd_card *card,
                     unsigned long port,
                     int irq,
-                    irqreturn_t (*irq_handler)(int, void *, struct pt_regs *),
+                    irq_handler_t irq_handler,
                     int dma8, int dma16,
                     unsigned short hardware,
                     struct snd_sb **r_chip);
@@ -316,7 +316,7 @@ int snd_sb16dsp_pcm(struct snd_sb *chip, int device, struct snd_pcm ** rpcm);
 const struct snd_pcm_ops *snd_sb16dsp_get_pcm_ops(int direction);
 int snd_sb16dsp_configure(struct snd_sb *chip);
 /* sb16.c */
-irqreturn_t snd_sb16dsp_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+irqreturn_t snd_sb16dsp_interrupt(int irq, void *dev_id);
 
 /* exported mixer stuffs */
 enum {
index 2ee849d0e198dc20c4afb1b5e26d203272de2e20..52fd6879b86e1142f1c604367b5eb552e2dc26f5 100644 (file)
@@ -1,3 +1,3 @@
-/* include/version.h.  Generated by configure.  */
-#define CONFIG_SND_VERSION "1.0.12rc1"
-#define CONFIG_SND_DATE " (Thu Jun 22 13:55:50 2006 UTC)"
+/* include/version.h.  Generated by alsa/ksync script.  */
+#define CONFIG_SND_VERSION "1.0.13"
+#define CONFIG_SND_DATE " (Sun Oct 22 08:56:16 2006 UTC)"
index dbca14170615bb93731a0b99d8c45c08f83211cc..217394652090d5853d2be332651a20673d33860c 100644 (file)
@@ -228,7 +228,7 @@ void snd_vx_free_firmware(struct vx_core *chip);
 /*
  * interrupt handler; exported for pcmcia
  */
-irqreturn_t snd_vx_irq_handler(int irq, void *dev, struct pt_regs *regs);
+irqreturn_t snd_vx_irq_handler(int irq, void *dev);
 
 /*
  * lowlevel functions
index 10382931eead561940c023bd1b376863b9b11dab..c8b2624af1767398632f68825014c825fbb7fe8e 100644 (file)
@@ -1,5 +1,6 @@
 config DEFCONFIG_LIST
        string
+       depends on !UML
        option defconfig_list
        default "/lib/modules/$UNAME_RELEASE/.config"
        default "/etc/kernel-config"
index ee123243fb530b4d4e589f731c5bfa4652148dc8..36f608a7cfbaf0fe1e2d3b1f37ff42e945bc100d 100644 (file)
@@ -503,6 +503,7 @@ asmlinkage void __init start_kernel(void)
        printk(KERN_NOTICE);
        printk(linux_banner);
        setup_arch(&command_line);
+       unwind_setup();
        setup_per_cpu_areas();
        smp_prepare_boot_cpu(); /* arch-specific boot-cpu hooks */
 
index f9889ee778256ddb7336c2527ab0c0fe48754d87..98106f6078b0005a89ef889574441c663f40732f 100644 (file)
@@ -340,7 +340,7 @@ static int kauditd_thread(void *dummy)
 {
        struct sk_buff *skb;
 
-       while (1) {
+       while (!kthread_should_stop()) {
                skb = skb_dequeue(&audit_skb_queue);
                wake_up(&audit_backlog_wait);
                if (skb) {
@@ -369,6 +369,7 @@ static int kauditd_thread(void *dummy)
                        remove_wait_queue(&kauditd_wait, &wait);
                }
        }
+       return 0;
 }
 
 int audit_send_list(void *_dest)
index 32c96628463eb46bab59ff81928d44e573711170..27dd3ee47099dd49c26790adf40b42efa1b950a3 100644 (file)
@@ -19,7 +19,7 @@
 static DEFINE_MUTEX(cpu_add_remove_lock);
 static DEFINE_MUTEX(cpu_bitmask_lock);
 
-static __cpuinitdata BLOCKING_NOTIFIER_HEAD(cpu_chain);
+static __cpuinitdata RAW_NOTIFIER_HEAD(cpu_chain);
 
 /* If set, cpu_up and cpu_down will return -EBUSY and do nothing.
  * Should always be manipulated under cpu_add_remove_lock
@@ -68,7 +68,11 @@ EXPORT_SYMBOL_GPL(unlock_cpu_hotplug);
 /* Need to know about CPUs going up/down? */
 int __cpuinit register_cpu_notifier(struct notifier_block *nb)
 {
-       return blocking_notifier_chain_register(&cpu_chain, nb);
+       int ret;
+       mutex_lock(&cpu_add_remove_lock);
+       ret = raw_notifier_chain_register(&cpu_chain, nb);
+       mutex_unlock(&cpu_add_remove_lock);
+       return ret;
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
@@ -77,7 +81,9 @@ EXPORT_SYMBOL(register_cpu_notifier);
 
 void unregister_cpu_notifier(struct notifier_block *nb)
 {
-       blocking_notifier_chain_unregister(&cpu_chain, nb);
+       mutex_lock(&cpu_add_remove_lock);
+       raw_notifier_chain_unregister(&cpu_chain, nb);
+       mutex_unlock(&cpu_add_remove_lock);
 }
 EXPORT_SYMBOL(unregister_cpu_notifier);
 
@@ -126,7 +132,7 @@ static int _cpu_down(unsigned int cpu)
        if (!cpu_online(cpu))
                return -EINVAL;
 
-       err = blocking_notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE,
+       err = raw_notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE,
                                                (void *)(long)cpu);
        if (err == NOTIFY_BAD) {
                printk("%s: attempt to take down CPU %u failed\n",
@@ -146,7 +152,7 @@ static int _cpu_down(unsigned int cpu)
 
        if (IS_ERR(p)) {
                /* CPU didn't die: tell everyone.  Can't complain. */
-               if (blocking_notifier_call_chain(&cpu_chain, CPU_DOWN_FAILED,
+               if (raw_notifier_call_chain(&cpu_chain, CPU_DOWN_FAILED,
                                (void *)(long)cpu) == NOTIFY_BAD)
                        BUG();
 
@@ -169,7 +175,7 @@ static int _cpu_down(unsigned int cpu)
        put_cpu();
 
        /* CPU is completely dead: tell everyone.  Too late to complain. */
-       if (blocking_notifier_call_chain(&cpu_chain, CPU_DEAD,
+       if (raw_notifier_call_chain(&cpu_chain, CPU_DEAD,
                        (void *)(long)cpu) == NOTIFY_BAD)
                BUG();
 
@@ -206,7 +212,7 @@ static int __devinit _cpu_up(unsigned int cpu)
        if (cpu_online(cpu) || !cpu_present(cpu))
                return -EINVAL;
 
-       ret = blocking_notifier_call_chain(&cpu_chain, CPU_UP_PREPARE, hcpu);
+       ret = raw_notifier_call_chain(&cpu_chain, CPU_UP_PREPARE, hcpu);
        if (ret == NOTIFY_BAD) {
                printk("%s: attempt to bring up CPU %u failed\n",
                                __FUNCTION__, cpu);
@@ -223,11 +229,11 @@ static int __devinit _cpu_up(unsigned int cpu)
        BUG_ON(!cpu_online(cpu));
 
        /* Now call notifier in preparation. */
-       blocking_notifier_call_chain(&cpu_chain, CPU_ONLINE, hcpu);
+       raw_notifier_call_chain(&cpu_chain, CPU_ONLINE, hcpu);
 
 out_notify:
        if (ret != 0)
-               blocking_notifier_call_chain(&cpu_chain,
+               raw_notifier_call_chain(&cpu_chain,
                                CPU_UP_CANCELED, hcpu);
 
        return ret;
index 9d850ae13b1b61e763d09fc8231c33d1d6e43139..6313c38c930e62025c0e76a057d83023b77a6bb5 100644 (file)
@@ -2137,7 +2137,7 @@ static int cpuset_handle_cpuhp(struct notifier_block *nb,
  * See also the previous routine cpuset_handle_cpuhp().
  */
 
-void cpuset_track_online_nodes()
+void cpuset_track_online_nodes(void)
 {
        common_cpu_mem_hotplug_unplug();
 }
index 7dc6140baac69325f1ce2fa08fa9bd858aa57258..29ebb30850eda41f743cdacb6d7bb0f696872a87 100644 (file)
@@ -984,6 +984,8 @@ static struct task_struct *copy_process(unsigned long clone_flags,
        if (!p)
                goto fork_out;
 
+       rt_mutex_init_task(p);
+
 #ifdef CONFIG_TRACE_IRQFLAGS
        DEBUG_LOCKS_WARN_ON(!p->hardirqs_enabled);
        DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled);
@@ -1088,8 +1090,6 @@ static struct task_struct *copy_process(unsigned long clone_flags,
        p->lockdep_recursion = 0;
 #endif
 
-       rt_mutex_init_task(p);
-
 #ifdef CONFIG_DEBUG_MUTEXES
        p->blocked_on = NULL; /* not blocked yet */
 #endif
index 4aaf91951a43959be9d448b66fe7538d46f7d244..b364e0026191caee9dd0ebee3a657e2f65b5c52e 100644 (file)
@@ -1612,10 +1612,10 @@ sys_set_robust_list(struct robust_list_head __user *head,
  * @len_ptr: pointer to a length field, the kernel fills in the header size
  */
 asmlinkage long
-sys_get_robust_list(int pid, struct robust_list_head __user **head_ptr,
+sys_get_robust_list(int pid, struct robust_list_head __user * __user *head_ptr,
                    size_t __user *len_ptr)
 {
-       struct robust_list_head *head;
+       struct robust_list_head __user *head;
        unsigned long ret;
 
        if (!pid)
@@ -1694,14 +1694,15 @@ retry:
  * Fetch a robust-list pointer. Bit 0 signals PI futexes:
  */
 static inline int fetch_robust_entry(struct robust_list __user **entry,
-                                    struct robust_list __user **head, int *pi)
+                                    struct robust_list __user * __user *head,
+                                    int *pi)
 {
        unsigned long uentry;
 
-       if (get_user(uentry, (unsigned long *)head))
+       if (get_user(uentry, (unsigned long __user *)head))
                return -EFAULT;
 
-       *entry = (void *)(uentry & ~1UL);
+       *entry = (void __user *)(uentry & ~1UL);
        *pi = uentry & 1;
 
        return 0;
@@ -1739,7 +1740,7 @@ void exit_robust_list(struct task_struct *curr)
                return;
 
        if (pending)
-               handle_futex_death((void *)pending + futex_offset, curr, pip);
+               handle_futex_death((void __user *)pending + futex_offset, curr, pip);
 
        while (entry != &head->list) {
                /*
@@ -1747,7 +1748,7 @@ void exit_robust_list(struct task_struct *curr)
                 * don't process it twice:
                 */
                if (entry != pending)
-                       if (handle_futex_death((void *)entry + futex_offset,
+                       if (handle_futex_death((void __user *)entry + futex_offset,
                                                curr, pi))
                                return;
                /*
index c5cca3f65cb776f2757e4bd5eeb167a4f84f6ffd..50f24eea6cd02916bd53d0ea09b1b8de668f8823 100644 (file)
@@ -18,7 +18,7 @@
  */
 static inline int
 fetch_robust_entry(compat_uptr_t *uentry, struct robust_list __user **entry,
-                  compat_uptr_t *head, int *pi)
+                  compat_uptr_t __user *head, int *pi)
 {
        if (get_user(*uentry, head))
                return -EFAULT;
@@ -62,7 +62,7 @@ void compat_exit_robust_list(struct task_struct *curr)
                               &head->list_op_pending, &pip))
                return;
        if (upending)
-               handle_futex_death((void *)pending + futex_offset, curr, pip);
+               handle_futex_death((void __user *)pending + futex_offset, curr, pip);
 
        while (compat_ptr(uentry) != &head->list) {
                /*
@@ -70,7 +70,7 @@ void compat_exit_robust_list(struct task_struct *curr)
                 * dont process it twice:
                 */
                if (entry != pending)
-                       if (handle_futex_death((void *)entry + futex_offset,
+                       if (handle_futex_death((void __user *)entry + futex_offset,
                                                curr, pi))
                                return;
 
@@ -78,7 +78,7 @@ void compat_exit_robust_list(struct task_struct *curr)
                 * Fetch the next entry in the list:
                 */
                if (fetch_robust_entry(&uentry, &entry,
-                                      (compat_uptr_t *)&entry->next, &pi))
+                                      (compat_uptr_t __user *)&entry->next, &pi))
                        return;
                /*
                 * Avoid excessively long or circular lists:
@@ -103,10 +103,10 @@ compat_sys_set_robust_list(struct compat_robust_list_head __user *head,
 }
 
 asmlinkage long
-compat_sys_get_robust_list(int pid, compat_uptr_t *head_ptr,
+compat_sys_get_robust_list(int pid, compat_uptr_t __user *head_ptr,
                           compat_size_t __user *len_ptr)
 {
-       struct compat_robust_list_head *head;
+       struct compat_robust_list_head __user *head;
        unsigned long ret;
 
        if (!pid)
index 4cf65f5c6a74f5697d7411391207cdcd5431e1ea..2d0dc3efe8137452f2ebfa194e84ff157573e66d 100644 (file)
@@ -249,7 +249,6 @@ static inline void mask_ack_irq(struct irq_desc *desc, int irq)
  *     handle_simple_irq - Simple and software-decoded IRQs.
  *     @irq:   the interrupt number
  *     @desc:  the interrupt description structure for this irq
- *     @regs:  pointer to a register structure
  *
  *     Simple interrupts are either sent from a demultiplexing interrupt
  *     handler or come from hardware, where no interrupt hardware control
@@ -259,7 +258,7 @@ static inline void mask_ack_irq(struct irq_desc *desc, int irq)
  *     unmask issues if necessary.
  */
 void fastcall
-handle_simple_irq(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs)
+handle_simple_irq(unsigned int irq, struct irq_desc *desc)
 {
        struct irqaction *action;
        irqreturn_t action_ret;
@@ -279,9 +278,9 @@ handle_simple_irq(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs)
        desc->status |= IRQ_INPROGRESS;
        spin_unlock(&desc->lock);
 
-       action_ret = handle_IRQ_event(irq, regs, action);
+       action_ret = handle_IRQ_event(irq, action);
        if (!noirqdebug)
-               note_interrupt(irq, desc, action_ret, regs);
+               note_interrupt(irq, desc, action_ret);
 
        spin_lock(&desc->lock);
        desc->status &= ~IRQ_INPROGRESS;
@@ -293,7 +292,6 @@ out_unlock:
  *     handle_level_irq - Level type irq handler
  *     @irq:   the interrupt number
  *     @desc:  the interrupt description structure for this irq
- *     @regs:  pointer to a register structure
  *
  *     Level type interrupts are active as long as the hardware line has
  *     the active level. This may require to mask the interrupt and unmask
@@ -301,7 +299,7 @@ out_unlock:
  *     interrupt line is back to inactive.
  */
 void fastcall
-handle_level_irq(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs)
+handle_level_irq(unsigned int irq, struct irq_desc *desc)
 {
        unsigned int cpu = smp_processor_id();
        struct irqaction *action;
@@ -329,9 +327,9 @@ handle_level_irq(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs)
        desc->status &= ~IRQ_PENDING;
        spin_unlock(&desc->lock);
 
-       action_ret = handle_IRQ_event(irq, regs, action);
+       action_ret = handle_IRQ_event(irq, action);
        if (!noirqdebug)
-               note_interrupt(irq, desc, action_ret, regs);
+               note_interrupt(irq, desc, action_ret);
 
        spin_lock(&desc->lock);
        desc->status &= ~IRQ_INPROGRESS;
@@ -345,7 +343,6 @@ out_unlock:
  *     handle_fasteoi_irq - irq handler for transparent controllers
  *     @irq:   the interrupt number
  *     @desc:  the interrupt description structure for this irq
- *     @regs:  pointer to a register structure
  *
  *     Only a single callback will be issued to the chip: an ->eoi()
  *     call when the interrupt has been serviced. This enables support
@@ -353,8 +350,7 @@ out_unlock:
  *     details in hardware, transparently.
  */
 void fastcall
-handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc,
-                  struct pt_regs *regs)
+handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc)
 {
        unsigned int cpu = smp_processor_id();
        struct irqaction *action;
@@ -382,9 +378,9 @@ handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc,
        desc->status &= ~IRQ_PENDING;
        spin_unlock(&desc->lock);
 
-       action_ret = handle_IRQ_event(irq, regs, action);
+       action_ret = handle_IRQ_event(irq, action);
        if (!noirqdebug)
-               note_interrupt(irq, desc, action_ret, regs);
+               note_interrupt(irq, desc, action_ret);
 
        spin_lock(&desc->lock);
        desc->status &= ~IRQ_INPROGRESS;
@@ -398,7 +394,6 @@ out:
  *     handle_edge_irq - edge type IRQ handler
  *     @irq:   the interrupt number
  *     @desc:  the interrupt description structure for this irq
- *     @regs:  pointer to a register structure
  *
  *     Interrupt occures on the falling and/or rising edge of a hardware
  *     signal. The occurence is latched into the irq controller hardware
@@ -412,7 +407,7 @@ out:
  *     loop is left.
  */
 void fastcall
-handle_edge_irq(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs)
+handle_edge_irq(unsigned int irq, struct irq_desc *desc)
 {
        const unsigned int cpu = smp_processor_id();
 
@@ -463,9 +458,9 @@ handle_edge_irq(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs)
 
                desc->status &= ~IRQ_PENDING;
                spin_unlock(&desc->lock);
-               action_ret = handle_IRQ_event(irq, regs, action);
+               action_ret = handle_IRQ_event(irq, action);
                if (!noirqdebug)
-                       note_interrupt(irq, desc, action_ret, regs);
+                       note_interrupt(irq, desc, action_ret);
                spin_lock(&desc->lock);
 
        } while ((desc->status & (IRQ_PENDING | IRQ_DISABLED)) == IRQ_PENDING);
@@ -480,12 +475,11 @@ out_unlock:
  *     handle_percpu_IRQ - Per CPU local irq handler
  *     @irq:   the interrupt number
  *     @desc:  the interrupt description structure for this irq
- *     @regs:  pointer to a register structure
  *
  *     Per CPU interrupts on SMP machines without locking requirements
  */
 void fastcall
-handle_percpu_irq(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs)
+handle_percpu_irq(unsigned int irq, struct irq_desc *desc)
 {
        irqreturn_t action_ret;
 
@@ -494,9 +488,9 @@ handle_percpu_irq(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs)
        if (desc->chip->ack)
                desc->chip->ack(irq);
 
-       action_ret = handle_IRQ_event(irq, regs, desc->action);
+       action_ret = handle_IRQ_event(irq, desc->action);
        if (!noirqdebug)
-               note_interrupt(irq, desc, action_ret, regs);
+               note_interrupt(irq, desc, action_ret);
 
        if (desc->chip->eoi)
                desc->chip->eoi(irq);
@@ -505,10 +499,8 @@ handle_percpu_irq(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs)
 #endif /* CONFIG_SMP */
 
 void
-__set_irq_handler(unsigned int irq,
-                 void fastcall (*handle)(unsigned int, irq_desc_t *,
-                                         struct pt_regs *),
-                 int is_chained)
+__set_irq_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
+                 const char *name)
 {
        struct irq_desc *desc;
        unsigned long flags;
@@ -549,6 +541,7 @@ __set_irq_handler(unsigned int irq,
                desc->depth = 1;
        }
        desc->handle_irq = handle;
+       desc->name = name;
 
        if (handle != handle_bad_irq && is_chained) {
                desc->status &= ~IRQ_DISABLED;
@@ -561,36 +554,16 @@ __set_irq_handler(unsigned int irq,
 
 void
 set_irq_chip_and_handler(unsigned int irq, struct irq_chip *chip,
-                        void fastcall (*handle)(unsigned int,
-                                                struct irq_desc *,
-                                                struct pt_regs *))
+                        irq_flow_handler_t handle)
 {
        set_irq_chip(irq, chip);
-       __set_irq_handler(irq, handle, 0);
+       __set_irq_handler(irq, handle, 0, NULL);
 }
 
-/*
- * Get a descriptive string for the highlevel handler, for
- * /proc/interrupts output:
- */
-const char *
-handle_irq_name(void fastcall (*handle)(unsigned int, struct irq_desc *,
-                                       struct pt_regs *))
+void
+set_irq_chip_and_handler_name(unsigned int irq, struct irq_chip *chip,
+                             irq_flow_handler_t handle, const char *name)
 {
-       if (handle == handle_level_irq)
-               return "level  ";
-       if (handle == handle_fasteoi_irq)
-               return "fasteoi";
-       if (handle == handle_edge_irq)
-               return "edge   ";
-       if (handle == handle_simple_irq)
-               return "simple ";
-#ifdef CONFIG_SMP
-       if (handle == handle_percpu_irq)
-               return "percpu ";
-#endif
-       if (handle == handle_bad_irq)
-               return "bad    ";
-
-       return NULL;
+       set_irq_chip(irq, chip);
+       __set_irq_handler(irq, handle, 0, name);
 }
index 4c6cdbaed6617a5a0da7b7b39a43fa65a150e572..42aa6f1a3f0f95e7dce8be2480ab5d209c881db3 100644 (file)
@@ -27,7 +27,7 @@
  * Handles spurious and unhandled IRQ's. It also prints a debugmessage.
  */
 void fastcall
-handle_bad_irq(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs)
+handle_bad_irq(unsigned int irq, struct irq_desc *desc)
 {
        print_irq_desc(irq, desc);
        kstat_this_cpu.irqs[irq]++;
@@ -115,7 +115,7 @@ struct irq_chip dummy_irq_chip = {
 /*
  * Special, empty irq handler:
  */
-irqreturn_t no_action(int cpl, void *dev_id, struct pt_regs *regs)
+irqreturn_t no_action(int cpl, void *dev_id)
 {
        return IRQ_NONE;
 }
@@ -123,13 +123,11 @@ irqreturn_t no_action(int cpl, void *dev_id, struct pt_regs *regs)
 /**
  * handle_IRQ_event - irq action chain handler
  * @irq:       the interrupt number
- * @regs:      pointer to a register structure
  * @action:    the interrupt action chain for this irq
  *
  * Handles the action chain of an irq event
  */
-irqreturn_t handle_IRQ_event(unsigned int irq, struct pt_regs *regs,
-                            struct irqaction *action)
+irqreturn_t handle_IRQ_event(unsigned int irq, struct irqaction *action)
 {
        irqreturn_t ret, retval = IRQ_NONE;
        unsigned int status = 0;
@@ -140,7 +138,7 @@ irqreturn_t handle_IRQ_event(unsigned int irq, struct pt_regs *regs,
                local_irq_enable_in_hardirq();
 
        do {
-               ret = action->handler(irq, action->dev_id, regs);
+               ret = action->handler(irq, action->dev_id);
                if (ret == IRQ_HANDLED)
                        status |= action->flags;
                retval |= ret;
@@ -158,7 +156,6 @@ irqreturn_t handle_IRQ_event(unsigned int irq, struct pt_regs *regs,
 /**
  * __do_IRQ - original all in one highlevel IRQ handler
  * @irq:       the interrupt number
- * @regs:      pointer to a register structure
  *
  * __do_IRQ handles all normal device IRQ's (the special
  * SMP cross-CPU interrupts have their own specific
@@ -167,7 +164,7 @@ irqreturn_t handle_IRQ_event(unsigned int irq, struct pt_regs *regs,
  * This is the original x86 implementation which is used for every
  * interrupt type.
  */
-fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs)
+fastcall unsigned int __do_IRQ(unsigned int irq)
 {
        struct irq_desc *desc = irq_desc + irq;
        struct irqaction *action;
@@ -182,7 +179,7 @@ fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs)
                 */
                if (desc->chip->ack)
                        desc->chip->ack(irq);
-               action_ret = handle_IRQ_event(irq, regs, desc->action);
+               action_ret = handle_IRQ_event(irq, desc->action);
                desc->chip->end(irq);
                return 1;
        }
@@ -233,11 +230,11 @@ fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs)
 
                spin_unlock(&desc->lock);
 
-               action_ret = handle_IRQ_event(irq, regs, action);
+               action_ret = handle_IRQ_event(irq, action);
 
                spin_lock(&desc->lock);
                if (!noirqdebug)
-                       note_interrupt(irq, desc, action_ret, regs);
+                       note_interrupt(irq, desc, action_ret);
                if (likely(!(desc->status & IRQ_PENDING)))
                        break;
                desc->status &= ~IRQ_PENDING;
index 92be519eff26fe3fd467eb6ca0e3e063a36f50ce..6879202afe9a3c2d49b5b81ee187a151ce4f7e55 100644 (file)
@@ -427,8 +427,7 @@ EXPORT_SYMBOL(free_irq);
  *     IRQF_SAMPLE_RANDOM      The interrupt can be used for entropy
  *
  */
-int request_irq(unsigned int irq,
-               irqreturn_t (*handler)(int, void *, struct pt_regs *),
+int request_irq(unsigned int irq, irq_handler_t handler,
                unsigned long irqflags, const char *devname, void *dev_id)
 {
        struct irqaction *action;
@@ -475,4 +474,3 @@ int request_irq(unsigned int irq,
        return retval;
 }
 EXPORT_SYMBOL(request_irq);
-
index 607c7809ad0125e7aad8d28a308319601a7223ea..9a352667007ce52fe610c7c72cc190772cb126dd 100644 (file)
@@ -57,7 +57,7 @@ static int irq_affinity_write_proc(struct file *file, const char __user *buffer,
        if (!irq_desc[irq].chip->set_affinity || no_irq_affinity)
                return -EIO;
 
-       err = cpumask_parse(buffer, count, new_value);
+       err = cpumask_parse_user(buffer, count, new_value);
        if (err)
                return err;
 
index 35f10f7ff94aec43957fa71e7e97cf8f67b22b73..5bfeaed7e4872850049d40aef740d24b983adebf 100644 (file)
@@ -38,7 +38,7 @@ static void resend_irqs(unsigned long arg)
                clear_bit(irq, irqs_resend);
                desc = irq_desc + irq;
                local_irq_disable();
-               desc->handle_irq(irq, desc, NULL);
+               desc->handle_irq(irq, desc);
                local_irq_enable();
        }
 }
index 417e98092cf20a6e843c6ae973a6ee4c216cd435..543ea2e5ad9301944ab520303bd7fe84e4e92f88 100644 (file)
@@ -16,7 +16,7 @@ static int irqfixup __read_mostly;
 /*
  * Recovery handler for misrouted interrupts.
  */
-static int misrouted_irq(int irq, struct pt_regs *regs)
+static int misrouted_irq(int irq)
 {
        int i;
        int ok = 0;
@@ -49,7 +49,7 @@ static int misrouted_irq(int irq, struct pt_regs *regs)
                while (action) {
                        /* Only shared IRQ handlers are safe to call */
                        if (action->flags & IRQF_SHARED) {
-                               if (action->handler(i, action->dev_id, regs) ==
+                               if (action->handler(i, action->dev_id) ==
                                                IRQ_HANDLED)
                                        ok = 1;
                        }
@@ -70,7 +70,7 @@ static int misrouted_irq(int irq, struct pt_regs *regs)
                         */
                        work = 1;
                        spin_unlock(&desc->lock);
-                       handle_IRQ_event(i, regs, action);
+                       handle_IRQ_event(i, action);
                        spin_lock(&desc->lock);
                        desc->status &= ~IRQ_PENDING;
                }
@@ -136,7 +136,7 @@ report_bad_irq(unsigned int irq, struct irq_desc *desc, irqreturn_t action_ret)
 }
 
 void note_interrupt(unsigned int irq, struct irq_desc *desc,
-                   irqreturn_t action_ret, struct pt_regs *regs)
+                   irqreturn_t action_ret)
 {
        if (unlikely(action_ret != IRQ_HANDLED)) {
                desc->irqs_unhandled++;
@@ -147,7 +147,7 @@ void note_interrupt(unsigned int irq, struct irq_desc *desc,
        if (unlikely(irqfixup)) {
                /* Don't punish working computers */
                if ((irqfixup == 2 && irq == 0) || action_ret == IRQ_NONE) {
-                       int ok = misrouted_irq(irq, regs);
+                       int ok = misrouted_irq(irq);
                        if (action_ret == IRQ_NONE)
                                desc->irqs_unhandled -= ok;
                }
index 4c0553461000360e4f4cb459bde0d289f9f89b97..b739be2a6dc9adff9eb6a471a0044bbeedb54976 100644 (file)
@@ -575,6 +575,8 @@ static noinline int print_circular_bug_tail(void)
        return 0;
 }
 
+#define RECURSION_LIMIT 40
+
 static int noinline print_infinite_recursion_bug(void)
 {
        __raw_spin_unlock(&hash_lock);
@@ -595,7 +597,7 @@ check_noncircular(struct lock_class *source, unsigned int depth)
        debug_atomic_inc(&nr_cyclic_check_recursions);
        if (depth > max_recursion_depth)
                max_recursion_depth = depth;
-       if (depth >= 20)
+       if (depth >= RECURSION_LIMIT)
                return print_infinite_recursion_bug();
        /*
         * Check this lock's dependency list:
@@ -645,7 +647,7 @@ find_usage_forwards(struct lock_class *source, unsigned int depth)
 
        if (depth > max_recursion_depth)
                max_recursion_depth = depth;
-       if (depth >= 20)
+       if (depth >= RECURSION_LIMIT)
                return print_infinite_recursion_bug();
 
        debug_atomic_inc(&nr_find_usage_forwards_checks);
@@ -684,7 +686,7 @@ find_usage_backwards(struct lock_class *source, unsigned int depth)
 
        if (depth > max_recursion_depth)
                max_recursion_depth = depth;
-       if (depth >= 20)
+       if (depth >= RECURSION_LIMIT)
                return print_infinite_recursion_bug();
 
        debug_atomic_inc(&nr_find_usage_backwards_checks);
@@ -1114,8 +1116,6 @@ static int count_matching_names(struct lock_class *new_class)
        return count + 1;
 }
 
-extern void __error_too_big_MAX_LOCKDEP_SUBCLASSES(void);
-
 /*
  * Register a lock's class in the hash-table, if the class is not present
  * yet. Otherwise we look it up. We cache the result in the lock object
@@ -1153,8 +1153,7 @@ look_up_lock_class(struct lockdep_map *lock, unsigned int subclass)
         * (or spin_lock_init()) call - which acts as the key. For static
         * locks we use the lock object itself as the key.
         */
-       if (sizeof(struct lock_class_key) > sizeof(struct lock_class))
-               __error_too_big_MAX_LOCKDEP_SUBCLASSES();
+       BUILD_BUG_ON(sizeof(struct lock_class_key) > sizeof(struct lock_class));
 
        key = lock->key->subkeys + subclass;
 
@@ -1177,7 +1176,7 @@ look_up_lock_class(struct lockdep_map *lock, unsigned int subclass)
  * itself, so actual lookup of the hash should be once per lock object.
  */
 static inline struct lock_class *
-register_lock_class(struct lockdep_map *lock, unsigned int subclass)
+register_lock_class(struct lockdep_map *lock, unsigned int subclass, int force)
 {
        struct lockdep_subclass_key *key;
        struct list_head *hash_head;
@@ -1249,7 +1248,7 @@ register_lock_class(struct lockdep_map *lock, unsigned int subclass)
 out_unlock_set:
        __raw_spin_unlock(&hash_lock);
 
-       if (!subclass)
+       if (!subclass || force)
                lock->class_cache = class;
 
        DEBUG_LOCKS_WARN_ON(class->subclass != subclass);
@@ -1937,7 +1936,7 @@ void trace_softirqs_off(unsigned long ip)
  * Initialize a lock instance's lock-class mapping info:
  */
 void lockdep_init_map(struct lockdep_map *lock, const char *name,
-                     struct lock_class_key *key)
+                     struct lock_class_key *key, int subclass)
 {
        if (unlikely(!debug_locks))
                return;
@@ -1957,6 +1956,8 @@ void lockdep_init_map(struct lockdep_map *lock, const char *name,
        lock->name = name;
        lock->key = key;
        lock->class_cache = NULL;
+       if (subclass)
+               register_lock_class(lock, subclass, 1);
 }
 
 EXPORT_SYMBOL_GPL(lockdep_init_map);
@@ -1995,7 +1996,7 @@ static int __lock_acquire(struct lockdep_map *lock, unsigned int subclass,
         * Not cached yet or subclass?
         */
        if (unlikely(!class)) {
-               class = register_lock_class(lock, subclass);
+               class = register_lock_class(lock, subclass, 0);
                if (!class)
                        return 0;
        }
index 7f60e782de1e49fdfbcc96374e39898920cea94a..67009bd56c522b634d35a9b8c2852228b4b29730 100644 (file)
@@ -87,6 +87,12 @@ static inline int strong_try_module_get(struct module *mod)
        return try_module_get(mod);
 }
 
+static inline void add_taint_module(struct module *mod, unsigned flag)
+{
+       add_taint(flag);
+       mod->taints |= flag;
+}
+
 /* A thread that wants to hold a reference to a module only while it
  * is running can call ths to safely exit.
  * nfsd and lockd use this.
@@ -847,12 +853,10 @@ static int check_version(Elf_Shdr *sechdrs,
                return 0;
        }
        /* Not in module's version table.  OK, but that taints the kernel. */
-       if (!(tainted & TAINT_FORCED_MODULE)) {
+       if (!(tainted & TAINT_FORCED_MODULE))
                printk("%s: no version for \"%s\" found: kernel tainted.\n",
                       mod->name, symname);
-               add_taint(TAINT_FORCED_MODULE);
-               mod->taints |= TAINT_FORCED_MODULE;
-       }
+       add_taint_module(mod, TAINT_FORCED_MODULE);
        return 1;
 }
 
@@ -910,7 +914,8 @@ static unsigned long resolve_symbol(Elf_Shdr *sechdrs,
        unsigned long ret;
        const unsigned long *crc;
 
-       ret = __find_symbol(name, &owner, &crc, mod->license_gplok);
+       ret = __find_symbol(name, &owner, &crc,
+                       !(mod->taints & TAINT_PROPRIETARY_MODULE));
        if (ret) {
                /* use_module can fail due to OOM, or module unloading */
                if (!check_version(sechdrs, versindex, name, mod, crc) ||
@@ -1335,12 +1340,11 @@ static void set_license(struct module *mod, const char *license)
        if (!license)
                license = "unspecified";
 
-       mod->license_gplok = license_is_gpl_compatible(license);
-       if (!mod->license_gplok && !(tainted & TAINT_PROPRIETARY_MODULE)) {
-               printk(KERN_WARNING "%s: module license '%s' taints kernel.\n",
-                      mod->name, license);
-               add_taint(TAINT_PROPRIETARY_MODULE);
-               mod->taints |= TAINT_PROPRIETARY_MODULE;
+       if (!license_is_gpl_compatible(license)) {
+               if (!(tainted & TAINT_PROPRIETARY_MODULE))
+                       printk(KERN_WARNING "%s: module license '%s' taints"
+                               "kernel.\n", mod->name, license);
+               add_taint_module(mod, TAINT_PROPRIETARY_MODULE);
        }
 }
 
@@ -1619,8 +1623,7 @@ static struct module *load_module(void __user *umod,
        modmagic = get_modinfo(sechdrs, infoindex, "vermagic");
        /* This is allowed: modprobe --force will invalidate it. */
        if (!modmagic) {
-               add_taint(TAINT_FORCED_MODULE);
-               mod->taints |= TAINT_FORCED_MODULE;
+               add_taint_module(mod, TAINT_FORCED_MODULE);
                printk(KERN_WARNING "%s: no version magic, tainting kernel.\n",
                       mod->name);
        } else if (!same_magic(modmagic, vermagic)) {
@@ -1714,14 +1717,10 @@ static struct module *load_module(void __user *umod,
        /* Set up license info based on the info section */
        set_license(mod, get_modinfo(sechdrs, infoindex, "license"));
 
-       if (strcmp(mod->name, "ndiswrapper") == 0) {
-               add_taint(TAINT_PROPRIETARY_MODULE);
-               mod->taints |= TAINT_PROPRIETARY_MODULE;
-       }
-       if (strcmp(mod->name, "driverloader") == 0) {
-               add_taint(TAINT_PROPRIETARY_MODULE);
-               mod->taints |= TAINT_PROPRIETARY_MODULE;
-       }
+       if (strcmp(mod->name, "ndiswrapper") == 0)
+               add_taint_module(mod, TAINT_PROPRIETARY_MODULE);
+       if (strcmp(mod->name, "driverloader") == 0)
+               add_taint_module(mod, TAINT_PROPRIETARY_MODULE);
 
        /* Set up MODINFO_ATTR fields */
        setup_modinfo(mod, sechdrs, infoindex);
@@ -1766,8 +1765,7 @@ static struct module *load_module(void __user *umod,
            (mod->num_unused_gpl_syms && !unusedgplcrcindex)) {
                printk(KERN_WARNING "%s: No versions for exported symbols."
                       " Tainting kernel.\n", mod->name);
-               add_taint(TAINT_FORCED_MODULE);
-               mod->taints |= TAINT_FORCED_MODULE;
+               add_taint_module(mod, TAINT_FORCED_MODULE);
        }
 #endif
 
@@ -2132,9 +2130,33 @@ static void m_stop(struct seq_file *m, void *p)
        mutex_unlock(&module_mutex);
 }
 
+static char *taint_flags(unsigned int taints, char *buf)
+{
+       int bx = 0;
+
+       if (taints) {
+               buf[bx++] = '(';
+               if (taints & TAINT_PROPRIETARY_MODULE)
+                       buf[bx++] = 'P';
+               if (taints & TAINT_FORCED_MODULE)
+                       buf[bx++] = 'F';
+               /*
+                * TAINT_FORCED_RMMOD: could be added.
+                * TAINT_UNSAFE_SMP, TAINT_MACHINE_CHECK, TAINT_BAD_PAGE don't
+                * apply to modules.
+                */
+               buf[bx++] = ')';
+       }
+       buf[bx] = '\0';
+
+       return buf;
+}
+
 static int m_show(struct seq_file *m, void *p)
 {
        struct module *mod = list_entry(p, struct module, list);
+       char buf[8];
+
        seq_printf(m, "%s %lu",
                   mod->name, mod->init_size + mod->core_size);
        print_unload_info(m, mod);
@@ -2147,6 +2169,10 @@ static int m_show(struct seq_file *m, void *p)
        /* Used by oprofile and other similar tools. */
        seq_printf(m, " 0x%p", mod->module_core);
 
+       /* Taints info */
+       if (mod->taints)
+               seq_printf(m, " %s", taint_flags(mod->taints, buf));
+
        seq_printf(m, "\n");
        return 0;
 }
@@ -2235,28 +2261,6 @@ struct module *module_text_address(unsigned long addr)
        return mod;
 }
 
-static char *taint_flags(unsigned int taints, char *buf)
-{
-       *buf = '\0';
-       if (taints) {
-               int bx;
-
-               buf[0] = '(';
-               bx = 1;
-               if (taints & TAINT_PROPRIETARY_MODULE)
-                       buf[bx++] = 'P';
-               if (taints & TAINT_FORCED_MODULE)
-                       buf[bx++] = 'F';
-               /*
-                * TAINT_FORCED_RMMOD: could be added.
-                * TAINT_UNSAFE_SMP, TAINT_MACHINE_CHECK, TAINT_BAD_PAGE don't
-                * apply to modules.
-                */
-               buf[bx] = ')';
-       }
-       return buf;
-}
-
 /* Don't grab lock, we're oopsing. */
 void print_modules(void)
 {
index e3203c654dda80ab646ffcbd4b0306e942fde846..18651641a7b5aa6482e0aa73ce03b5133e6ffa91 100644 (file)
@@ -91,7 +91,7 @@ void debug_mutex_init(struct mutex *lock, const char *name,
         * Make sure we are not reinitializing a held lock:
         */
        debug_check_no_locks_freed((void *)lock, sizeof(*lock));
-       lockdep_init_map(&lock->dep_map, name, key);
+       lockdep_init_map(&lock->dep_map, name, key, 0);
 #endif
        lock->owner = NULL;
        lock->magic = lock;
index 6ebdb82a0ce43a5211e3862008959cb5091febcd..674aceb7335ad56f7a2a8ba2996d0faa4ed850db 100644 (file)
@@ -44,11 +44,9 @@ static inline struct nsproxy *clone_namespaces(struct nsproxy *orig)
 {
        struct nsproxy *ns;
 
-       ns = kmalloc(sizeof(struct nsproxy), GFP_KERNEL);
-       if (ns) {
-               memcpy(ns, orig, sizeof(struct nsproxy));
+       ns = kmemdup(orig, sizeof(struct nsproxy), GFP_KERNEL);
+       if (ns)
                atomic_set(&ns->count, 1);
-       }
        return ns;
 }
 
index 479b16b44f79f6b639683c724405f51b3ecc156f..7c3e1e6dfb5b5eef84f61f6259e764703846d9fd 100644 (file)
@@ -87,6 +87,19 @@ static inline union cpu_time_count cpu_time_sub(const clockid_t which_clock,
        return a;
 }
 
+/*
+ * Divide and limit the result to res >= 1
+ *
+ * This is necessary to prevent signal delivery starvation, when the result of
+ * the division would be rounded down to 0.
+ */
+static inline cputime_t cputime_div_non_zero(cputime_t time, unsigned long div)
+{
+       cputime_t res = cputime_div(time, div);
+
+       return max_t(cputime_t, res, 1);
+}
+
 /*
  * Update expiry time from increment, and increase overrun count,
  * given the current clock sample.
@@ -483,8 +496,8 @@ static void process_timer_rebalance(struct task_struct *p,
                BUG();
                break;
        case CPUCLOCK_PROF:
-               left = cputime_div(cputime_sub(expires.cpu, val.cpu),
-                                  nthreads);
+               left = cputime_div_non_zero(cputime_sub(expires.cpu, val.cpu),
+                                      nthreads);
                do {
                        if (likely(!(t->flags & PF_EXITING))) {
                                ticks = cputime_add(prof_ticks(t), left);
@@ -498,8 +511,8 @@ static void process_timer_rebalance(struct task_struct *p,
                } while (t != p);
                break;
        case CPUCLOCK_VIRT:
-               left = cputime_div(cputime_sub(expires.cpu, val.cpu),
-                                  nthreads);
+               left = cputime_div_non_zero(cputime_sub(expires.cpu, val.cpu),
+                                      nthreads);
                do {
                        if (likely(!(t->flags & PF_EXITING))) {
                                ticks = cputime_add(virt_ticks(t), left);
@@ -515,6 +528,7 @@ static void process_timer_rebalance(struct task_struct *p,
        case CPUCLOCK_SCHED:
                nsleft = expires.sched - val.sched;
                do_div(nsleft, nthreads);
+               nsleft = max_t(unsigned long long, nsleft, 1);
                do {
                        if (likely(!(t->flags & PF_EXITING))) {
                                ns = t->sched_time + nsleft;
@@ -1159,12 +1173,13 @@ static void check_process_timers(struct task_struct *tsk,
 
                prof_left = cputime_sub(prof_expires, utime);
                prof_left = cputime_sub(prof_left, stime);
-               prof_left = cputime_div(prof_left, nthreads);
+               prof_left = cputime_div_non_zero(prof_left, nthreads);
                virt_left = cputime_sub(virt_expires, utime);
-               virt_left = cputime_div(virt_left, nthreads);
+               virt_left = cputime_div_non_zero(virt_left, nthreads);
                if (sched_expires) {
                        sched_left = sched_expires - sched_time;
                        do_div(sched_left, nthreads);
+                       sched_left = max_t(unsigned long long, sched_left, 1);
                } else {
                        sched_left = 0;
                }
index d72234942798e6606d613cf6c99d5fc72ab40c09..d3a158a60312187242c8e1238b68ac5151d11459 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/fs.h>
 #include <linux/mount.h>
 #include <linux/pm.h>
+#include <linux/console.h>
 #include <linux/cpu.h>
 
 #include "power.h"
@@ -119,8 +120,10 @@ int pm_suspend_disk(void)
        if (error)
                return error;
 
+       suspend_console();
        error = device_suspend(PMSG_FREEZE);
        if (error) {
+               resume_console();
                printk("Some devices failed to suspend\n");
                unprepare_processes();
                return error;
@@ -133,6 +136,7 @@ int pm_suspend_disk(void)
 
        if (in_suspend) {
                device_resume();
+               resume_console();
                pr_debug("PM: writing image.\n");
                error = swsusp_write();
                if (!error)
@@ -148,6 +152,7 @@ int pm_suspend_disk(void)
        swsusp_free();
  Done:
        device_resume();
+       resume_console();
        unprepare_processes();
        return error;
 }
@@ -212,7 +217,9 @@ static int software_resume(void)
 
        pr_debug("PM: Preparing devices for restore.\n");
 
+       suspend_console();
        if ((error = device_suspend(PMSG_PRETHAW))) {
+               resume_console();
                printk("Some devices failed to suspend\n");
                swsusp_free();
                goto Thaw;
@@ -224,6 +231,7 @@ static int software_resume(void)
        swsusp_resume();
        pr_debug("PM: Restore failed, recovering.n");
        device_resume();
+       resume_console();
  Thaw:
        unprepare_processes();
  Done:
index 7a4144ba3afd41a070ab340cab472dfe50f19978..f1f900ac31640c2072778e9a4ece504fe8200d68 100644 (file)
@@ -23,8 +23,7 @@ static void do_poweroff(void *dummy)
 
 static DECLARE_WORK(poweroff_work, do_poweroff, NULL);
 
-static void handle_poweroff(int key, struct pt_regs *pt_regs,
-                               struct tty_struct *tty)
+static void handle_poweroff(int key, struct tty_struct *tty)
 {
        schedule_work(&poweroff_work);
 }
index 9b2ee5344dee10b51ae4f0d1fda84b1aa99d3de4..1a3b0dd2c3fcc18b2db25fc7472560cb67edfb7e 100644 (file)
@@ -425,7 +425,8 @@ static int submit(int rw, pgoff_t page_off, struct page *page,
                        bio_set_pages_dirty(bio);
                bio_put(bio);
        } else {
-               get_page(page);
+               if (rw == READ)
+                       get_page(page); /* These pages are freed later */
                bio->bi_private = *bio_chain;
                *bio_chain = bio;
                submit_bio(rw | (1 << BIO_RW_SYNC), bio);
index 72825c853cd7251bf73fa13cbea63e78c09d8845..d991d3b0e5a4e326ea29b6b7fc50c4a926dd5e3e 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/swapops.h>
 #include <linux/pm.h>
 #include <linux/fs.h>
+#include <linux/console.h>
 #include <linux/cpu.h>
 
 #include <asm/uaccess.h>
@@ -145,10 +146,10 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
                        error = freeze_processes();
                        if (error) {
                                thaw_processes();
+                               enable_nonboot_cpus();
                                error = -EBUSY;
                        }
                }
-               enable_nonboot_cpus();
                up(&pm_sem);
                if (!error)
                        data->frozen = 1;
@@ -173,12 +174,14 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
                /* Free memory before shutting down devices. */
                error = swsusp_shrink_memory();
                if (!error) {
+                       suspend_console();
                        error = device_suspend(PMSG_FREEZE);
                        if (!error) {
                                in_suspend = 1;
                                error = swsusp_suspend();
                                device_resume();
                        }
+                       resume_console();
                }
                up(&pm_sem);
                if (!error)
@@ -196,11 +199,13 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
                snapshot_free_unused_memory(&data->handle);
                down(&pm_sem);
                pm_prepare_console();
+               suspend_console();
                error = device_suspend(PMSG_PRETHAW);
                if (!error) {
                        error = swsusp_resume();
                        device_resume();
                }
+               resume_console();
                pm_restore_console();
                up(&pm_sem);
                break;
@@ -289,6 +294,7 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
                }
 
                /* Put devices to sleep */
+               suspend_console();
                error = device_suspend(PMSG_SUSPEND);
                if (error) {
                        printk(KERN_ERR "Failed to suspend some devices.\n");
@@ -299,7 +305,7 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
                        /* Wake up devices */
                        device_resume();
                }
-
+               resume_console();
                if (pm_ops->finish)
                        pm_ops->finish(PM_SUSPEND_MEM);
 
index 771f5e861bcd38af1d5d7f91666b2413b1d4008b..f7d427ef50385d70db6a0222ea3c53a0d8738d03 100644 (file)
@@ -820,15 +820,8 @@ void release_console_sem(void)
        console_locked = 0;
        up(&console_sem);
        spin_unlock_irqrestore(&logbuf_lock, flags);
-       if (wake_klogd && !oops_in_progress && waitqueue_active(&log_wait)) {
-               /*
-                * If we printk from within the lock dependency code,
-                * from within the scheduler code, then do not lock
-                * up due to self-recursion:
-                */
-               if (!lockdep_internal())
-                       wake_up_interruptible(&log_wait);
-       }
+       if (wake_klogd && !oops_in_progress && waitqueue_active(&log_wait))
+               wake_up_interruptible(&log_wait);
 }
 EXPORT_SYMBOL(release_console_sem);
 
index fb660c7d35baa3aea34abe194d78650070f09f0a..f940b462eec9a34eb7c3cad4ee958a2ec0f1f5bc 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/mutex.h>
 #include <asm/sections.h>
 #include <asm/semaphore.h>
+#include <asm/irq_regs.h>
 
 struct profile_hit {
        u32 pc, hits;
@@ -366,8 +367,10 @@ void profile_hit(int type, void *__pc)
 }
 #endif /* !CONFIG_SMP */
 
-void profile_tick(int type, struct pt_regs *regs)
+void profile_tick(int type)
 {
+       struct pt_regs *regs = get_irq_regs();
+
        if (type == CPU_PROFILING && timer_hook)
                timer_hook(regs);
        if (!user_mode(regs) && cpu_isset(smp_processor_id(), prof_cpu_mask))
@@ -396,7 +399,7 @@ static int prof_cpu_mask_write_proc (struct file *file, const char __user *buffe
        unsigned long full_count = count, err;
        cpumask_t new_value;
 
-       err = cpumask_parse(buffer, count, new_value);
+       err = cpumask_parse_user(buffer, count, new_value);
        if (err)
                return err;
 
index 1d63ecddfa7018cd4a14f8b6dc24c352a9ddc447..f04bbdb56ac2a9123003b45d909f9ef6e971fd5e 100644 (file)
@@ -887,7 +887,7 @@ static int subbuf_read_actor(size_t read_start,
 
        from = buf->start + read_start;
        ret = avail;
-       if (copy_to_user(desc->arg.data, from, avail)) {
+       if (copy_to_user(desc->arg.buf, from, avail)) {
                desc->error = -EFAULT;
                ret = 0;
        }
@@ -946,24 +946,17 @@ typedef int (*subbuf_actor_t) (size_t read_start,
  */
 static inline ssize_t relay_file_read_subbufs(struct file *filp,
                                              loff_t *ppos,
-                                             size_t count,
                                              subbuf_actor_t subbuf_actor,
                                              read_actor_t actor,
-                                             void *target)
+                                             read_descriptor_t *desc)
 {
        struct rchan_buf *buf = filp->private_data;
        size_t read_start, avail;
-       read_descriptor_t desc;
        int ret;
 
-       if (!count)
+       if (!desc->count)
                return 0;
 
-       desc.written = 0;
-       desc.count = count;
-       desc.arg.data = target;
-       desc.error = 0;
-
        mutex_lock(&filp->f_dentry->d_inode->i_mutex);
        do {
                if (!relay_file_read_avail(buf, *ppos))
@@ -974,19 +967,19 @@ static inline ssize_t relay_file_read_subbufs(struct file *filp,
                if (!avail)
                        break;
 
-               avail = min(desc.count, avail);
-               ret = subbuf_actor(read_start, buf, avail, &desc, actor);
-               if (desc.error < 0)
+               avail = min(desc->count, avail);
+               ret = subbuf_actor(read_start, buf, avail, desc, actor);
+               if (desc->error < 0)
                        break;
 
                if (ret) {
                        relay_file_read_consume(buf, read_start, ret);
                        *ppos = relay_file_read_end_pos(buf, read_start, ret);
                }
-       } while (desc.count && ret);
+       } while (desc->count && ret);
        mutex_unlock(&filp->f_dentry->d_inode->i_mutex);
 
-       return desc.written;
+       return desc->written;
 }
 
 static ssize_t relay_file_read(struct file *filp,
@@ -994,8 +987,13 @@ static ssize_t relay_file_read(struct file *filp,
                               size_t count,
                               loff_t *ppos)
 {
-       return relay_file_read_subbufs(filp, ppos, count, subbuf_read_actor,
-                                      NULL, buffer);
+       read_descriptor_t desc;
+       desc.written = 0;
+       desc.count = count;
+       desc.arg.buf = buffer;
+       desc.error = 0;
+       return relay_file_read_subbufs(filp, ppos, subbuf_read_actor,
+                                      NULL, &desc);
 }
 
 static ssize_t relay_file_sendfile(struct file *filp,
@@ -1004,8 +1002,13 @@ static ssize_t relay_file_sendfile(struct file *filp,
                                   read_actor_t actor,
                                   void *target)
 {
-       return relay_file_read_subbufs(filp, ppos, count, subbuf_send_actor,
-                                      actor, target);
+       read_descriptor_t desc;
+       desc.written = 0;
+       desc.count = count;
+       desc.arg.data = target;
+       desc.error = 0;
+       return relay_file_read_subbufs(filp, ppos, subbuf_send_actor,
+                                      actor, &desc);
 }
 
 struct file_operations relay_file_operations = {
index 53608a59d6e3c0fd3d0b18dbf919beb9b0125397..3399701c680e392f46e21829cee8da0bf5482303 100644 (file)
 #define TASK_PREEMPTS_CURR(p, rq) \
        ((p)->prio < (rq)->curr->prio)
 
-/*
- * task_timeslice() scales user-nice values [ -20 ... 0 ... 19 ]
- * to time slice values: [800ms ... 100ms ... 5ms]
- *
- * The higher a thread's priority, the bigger timeslices
- * it gets during one round of execution. But even the lowest
- * priority thread gets MIN_TIMESLICE worth of execution time.
- */
-
 #define SCALE_PRIO(x, prio) \
        max(x * (MAX_PRIO - prio) / (MAX_USER_PRIO / 2), MIN_TIMESLICE)
 
@@ -180,6 +171,15 @@ static unsigned int static_prio_timeslice(int static_prio)
                return SCALE_PRIO(DEF_TIMESLICE, static_prio);
 }
 
+/*
+ * task_timeslice() scales user-nice values [ -20 ... 0 ... 19 ]
+ * to time slice values: [800ms ... 100ms ... 5ms]
+ *
+ * The higher a thread's priority, the bigger timeslices
+ * it gets during one round of execution. But even the lowest
+ * priority thread gets MIN_TIMESLICE worth of execution time.
+ */
+
 static inline unsigned int task_timeslice(struct task_struct *p)
 {
        return static_prio_timeslice(p->static_prio);
@@ -1822,14 +1822,14 @@ context_switch(struct rq *rq, struct task_struct *prev,
        struct mm_struct *mm = next->mm;
        struct mm_struct *oldmm = prev->active_mm;
 
-       if (unlikely(!mm)) {
+       if (!mm) {
                next->active_mm = oldmm;
                atomic_inc(&oldmm->mm_count);
                enter_lazy_tlb(oldmm, next);
        } else
                switch_mm(oldmm, mm, next);
 
-       if (unlikely(!prev->mm)) {
+       if (!prev->mm) {
                prev->active_mm = NULL;
                WARN_ON(rq->prev_mm);
                rq->prev_mm = oldmm;
@@ -3491,7 +3491,7 @@ asmlinkage void __sched preempt_schedule(void)
         * If there is a non-zero preempt_count or interrupts are disabled,
         * we do not want to preempt the current task.  Just return..
         */
-       if (unlikely(ti->preempt_count || irqs_disabled()))
+       if (likely(ti->preempt_count || irqs_disabled()))
                return;
 
 need_resched:
index 7a3b2e75f0402122ced8b15d5488a6b9de49ee8e..0e53314b14de7124456faa2ea6cc0f7aa87fcdb9 100644 (file)
@@ -49,6 +49,7 @@ cond_syscall(compat_sys_get_robust_list);
 cond_syscall(sys_epoll_create);
 cond_syscall(sys_epoll_ctl);
 cond_syscall(sys_epoll_wait);
+cond_syscall(sys_epoll_pwait);
 cond_syscall(sys_semget);
 cond_syscall(sys_semop);
 cond_syscall(sys_semtimedop);
index 8020fb273c4f1d0ddce105037bc7803b3c98331a..8bff2c18fb5ae1f697cd764feb4d7fb963309f83 100644 (file)
@@ -136,8 +136,10 @@ static int parse_table(int __user *, int, void __user *, size_t __user *,
 static int proc_do_uts_string(ctl_table *table, int write, struct file *filp,
                  void __user *buffer, size_t *lenp, loff_t *ppos);
 
+#ifdef CONFIG_PROC_SYSCTL
 static int proc_do_cad_pid(ctl_table *table, int write, struct file *filp,
                  void __user *buffer, size_t *lenp, loff_t *ppos);
+#endif
 
 static ctl_table root_table[];
 static struct ctl_table_header root_table_header =
@@ -542,6 +544,7 @@ static ctl_table kern_table[] = {
                .proc_handler   = &proc_dointvec,
        },
 #endif
+#ifdef CONFIG_PROC_SYSCTL
        {
                .ctl_name       = KERN_CADPID,
                .procname       = "cad_pid",
@@ -550,6 +553,7 @@ static ctl_table kern_table[] = {
                .mode           = 0600,
                .proc_handler   = &proc_do_cad_pid,
        },
+#endif
        {
                .ctl_name       = KERN_MAX_THREADS,
                .procname       = "threads-max",
index 126bb30c4afe42b01b78945d2105033f994979b3..a99b2a6e6a07354781da79b6067b1944d438d5f9 100644 (file)
@@ -57,7 +57,7 @@ static cycle_t jiffies_read(void)
 
 struct clocksource clocksource_jiffies = {
        .name           = "jiffies",
-       .rating         = 0, /* lowest rating*/
+       .rating         = 1, /* lowest valid rating*/
        .read           = jiffies_read,
        .mask           = 0xffffffff, /*32bits*/
        .mult           = NSEC_PER_JIFFY << JIFFIES_SHIFT, /* details above */
index 2e2368607aab1a8293739315d832c608463d8d5f..f7e50d16dbf6b6ba55980dda3e0841d0a9d0d394 100644 (file)
 
 #include <linux/unwind.h>
 #include <linux/module.h>
-#include <linux/delay.h>
+#include <linux/bootmem.h>
+#include <linux/sort.h>
 #include <linux/stop_machine.h>
 #include <asm/sections.h>
 #include <asm/uaccess.h>
 #include <asm/unaligned.h>
 
 extern char __start_unwind[], __end_unwind[];
+extern const u8 __start_unwind_hdr[], __end_unwind_hdr[];
 
 #define MAX_STACK_DEPTH 8
 
@@ -100,6 +102,8 @@ static struct unwind_table {
        } core, init;
        const void *address;
        unsigned long size;
+       const unsigned char *header;
+       unsigned long hdrsz;
        struct unwind_table *link;
        const char *name;
 } root_table;
@@ -145,6 +149,10 @@ static struct unwind_table *find_table(unsigned long pc)
        return table;
 }
 
+static unsigned long read_pointer(const u8 **pLoc,
+                                  const void *end,
+                                  signed ptrType);
+
 static void init_unwind_table(struct unwind_table *table,
                               const char *name,
                               const void *core_start,
@@ -152,14 +160,30 @@ static void init_unwind_table(struct unwind_table *table,
                               const void *init_start,
                               unsigned long init_size,
                               const void *table_start,
-                              unsigned long table_size)
+                              unsigned long table_size,
+                              const u8 *header_start,
+                              unsigned long header_size)
 {
+       const u8 *ptr = header_start + 4;
+       const u8 *end = header_start + header_size;
+
        table->core.pc = (unsigned long)core_start;
        table->core.range = core_size;
        table->init.pc = (unsigned long)init_start;
        table->init.range = init_size;
        table->address = table_start;
        table->size = table_size;
+       /* See if the linker provided table looks valid. */
+       if (header_size <= 4
+           || header_start[0] != 1
+           || (void *)read_pointer(&ptr, end, header_start[1]) != table_start
+           || header_start[2] == DW_EH_PE_omit
+           || read_pointer(&ptr, end, header_start[2]) <= 0
+           || header_start[3] == DW_EH_PE_omit)
+               header_start = NULL;
+       table->hdrsz = header_size;
+       smp_wmb();
+       table->header = header_start;
        table->link = NULL;
        table->name = name;
 }
@@ -169,7 +193,143 @@ void __init unwind_init(void)
        init_unwind_table(&root_table, "kernel",
                          _text, _end - _text,
                          NULL, 0,
-                         __start_unwind, __end_unwind - __start_unwind);
+                         __start_unwind, __end_unwind - __start_unwind,
+                         __start_unwind_hdr, __end_unwind_hdr - __start_unwind_hdr);
+}
+
+static const u32 bad_cie, not_fde;
+static const u32 *cie_for_fde(const u32 *fde, const struct unwind_table *);
+static signed fde_pointer_type(const u32 *cie);
+
+struct eh_frame_hdr_table_entry {
+       unsigned long start, fde;
+};
+
+static int cmp_eh_frame_hdr_table_entries(const void *p1, const void *p2)
+{
+       const struct eh_frame_hdr_table_entry *e1 = p1;
+       const struct eh_frame_hdr_table_entry *e2 = p2;
+
+       return (e1->start > e2->start) - (e1->start < e2->start);
+}
+
+static void swap_eh_frame_hdr_table_entries(void *p1, void *p2, int size)
+{
+       struct eh_frame_hdr_table_entry *e1 = p1;
+       struct eh_frame_hdr_table_entry *e2 = p2;
+       unsigned long v;
+
+       v = e1->start;
+       e1->start = e2->start;
+       e2->start = v;
+       v = e1->fde;
+       e1->fde = e2->fde;
+       e2->fde = v;
+}
+
+static void __init setup_unwind_table(struct unwind_table *table,
+                                       void *(*alloc)(unsigned long))
+{
+       const u8 *ptr;
+       unsigned long tableSize = table->size, hdrSize;
+       unsigned n;
+       const u32 *fde;
+       struct {
+               u8 version;
+               u8 eh_frame_ptr_enc;
+               u8 fde_count_enc;
+               u8 table_enc;
+               unsigned long eh_frame_ptr;
+               unsigned int fde_count;
+               struct eh_frame_hdr_table_entry table[];
+       } __attribute__((__packed__)) *header;
+
+       if (table->header)
+               return;
+
+       if (table->hdrsz)
+               printk(KERN_WARNING ".eh_frame_hdr for '%s' present but unusable\n",
+                      table->name);
+
+       if (tableSize & (sizeof(*fde) - 1))
+               return;
+
+       for (fde = table->address, n = 0;
+            tableSize > sizeof(*fde) && tableSize - sizeof(*fde) >= *fde;
+            tableSize -= sizeof(*fde) + *fde, fde += 1 + *fde / sizeof(*fde)) {
+               const u32 *cie = cie_for_fde(fde, table);
+               signed ptrType;
+
+               if (cie == &not_fde)
+                       continue;
+               if (cie == NULL
+                   || cie == &bad_cie
+                   || (ptrType = fde_pointer_type(cie)) < 0)
+                       return;
+               ptr = (const u8 *)(fde + 2);
+               if (!read_pointer(&ptr,
+                                 (const u8 *)(fde + 1) + *fde,
+                                 ptrType))
+                       return;
+               ++n;
+       }
+
+       if (tableSize || !n)
+               return;
+
+       hdrSize = 4 + sizeof(unsigned long) + sizeof(unsigned int)
+               + 2 * n * sizeof(unsigned long);
+       header = alloc(hdrSize);
+       if (!header)
+               return;
+       header->version          = 1;
+       header->eh_frame_ptr_enc = DW_EH_PE_abs|DW_EH_PE_native;
+       header->fde_count_enc    = DW_EH_PE_abs|DW_EH_PE_data4;
+       header->table_enc        = DW_EH_PE_abs|DW_EH_PE_native;
+       put_unaligned((unsigned long)table->address, &header->eh_frame_ptr);
+       BUILD_BUG_ON(offsetof(typeof(*header), fde_count)
+                    % __alignof(typeof(header->fde_count)));
+       header->fde_count        = n;
+
+       BUILD_BUG_ON(offsetof(typeof(*header), table)
+                    % __alignof(typeof(*header->table)));
+       for (fde = table->address, tableSize = table->size, n = 0;
+            tableSize;
+            tableSize -= sizeof(*fde) + *fde, fde += 1 + *fde / sizeof(*fde)) {
+               const u32 *cie = fde + 1 - fde[1] / sizeof(*fde);
+
+               if (!fde[1])
+                       continue; /* this is a CIE */
+               ptr = (const u8 *)(fde + 2);
+               header->table[n].start = read_pointer(&ptr,
+                                                     (const u8 *)(fde + 1) + *fde,
+                                                     fde_pointer_type(cie));
+               header->table[n].fde = (unsigned long)fde;
+               ++n;
+       }
+       WARN_ON(n != header->fde_count);
+
+       sort(header->table,
+            n,
+            sizeof(*header->table),
+            cmp_eh_frame_hdr_table_entries,
+            swap_eh_frame_hdr_table_entries);
+
+       table->hdrsz = hdrSize;
+       smp_wmb();
+       table->header = (const void *)header;
+}
+
+static void *__init balloc(unsigned long sz)
+{
+       return __alloc_bootmem_nopanic(sz,
+                                      sizeof(unsigned int),
+                                      __pa(MAX_DMA_ADDRESS));
+}
+
+void __init unwind_setup(void)
+{
+       setup_unwind_table(&root_table, balloc);
 }
 
 #ifdef CONFIG_MODULES
@@ -193,7 +353,8 @@ void *unwind_add_table(struct module *module,
        init_unwind_table(table, module->name,
                          module->module_core, module->core_size,
                          module->module_init, module->init_size,
-                         table_start, table_size);
+                         table_start, table_size,
+                         NULL, 0);
 
        if (last_table)
                last_table->link = table;
@@ -303,6 +464,26 @@ static sleb128_t get_sleb128(const u8 **pcur, const u8 *end)
        return value;
 }
 
+static const u32 *cie_for_fde(const u32 *fde, const struct unwind_table *table)
+{
+       const u32 *cie;
+
+       if (!*fde || (*fde & (sizeof(*fde) - 1)))
+               return &bad_cie;
+       if (!fde[1])
+               return &not_fde; /* this is a CIE */
+       if ((fde[1] & (sizeof(*fde) - 1))
+           || fde[1] > (unsigned long)(fde + 1) - (unsigned long)table->address)
+               return NULL; /* this is not a valid FDE */
+       cie = fde + 1 - fde[1] / sizeof(*fde);
+       if (*cie <= sizeof(*cie) + 4
+           || *cie >= fde[1] - sizeof(*fde)
+           || (*cie & (sizeof(*cie) - 1))
+           || cie[1])
+               return NULL; /* this is not a (valid) CIE */
+       return cie;
+}
+
 static unsigned long read_pointer(const u8 **pLoc,
                                   const void *end,
                                   signed ptrType)
@@ -610,49 +791,108 @@ int unwind(struct unwind_frame_info *frame)
        unsigned i;
        signed ptrType = -1;
        uleb128_t retAddrReg = 0;
-       struct unwind_table *table;
+       const struct unwind_table *table;
        struct unwind_state state;
 
        if (UNW_PC(frame) == 0)
                return -EINVAL;
        if ((table = find_table(pc)) != NULL
            && !(table->size & (sizeof(*fde) - 1))) {
-               unsigned long tableSize = table->size;
-
-               for (fde = table->address;
-                    tableSize > sizeof(*fde) && tableSize - sizeof(*fde) >= *fde;
-                    tableSize -= sizeof(*fde) + *fde,
-                    fde += 1 + *fde / sizeof(*fde)) {
-                       if (!*fde || (*fde & (sizeof(*fde) - 1)))
-                               break;
-                       if (!fde[1])
-                               continue; /* this is a CIE */
-                       if ((fde[1] & (sizeof(*fde) - 1))
-                           || fde[1] > (unsigned long)(fde + 1)
-                                       - (unsigned long)table->address)
-                               continue; /* this is not a valid FDE */
-                       cie = fde + 1 - fde[1] / sizeof(*fde);
-                       if (*cie <= sizeof(*cie) + 4
-                           || *cie >= fde[1] - sizeof(*fde)
-                           || (*cie & (sizeof(*cie) - 1))
-                           || cie[1]
-                           || (ptrType = fde_pointer_type(cie)) < 0) {
-                               cie = NULL; /* this is not a (valid) CIE */
-                               continue;
+               const u8 *hdr = table->header;
+               unsigned long tableSize;
+
+               smp_rmb();
+               if (hdr && hdr[0] == 1) {
+                       switch(hdr[3] & DW_EH_PE_FORM) {
+                       case DW_EH_PE_native: tableSize = sizeof(unsigned long); break;
+                       case DW_EH_PE_data2: tableSize = 2; break;
+                       case DW_EH_PE_data4: tableSize = 4; break;
+                       case DW_EH_PE_data8: tableSize = 8; break;
+                       default: tableSize = 0; break;
+                       }
+                       ptr = hdr + 4;
+                       end = hdr + table->hdrsz;
+                       if (tableSize
+                           && read_pointer(&ptr, end, hdr[1])
+                              == (unsigned long)table->address
+                           && (i = read_pointer(&ptr, end, hdr[2])) > 0
+                           && i == (end - ptr) / (2 * tableSize)
+                           && !((end - ptr) % (2 * tableSize))) {
+                               do {
+                                       const u8 *cur = ptr + (i / 2) * (2 * tableSize);
+
+                                       startLoc = read_pointer(&cur,
+                                                               cur + tableSize,
+                                                               hdr[3]);
+                                       if (pc < startLoc)
+                                               i /= 2;
+                                       else {
+                                               ptr = cur - tableSize;
+                                               i = (i + 1) / 2;
+                                       }
+                               } while (startLoc && i > 1);
+                               if (i == 1
+                                   && (startLoc = read_pointer(&ptr,
+                                                               ptr + tableSize,
+                                                               hdr[3])) != 0
+                                   && pc >= startLoc)
+                                       fde = (void *)read_pointer(&ptr,
+                                                                  ptr + tableSize,
+                                                                  hdr[3]);
                        }
+               }
+
+               if (fde != NULL) {
+                       cie = cie_for_fde(fde, table);
                        ptr = (const u8 *)(fde + 2);
-                       startLoc = read_pointer(&ptr,
-                                               (const u8 *)(fde + 1) + *fde,
-                                               ptrType);
-                       endLoc = startLoc
-                                + read_pointer(&ptr,
-                                               (const u8 *)(fde + 1) + *fde,
-                                               ptrType & DW_EH_PE_indirect
-                                               ? ptrType
-                                               : ptrType & (DW_EH_PE_FORM|DW_EH_PE_signed));
-                       if (pc >= startLoc && pc < endLoc)
-                               break;
-                       cie = NULL;
+                       if(cie != NULL
+                          && cie != &bad_cie
+                          && cie != &not_fde
+                          && (ptrType = fde_pointer_type(cie)) >= 0
+                          && read_pointer(&ptr,
+                                          (const u8 *)(fde + 1) + *fde,
+                                          ptrType) == startLoc) {
+                               if (!(ptrType & DW_EH_PE_indirect))
+                                       ptrType &= DW_EH_PE_FORM|DW_EH_PE_signed;
+                               endLoc = startLoc
+                                        + read_pointer(&ptr,
+                                                       (const u8 *)(fde + 1) + *fde,
+                                                       ptrType);
+                               if(pc >= endLoc)
+                                       fde = NULL;
+                       } else
+                               fde = NULL;
+               }
+               if (fde == NULL) {
+                       for (fde = table->address, tableSize = table->size;
+                            cie = NULL, tableSize > sizeof(*fde)
+                            && tableSize - sizeof(*fde) >= *fde;
+                            tableSize -= sizeof(*fde) + *fde,
+                            fde += 1 + *fde / sizeof(*fde)) {
+                               cie = cie_for_fde(fde, table);
+                               if (cie == &bad_cie) {
+                                       cie = NULL;
+                                       break;
+                               }
+                               if (cie == NULL
+                                   || cie == &not_fde
+                                   || (ptrType = fde_pointer_type(cie)) < 0)
+                                       continue;
+                               ptr = (const u8 *)(fde + 2);
+                               startLoc = read_pointer(&ptr,
+                                                       (const u8 *)(fde + 1) + *fde,
+                                                       ptrType);
+                               if (!startLoc)
+                                       continue;
+                               if (!(ptrType & DW_EH_PE_indirect))
+                                       ptrType &= DW_EH_PE_FORM|DW_EH_PE_signed;
+                               endLoc = startLoc
+                                        + read_pointer(&ptr,
+                                                       (const u8 *)(fde + 1) + *fde,
+                                                       ptrType);
+                               if (pc >= startLoc && pc < endLoc)
+                                       break;
+                       }
                }
        }
        if (cie != NULL) {
index cfc737bffe6deb8d5b2c97658b19e7917e296cce..3df9bfc7ff78fed6215a2d6f138a18a016d7e04a 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/notifier.h>
 #include <linux/kthread.h>
 #include <linux/hardirq.h>
+#include <linux/mempolicy.h>
 
 /*
  * The per-CPU workqueue (if single thread, we always use the first
@@ -245,6 +246,12 @@ static int worker_thread(void *__cwq)
        sigprocmask(SIG_BLOCK, &blocked, NULL);
        flush_signals(current);
 
+       /*
+        * We inherited MPOL_INTERLEAVE from the booting kernel.
+        * Set MPOL_DEFAULT to insure node local allocations.
+        */
+       numa_default_policy();
+
        /* SIG_IGN makes children autoreap: see do_notify_parent(). */
        sa.sa.sa_handler = SIG_IGN;
        sa.sa.sa_flags = 0;
index 756a908c441d28710e773e15b7b619191f9efdcd..77491e311791ee807d8ee082b4bae7e966d499d2 100644 (file)
@@ -71,7 +71,7 @@ config LOG_BUF_SHIFT
 
 config DETECT_SOFTLOCKUP
        bool "Detect Soft Lockups"
-       depends on DEBUG_KERNEL
+       depends on DEBUG_KERNEL && !S390
        default y
        help
          Say Y here to enable the kernel to detect "soft lockups",
@@ -371,6 +371,20 @@ config FORCED_INLINING
          become the default in the future, until then this option is there to
          test gcc for this.
 
+config HEADERS_CHECK
+       bool "Run 'make headers_check' when building vmlinux"
+       depends on !UML
+       help
+         This option will extract the user-visible kernel headers whenever
+         building the kernel, and will run basic sanity checks on them to
+         ensure that exported files do not attempt to include files which
+         were not exported, etc.
+
+         If you're making modifications to header files which are
+         relevant for userspace, say 'Y', and check the headers
+         exported to $(INSTALL_HDR_PATH) (usually 'usr/include' in
+         your build tree), to make sure they're suitable.
+
 config RCU_TORTURE_TEST
        tristate "torture tests for RCU"
        depends on DEBUG_KERNEL
index b0361756e22e2ff0801a12e4291b7d51a22305a8..cf98fabaa549524d2f882d06649abfaa4c91239d 100644 (file)
@@ -5,14 +5,14 @@
 lib-y := ctype.o string.o vsprintf.o cmdline.o \
         bust_spinlocks.o rbtree.o radix-tree.o dump_stack.o \
         idr.o div64.o int_sqrt.o bitmap.o extable.o prio_tree.o \
-        sha1.o
+        sha1.o irq_regs.o
 
 lib-$(CONFIG_MMU) += ioremap.o
 lib-$(CONFIG_SMP) += cpumask.o
 
 lib-y  += kobject.o kref.o kobject_uevent.o klist.o
 
-obj-y += sort.o parser.o halfmd4.o iomap_copy.o debug_locks.o
+obj-y += sort.o parser.o halfmd4.o iomap_copy.o debug_locks.o random32.o
 
 ifeq ($(CONFIG_DEBUG_KOBJECT),y)
 CFLAGS_kobject.o += -DDEBUG
index d71e38c54ea50444c5d76c91471c3827c4beaf64..037fa9aa2ed77f554296c7f1f4b64f769fdd2a73 100644 (file)
@@ -316,10 +316,11 @@ int bitmap_scnprintf(char *buf, unsigned int buflen,
 EXPORT_SYMBOL(bitmap_scnprintf);
 
 /**
- * bitmap_parse - convert an ASCII hex string into a bitmap.
- * @ubuf: pointer to buffer in user space containing string.
- * @ubuflen: buffer size in bytes.  If string is smaller than this
+ * __bitmap_parse - convert an ASCII hex string into a bitmap.
+ * @buf: pointer to buffer containing string.
+ * @buflen: buffer size in bytes.  If string is smaller than this
  *    then it must be terminated with a \0.
+ * @is_user: location of buffer, 0 indicates kernel space
  * @maskp: pointer to bitmap array that will contain result.
  * @nmaskbits: size of bitmap, in bits.
  *
@@ -330,11 +331,13 @@ EXPORT_SYMBOL(bitmap_scnprintf);
  * characters and for grouping errors such as "1,,5", ",44", "," and "".
  * Leading and trailing whitespace accepted, but not embedded whitespace.
  */
-int bitmap_parse(const char __user *ubuf, unsigned int ubuflen,
-        unsigned long *maskp, int nmaskbits)
+int __bitmap_parse(const char *buf, unsigned int buflen,
+               int is_user, unsigned long *maskp,
+               int nmaskbits)
 {
        int c, old_c, totaldigits, ndigits, nchunks, nbits;
        u32 chunk;
+       const char __user *ubuf = buf;
 
        bitmap_zero(maskp, nmaskbits);
 
@@ -343,11 +346,15 @@ int bitmap_parse(const char __user *ubuf, unsigned int ubuflen,
                chunk = ndigits = 0;
 
                /* Get the next chunk of the bitmap */
-               while (ubuflen) {
+               while (buflen) {
                        old_c = c;
-                       if (get_user(c, ubuf++))
-                               return -EFAULT;
-                       ubuflen--;
+                       if (is_user) {
+                               if (__get_user(c, ubuf++))
+                                       return -EFAULT;
+                       }
+                       else
+                               c = *buf++;
+                       buflen--;
                        if (isspace(c))
                                continue;
 
@@ -388,11 +395,36 @@ int bitmap_parse(const char __user *ubuf, unsigned int ubuflen,
                nbits += (nchunks == 1) ? nbits_to_hold_value(chunk) : CHUNKSZ;
                if (nbits > nmaskbits)
                        return -EOVERFLOW;
-       } while (ubuflen && c == ',');
+       } while (buflen && c == ',');
 
        return 0;
 }
-EXPORT_SYMBOL(bitmap_parse);
+EXPORT_SYMBOL(__bitmap_parse);
+
+/**
+ * bitmap_parse_user()
+ *
+ * @ubuf: pointer to user buffer containing string.
+ * @ulen: buffer size in bytes.  If string is smaller than this
+ *    then it must be terminated with a \0.
+ * @maskp: pointer to bitmap array that will contain result.
+ * @nmaskbits: size of bitmap, in bits.
+ *
+ * Wrapper for __bitmap_parse(), providing it with user buffer.
+ *
+ * We cannot have this as an inline function in bitmap.h because it needs
+ * linux/uaccess.h to get the access_ok() declaration and this causes
+ * cyclic dependencies.
+ */
+int bitmap_parse_user(const char __user *ubuf,
+                       unsigned int ulen, unsigned long *maskp,
+                       int nmaskbits)
+{
+       if (!access_ok(VERIFY_READ, ubuf, ulen))
+               return -EFAULT;
+       return __bitmap_parse((const char *)ubuf, ulen, 1, maskp, nmaskbits);
+}
+EXPORT_SYMBOL(bitmap_parse_user);
 
 /*
  * bscnl_emit(buf, buflen, rbot, rtop, bp)
index 7a2a73f88d594dc73282c24e3d0304a602a10a25..3a67dc5ada7d5b2655ae461890519e995d50d7c9 100644 (file)
@@ -43,19 +43,3 @@ int __any_online_cpu(const cpumask_t *mask)
        return cpu;
 }
 EXPORT_SYMBOL(__any_online_cpu);
-
-#if MAX_NUMNODES > 1
-/*
- * Find the highest possible node id.
- */
-int highest_possible_node_id(void)
-{
-       unsigned int node;
-       unsigned int highest = 0;
-
-       for_each_node_mask(node, node_possible_map)
-               highest = node;
-       return highest;
-}
-EXPORT_SYMBOL(highest_possible_node_id);
-#endif
diff --git a/lib/irq_regs.c b/lib/irq_regs.c
new file mode 100644 (file)
index 0000000..753880a
--- /dev/null
@@ -0,0 +1,17 @@
+/* saved per-CPU IRQ register pointer
+ *
+ * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include <linux/module.h>
+#include <asm/irq_regs.h>
+
+#ifndef ARCH_HAS_OWN_IRQ_REGS
+DEFINE_PER_CPU(struct pt_regs *, __irq_regs);
+EXPORT_PER_CPU_SYMBOL(__irq_regs);
+#endif
index 1699eb9161f34594a38cc28fbea1f0ab2db56893..7dd5c0e9d996adb07681e02037e746b68a2a2f50 100644 (file)
@@ -119,6 +119,7 @@ char *kobject_get_path(struct kobject *kobj, gfp_t gfp_mask)
 
        return path;
 }
+EXPORT_SYMBOL_GPL(kobject_get_path);
 
 /**
  *     kobject_init - initialize object.
index 637d55608de55b463974afeb62eb704977426bbc..aa9bfd0bdbd1bd720ed1eb8c5416b180bad3b98a 100644 (file)
@@ -160,13 +160,13 @@ static inline int tag_get(struct radix_tree_node *node, unsigned int tag,
 
 static inline void root_tag_set(struct radix_tree_root *root, unsigned int tag)
 {
-       root->gfp_mask |= (1 << (tag + __GFP_BITS_SHIFT));
+       root->gfp_mask |= (__force gfp_t)(1 << (tag + __GFP_BITS_SHIFT));
 }
 
 
 static inline void root_tag_clear(struct radix_tree_root *root, unsigned int tag)
 {
-       root->gfp_mask &= ~(1 << (tag + __GFP_BITS_SHIFT));
+       root->gfp_mask &= (__force gfp_t)~(1 << (tag + __GFP_BITS_SHIFT));
 }
 
 static inline void root_tag_clear_all(struct radix_tree_root *root)
@@ -176,7 +176,7 @@ static inline void root_tag_clear_all(struct radix_tree_root *root)
 
 static inline int root_tag_get(struct radix_tree_root *root, unsigned int tag)
 {
-       return root->gfp_mask & (1 << (tag + __GFP_BITS_SHIFT));
+       return (__force unsigned)root->gfp_mask & (1 << (tag + __GFP_BITS_SHIFT));
 }
 
 /*
diff --git a/lib/random32.c b/lib/random32.c
new file mode 100644 (file)
index 0000000..4a15ce5
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+  This is a maximally equidistributed combined Tausworthe generator
+  based on code from GNU Scientific Library 1.5 (30 Jun 2004)
+
+   x_n = (s1_n ^ s2_n ^ s3_n)
+
+   s1_{n+1} = (((s1_n & 4294967294) <<12) ^ (((s1_n <<13) ^ s1_n) >>19))
+   s2_{n+1} = (((s2_n & 4294967288) << 4) ^ (((s2_n << 2) ^ s2_n) >>25))
+   s3_{n+1} = (((s3_n & 4294967280) <<17) ^ (((s3_n << 3) ^ s3_n) >>11))
+
+   The period of this generator is about 2^88.
+
+   From: P. L'Ecuyer, "Maximally Equidistributed Combined Tausworthe
+   Generators", Mathematics of Computation, 65, 213 (1996), 203--213.
+
+   This is available on the net from L'Ecuyer's home page,
+
+   http://www.iro.umontreal.ca/~lecuyer/myftp/papers/tausme.ps
+   ftp://ftp.iro.umontreal.ca/pub/simulation/lecuyer/papers/tausme.ps
+
+   There is an erratum in the paper "Tables of Maximally
+   Equidistributed Combined LFSR Generators", Mathematics of
+   Computation, 68, 225 (1999), 261--269:
+   http://www.iro.umontreal.ca/~lecuyer/myftp/papers/tausme2.ps
+
+        ... the k_j most significant bits of z_j must be non-
+        zero, for each j. (Note: this restriction also applies to the
+        computer code given in [4], but was mistakenly not mentioned in
+        that paper.)
+
+   This affects the seeding procedure by imposing the requirement
+   s1 > 1, s2 > 7, s3 > 15.
+
+*/
+
+#include <linux/types.h>
+#include <linux/percpu.h>
+#include <linux/module.h>
+#include <linux/random.h>
+
+struct rnd_state {
+       u32 s1, s2, s3;
+};
+
+static DEFINE_PER_CPU(struct rnd_state, net_rand_state);
+
+static u32 __random32(struct rnd_state *state)
+{
+#define TAUSWORTHE(s,a,b,c,d) ((s&c)<<d) ^ (((s <<a) ^ s)>>b)
+
+       state->s1 = TAUSWORTHE(state->s1, 13, 19, 4294967294UL, 12);
+       state->s2 = TAUSWORTHE(state->s2, 2, 25, 4294967288UL, 4);
+       state->s3 = TAUSWORTHE(state->s3, 3, 11, 4294967280UL, 17);
+
+       return (state->s1 ^ state->s2 ^ state->s3);
+}
+
+static void __set_random32(struct rnd_state *state, unsigned long s)
+{
+       if (s == 0)
+               s = 1;      /* default seed is 1 */
+
+#define LCG(n) (69069 * n)
+       state->s1 = LCG(s);
+       state->s2 = LCG(state->s1);
+       state->s3 = LCG(state->s2);
+
+       /* "warm it up" */
+       __random32(state);
+       __random32(state);
+       __random32(state);
+       __random32(state);
+       __random32(state);
+       __random32(state);
+}
+
+/**
+ *     random32 - pseudo random number generator
+ *
+ *     A 32 bit pseudo-random number is generated using a fast
+ *     algorithm suitable for simulation. This algorithm is NOT
+ *     considered safe for cryptographic use.
+ */
+u32 random32(void)
+{
+       unsigned long r;
+       struct rnd_state *state = &get_cpu_var(net_rand_state);
+       r = __random32(state);
+       put_cpu_var(state);
+       return r;
+}
+EXPORT_SYMBOL(random32);
+
+/**
+ *     srandom32 - add entropy to pseudo random number generator
+ *     @seed: seed value
+ *
+ *     Add some additional seeding to the random32() pool.
+ *     Note: this pool is per cpu so it only affects current CPU.
+ */
+void srandom32(u32 entropy)
+{
+       struct rnd_state *state = &get_cpu_var(net_rand_state);
+       __set_random32(state, state->s1 ^ entropy);
+       put_cpu_var(state);
+}
+EXPORT_SYMBOL(srandom32);
+
+/*
+ *     Generate some initially weak seeding values to allow
+ *     to start the random32() engine.
+ */
+static int __init random32_init(void)
+{
+       int i;
+
+       for_each_possible_cpu(i) {
+               struct rnd_state *state = &per_cpu(net_rand_state,i);
+               __set_random32(state, i + jiffies);
+       }
+       return 0;
+}
+core_initcall(random32_init);
+
+/*
+ *     Generate better values after random number generator
+ *     is fully initalized.
+ */
+static int __init random32_reseed(void)
+{
+       int i;
+       unsigned long seed;
+
+       for_each_possible_cpu(i) {
+               struct rnd_state *state = &per_cpu(net_rand_state,i);
+
+               get_random_bytes(&seed, sizeof(seed));
+               __set_random32(state, seed);
+       }
+       return 0;
+}
+late_initcall(random32_reseed);
index db4fed74b9407d5ec2ddae1a95247f583ab0d569..c4cfd6c0342ff1e4fbc04b9fff3b93f0d00118bd 100644 (file)
@@ -28,7 +28,7 @@ void __init_rwsem(struct rw_semaphore *sem, const char *name,
         * Make sure we are not reinitializing a held semaphore:
         */
        debug_check_no_locks_freed((void *)sem, sizeof(*sem));
-       lockdep_init_map(&sem->dep_map, name, key);
+       lockdep_init_map(&sem->dep_map, name, key, 0);
 #endif
        sem->activity = 0;
        spin_lock_init(&sem->wait_lock);
index 901d0e7da89220fae47848d349633ae43c1afd7e..cdb4e3d0560733c2706a27ccd20681017da2e34a 100644 (file)
@@ -19,7 +19,7 @@ void __init_rwsem(struct rw_semaphore *sem, const char *name,
         * Make sure we are not reinitializing a held semaphore:
         */
        debug_check_no_locks_freed((void *)sem, sizeof(*sem));
-       lockdep_init_map(&sem->dep_map, name, key);
+       lockdep_init_map(&sem->dep_map, name, key, 0);
 #endif
        sem->count = RWSEM_UNLOCKED_VALUE;
        spin_lock_init(&sem->wait_lock);
index dafaf1de2491aedb0a323aed4951e5084e58e18c..b6c4f898197c52f0b175ad0ea9e26466c338ea30 100644 (file)
@@ -20,7 +20,7 @@ void __spin_lock_init(spinlock_t *lock, const char *name,
         * Make sure we are not reinitializing a held lock:
         */
        debug_check_no_locks_freed((void *)lock, sizeof(*lock));
-       lockdep_init_map(&lock->dep_map, name, key);
+       lockdep_init_map(&lock->dep_map, name, key, 0);
 #endif
        lock->raw_lock = (raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED;
        lock->magic = SPINLOCK_MAGIC;
@@ -38,7 +38,7 @@ void __rwlock_init(rwlock_t *lock, const char *name,
         * Make sure we are not reinitializing a held lock:
         */
        debug_check_no_locks_freed((void *)lock, sizeof(*lock));
-       lockdep_init_map(&lock->dep_map, name, key);
+       lockdep_init_map(&lock->dep_map, name, key, 0);
 #endif
        lock->raw_lock = (raw_rwlock_t) __RAW_RW_LOCK_UNLOCKED;
        lock->magic = RWLOCK_MAGIC;
index 12b3a4eee88d56a3b4d4fe6c4255fa4a1ca81352..f3c077eb0b8ef505afe79b5c13363f45edea4aad 100644 (file)
@@ -10,7 +10,8 @@ mmu-$(CONFIG_MMU)     := fremap.o highmem.o madvise.o memory.o mincore.o \
 obj-y                  := bootmem.o filemap.o mempool.o oom_kill.o fadvise.o \
                           page_alloc.o page-writeback.o pdflush.o \
                           readahead.o swap.o truncate.o vmscan.o \
-                          prio_tree.o util.o mmzone.o vmstat.o $(mmu-y)
+                          prio_tree.o util.o mmzone.o vmstat.o backing-dev.o \
+                          $(mmu-y)
 
 ifeq ($(CONFIG_MMU)$(CONFIG_BLOCK),yy)
 obj-y                  += bounce.o
diff --git a/mm/backing-dev.c b/mm/backing-dev.c
new file mode 100644 (file)
index 0000000..f50a281
--- /dev/null
@@ -0,0 +1,69 @@
+
+#include <linux/wait.h>
+#include <linux/backing-dev.h>
+#include <linux/fs.h>
+#include <linux/sched.h>
+#include <linux/module.h>
+
+static wait_queue_head_t congestion_wqh[2] = {
+               __WAIT_QUEUE_HEAD_INITIALIZER(congestion_wqh[0]),
+               __WAIT_QUEUE_HEAD_INITIALIZER(congestion_wqh[1])
+       };
+
+
+void clear_bdi_congested(struct backing_dev_info *bdi, int rw)
+{
+       enum bdi_state bit;
+       wait_queue_head_t *wqh = &congestion_wqh[rw];
+
+       bit = (rw == WRITE) ? BDI_write_congested : BDI_read_congested;
+       clear_bit(bit, &bdi->state);
+       smp_mb__after_clear_bit();
+       if (waitqueue_active(wqh))
+               wake_up(wqh);
+}
+EXPORT_SYMBOL(clear_bdi_congested);
+
+void set_bdi_congested(struct backing_dev_info *bdi, int rw)
+{
+       enum bdi_state bit;
+
+       bit = (rw == WRITE) ? BDI_write_congested : BDI_read_congested;
+       set_bit(bit, &bdi->state);
+}
+EXPORT_SYMBOL(set_bdi_congested);
+
+/**
+ * congestion_wait - wait for a backing_dev to become uncongested
+ * @rw: READ or WRITE
+ * @timeout: timeout in jiffies
+ *
+ * Waits for up to @timeout jiffies for a backing_dev (any backing_dev) to exit
+ * write congestion.  If no backing_devs are congested then just wait for the
+ * next write to be completed.
+ */
+long congestion_wait(int rw, long timeout)
+{
+       long ret;
+       DEFINE_WAIT(wait);
+       wait_queue_head_t *wqh = &congestion_wqh[rw];
+
+       prepare_to_wait(wqh, &wait, TASK_UNINTERRUPTIBLE);
+       ret = io_schedule_timeout(timeout);
+       finish_wait(wqh, &wait);
+       return ret;
+}
+EXPORT_SYMBOL(congestion_wait);
+
+/**
+ * congestion_end - wake up sleepers on a congested backing_dev_info
+ * @rw: READ or WRITE
+ */
+void congestion_end(int rw)
+{
+       wait_queue_head_t *wqh = &congestion_wqh[rw];
+
+       if (waitqueue_active(wqh))
+               wake_up(wqh);
+}
+EXPORT_SYMBOL(congestion_end);
index 3464b681f8449eda37ee74b9581ad03266f6e619..cb26e33fd0ff15cc9932ec44592c7ae7174ac0b7 100644 (file)
@@ -75,8 +75,8 @@ generic_file_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
  *  ->mmap_sem
  *    ->lock_page              (access_process_vm)
  *
- *  ->mmap_sem
- *    ->i_mutex                        (msync)
+ *  ->i_mutex                  (generic_file_buffered_write)
+ *    ->mmap_sem               (fault_in_pages_readable->do_page_fault)
  *
  *  ->i_mutex
  *    ->i_alloc_sem             (various)
@@ -1884,11 +1884,10 @@ repeat:
  *     if suid or (sgid and xgrp)
  *             remove privs
  */
-int remove_suid(struct dentry *dentry)
+int should_remove_suid(struct dentry *dentry)
 {
        mode_t mode = dentry->d_inode->i_mode;
        int kill = 0;
-       int result = 0;
 
        /* suid always must be killed */
        if (unlikely(mode & S_ISUID))
@@ -1901,13 +1900,28 @@ int remove_suid(struct dentry *dentry)
        if (unlikely((mode & S_ISGID) && (mode & S_IXGRP)))
                kill |= ATTR_KILL_SGID;
 
-       if (unlikely(kill && !capable(CAP_FSETID))) {
-               struct iattr newattrs;
+       if (unlikely(kill && !capable(CAP_FSETID)))
+               return kill;
 
-               newattrs.ia_valid = ATTR_FORCE | kill;
-               result = notify_change(dentry, &newattrs);
-       }
-       return result;
+       return 0;
+}
+
+int __remove_suid(struct dentry *dentry, int kill)
+{
+       struct iattr newattrs;
+
+       newattrs.ia_valid = ATTR_FORCE | kill;
+       return notify_change(dentry, &newattrs);
+}
+
+int remove_suid(struct dentry *dentry)
+{
+       int kill = should_remove_suid(dentry);
+
+       if (unlikely(kill))
+               return __remove_suid(dentry, kill);
+
+       return 0;
 }
 EXPORT_SYMBOL(remove_suid);
 
@@ -2222,7 +2236,7 @@ __generic_file_aio_write_nolock(struct kiocb *iocb, const struct iovec *iov,
                                unsigned long nr_segs, loff_t *ppos)
 {
        struct file *file = iocb->ki_filp;
-       const struct address_space * mapping = file->f_mapping;
+       struct address_space * mapping = file->f_mapping;
        size_t ocount;          /* original count */
        size_t count;           /* after file limit checks */
        struct inode    *inode = mapping->host;
@@ -2275,8 +2289,11 @@ __generic_file_aio_write_nolock(struct kiocb *iocb, const struct iovec *iov,
 
        /* coalesce the iovecs and go direct-to-BIO for O_DIRECT */
        if (unlikely(file->f_flags & O_DIRECT)) {
-               written = generic_file_direct_write(iocb, iov,
-                               &nr_segs, pos, ppos, count, ocount);
+               loff_t endbyte;
+               ssize_t written_buffered;
+
+               written = generic_file_direct_write(iocb, iov, &nr_segs, pos,
+                                                       ppos, count, ocount);
                if (written < 0 || written == count)
                        goto out;
                /*
@@ -2285,10 +2302,46 @@ __generic_file_aio_write_nolock(struct kiocb *iocb, const struct iovec *iov,
                 */
                pos += written;
                count -= written;
-       }
+               written_buffered = generic_file_buffered_write(iocb, iov,
+                                               nr_segs, pos, ppos, count,
+                                               written);
+               /*
+                * If generic_file_buffered_write() retuned a synchronous error
+                * then we want to return the number of bytes which were
+                * direct-written, or the error code if that was zero.  Note
+                * that this differs from normal direct-io semantics, which
+                * will return -EFOO even if some bytes were written.
+                */
+               if (written_buffered < 0) {
+                       err = written_buffered;
+                       goto out;
+               }
 
-       written = generic_file_buffered_write(iocb, iov, nr_segs,
-                       pos, ppos, count, written);
+               /*
+                * We need to ensure that the page cache pages are written to
+                * disk and invalidated to preserve the expected O_DIRECT
+                * semantics.
+                */
+               endbyte = pos + written_buffered - written - 1;
+               err = do_sync_file_range(file, pos, endbyte,
+                                        SYNC_FILE_RANGE_WAIT_BEFORE|
+                                        SYNC_FILE_RANGE_WRITE|
+                                        SYNC_FILE_RANGE_WAIT_AFTER);
+               if (err == 0) {
+                       written = written_buffered;
+                       invalidate_mapping_pages(mapping,
+                                                pos >> PAGE_CACHE_SHIFT,
+                                                endbyte >> PAGE_CACHE_SHIFT);
+               } else {
+                       /*
+                        * We don't know how much we wrote, so just return
+                        * the number of bytes which were direct-written
+                        */
+               }
+       } else {
+               written = generic_file_buffered_write(iocb, iov, nr_segs,
+                               pos, ppos, count, written);
+       }
 out:
        current->backing_dev_info = NULL;
        return written ? written : err;
index 1d709ff528e1e91cd9bbbf086f119c5d4ba3154a..2dbec90dc3bad98cab038db4513f566360e8de8d 100644 (file)
@@ -356,8 +356,8 @@ nomem:
        return -ENOMEM;
 }
 
-void unmap_hugepage_range(struct vm_area_struct *vma, unsigned long start,
-                         unsigned long end)
+void __unmap_hugepage_range(struct vm_area_struct *vma, unsigned long start,
+                           unsigned long end)
 {
        struct mm_struct *mm = vma->vm_mm;
        unsigned long address;
@@ -398,6 +398,24 @@ void unmap_hugepage_range(struct vm_area_struct *vma, unsigned long start,
        }
 }
 
+void unmap_hugepage_range(struct vm_area_struct *vma, unsigned long start,
+                         unsigned long end)
+{
+       /*
+        * It is undesirable to test vma->vm_file as it should be non-null
+        * for valid hugetlb area. However, vm_file will be NULL in the error
+        * cleanup path of do_mmap_pgoff. When hugetlbfs ->mmap method fails,
+        * do_mmap_pgoff() nullifies vma->vm_file before calling this function
+        * to clean up. Since no pte has actually been setup, it is safe to
+        * do nothing in this case.
+        */
+       if (vma->vm_file) {
+               spin_lock(&vma->vm_file->f_mapping->i_mmap_lock);
+               __unmap_hugepage_range(vma, start, end);
+               spin_unlock(&vma->vm_file->f_mapping->i_mmap_lock);
+       }
+}
+
 static int hugetlb_cow(struct mm_struct *mm, struct vm_area_struct *vma,
                        unsigned long address, pte_t *ptep, pte_t pte)
 {
index 9cf3f341a28a6cf4c53af58f01959a9cf7c23eb1..156861fcac436e4716537c7e5dff565dded43224 100644 (file)
@@ -1086,6 +1086,7 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
                                default:
                                        BUG();
                                }
+                               cond_resched();
                        }
                        if (pages) {
                                pages[i] = page;
@@ -1451,6 +1452,7 @@ static inline void cow_user_page(struct page *dst, struct page *src, unsigned lo
                if (__copy_from_user_inatomic(kaddr, uaddr, PAGE_SIZE))
                        memset(kaddr, 0, PAGE_SIZE);
                kunmap_atomic(kaddr, KM_USER0);
+               flush_dcache_page(dst);
                return;
                
        }
@@ -2169,11 +2171,13 @@ retry:
         * after the next truncate_count read.
         */
 
-       /* no page was available -- either SIGBUS or OOM */
-       if (new_page == NOPAGE_SIGBUS)
+       /* no page was available -- either SIGBUS, OOM or REFAULT */
+       if (unlikely(new_page == NOPAGE_SIGBUS))
                return VM_FAULT_SIGBUS;
-       if (new_page == NOPAGE_OOM)
+       else if (unlikely(new_page == NOPAGE_OOM))
                return VM_FAULT_OOM;
+       else if (unlikely(new_page == NOPAGE_REFAULT))
+               return VM_FAULT_MINOR;
 
        /*
         * Should we do an early C-O-W break?
index 25788b1b7fcff4b6d116dffab3abe6e1ecc17d08..617fb31086eef17d45f5b04df65ff3a851a7a19c 100644 (file)
@@ -727,7 +727,7 @@ int do_migrate_pages(struct mm_struct *mm,
        return -ENOSYS;
 }
 
-static struct page *new_vma_page(struct page *page, unsigned long private)
+static struct page *new_vma_page(struct page *page, unsigned long private, int **x)
 {
        return NULL;
 }
index eea8eefd51a86588bd1c091d94fe74df800a9bc2..497e502dfd6b6e54fc2bf902ea55fac36e70ac72 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -900,17 +900,6 @@ unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
        int accountable = 1;
        unsigned long charged = 0, reqprot = prot;
 
-       if (file) {
-               if (is_file_hugepages(file))
-                       accountable = 0;
-
-               if (!file->f_op || !file->f_op->mmap)
-                       return -ENODEV;
-
-               if ((prot & PROT_EXEC) &&
-                   (file->f_vfsmnt->mnt_flags & MNT_NOEXEC))
-                       return -EPERM;
-       }
        /*
         * Does the application expect PROT_READ to imply PROT_EXEC?
         *
@@ -1000,6 +989,16 @@ unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
                case MAP_PRIVATE:
                        if (!(file->f_mode & FMODE_READ))
                                return -EACCES;
+                       if (file->f_vfsmnt->mnt_flags & MNT_NOEXEC) {
+                               if (vm_flags & VM_EXEC)
+                                       return -EPERM;
+                               vm_flags &= ~VM_MAYEXEC;
+                       }
+                       if (is_file_hugepages(file))
+                               accountable = 0;
+
+                       if (!file->f_op || !file->f_op->mmap)
+                               return -ENODEV;
                        break;
 
                default:
index 20f41b082e16484a8c52aa04272bf4f30359593c..2e3ce3a928b97dd8eeb54b42fb6f363d15a6d2ae 100644 (file)
@@ -15,6 +15,7 @@
  *  kernel subsystems and hints as to where to find out what things do.
  */
 
+#include <linux/oom.h>
 #include <linux/mm.h>
 #include <linux/sched.h>
 #include <linux/swap.h>
index a0f33905744978df4c961e0e29187f3cf1cef54c..8d9b19f239c3ec03038e88cdd0a44e8a71c0d3e9 100644 (file)
@@ -222,7 +222,7 @@ static void balance_dirty_pages(struct address_space *mapping)
                        if (pages_written >= write_chunk)
                                break;          /* We've done our duty */
                }
-               blk_congestion_wait(WRITE, HZ/10);
+               congestion_wait(WRITE, HZ/10);
        }
 
        if (nr_reclaimable + global_page_state(NR_WRITEBACK)
@@ -314,7 +314,7 @@ void throttle_vm_writeout(void)
                 if (global_page_state(NR_UNSTABLE_NFS) +
                        global_page_state(NR_WRITEBACK) <= dirty_thresh)
                                break;
-                blk_congestion_wait(WRITE, HZ/10);
+                congestion_wait(WRITE, HZ/10);
         }
 }
 
@@ -351,7 +351,7 @@ static void background_writeout(unsigned long _min_pages)
                min_pages -= MAX_WRITEBACK_PAGES - wbc.nr_to_write;
                if (wbc.nr_to_write > 0 || wbc.pages_skipped > 0) {
                        /* Wrote less than expected */
-                       blk_congestion_wait(WRITE, HZ/10);
+                       congestion_wait(WRITE, HZ/10);
                        if (!wbc.encountered_congestion)
                                break;
                }
@@ -422,7 +422,7 @@ static void wb_kupdate(unsigned long arg)
                writeback_inodes(&wbc);
                if (wbc.nr_to_write > 0) {
                        if (wbc.encountered_congestion)
-                               blk_congestion_wait(WRITE, HZ/10);
+                               congestion_wait(WRITE, HZ/10);
                        else
                                break;  /* All the old data is written */
                }
@@ -955,15 +955,6 @@ int test_set_page_writeback(struct page *page)
 }
 EXPORT_SYMBOL(test_set_page_writeback);
 
-/*
- * Wakes up tasks that are being throttled due to writeback congestion
- */
-void writeback_congestion_end(void)
-{
-       blk_congestion_end(WRITE);
-}
-EXPORT_SYMBOL(writeback_congestion_end);
-
 /*
  * Return true if any of the pages in the mapping are marged with the
  * passed tag.
index a8c003e7b3d51ae97c1a443f0c8d2fb1989f57a4..f5fc45472d5ca77d3406b9ced195c45fde97ca78 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/stop_machine.h>
 #include <linux/sort.h>
 #include <linux/pfn.h>
+#include <linux/backing-dev.h>
 
 #include <asm/tlbflush.h>
 #include <asm/div64.h>
@@ -495,17 +496,16 @@ static void __free_pages_ok(struct page *page, unsigned int order)
        int i;
        int reserved = 0;
 
-       arch_free_page(page, order);
-       if (!PageHighMem(page))
-               debug_check_no_locks_freed(page_address(page),
-                                          PAGE_SIZE<<order);
-
        for (i = 0 ; i < (1 << order) ; ++i)
                reserved += free_pages_check(page + i);
        if (reserved)
                return;
 
+       if (!PageHighMem(page))
+               debug_check_no_locks_freed(page_address(page),PAGE_SIZE<<order);
+       arch_free_page(page, order);
        kernel_map_pages(page, 1 << order, 0);
+
        local_irq_save(flags);
        __count_vm_events(PGFREE, 1 << order);
        free_one_page(page_zone(page), page, order);
@@ -781,13 +781,14 @@ static void fastcall free_hot_cold_page(struct page *page, int cold)
        struct per_cpu_pages *pcp;
        unsigned long flags;
 
-       arch_free_page(page, 0);
-
        if (PageAnon(page))
                page->mapping = NULL;
        if (free_pages_check(page))
                return;
 
+       if (!PageHighMem(page))
+               debug_check_no_locks_freed(page_address(page), PAGE_SIZE);
+       arch_free_page(page, 0);
        kernel_map_pages(page, 1, 0);
 
        pcp = &zone_pcp(zone, get_cpu())->pcp[cold];
@@ -1050,7 +1051,7 @@ nofail_alloc:
                        if (page)
                                goto got_pg;
                        if (gfp_mask & __GFP_NOFAIL) {
-                               blk_congestion_wait(WRITE, HZ/50);
+                               congestion_wait(WRITE, HZ/50);
                                goto nofail_alloc;
                        }
                }
@@ -1113,7 +1114,7 @@ rebalance:
                        do_retry = 1;
        }
        if (do_retry) {
-               blk_congestion_wait(WRITE, HZ/50);
+               congestion_wait(WRITE, HZ/50);
                goto rebalance;
        }
 
@@ -1688,6 +1689,8 @@ void __meminit memmap_init_zone(unsigned long size, int nid, unsigned long zone,
        for (pfn = start_pfn; pfn < end_pfn; pfn++) {
                if (!early_pfn_valid(pfn))
                        continue;
+               if (!early_pfn_in_nid(pfn, nid))
+                       continue;
                page = pfn_to_page(pfn);
                set_page_links(page, zone, nid, pfn);
                init_page_count(page);
@@ -2294,19 +2297,6 @@ unsigned long __init zone_absent_pages_in_node(int nid,
        return __absent_pages_in_range(nid, zone_start_pfn, zone_end_pfn);
 }
 
-/* Return the zone index a PFN is in */
-int memmap_zone_idx(struct page *lmem_map)
-{
-       int i;
-       unsigned long phys_addr = virt_to_phys(lmem_map);
-       unsigned long pfn = phys_addr >> PAGE_SHIFT;
-
-       for (i = 0; i < MAX_NR_ZONES; i++)
-               if (pfn < arch_zone_highest_possible_pfn[i])
-                       break;
-
-       return i;
-}
 #else
 static inline unsigned long zone_spanned_pages_in_node(int nid,
                                        unsigned long zone_type,
@@ -2325,10 +2315,6 @@ static inline unsigned long zone_absent_pages_in_node(int nid,
        return zholes_size[zone_type];
 }
 
-static inline int memmap_zone_idx(struct page *lmem_map)
-{
-       return MAX_NR_ZONES;
-}
 #endif
 
 static void __init calculate_node_totalpages(struct pglist_data *pgdat,
@@ -3136,3 +3122,19 @@ unsigned long page_to_pfn(struct page *page)
 EXPORT_SYMBOL(pfn_to_page);
 EXPORT_SYMBOL(page_to_pfn);
 #endif /* CONFIG_OUT_OF_LINE_PFN_TO_PAGE */
+
+#if MAX_NUMNODES > 1
+/*
+ * Find the highest possible node id.
+ */
+int highest_possible_node_id(void)
+{
+       unsigned int node;
+       unsigned int highest = 0;
+
+       for_each_node_mask(node, node_possible_map)
+               highest = node;
+       return highest;
+}
+EXPORT_SYMBOL(highest_possible_node_id);
+#endif
index e2155d791d9967a6e1bbf496ee9b8728dd9bb4c5..d8a842a586db774f7a6b38fe08b187d0563e13fd 100644 (file)
--- a/mm/rmap.c
+++ b/mm/rmap.c
  * Lock ordering in mm:
  *
  * inode->i_mutex      (while writing or truncating, not reading or faulting)
- *   inode->i_alloc_sem
- *
- * When a page fault occurs in writing from user to file, down_read
- * of mmap_sem nests within i_mutex; in sys_msync, i_mutex nests within
- * down_read of mmap_sem; i_mutex and down_write of mmap_sem are never
- * taken together; in truncation, i_mutex is taken outermost.
- *
- * mm->mmap_sem
- *   page->flags PG_locked (lock_page)
- *     mapping->i_mmap_lock
- *       anon_vma->lock
- *         mm->page_table_lock or pte_lock
- *           zone->lru_lock (in mark_page_accessed, isolate_lru_page)
- *           swap_lock (in swap_duplicate, swap_info_get)
- *             mmlist_lock (in mmput, drain_mmlist and others)
- *             mapping->private_lock (in __set_page_dirty_buffers)
- *             inode_lock (in set_page_dirty's __mark_inode_dirty)
- *               sb_lock (within inode_lock in fs/fs-writeback.c)
- *               mapping->tree_lock (widely used, in set_page_dirty,
- *                         in arch-dependent flush_dcache_mmap_lock,
- *                         within inode_lock in __sync_single_inode)
+ *   inode->i_alloc_sem (vmtruncate_range)
+ *   mm->mmap_sem
+ *     page->flags PG_locked (lock_page)
+ *       mapping->i_mmap_lock
+ *         anon_vma->lock
+ *           mm->page_table_lock or pte_lock
+ *             zone->lru_lock (in mark_page_accessed, isolate_lru_page)
+ *             swap_lock (in swap_duplicate, swap_info_get)
+ *               mmlist_lock (in mmput, drain_mmlist and others)
+ *               mapping->private_lock (in __set_page_dirty_buffers)
+ *               inode_lock (in set_page_dirty's __mark_inode_dirty)
+ *                 sb_lock (within inode_lock in fs/fs-writeback.c)
+ *                 mapping->tree_lock (widely used, in set_page_dirty,
+ *                           in arch-dependent flush_dcache_mmap_lock,
+ *                           within inode_lock in __sync_single_inode)
  */
 
 #include <linux/mm.h>
@@ -576,15 +570,14 @@ void page_add_file_rmap(struct page *page)
 void page_remove_rmap(struct page *page)
 {
        if (atomic_add_negative(-1, &page->_mapcount)) {
-#ifdef CONFIG_DEBUG_VM
                if (unlikely(page_mapcount(page) < 0)) {
                        printk (KERN_EMERG "Eeek! page_mapcount(page) went negative! (%d)\n", page_mapcount(page));
                        printk (KERN_EMERG "  page->flags = %lx\n", page->flags);
                        printk (KERN_EMERG "  page->count = %x\n", page_count(page));
                        printk (KERN_EMERG "  page->mapping = %p\n", page->mapping);
+                       BUG();
                }
-#endif
-               BUG_ON(page_mapcount(page) < 0);
+
                /*
                 * It would be tidy to reset the PageAnon mapping here,
                 * but that might overwrite a racing page_add_anon_rmap
index bb8ca7ef70940de154adfcbb7f30debd3f3c3737..4959535fc14c4a7aa3308bb316c4a13a3ba2baa3 100644 (file)
@@ -48,6 +48,7 @@
 #include <linux/ctype.h>
 #include <linux/migrate.h>
 #include <linux/highmem.h>
+#include <linux/backing-dev.h>
 
 #include <asm/uaccess.h>
 #include <asm/div64.h>
@@ -1131,7 +1132,7 @@ repeat:
                        page_cache_release(swappage);
                        if (error == -ENOMEM) {
                                /* let kswapd refresh zone for GFP_ATOMICs */
-                               blk_congestion_wait(WRITE, HZ/50);
+                               congestion_wait(WRITE, HZ/50);
                        }
                        goto repeat;
                }
@@ -1362,6 +1363,7 @@ shmem_get_inode(struct super_block *sb, int mode, dev_t dev)
                inode->i_mapping->a_ops = &shmem_aops;
                inode->i_mapping->backing_dev_info = &shmem_backing_dev_info;
                inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+               inode->i_generation = get_seconds();
                info = SHMEM_I(inode);
                memset(info, 0, (char *)inode - (char *)info);
                spin_lock_init(&info->lock);
@@ -1956,6 +1958,85 @@ static struct xattr_handler *shmem_xattr_handlers[] = {
 };
 #endif
 
+static struct dentry *shmem_get_parent(struct dentry *child)
+{
+       return ERR_PTR(-ESTALE);
+}
+
+static int shmem_match(struct inode *ino, void *vfh)
+{
+       __u32 *fh = vfh;
+       __u64 inum = fh[2];
+       inum = (inum << 32) | fh[1];
+       return ino->i_ino == inum && fh[0] == ino->i_generation;
+}
+
+static struct dentry *shmem_get_dentry(struct super_block *sb, void *vfh)
+{
+       struct dentry *de = NULL;
+       struct inode *inode;
+       __u32 *fh = vfh;
+       __u64 inum = fh[2];
+       inum = (inum << 32) | fh[1];
+
+       inode = ilookup5(sb, (unsigned long)(inum+fh[0]), shmem_match, vfh);
+       if (inode) {
+               de = d_find_alias(inode);
+               iput(inode);
+       }
+
+       return de? de: ERR_PTR(-ESTALE);
+}
+
+static struct dentry *shmem_decode_fh(struct super_block *sb, __u32 *fh,
+               int len, int type,
+               int (*acceptable)(void *context, struct dentry *de),
+               void *context)
+{
+       if (len < 3)
+               return ERR_PTR(-ESTALE);
+
+       return sb->s_export_op->find_exported_dentry(sb, fh, NULL, acceptable,
+                                                       context);
+}
+
+static int shmem_encode_fh(struct dentry *dentry, __u32 *fh, int *len,
+                               int connectable)
+{
+       struct inode *inode = dentry->d_inode;
+
+       if (*len < 3)
+               return 255;
+
+       if (hlist_unhashed(&inode->i_hash)) {
+               /* Unfortunately insert_inode_hash is not idempotent,
+                * so as we hash inodes here rather than at creation
+                * time, we need a lock to ensure we only try
+                * to do it once
+                */
+               static DEFINE_SPINLOCK(lock);
+               spin_lock(&lock);
+               if (hlist_unhashed(&inode->i_hash))
+                       __insert_inode_hash(inode,
+                                           inode->i_ino + inode->i_generation);
+               spin_unlock(&lock);
+       }
+
+       fh[0] = inode->i_generation;
+       fh[1] = inode->i_ino;
+       fh[2] = ((__u64)inode->i_ino) >> 32;
+
+       *len = 3;
+       return 1;
+}
+
+static struct export_operations shmem_export_ops = {
+       .get_parent     = shmem_get_parent,
+       .get_dentry     = shmem_get_dentry,
+       .encode_fh      = shmem_encode_fh,
+       .decode_fh      = shmem_decode_fh,
+};
+
 static int shmem_parse_options(char *options, int *mode, uid_t *uid,
        gid_t *gid, unsigned long *blocks, unsigned long *inodes,
        int *policy, nodemask_t *policy_nodes)
@@ -2128,6 +2209,7 @@ static int shmem_fill_super(struct super_block *sb,
                                        &inodes, &policy, &policy_nodes))
                        return -EINVAL;
        }
+       sb->s_export_op = &shmem_export_ops;
 #else
        sb->s_flags |= MS_NOUSER;
 #endif
index c946bf4687181a301b33f506ee7b454b1fed6e05..f5664c5b9eb1433425501486562c3c6bb98b2237 100644 (file)
@@ -35,7 +35,7 @@ shmem_get_acl(struct inode *inode, int type)
 }
 
 /**
- * shmem_get_acl  -   generic_acl_operations->setacl() operation
+ * shmem_set_acl  -   generic_acl_operations->setacl() operation
  */
 static void
 shmem_set_acl(struct inode *inode, int type, struct posix_acl *acl)
index e9a63b5a7fb988287093f614ef8dbf233cbdffc6..84c631f30741016e0e73602129ed6c33d6ca88f9 100644 (file)
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -1106,15 +1106,18 @@ static inline int cache_free_alien(struct kmem_cache *cachep, void *objp)
        int nodeid = slabp->nodeid;
        struct kmem_list3 *l3;
        struct array_cache *alien = NULL;
+       int node;
+
+       node = numa_node_id();
 
        /*
         * Make sure we are not freeing a object from another node to the array
         * cache on this cpu.
         */
-       if (likely(slabp->nodeid == numa_node_id()))
+       if (likely(slabp->nodeid == node))
                return 0;
 
-       l3 = cachep->nodelists[numa_node_id()];
+       l3 = cachep->nodelists[node];
        STATS_INC_NODEFREES(cachep);
        if (l3->alien && l3->alien[nodeid]) {
                alien = l3->alien[nodeid];
@@ -1325,7 +1328,6 @@ static void init_list(struct kmem_cache *cachep, struct kmem_list3 *list,
 {
        struct kmem_list3 *ptr;
 
-       BUG_ON(cachep->nodelists[nodeid] != list);
        ptr = kmalloc_node(sizeof(struct kmem_list3), GFP_KERNEL, nodeid);
        BUG_ON(!ptr);
 
@@ -1352,6 +1354,7 @@ void __init kmem_cache_init(void)
        struct cache_names *names;
        int i;
        int order;
+       int node;
 
        for (i = 0; i < NUM_INIT_LISTS; i++) {
                kmem_list3_init(&initkmem_list3[i]);
@@ -1386,12 +1389,14 @@ void __init kmem_cache_init(void)
         * 6) Resize the head arrays of the kmalloc caches to their final sizes.
         */
 
+       node = numa_node_id();
+
        /* 1) create the cache_cache */
        INIT_LIST_HEAD(&cache_chain);
        list_add(&cache_cache.next, &cache_chain);
        cache_cache.colour_off = cache_line_size();
        cache_cache.array[smp_processor_id()] = &initarray_cache.cache;
-       cache_cache.nodelists[numa_node_id()] = &initkmem_list3[CACHE_CACHE];
+       cache_cache.nodelists[node] = &initkmem_list3[CACHE_CACHE];
 
        cache_cache.buffer_size = ALIGN(cache_cache.buffer_size,
                                        cache_line_size());
@@ -1496,19 +1501,18 @@ void __init kmem_cache_init(void)
        }
        /* 5) Replace the bootstrap kmem_list3's */
        {
-               int node;
+               int nid;
+
                /* Replace the static kmem_list3 structures for the boot cpu */
-               init_list(&cache_cache, &initkmem_list3[CACHE_CACHE],
-                         numa_node_id());
+               init_list(&cache_cache, &initkmem_list3[CACHE_CACHE], node);
 
-               for_each_online_node(node) {
+               for_each_online_node(nid) {
                        init_list(malloc_sizes[INDEX_AC].cs_cachep,
-                                 &initkmem_list3[SIZE_AC + node], node);
+                                 &initkmem_list3[SIZE_AC + nid], nid);
 
                        if (INDEX_AC != INDEX_L3) {
                                init_list(malloc_sizes[INDEX_L3].cs_cachep,
-                                         &initkmem_list3[SIZE_L3 + node],
-                                         node);
+                                         &initkmem_list3[SIZE_L3 + nid], nid);
                        }
                }
        }
@@ -2918,6 +2922,9 @@ static void *cache_alloc_refill(struct kmem_cache *cachep, gfp_t flags)
        int batchcount;
        struct kmem_list3 *l3;
        struct array_cache *ac;
+       int node;
+
+       node = numa_node_id();
 
        check_irq_off();
        ac = cpu_cache_get(cachep);
@@ -2931,7 +2938,7 @@ retry:
                 */
                batchcount = BATCHREFILL_LIMIT;
        }
-       l3 = cachep->nodelists[numa_node_id()];
+       l3 = cachep->nodelists[node];
 
        BUG_ON(ac->avail > 0 || !l3);
        spin_lock(&l3->list_lock);
@@ -2961,7 +2968,7 @@ retry:
                        STATS_SET_HIGH(cachep);
 
                        ac->entry[ac->avail++] = slab_get_obj(cachep, slabp,
-                                                           numa_node_id());
+                                                           node);
                }
                check_slabp(cachep, slabp);
 
@@ -2980,7 +2987,7 @@ alloc_done:
 
        if (unlikely(!ac->avail)) {
                int x;
-               x = cache_grow(cachep, flags, numa_node_id());
+               x = cache_grow(cachep, flags, node);
 
                /* cache_grow can reenable interrupts, then ac could change. */
                ac = cpu_cache_get(cachep);
@@ -3145,12 +3152,15 @@ void *fallback_alloc(struct kmem_cache *cache, gfp_t flags)
        struct zone **z;
        void *obj = NULL;
 
-       for (z = zonelist->zones; *z && !obj; z++)
+       for (z = zonelist->zones; *z && !obj; z++) {
+               int nid = zone_to_nid(*z);
+
                if (zone_idx(*z) <= ZONE_NORMAL &&
-                               cpuset_zone_allowed(*z, flags))
+                               cpuset_zone_allowed(*z, flags) &&
+                               cache->nodelists[nid])
                        obj = __cache_alloc_node(cache,
-                                       flags | __GFP_THISNODE,
-                                       zone_to_nid(*z));
+                                       flags | __GFP_THISNODE, nid);
+       }
        return obj;
 }
 
index f4edbc179d14423e1f3acf9555b96bc9795b37bc..e07b1e682c38f5fca96436904eb1a9a262ce1426 100644 (file)
@@ -96,7 +96,6 @@ invalidate_complete_page(struct address_space *mapping, struct page *page)
                return 0;
 
        ret = remove_mapping(mapping, page);
-       ClearPageUptodate(page);
 
        return ret;
 }
@@ -302,7 +301,7 @@ invalidate_complete_page2(struct address_space *mapping, struct page *page)
        if (page->mapping != mapping)
                return 0;
 
-       if (PagePrivate(page) && !try_to_release_page(page, 0))
+       if (PagePrivate(page) && !try_to_release_page(page, GFP_KERNEL))
                return 0;
 
        write_lock_irq(&mapping->tree_lock);
@@ -396,6 +395,7 @@ int invalidate_inode_pages2_range(struct address_space *mapping,
                pagevec_release(&pvec);
                cond_resched();
        }
+       WARN_ON_ONCE(ret);
        return ret;
 }
 EXPORT_SYMBOL_GPL(invalidate_inode_pages2_range);
index 750ab6ed13fca56ca42581dd32f74912fd1b347c..1133dd3aafcf4c02e5b2d109b02f45013b7d9d11 100644 (file)
@@ -428,8 +428,11 @@ void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask,
        if (array_size > PAGE_SIZE) {
                pages = __vmalloc_node(array_size, gfp_mask, PAGE_KERNEL, node);
                area->flags |= VM_VPAGES;
-       } else
-               pages = kmalloc_node(array_size, (gfp_mask & ~__GFP_HIGHMEM), node);
+       } else {
+               pages = kmalloc_node(array_size,
+                               (gfp_mask & ~(__GFP_HIGHMEM | __GFP_ZERO)),
+                               node);
+       }
        area->pages = pages;
        if (!area->pages) {
                remove_vm_area(area->addr);
index eca70310adb26239e94c5435eaf2abf0271c89fa..f05527bf792b1e28b78d3a45cf2244efb4b34cf2 100644 (file)
@@ -378,6 +378,12 @@ static pageout_t pageout(struct page *page, struct address_space *mapping)
        return PAGE_CLEAN;
 }
 
+/*
+ * Attempt to detach a locked page from its ->mapping.  If it is dirty or if
+ * someone else has a ref on the page, abort and return 0.  If it was
+ * successfully detached, return 1.  Assumes the caller has a single ref on
+ * this page.
+ */
 int remove_mapping(struct address_space *mapping, struct page *page)
 {
        BUG_ON(!PageLocked(page));
@@ -1053,7 +1059,7 @@ unsigned long try_to_free_pages(struct zone **zones, gfp_t gfp_mask)
 
                /* Take a nap, wait for some writeback to complete */
                if (sc.nr_scanned && priority < DEF_PRIORITY - 2)
-                       blk_congestion_wait(WRITE, HZ/10);
+                       congestion_wait(WRITE, HZ/10);
        }
        /* top priority shrink_caches still had more to do? don't OOM, then */
        if (!sc.all_unreclaimable)
@@ -1208,7 +1214,7 @@ scan:
                 * another pass across the zones.
                 */
                if (total_scanned && priority < DEF_PRIORITY - 2)
-                       blk_congestion_wait(WRITE, HZ/10);
+                       congestion_wait(WRITE, HZ/10);
 
                /*
                 * We do this so kswapd doesn't build up large priorities for
@@ -1452,7 +1458,7 @@ unsigned long shrink_all_memory(unsigned long nr_pages)
                                goto out;
 
                        if (sc.nr_scanned && prio < DEF_PRIORITY - 2)
-                               blk_congestion_wait(WRITE, HZ / 10);
+                               congestion_wait(WRITE, HZ / 10);
                }
 
                lru_pages = 0;
index da9cfe92715815d5c754eb268c2fd8f84e1467a8..60a508eb1945bd78c05b3a3424a93cb30af7b20f 100644 (file)
@@ -62,7 +62,7 @@ int vlan_dev_rebuild_header(struct sk_buff *skb)
        default:
                printk(VLAN_DBG
                       "%s: unable to resolve type %X addresses.\n", 
-                      dev->name, (int)veth->h_vlan_encapsulated_proto);
+                      dev->name, ntohs(veth->h_vlan_encapsulated_proto));
         
                memcpy(veth->h_source, dev->dev_addr, ETH_ALEN);
                break;
index c0a4ae28fcfab23025ffdaf079dfd9199c8aa8dd..62f6ed1f2f98c9c5c25d70759f87d60e3e4f699d 100644 (file)
@@ -141,7 +141,7 @@ static struct class atm_class = {
 int atm_register_sysfs(struct atm_dev *adev)
 {
        struct class_device *cdev = &adev->class_dev;
-       int i, err;
+       int i, j, err;
 
        cdev->class = &atm_class;
        class_set_devdata(cdev, adev);
@@ -151,10 +151,19 @@ int atm_register_sysfs(struct atm_dev *adev)
        if (err < 0)
                return err;
 
-       for (i = 0; atm_attrs[i]; i++)
-               class_device_create_file(cdev, atm_attrs[i]);
+       for (i = 0; atm_attrs[i]; i++) {
+               err = class_device_create_file(cdev, atm_attrs[i]);
+               if (err)
+                       goto err_out;
+       }
 
        return 0;
+
+err_out:
+       for (j = 0; j < i; j++)
+               class_device_remove_file(cdev, atm_attrs[j]);
+       class_device_del(cdev);
+       return err;
 }
 
 void atm_unregister_sysfs(struct atm_dev *adev)
index 305a099b7477eb8fd0e4a7a7b487b7bd435e6677..67df99e2e5c82b2a4fc72e28dc748a33209fcd55 100644 (file)
 #define BT_DBG(D...)
 #endif
 
-#define VERSION "2.10"
+#define VERSION "2.11"
 
 /* Bluetooth sockets */
 #define BT_MAX_PROTO   8
 static struct net_proto_family *bt_proto[BT_MAX_PROTO];
+static DEFINE_RWLOCK(bt_proto_lock);
 
 int bt_sock_register(int proto, struct net_proto_family *ops)
 {
+       int err = 0;
+
        if (proto < 0 || proto >= BT_MAX_PROTO)
                return -EINVAL;
 
+       write_lock(&bt_proto_lock);
+
        if (bt_proto[proto])
-               return -EEXIST;
+               err = -EEXIST;
+       else
+               bt_proto[proto] = ops;
 
-       bt_proto[proto] = ops;
-       return 0;
+       write_unlock(&bt_proto_lock);
+
+       return err;
 }
 EXPORT_SYMBOL(bt_sock_register);
 
 int bt_sock_unregister(int proto)
 {
+       int err = 0;
+
        if (proto < 0 || proto >= BT_MAX_PROTO)
                return -EINVAL;
 
+       write_lock(&bt_proto_lock);
+
        if (!bt_proto[proto])
-               return -ENOENT;
+               err = -ENOENT;
+       else
+               bt_proto[proto] = NULL;
 
-       bt_proto[proto] = NULL;
-       return 0;
+       write_unlock(&bt_proto_lock);
+
+       return err;
 }
 EXPORT_SYMBOL(bt_sock_unregister);
 
 static int bt_sock_create(struct socket *sock, int proto)
 {
-       int err = 0;
+       int err;
 
        if (proto < 0 || proto >= BT_MAX_PROTO)
                return -EINVAL;
@@ -92,11 +107,18 @@ static int bt_sock_create(struct socket *sock, int proto)
                request_module("bt-proto-%d", proto);
        }
 #endif
+
        err = -EPROTONOSUPPORT;
+
+       read_lock(&bt_proto_lock);
+
        if (bt_proto[proto] && try_module_get(bt_proto[proto]->owner)) {
                err = bt_proto[proto]->create(sock, proto);
                module_put(bt_proto[proto]->owner);
        }
+
+       read_unlock(&bt_proto_lock);
+
        return err; 
 }
 
index 2312d050eeedfb66ed382108f0703f6d2dfc5b9d..4d3424c2421c07b4d925559a1e02e4a6f59b7b19 100644 (file)
@@ -528,12 +528,10 @@ static struct device *bnep_get_device(struct bnep_session *session)
                return NULL;
 
        conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst);
-       if (!conn)
-               return NULL;
 
        hci_dev_put(hdev);
 
-       return &conn->dev;
+       return conn ? &conn->dev : NULL;
 }
 
 int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock)
index 28c55835422afb90f1bbf660f5dcb387bde3779b..5563db1bf526e94d4a48c5af511315c4d3646786 100644 (file)
@@ -43,6 +43,7 @@
 #include <linux/ioctl.h>
 #include <linux/file.h>
 #include <linux/init.h>
+#include <linux/compat.h>
 #include <net/sock.h>
 
 #include <asm/system.h>
@@ -146,24 +147,56 @@ static int bnep_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long
        return 0;
 }
 
+#ifdef CONFIG_COMPAT
+static int bnep_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
+{
+       if (cmd == BNEPGETCONNLIST) {
+               struct bnep_connlist_req cl;
+               uint32_t uci;
+               int err;
+
+               if (get_user(cl.cnum, (uint32_t __user *) arg) ||
+                               get_user(uci, (u32 __user *) (arg + 4)))
+                       return -EFAULT;
+
+               cl.ci = compat_ptr(uci);
+
+               if (cl.cnum <= 0)
+                       return -EINVAL;
+       
+               err = bnep_get_connlist(&cl);
+
+               if (!err && put_user(cl.cnum, (uint32_t __user *) arg))
+                       err = -EFAULT;
+
+               return err;
+       }
+
+       return bnep_sock_ioctl(sock, cmd, arg);
+}
+#endif
+
 static const struct proto_ops bnep_sock_ops = {
-       .family     = PF_BLUETOOTH,
-       .owner      = THIS_MODULE,
-       .release    = bnep_sock_release,
-       .ioctl      = bnep_sock_ioctl,
-       .bind       = sock_no_bind,
-       .getname    = sock_no_getname,
-       .sendmsg    = sock_no_sendmsg,
-       .recvmsg    = sock_no_recvmsg,
-       .poll       = sock_no_poll,
-       .listen     = sock_no_listen,
-       .shutdown   = sock_no_shutdown,
-       .setsockopt = sock_no_setsockopt,
-       .getsockopt = sock_no_getsockopt,
-       .connect    = sock_no_connect,
-       .socketpair = sock_no_socketpair,
-       .accept     = sock_no_accept,
-       .mmap       = sock_no_mmap
+       .family         = PF_BLUETOOTH,
+       .owner          = THIS_MODULE,
+       .release        = bnep_sock_release,
+       .ioctl          = bnep_sock_ioctl,
+#ifdef CONFIG_COMPAT
+       .compat_ioctl   = bnep_sock_compat_ioctl,
+#endif
+       .bind           = sock_no_bind,
+       .getname        = sock_no_getname,
+       .sendmsg        = sock_no_sendmsg,
+       .recvmsg        = sock_no_recvmsg,
+       .poll           = sock_no_poll,
+       .listen         = sock_no_listen,
+       .shutdown       = sock_no_shutdown,
+       .setsockopt     = sock_no_setsockopt,
+       .getsockopt     = sock_no_getsockopt,
+       .connect        = sock_no_connect,
+       .socketpair     = sock_no_socketpair,
+       .accept         = sock_no_accept,
+       .mmap           = sock_no_mmap
 };
 
 static struct proto bnep_proto = {
@@ -181,7 +214,7 @@ static int bnep_sock_create(struct socket *sock, int protocol)
        if (sock->type != SOCK_RAW)
                return -ESOCKTNOSUPPORT;
 
-       sk = sk_alloc(PF_BLUETOOTH, GFP_KERNEL, &bnep_proto, 1);
+       sk = sk_alloc(PF_BLUETOOTH, GFP_ATOMIC, &bnep_proto, 1);
        if (!sk)
                return -ENOMEM;
 
index 10ad7fd91d833f26a188b073d46fea1ed1d2cd16..53295d33dc5c31eb610c1766e5795f3c7a123cfd 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/socket.h>
 #include <linux/ioctl.h>
 #include <linux/file.h>
+#include <linux/compat.h>
 #include <net/sock.h>
 
 #include <linux/isdn/capilli.h>
@@ -137,11 +138,43 @@ static int cmtp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long
        return -EINVAL;
 }
 
+#ifdef CONFIG_COMPAT
+static int cmtp_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
+{
+       if (cmd == CMTPGETCONNLIST) {
+               struct cmtp_connlist_req cl;
+               uint32_t uci;
+               int err;
+
+               if (get_user(cl.cnum, (uint32_t __user *) arg) ||
+                               get_user(uci, (u32 __user *) (arg + 4)))
+                       return -EFAULT;
+
+               cl.ci = compat_ptr(uci);
+
+               if (cl.cnum <= 0)
+                       return -EINVAL;
+       
+               err = cmtp_get_connlist(&cl);
+
+               if (!err && put_user(cl.cnum, (uint32_t __user *) arg))
+                       err = -EFAULT;
+
+               return err;
+       }
+
+       return cmtp_sock_ioctl(sock, cmd, arg);
+}
+#endif
+
 static const struct proto_ops cmtp_sock_ops = {
        .family         = PF_BLUETOOTH,
        .owner          = THIS_MODULE,
        .release        = cmtp_sock_release,
        .ioctl          = cmtp_sock_ioctl,
+#ifdef CONFIG_COMPAT
+       .compat_ioctl   = cmtp_sock_compat_ioctl,
+#endif
        .bind           = sock_no_bind,
        .getname        = sock_no_getname,
        .sendmsg        = sock_no_sendmsg,
@@ -172,7 +205,7 @@ static int cmtp_sock_create(struct socket *sock, int protocol)
        if (sock->type != SOCK_RAW)
                return -ESOCKTNOSUPPORT;
 
-       sk = sk_alloc(PF_BLUETOOTH, GFP_KERNEL, &cmtp_proto, 1);
+       sk = sk_alloc(PF_BLUETOOTH, GFP_ATOMIC, &cmtp_proto, 1);
        if (!sk)
                return -ENOMEM;
 
index 90e3a285a17eaf9a4bde198879748d8a4da680a7..6cd5711fa28a59265403a81f608e6698e7f03dfa 100644 (file)
@@ -51,7 +51,7 @@
 #define BT_DBG(D...)
 #endif
 
-static void hci_acl_connect(struct hci_conn *conn)
+void hci_acl_connect(struct hci_conn *conn)
 {
        struct hci_dev *hdev = conn->hdev;
        struct inquiry_entry *ie;
@@ -63,6 +63,8 @@ static void hci_acl_connect(struct hci_conn *conn)
        conn->out   = 1;
        conn->link_mode = HCI_LM_MASTER;
 
+       conn->attempt++;
+
        memset(&cp, 0, sizeof(cp));
        bacpy(&cp.bdaddr, &conn->dst);
        cp.pscan_rep_mode = 0x02;
@@ -80,7 +82,7 @@ static void hci_acl_connect(struct hci_conn *conn)
                cp.role_switch  = 0x01;
        else
                cp.role_switch  = 0x00;
-               
+
        hci_send_cmd(hdev, OGF_LINK_CTL, OCF_CREATE_CONN, sizeof(cp), &cp);
 }
 
index d43d0c8909752564796b540a61cb58389cc8cb0d..65f094845719126013cfb9f3c1c19e11f4b2b566 100644 (file)
@@ -414,9 +414,12 @@ static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
 
        if (status) {
                if (conn && conn->state == BT_CONNECT) {
-                       conn->state = BT_CLOSED;
-                       hci_proto_connect_cfm(conn, status);
-                       hci_conn_del(conn);
+                       if (status != 0x0c || conn->attempt > 2) {
+                               conn->state = BT_CLOSED;
+                               hci_proto_connect_cfm(conn, status);
+                               hci_conn_del(conn);
+                       } else
+                               conn->state = BT_CONNECT2;
                }
        } else {
                if (!conn) {
@@ -728,7 +731,7 @@ static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *sk
 static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
        struct hci_ev_conn_complete *ev = (struct hci_ev_conn_complete *) skb->data;
-       struct hci_conn *conn;
+       struct hci_conn *conn, *pend;
 
        BT_DBG("%s", hdev->name);
 
@@ -801,6 +804,10 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s
        if (ev->status)
                hci_conn_del(conn);
 
+       pend = hci_conn_hash_lookup_state(hdev, ACL_LINK, BT_CONNECT2);
+       if (pend)
+               hci_acl_connect(pend);
+
        hci_dev_unlock(hdev);
 }
 
index 1a35d343e08a593f91cc71fce52306a50d991c4b..f26a9eb49945c8805db60c07964b9c1a734f4556 100644 (file)
@@ -618,7 +618,7 @@ static int hci_sock_create(struct socket *sock, int protocol)
 
        sock->ops = &hci_sock_ops;
 
-       sk = sk_alloc(PF_BLUETOOTH, GFP_KERNEL, &hci_sk_proto, 1);
+       sk = sk_alloc(PF_BLUETOOTH, GFP_ATOMIC, &hci_sk_proto, 1);
        if (!sk)
                return -ENOMEM;
 
index 989b22d9042e92f929435d9f0290d2d429e7fd75..954eb74eb370a34cb97050c9bec17e8cbfdff08c 100644 (file)
@@ -242,10 +242,14 @@ static void add_conn(void *data)
        struct hci_conn *conn = data;
        int i;
 
-       device_register(&conn->dev);
+       if (device_register(&conn->dev) < 0) {
+               BT_ERR("Failed to register connection device");
+               return;
+       }
 
        for (i = 0; conn_attrs[i]; i++)
-               device_create_file(&conn->dev, conn_attrs[i]);
+               if (device_create_file(&conn->dev, conn_attrs[i]) < 0)
+                       BT_ERR("Failed to create connection attribute");
 }
 
 void hci_conn_add_sysfs(struct hci_conn *conn)
@@ -295,11 +299,7 @@ int hci_register_sysfs(struct hci_dev *hdev)
        BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
 
        dev->class = bt_class;
-
-       if (hdev->parent)
-               dev->parent = hdev->parent;
-       else
-               dev->parent = &bt_platform->dev;
+       dev->parent = hdev->parent;
 
        strlcpy(dev->bus_id, hdev->name, BUS_ID_SIZE);
 
@@ -312,7 +312,8 @@ int hci_register_sysfs(struct hci_dev *hdev)
                return err;
 
        for (i = 0; bt_attrs[i]; i++)
-               device_create_file(dev, bt_attrs[i]);
+               if (device_create_file(dev, bt_attrs[i]) < 0)
+                       BT_ERR("Failed to create device attribute");
 
        return 0;
 }
index 03b5dadb49511f90b0c57ee6d9d677d580c5ef18..66782010f82cbacf442eba7a2d6c64f17d8c0964 100644 (file)
@@ -507,14 +507,12 @@ static int hidp_session(void *arg)
 
        hidp_del_timer(session);
 
-       if (intr_sk->sk_state != BT_CONNECTED)
-               wait_event_timeout(*(ctrl_sk->sk_sleep), (ctrl_sk->sk_state == BT_CLOSED), HZ);
-
-       fput(session->ctrl_sock->file);
+       fput(session->intr_sock->file);
 
-       wait_event_timeout(*(intr_sk->sk_sleep), (intr_sk->sk_state == BT_CLOSED), HZ);
+       wait_event_timeout(*(ctrl_sk->sk_sleep),
+               (ctrl_sk->sk_state == BT_CLOSED), msecs_to_jiffies(500));
 
-       fput(session->intr_sock->file);
+       fput(session->ctrl_sock->file);
 
        __hidp_unlink_session(session);
 
@@ -541,12 +539,10 @@ static struct device *hidp_get_device(struct hidp_session *session)
                return NULL;
 
        conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst);
-       if (!conn)
-               return NULL;
 
        hci_dev_put(hdev);
 
-       return &conn->dev;
+       return conn ? &conn->dev : NULL;
 }
 
 static inline void hidp_setup_input(struct hidp_session *session, struct hidp_connadd_req *req)
index 099646e4e2ef7407b45687f2188d0bfe2cd7402b..407fba43c1b973cda01122be9cc3dce198c2b930 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/ioctl.h>
 #include <linux/file.h>
 #include <linux/init.h>
+#include <linux/compat.h>
 #include <net/sock.h>
 
 #include "hidp.h"
@@ -143,11 +144,88 @@ static int hidp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long
        return -EINVAL;
 }
 
+#ifdef CONFIG_COMPAT
+struct compat_hidp_connadd_req {
+       int   ctrl_sock;        // Connected control socket
+       int   intr_sock;        // Connteted interrupt socket
+       __u16 parser;
+       __u16 rd_size;
+       compat_uptr_t rd_data;
+       __u8  country;
+       __u8  subclass;
+       __u16 vendor;
+       __u16 product;
+       __u16 version;
+       __u32 flags;
+       __u32 idle_to;
+       char  name[128];
+};
+
+static int hidp_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
+{
+       if (cmd == HIDPGETCONNLIST) {
+               struct hidp_connlist_req cl;
+               uint32_t uci;
+               int err;
+
+               if (get_user(cl.cnum, (uint32_t __user *) arg) ||
+                               get_user(uci, (u32 __user *) (arg + 4)))
+                       return -EFAULT;
+
+               cl.ci = compat_ptr(uci);
+
+               if (cl.cnum <= 0)
+                       return -EINVAL;
+
+               err = hidp_get_connlist(&cl);
+
+               if (!err && put_user(cl.cnum, (uint32_t __user *) arg))
+                       err = -EFAULT;
+
+               return err;
+       } else if (cmd == HIDPCONNADD) {
+               struct compat_hidp_connadd_req ca;
+               struct hidp_connadd_req __user *uca;
+
+               uca = compat_alloc_user_space(sizeof(*uca));
+
+               if (copy_from_user(&ca, (void *) arg, sizeof(ca)))
+                       return -EFAULT;
+
+               if (put_user(ca.ctrl_sock, &uca->ctrl_sock) ||
+                               put_user(ca.intr_sock, &uca->intr_sock) ||
+                               put_user(ca.parser, &uca->parser) ||
+                               put_user(ca.rd_size, &uca->parser) ||
+                               put_user(compat_ptr(ca.rd_data), &uca->rd_data) ||
+                               put_user(ca.country, &uca->country) ||
+                               put_user(ca.subclass, &uca->subclass) ||
+                               put_user(ca.vendor, &uca->vendor) ||
+                               put_user(ca.product, &uca->product) ||
+                               put_user(ca.version, &uca->version) ||
+                               put_user(ca.flags, &uca->flags) ||
+                               put_user(ca.idle_to, &uca->idle_to) ||
+                               copy_to_user(&uca->name[0], &ca.name[0], 128))
+                       return -EFAULT;
+               
+               arg = (unsigned long) uca;
+
+               /* Fall through. We don't actually write back any _changes_
+                  to the structure anyway, so there's no need to copy back
+                  into the original compat version */
+       }
+
+       return hidp_sock_ioctl(sock, cmd, arg);
+}
+#endif
+
 static const struct proto_ops hidp_sock_ops = {
        .family         = PF_BLUETOOTH,
        .owner          = THIS_MODULE,
        .release        = hidp_sock_release,
        .ioctl          = hidp_sock_ioctl,
+#ifdef CONFIG_COMPAT
+       .compat_ioctl   = hidp_sock_compat_ioctl,
+#endif
        .bind           = sock_no_bind,
        .getname        = sock_no_getname,
        .sendmsg        = sock_no_sendmsg,
@@ -178,7 +256,7 @@ static int hidp_sock_create(struct socket *sock, int protocol)
        if (sock->type != SOCK_RAW)
                return -ESOCKTNOSUPPORT;
 
-       sk = sk_alloc(PF_BLUETOOTH, GFP_KERNEL, &hidp_proto, 1);
+       sk = sk_alloc(PF_BLUETOOTH, GFP_ATOMIC, &hidp_proto, 1);
        if (!sk)
                return -ENOMEM;
 
index d56f60b392ac512b36a736f928844208ec88847a..2b3dcb8f90fadebdcde2ace1feed9cd90cf76b0e 100644 (file)
@@ -559,7 +559,7 @@ static int l2cap_sock_create(struct socket *sock, int protocol)
 
        sock->ops = &l2cap_sock_ops;
 
-       sk = l2cap_sock_alloc(sock, protocol, GFP_KERNEL);
+       sk = l2cap_sock_alloc(sock, protocol, GFP_ATOMIC);
        if (!sk)
                return -ENOMEM;
 
@@ -2216,7 +2216,8 @@ static int __init l2cap_init(void)
                goto error;
        }
 
-       class_create_file(bt_class, &class_attr_l2cap);
+       if (class_create_file(bt_class, &class_attr_l2cap) < 0)
+               BT_ERR("Failed to create L2CAP info file");
 
        BT_INFO("L2CAP ver %s", VERSION);
        BT_INFO("L2CAP socket layer initialized");
index 468df3b953f6d3c615169a0939e50ec924eb1af8..ddc4e9d5963e850f86d768abef9481f849392439 100644 (file)
@@ -2058,7 +2058,8 @@ static int __init rfcomm_init(void)
 
        kernel_thread(rfcomm_run, NULL, CLONE_KERNEL);
 
-       class_create_file(bt_class, &class_attr_rfcomm_dlc);
+       if (class_create_file(bt_class, &class_attr_rfcomm_dlc) < 0)
+               BT_ERR("Failed to create RFCOMM info file");
 
        rfcomm_init_sockets();
 
index 220fee04e7f274a3d31505f0133af59e742a4f74..544d65b7baa7de67fe796ec2e4cf68a0c6051e1f 100644 (file)
@@ -336,7 +336,8 @@ static int rfcomm_sock_create(struct socket *sock, int protocol)
 
        sock->ops = &rfcomm_sock_ops;
 
-       if (!(sk = rfcomm_sock_alloc(sock, protocol, GFP_KERNEL)))
+       sk = rfcomm_sock_alloc(sock, protocol, GFP_ATOMIC);
+       if (!sk)
                return -ENOMEM;
 
        rfcomm_sock_init(sk, NULL);
@@ -944,7 +945,8 @@ int __init rfcomm_init_sockets(void)
        if (err < 0)
                goto error;
 
-       class_create_file(bt_class, &class_attr_rfcomm);
+       if (class_create_file(bt_class, &class_attr_rfcomm) < 0)
+               BT_ERR("Failed to create RFCOMM info file");
 
        BT_INFO("RFCOMM socket layer initialized");
 
index 1958ad1b8541e57be7f32bb70b2b19a242884dce..b8e3a5f1c8a80683d5806662cc7f55c46a656bee 100644 (file)
@@ -172,12 +172,10 @@ static struct device *rfcomm_get_device(struct rfcomm_dev *dev)
                return NULL;
 
        conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &dev->dst);
-       if (!conn)
-               return NULL;
 
        hci_dev_put(hdev);
 
-       return &conn->dev;
+       return conn ? &conn->dev : NULL;
 }
 
 static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
@@ -767,6 +765,9 @@ static void rfcomm_tty_set_termios(struct tty_struct *tty, struct termios *old)
 
        BT_DBG("tty %p termios %p", tty, old);
 
+       if (!dev)
+               return;
+
        /* Handle turning off CRTSCTS */
        if ((old->c_cflag & CRTSCTS) && !(new->c_cflag & CRTSCTS)) 
                BT_DBG("Turning off CRTSCTS unsupported");
index 7714a2ec3854d032ed0038ebcc8aea5e39494de7..5d13d4f317538e1280118ac7f7f35994437163bf 100644 (file)
@@ -452,7 +452,8 @@ static int sco_sock_create(struct socket *sock, int protocol)
 
        sock->ops = &sco_sock_ops;
 
-       if (!(sk = sco_sock_alloc(sock, protocol, GFP_KERNEL)))
+       sk = sco_sock_alloc(sock, protocol, GFP_ATOMIC);
+       if (!sk)
                return -ENOMEM;
 
        sco_sock_init(sk, NULL);
@@ -967,7 +968,8 @@ static int __init sco_init(void)
                goto error;
        }
 
-       class_create_file(bt_class, &class_attr_sco);
+       if (class_create_file(bt_class, &class_attr_sco) < 0)
+               BT_ERR("Failed to create SCO info file");
 
        BT_INFO("SCO (Voice Link) ver %s", VERSION);
        BT_INFO("SCO socket layer initialized");
index 3a73b8c94271c94beaf3159a078a4fa46c2bb6b0..d9f04864d15d859d0ada8bbb57564999e55eb676 100644 (file)
@@ -128,7 +128,10 @@ void br_fdb_cleanup(unsigned long _data)
        mod_timer(&br->gc_timer, jiffies + HZ/10);
 }
 
-void br_fdb_delete_by_port(struct net_bridge *br, struct net_bridge_port *p)
+
+void br_fdb_delete_by_port(struct net_bridge *br,
+                          const struct net_bridge_port *p,
+                          int do_all)
 {
        int i;
 
@@ -142,6 +145,8 @@ void br_fdb_delete_by_port(struct net_bridge *br, struct net_bridge_port *p)
                        if (f->dst != p) 
                                continue;
 
+                       if (f->is_static && !do_all)
+                               continue;
                        /*
                         * if multiple ports all have the same device address
                         * then when one port is deleted, assign
index b1211d5342f6cac5f43926a2c6a39f1651cb6761..f753c40c11d25743d6d13982443b7ebaa1020e38 100644 (file)
@@ -163,7 +163,7 @@ static void del_nbp(struct net_bridge_port *p)
        br_stp_disable_port(p);
        spin_unlock_bh(&br->lock);
 
-       br_fdb_delete_by_port(br, p);
+       br_fdb_delete_by_port(br, p, 1);
 
        list_del_rcu(&p->list);
 
@@ -448,7 +448,7 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
 
        return 0;
 err2:
-       br_fdb_delete_by_port(br, p);
+       br_fdb_delete_by_port(br, p, 1);
 err1:
        kobject_del(&p->kobj);
 err0:
index c491fb2f280ebf7b1cf2395371c43d33bf36f43c..74258d86f256daf06b1717331026798640820b87 100644 (file)
@@ -143,7 +143,7 @@ extern void br_fdb_changeaddr(struct net_bridge_port *p,
                              const unsigned char *newaddr);
 extern void br_fdb_cleanup(unsigned long arg);
 extern void br_fdb_delete_by_port(struct net_bridge *br,
-                          struct net_bridge_port *p);
+                                 const struct net_bridge_port *p, int do_all);
 extern struct net_bridge_fdb_entry *__br_fdb_get(struct net_bridge *br,
                                                 const unsigned char *addr);
 extern struct net_bridge_fdb_entry *br_fdb_get(struct net_bridge *br,
index 14cd025079af0393abba67e7c3704dc2bd688470..d294224592db0455e0bd31d7f04ab6a290abc21e 100644 (file)
@@ -113,6 +113,8 @@ void br_stp_disable_port(struct net_bridge_port *p)
        del_timer(&p->forward_delay_timer);
        del_timer(&p->hold_timer);
 
+       br_fdb_delete_by_port(br, p, 0);
+
        br_configuration_update(br);
 
        br_port_state_selection(br);
index d5d69fa15d07a65a26975797d654813e5f055568..52d32f1bc7281c6da3276ae78a0cad1e63aa4426 100644 (file)
@@ -285,8 +285,7 @@ void scm_detach_fds_compat(struct msghdr *kmsg, struct scm_cookie *scm)
 
        if (i > 0) {
                int cmlen = CMSG_COMPAT_LEN(i * sizeof(int));
-               if (!err)
-                       err = put_user(SOL_SOCKET, &cm->cmsg_level);
+               err = put_user(SOL_SOCKET, &cm->cmsg_level);
                if (!err)
                        err = put_user(SCM_RIGHTS, &cm->cmsg_type);
                if (!err)
index 4d891beab13899cd96c74b8a6a88b5ef5d6aba43..81c426adcd1ec66b760f1447d6cd9dfe4402e574 100644 (file)
@@ -3502,8 +3502,6 @@ static int __init net_dev_init(void)
 
        BUG_ON(!dev_boot_phase);
 
-       net_random_init();
-
        if (dev_proc_init())
                goto out;
 
index f23e7e38654319682cd2f92d8feadf5c172615f1..b16d31ae5e54db47078a2f6039e1a776e6a02578 100644 (file)
@@ -85,6 +85,14 @@ static void flow_cache_new_hashrnd(unsigned long arg)
        add_timer(&flow_hash_rnd_timer);
 }
 
+static void flow_entry_kill(int cpu, struct flow_cache_entry *fle)
+{
+       if (fle->object)
+               atomic_dec(fle->object_ref);
+       kmem_cache_free(flow_cachep, fle);
+       flow_count(cpu)--;
+}
+
 static void __flow_cache_shrink(int cpu, int shrink_to)
 {
        struct flow_cache_entry *fle, **flp;
@@ -100,10 +108,7 @@ static void __flow_cache_shrink(int cpu, int shrink_to)
                }
                while ((fle = *flp) != NULL) {
                        *flp = fle->next;
-                       if (fle->object)
-                               atomic_dec(fle->object_ref);
-                       kmem_cache_free(flow_cachep, fle);
-                       flow_count(cpu)--;
+                       flow_entry_kill(cpu, fle);
                }
        }
 }
@@ -220,24 +225,33 @@ void *flow_cache_lookup(struct flowi *key, u16 family, u8 dir,
 
 nocache:
        {
+               int err;
                void *obj;
                atomic_t *obj_ref;
 
-               resolver(key, family, dir, &obj, &obj_ref);
+               err = resolver(key, family, dir, &obj, &obj_ref);
 
                if (fle) {
-                       fle->genid = atomic_read(&flow_cache_genid);
-
-                       if (fle->object)
-                               atomic_dec(fle->object_ref);
-
-                       fle->object = obj;
-                       fle->object_ref = obj_ref;
-                       if (obj)
-                               atomic_inc(fle->object_ref);
+                       if (err) {
+                               /* Force security policy check on next lookup */
+                               *head = fle->next;
+                               flow_entry_kill(cpu, fle);
+                       } else {
+                               fle->genid = atomic_read(&flow_cache_genid);
+
+                               if (fle->object)
+                                       atomic_dec(fle->object_ref);
+
+                               fle->object = obj;
+                               fle->object_ref = obj_ref;
+                               if (obj)
+                                       atomic_inc(fle->object_ref);
+                       }
                }
                local_bh_enable();
 
+               if (err)
+                       obj = ERR_PTR(err);
                return obj;
        }
 }
index ead5920c26d644d949369987f28adb83f461d1c9..9308af060b44d61284d6ce654b82029dbc0d6738 100644 (file)
@@ -335,13 +335,13 @@ void netpoll_send_udp(struct netpoll *np, const char *msg, int len)
        memcpy(skb->data, msg, len);
        skb->len += len;
 
-       udph = (struct udphdr *) skb_push(skb, sizeof(*udph));
+       skb->h.uh = udph = (struct udphdr *) skb_push(skb, sizeof(*udph));
        udph->source = htons(np->local_port);
        udph->dest = htons(np->remote_port);
        udph->len = htons(udp_len);
        udph->check = 0;
 
-       iph = (struct iphdr *)skb_push(skb, sizeof(*iph));
+       skb->nh.iph = iph = (struct iphdr *)skb_push(skb, sizeof(*iph));
 
        /* iph->version = 4; iph->ihl = 5; */
        put_unaligned(0x45, (unsigned char *)iph);
@@ -357,8 +357,8 @@ void netpoll_send_udp(struct netpoll *np, const char *msg, int len)
        iph->check    = ip_fast_csum((unsigned char *)iph, iph->ihl);
 
        eth = (struct ethhdr *) skb_push(skb, ETH_HLEN);
-
-       eth->h_proto = htons(ETH_P_IP);
+       skb->mac.raw = skb->data;
+       skb->protocol = eth->h_proto = htons(ETH_P_IP);
        memcpy(eth->h_source, np->local_mac, 6);
        memcpy(eth->h_dest, np->remote_mac, 6);
 
index 221e4038216b8da1e61a67b32087eb146b02af3c..02f3c794789815e5a39717e3caf6eb3119c035e9 100644 (file)
@@ -602,7 +602,7 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
                goto errout;
        }
 
-       err = rtnl_unicast(skb, NETLINK_CB(skb).pid);
+       err = rtnl_unicast(nskb, NETLINK_CB(skb).pid);
 errout:
        kfree(iw_buf);
        dev_put(dev);
index 649d01ef35b6dc4dca5f3b74b593e7f5bfc272d2..271cf060ef8c69fb79f37768972af65b5457d835 100644 (file)
@@ -245,8 +245,7 @@ void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm)
        if (i > 0)
        {
                int cmlen = CMSG_LEN(i*sizeof(int));
-               if (!err)
-                       err = put_user(SOL_SOCKET, &cm->cmsg_level);
+               err = put_user(SOL_SOCKET, &cm->cmsg_level);
                if (!err)
                        err = put_user(SCM_RIGHTS, &cm->cmsg_type);
                if (!err)
index b77e155cbe6c036acc1413a1470c5f92d9b05c6c..d472db4776c3bd72fcf396287ad7edf873affffb 100644 (file)
@@ -823,7 +823,7 @@ static void inline sock_lock_init(struct sock *sk)
                                   af_family_slock_key_strings[sk->sk_family]);
        lockdep_init_map(&sk->sk_lock.dep_map,
                         af_family_key_strings[sk->sk_family],
-                        af_family_keys + sk->sk_family);
+                        af_family_keys + sk->sk_family, 0);
 }
 
 /**
index 94c5d761c830e3a156501b9e0320ec16929d5564..d93fe64f6693b3e23624c27741e1d0ffa167663e 100644 (file)
 #include <asm/system.h>
 #include <asm/uaccess.h>
 
-/*
-  This is a maximally equidistributed combined Tausworthe generator
-  based on code from GNU Scientific Library 1.5 (30 Jun 2004)
-
-   x_n = (s1_n ^ s2_n ^ s3_n) 
-
-   s1_{n+1} = (((s1_n & 4294967294) <<12) ^ (((s1_n <<13) ^ s1_n) >>19))
-   s2_{n+1} = (((s2_n & 4294967288) << 4) ^ (((s2_n << 2) ^ s2_n) >>25))
-   s3_{n+1} = (((s3_n & 4294967280) <<17) ^ (((s3_n << 3) ^ s3_n) >>11))
-
-   The period of this generator is about 2^88.
-
-   From: P. L'Ecuyer, "Maximally Equidistributed Combined Tausworthe
-   Generators", Mathematics of Computation, 65, 213 (1996), 203--213.
-
-   This is available on the net from L'Ecuyer's home page,
-
-   http://www.iro.umontreal.ca/~lecuyer/myftp/papers/tausme.ps
-   ftp://ftp.iro.umontreal.ca/pub/simulation/lecuyer/papers/tausme.ps 
-
-   There is an erratum in the paper "Tables of Maximally
-   Equidistributed Combined LFSR Generators", Mathematics of
-   Computation, 68, 225 (1999), 261--269:
-   http://www.iro.umontreal.ca/~lecuyer/myftp/papers/tausme2.ps
-
-        ... the k_j most significant bits of z_j must be non-
-        zero, for each j. (Note: this restriction also applies to the 
-        computer code given in [4], but was mistakenly not mentioned in
-        that paper.)
-   
-   This affects the seeding procedure by imposing the requirement
-   s1 > 1, s2 > 7, s3 > 15.
-
-*/
-struct nrnd_state {
-       u32 s1, s2, s3;
-};
-
-static DEFINE_PER_CPU(struct nrnd_state, net_rand_state);
-
-static u32 __net_random(struct nrnd_state *state)
-{
-#define TAUSWORTHE(s,a,b,c,d) ((s&c)<<d) ^ (((s <<a) ^ s)>>b)
-
-       state->s1 = TAUSWORTHE(state->s1, 13, 19, 4294967294UL, 12);
-       state->s2 = TAUSWORTHE(state->s2, 2, 25, 4294967288UL, 4);
-       state->s3 = TAUSWORTHE(state->s3, 3, 11, 4294967280UL, 17);
-
-       return (state->s1 ^ state->s2 ^ state->s3);
-}
-
-static void __net_srandom(struct nrnd_state *state, unsigned long s)
-{
-       if (s == 0)
-               s = 1;      /* default seed is 1 */
-
-#define LCG(n) (69069 * n)
-       state->s1 = LCG(s);
-       state->s2 = LCG(state->s1);
-       state->s3 = LCG(state->s2);
-
-       /* "warm it up" */
-       __net_random(state);
-       __net_random(state);
-       __net_random(state);
-       __net_random(state);
-       __net_random(state);
-       __net_random(state);
-}
-
-
-unsigned long net_random(void)
-{
-       unsigned long r;
-       struct nrnd_state *state = &get_cpu_var(net_rand_state);
-       r = __net_random(state);
-       put_cpu_var(state);
-       return r;
-}
-
-
-void net_srandom(unsigned long entropy)
-{
-       struct nrnd_state *state = &get_cpu_var(net_rand_state);
-       __net_srandom(state, state->s1^entropy);
-       put_cpu_var(state);
-}
-
-void __init net_random_init(void)
-{
-       int i;
-
-       for_each_possible_cpu(i) {
-               struct nrnd_state *state = &per_cpu(net_rand_state,i);
-               __net_srandom(state, i+jiffies);
-       }
-}
-
-static int net_random_reseed(void)
-{
-       int i;
-       unsigned long seed;
-
-       for_each_possible_cpu(i) {
-               struct nrnd_state *state = &per_cpu(net_rand_state,i);
-
-               get_random_bytes(&seed, sizeof(seed));
-               __net_srandom(state, seed);
-       }
-       return 0;
-}
-late_initcall(net_random_reseed);
-
 int net_msg_cost = 5*HZ;
 int net_msg_burst = 10;
 
@@ -153,10 +40,7 @@ int net_ratelimit(void)
 {
        return __printk_ratelimit(net_msg_cost, net_msg_burst);
 }
-
-EXPORT_SYMBOL(net_random);
 EXPORT_SYMBOL(net_ratelimit);
-EXPORT_SYMBOL(net_srandom);
 
 /*
  * Convert an ASCII string to binary IP.
index ffff0da46c6ee2a3703a9f3116eab0162b4727e6..cb1b8728d7eec0c55c6151da9fba7d00f42747e9 100644 (file)
@@ -748,11 +748,39 @@ static int ioctl_standard_call(struct net_device *        dev,
                int     extra_size;
                int     user_length = 0;
                int     err;
+               int     essid_compat = 0;
 
                /* Calculate space needed by arguments. Always allocate
                 * for max space. Easier, and won't last long... */
                extra_size = descr->max_tokens * descr->token_size;
 
+               /* Check need for ESSID compatibility for WE < 21 */
+               switch (cmd) {
+               case SIOCSIWESSID:
+               case SIOCGIWESSID:
+               case SIOCSIWNICKN:
+               case SIOCGIWNICKN:
+                       if (iwr->u.data.length == descr->max_tokens + 1)
+                               essid_compat = 1;
+                       else if (IW_IS_SET(cmd) && (iwr->u.data.length != 0)) {
+                               char essid[IW_ESSID_MAX_SIZE + 1];
+
+                               err = copy_from_user(essid, iwr->u.data.pointer,
+                                                    iwr->u.data.length *
+                                                    descr->token_size);
+                               if (err)
+                                       return -EFAULT;
+
+                               if (essid[iwr->u.data.length - 1] == '\0')
+                                       essid_compat = 1;
+                       }
+                       break;
+               default:
+                       break;
+               }
+
+               iwr->u.data.length -= essid_compat;
+
                /* Check what user space is giving us */
                if(IW_IS_SET(cmd)) {
                        /* Check NULL pointer */
@@ -795,7 +823,8 @@ static int ioctl_standard_call(struct net_device *  dev,
 #endif /* WE_IOCTL_DEBUG */
 
                /* Create the kernel buffer */
-               extra = kmalloc(extra_size, GFP_KERNEL);
+               /*    kzalloc ensures NULL-termination for essid_compat */
+               extra = kzalloc(extra_size, GFP_KERNEL);
                if (extra == NULL) {
                        return -ENOMEM;
                }
@@ -819,6 +848,8 @@ static int ioctl_standard_call(struct net_device *  dev,
                /* Call the handler */
                ret = handler(dev, &info, &(iwr->u), extra);
 
+               iwr->u.data.length += essid_compat;
+
                /* If we have something to return to the user */
                if (!ret && IW_IS_GET(cmd)) {
                        /* Check if there is enough buffer up there */
index bf692c1c116f69a1384d7124c03212ee2d504ebb..aaaf4d09516b0d5dc218ccee0cbcef4933244f0d 100644 (file)
@@ -311,7 +311,7 @@ static void dccp_v4_err(struct sk_buff *skb, u32 info)
        }
 
        if (sk->sk_state == DCCP_TIME_WAIT) {
-               inet_twsk_put((struct inet_timewait_sock *)sk);
+               inet_twsk_put(inet_twsk(sk));
                return;
        }
 
@@ -449,6 +449,8 @@ static inline u64 dccp_v4_init_sequence(const struct sock *sk,
                                           dccp_hdr(skb)->dccph_sport);
 }
 
+static struct request_sock_ops dccp_request_sock_ops;
+
 int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
 {
        struct inet_request_sock *ireq;
@@ -489,7 +491,7 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
        if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1)
                goto drop;
 
-       req = reqsk_alloc(sk->sk_prot->rsk_prot);
+       req = reqsk_alloc(&dccp_request_sock_ops);
        if (req == NULL)
                goto drop;
 
@@ -614,7 +616,7 @@ static struct sock *dccp_v4_hnd_req(struct sock *sk, struct sk_buff *skb)
                        bh_lock_sock(nsk);
                        return nsk;
                }
-               inet_twsk_put((struct inet_timewait_sock *)nsk);
+               inet_twsk_put(inet_twsk(nsk));
                return NULL;
        }
 
@@ -980,7 +982,7 @@ discard_and_relse:
        goto discard_it;
 
 do_time_wait:
-       inet_twsk_put((struct inet_timewait_sock *)sk);
+       inet_twsk_put(inet_twsk(sk));
        goto no_dccp_socket;
 }
 
index 7a47399cf31fd81817c83b41894d4184a88481e4..c8bf89bfb0883377dba84d594cbc756c4ac62ea8 100644 (file)
@@ -285,7 +285,7 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
        }
 
        if (sk->sk_state == DCCP_TIME_WAIT) {
-               inet_twsk_put((struct inet_timewait_sock *)sk);
+               inet_twsk_put(inet_twsk(sk));
                return;
        }
 
@@ -663,7 +663,7 @@ static struct sock *dccp_v6_hnd_req(struct sock *sk,struct sk_buff *skb)
                        bh_lock_sock(nsk);
                        return nsk;
                }
-               inet_twsk_put((struct inet_timewait_sock *)nsk);
+               inet_twsk_put(inet_twsk(nsk));
                return NULL;
        }
 
@@ -672,7 +672,6 @@ static struct sock *dccp_v6_hnd_req(struct sock *sk,struct sk_buff *skb)
 
 static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
 {
-       struct inet_request_sock *ireq;
        struct dccp_sock dp;
        struct request_sock *req;
        struct dccp_request_sock *dreq;
@@ -701,7 +700,7 @@ static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
        if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1)
                goto drop;
 
-       req = inet6_reqsk_alloc(sk->sk_prot->rsk_prot);
+       req = inet6_reqsk_alloc(&dccp6_request_sock_ops);
        if (req == NULL)
                goto drop;
 
@@ -713,7 +712,6 @@ static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
                goto drop_and_free;
 
        ireq6 = inet6_rsk(req);
-       ireq = inet_rsk(req);
        ipv6_addr_copy(&ireq6->rmt_addr, &skb->nh.ipv6h->saddr);
        ipv6_addr_copy(&ireq6->loc_addr, &skb->nh.ipv6h->daddr);
        req->rcv_wnd    = dccp_feat_default_sequence_window;
@@ -997,6 +995,10 @@ static int dccp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
        if (sk->sk_state == DCCP_OPEN) { /* Fast path */
                if (dccp_rcv_established(sk, skb, dccp_hdr(skb), skb->len))
                        goto reset;
+               if (opt_skb) {
+                       /* This is where we would goto ipv6_pktoptions. */
+                       __kfree_skb(opt_skb);
+               }
                return 0;
        }
 
@@ -1021,6 +1023,10 @@ static int dccp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
 
        if (dccp_rcv_state_process(sk, skb, dccp_hdr(skb), skb->len))
                goto reset;
+       if (opt_skb) {
+               /* This is where we would goto ipv6_pktoptions. */
+               __kfree_skb(opt_skb);
+       }
        return 0;
 
 reset:
@@ -1109,7 +1115,7 @@ discard_and_relse:
        goto discard_it;
 
 do_time_wait:
-       inet_twsk_put((struct inet_timewait_sock *)sk);
+       inet_twsk_put(inet_twsk(sk));
        goto no_dccp_socket;
 }
 
index 70e027375682cdf52030314be662ed7477b4e888..3456cd331835c738286d6a2cf6c67a5de8aee16b 100644 (file)
@@ -1178,8 +1178,10 @@ static int dn_getname(struct socket *sock, struct sockaddr *uaddr,int *uaddr_len
        if (peer) {
                if ((sock->state != SS_CONNECTED && 
                     sock->state != SS_CONNECTING) && 
-                   scp->accept_mode == ACC_IMMED)
+                   scp->accept_mode == ACC_IMMED) {
+                       release_sock(sk);
                        return -ENOTCONN;
+               }
 
                memcpy(sa, &scp->peer, sizeof(struct sockaddr_dn));
        } else {
index dd0761e3d280cc311cbdf88b278b5e91cd4951ab..23489f7232d28776585f0463deda496d188d591b 100644 (file)
@@ -267,9 +267,14 @@ static void dn_dst_link_failure(struct sk_buff *skb)
 
 static inline int compare_keys(struct flowi *fl1, struct flowi *fl2)
 {
-       return memcmp(&fl1->nl_u.dn_u, &fl2->nl_u.dn_u, sizeof(fl1->nl_u.dn_u)) == 0 &&
-               fl1->oif == fl2->oif &&
-               fl1->iif == fl2->iif;
+       return ((fl1->nl_u.dn_u.daddr ^ fl2->nl_u.dn_u.daddr) |
+               (fl1->nl_u.dn_u.saddr ^ fl2->nl_u.dn_u.saddr) |
+#ifdef CONFIG_DECNET_ROUTE_FWMARK
+               (fl1->nl_u.dn_u.fwmark ^ fl2->nl_u.dn_u.fwmark) |
+#endif
+               (fl1->nl_u.dn_u.scope ^ fl2->nl_u.dn_u.scope) |
+               (fl1->oif ^ fl2->oif) |
+               (fl1->iif ^ fl2->iif)) == 0;
 }
 
 static int dn_insert_route(struct dn_route *rt, unsigned hash, struct dn_route **rp)
@@ -1270,7 +1275,6 @@ static int dn_route_input_slow(struct sk_buff *skb)
                        goto e_inval;
 
                res.type = RTN_LOCAL;
-               flags |= RTCF_DIRECTSRC;
        } else {
                __le16 src_map = fl.fld_src;
                free_res = 1;
@@ -1341,7 +1345,7 @@ static int dn_route_input_slow(struct sk_buff *skb)
                        goto make_route;
 
                /* Packet was intra-ethernet, so we know its on-link */
-               if (cb->rt_flags | DN_RT_F_IE) {
+               if (cb->rt_flags & DN_RT_F_IE) {
                        gateway = cb->src;
                        flags |= RTCF_DIRECTSRC;
                        goto make_route;
index 589f6d2c548a7ba0167598def59daab5b7eb13c4..cf51c87a971d786f0035b7e5d34cc6076889cc23 100644 (file)
@@ -48,7 +48,7 @@ ieee80211softmac_assoc(struct ieee80211softmac_device *mac, struct ieee80211soft
        dprintk(KERN_INFO PFX "sent association request!\n");
 
        spin_lock_irqsave(&mac->lock, flags);
-       mac->associated = 0; /* just to make sure */
+       mac->associnfo.associated = 0; /* just to make sure */
 
        /* Set a timer for timeout */
        /* FIXME: make timeout configurable */
@@ -62,24 +62,22 @@ ieee80211softmac_assoc_timeout(void *d)
 {
        struct ieee80211softmac_device *mac = (struct ieee80211softmac_device *)d;
        struct ieee80211softmac_network *n;
-       unsigned long flags;
 
-       spin_lock_irqsave(&mac->lock, flags);
+       mutex_lock(&mac->associnfo.mutex);
        /* we might race against ieee80211softmac_handle_assoc_response,
         * so make sure only one of us does something */
-       if (!mac->associnfo.associating) {
-               spin_unlock_irqrestore(&mac->lock, flags);
-               return;
-       }
+       if (!mac->associnfo.associating)
+               goto out;
        mac->associnfo.associating = 0;
        mac->associnfo.bssvalid = 0;
-       mac->associated = 0;
+       mac->associnfo.associated = 0;
 
        n = ieee80211softmac_get_network_by_bssid_locked(mac, mac->associnfo.bssid);
-       spin_unlock_irqrestore(&mac->lock, flags);
 
        dprintk(KERN_INFO PFX "assoc request timed out!\n");
        ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_TIMEOUT, n);
+out:
+       mutex_unlock(&mac->associnfo.mutex);
 }
 
 void
@@ -93,7 +91,7 @@ ieee80211softmac_disassoc(struct ieee80211softmac_device *mac)
 
        netif_carrier_off(mac->dev);
 
-       mac->associated = 0;
+       mac->associnfo.associated = 0;
        mac->associnfo.bssvalid = 0;
        mac->associnfo.associating = 0;
        ieee80211softmac_init_bss(mac);
@@ -107,7 +105,7 @@ ieee80211softmac_send_disassoc_req(struct ieee80211softmac_device *mac, u16 reas
 {
        struct ieee80211softmac_network *found;
 
-       if (mac->associnfo.bssvalid && mac->associated) {
+       if (mac->associnfo.bssvalid && mac->associnfo.associated) {
                found = ieee80211softmac_get_network_by_bssid(mac, mac->associnfo.bssid);
                if (found)
                        ieee80211softmac_send_mgt_frame(mac, found, IEEE80211_STYPE_DISASSOC, reason);
@@ -196,17 +194,18 @@ ieee80211softmac_assoc_work(void *d)
        int bssvalid;
        unsigned long flags;
 
+       mutex_lock(&mac->associnfo.mutex);
+
+       if (!mac->associnfo.associating)
+               goto out;
+
        /* ieee80211_disassoc might clear this */
        bssvalid = mac->associnfo.bssvalid;
 
        /* meh */
-       if (mac->associated)
+       if (mac->associnfo.associated)
                ieee80211softmac_send_disassoc_req(mac, WLAN_REASON_DISASSOC_STA_HAS_LEFT);
 
-       spin_lock_irqsave(&mac->lock, flags);
-       mac->associnfo.associating = 1;
-       spin_unlock_irqrestore(&mac->lock, flags);
-
        /* try to find the requested network in our list, if we found one already */
        if (bssvalid || mac->associnfo.bssfixed)
                found = ieee80211softmac_get_network_by_bssid(mac, mac->associnfo.bssid);       
@@ -260,10 +259,8 @@ ieee80211softmac_assoc_work(void *d)
 
        if (!found) {
                if (mac->associnfo.scan_retry > 0) {
-                       spin_lock_irqsave(&mac->lock, flags);
                        mac->associnfo.scan_retry--;
-                       spin_unlock_irqrestore(&mac->lock, flags);
-               
+
                        /* We know of no such network. Let's scan. 
                         * NB: this also happens if we had no memory to copy the network info...
                         * Maybe we can hope to have more memory after scanning finishes ;)
@@ -272,19 +269,17 @@ ieee80211softmac_assoc_work(void *d)
                        ieee80211softmac_notify(mac->dev, IEEE80211SOFTMAC_EVENT_SCAN_FINISHED, ieee80211softmac_assoc_notify_scan, NULL);
                        if (ieee80211softmac_start_scan(mac))
                                dprintk(KERN_INFO PFX "Associate: failed to initiate scan. Is device up?\n");
-                       return;
+                       goto out;
                } else {
-                       spin_lock_irqsave(&mac->lock, flags);
                        mac->associnfo.associating = 0;
-                       mac->associated = 0;
-                       spin_unlock_irqrestore(&mac->lock, flags);
+                       mac->associnfo.associated = 0;
 
                        dprintk(KERN_INFO PFX "Unable to find matching network after scan!\n");
                        /* reset the retry counter for the next user request since we
                         * break out and don't reschedule ourselves after this point. */
                        mac->associnfo.scan_retry = IEEE80211SOFTMAC_ASSOC_SCAN_RETRY_LIMIT;
                        ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_NET_NOT_FOUND, NULL);
-                       return;
+                       goto out;
                }
        }
 
@@ -297,7 +292,7 @@ ieee80211softmac_assoc_work(void *d)
        /* copy the ESSID for displaying it */
        mac->associnfo.associate_essid.len = found->essid.len;
        memcpy(mac->associnfo.associate_essid.data, found->essid.data, IW_ESSID_MAX_SIZE + 1);
-       
+
        /* we found a network! authenticate (if necessary) and associate to it. */
        if (found->authenticating) {
                dprintk(KERN_INFO PFX "Already requested authentication, waiting...\n");
@@ -305,7 +300,7 @@ ieee80211softmac_assoc_work(void *d)
                        mac->associnfo.assoc_wait = 1;
                        ieee80211softmac_notify_internal(mac, IEEE80211SOFTMAC_EVENT_ANY, found, ieee80211softmac_assoc_notify_auth, NULL, GFP_KERNEL);
                }
-               return;
+               goto out;
        }
        if (!found->authenticated && !found->authenticating) {
                /* This relies on the fact that _auth_req only queues the work,
@@ -321,11 +316,14 @@ ieee80211softmac_assoc_work(void *d)
                        mac->associnfo.assoc_wait = 0;
                        ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_FAILED, found);
                }
-               return;
+               goto out;
        }
        /* finally! now we can start associating */
        mac->associnfo.assoc_wait = 0;
        ieee80211softmac_assoc(mac, found);
+
+out:
+       mutex_unlock(&mac->associnfo.mutex);
 }
 
 /* call this to do whatever is necessary when we're associated */
@@ -341,7 +339,7 @@ ieee80211softmac_associated(struct ieee80211softmac_device *mac,
        mac->bssinfo.supported_rates = net->supported_rates;
        ieee80211softmac_recalc_txrates(mac);
 
-       mac->associated = 1;
+       mac->associnfo.associated = 1;
 
        mac->associnfo.short_preamble_available =
                (cap & WLAN_CAPABILITY_SHORT_PREAMBLE) != 0;
@@ -421,7 +419,7 @@ ieee80211softmac_handle_assoc_response(struct net_device * dev,
                        dprintk(KERN_INFO PFX "associating failed (reason: 0x%x)!\n", status);
                        mac->associnfo.associating = 0;
                        mac->associnfo.bssvalid = 0;
-                       mac->associated = 0;
+                       mac->associnfo.associated = 0;
                        ieee80211softmac_call_events_locked(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_FAILED, network);
        }
        
index 82bfddbf33a28e999b944d86660f21560206438b..b96931001b43d131bc30d8d7841fda97b0897ce0 100644 (file)
@@ -304,7 +304,7 @@ ieee80211softmac_auth(struct ieee80211_auth **pkt,
                2 +             /* Auth Transaction Seq */
                2 +             /* Status Code */
                 /* Challenge Text IE */
-               is_shared_response ? 0 : 1 + 1 + net->challenge_len
+               (is_shared_response ? 1 + 1 + net->challenge_len : 0)
        );
        if (unlikely((*pkt) == NULL))
                return 0;
@@ -475,8 +475,13 @@ int ieee80211softmac_handle_beacon(struct net_device *dev,
 {
        struct ieee80211softmac_device *mac = ieee80211_priv(dev);
 
-       if (mac->associated && memcmp(network->bssid, mac->associnfo.bssid, ETH_ALEN) == 0)
-               ieee80211softmac_process_erp(mac, network->erp_value);
+       /* This might race, but we don't really care and it's not worth
+        * adding heavyweight locking in this fastpath.
+        */
+       if (mac->associnfo.associated) {
+               if (memcmp(network->bssid, mac->associnfo.bssid, ETH_ALEN) == 0)
+                       ieee80211softmac_process_erp(mac, network->erp_value);
+       }
 
        return 0;
 }
index addea1cf73ae3f5ba9f2787af8503bb354b97778..33aff4f4a471fde8fe6538c46dbe8527c48536a6 100644 (file)
@@ -57,6 +57,7 @@ struct net_device *alloc_ieee80211softmac(int sizeof_priv)
        INIT_LIST_HEAD(&softmac->network_list);
        INIT_LIST_HEAD(&softmac->events);
 
+       mutex_init(&softmac->associnfo.mutex);
        INIT_WORK(&softmac->associnfo.work, ieee80211softmac_assoc_work, softmac);
        INIT_WORK(&softmac->associnfo.timeout, ieee80211softmac_assoc_timeout, softmac);
        softmac->start_scan = ieee80211softmac_start_scan_implementation;
index 2aa779d18f3861a2f6f2119f99c89c6c2c56b583..23068a830f7dba7916c0380ef1767758d1f95815 100644 (file)
@@ -73,13 +73,14 @@ ieee80211softmac_wx_set_essid(struct net_device *net_dev,
        struct ieee80211softmac_network *n;
        struct ieee80211softmac_auth_queue_item *authptr;
        int length = 0;
-       unsigned long flags;
+
+       mutex_lock(&sm->associnfo.mutex);
 
        /* Check if we're already associating to this or another network
         * If it's another network, cancel and start over with our new network
         * If it's our network, ignore the change, we're already doing it!
         */
-       if((sm->associnfo.associating || sm->associated) &&
+       if((sm->associnfo.associating || sm->associnfo.associated) &&
           (data->essid.flags && data->essid.length)) {
                /* Get the associating network */
                n = ieee80211softmac_get_network_by_bssid(sm, sm->associnfo.bssid);
@@ -87,10 +88,9 @@ ieee80211softmac_wx_set_essid(struct net_device *net_dev,
                   !memcmp(n->essid.data, extra, n->essid.len)) {
                        dprintk(KERN_INFO PFX "Already associating or associated to "MAC_FMT"\n",
                                MAC_ARG(sm->associnfo.bssid));
-                       return 0;
+                       goto out;
                } else {
                        dprintk(KERN_INFO PFX "Canceling existing associate request!\n");
-                       spin_lock_irqsave(&sm->lock,flags);
                        /* Cancel assoc work */
                        cancel_delayed_work(&sm->associnfo.work);
                        /* We don't have to do this, but it's a little cleaner */
@@ -98,14 +98,13 @@ ieee80211softmac_wx_set_essid(struct net_device *net_dev,
                                cancel_delayed_work(&authptr->work);
                        sm->associnfo.bssvalid = 0;
                        sm->associnfo.bssfixed = 0;
-                       spin_unlock_irqrestore(&sm->lock,flags);
                        flush_scheduled_work();
+                       sm->associnfo.associating = 0;
+                       sm->associnfo.associated = 0;
                }
        }
 
 
-       spin_lock_irqsave(&sm->lock, flags);
-
        sm->associnfo.static_essid = 0;
        sm->associnfo.assoc_wait = 0;
 
@@ -121,10 +120,12 @@ ieee80211softmac_wx_set_essid(struct net_device *net_dev,
         * If applicable, we have already copied the data in */
        sm->associnfo.req_essid.len = length;
 
+       sm->associnfo.associating = 1;
        /* queue lower level code to do work (if necessary) */
        schedule_work(&sm->associnfo.work);
+out:
+       mutex_unlock(&sm->associnfo.mutex);
 
-       spin_unlock_irqrestore(&sm->lock, flags);
        return 0;
 }
 EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_essid);
@@ -136,10 +137,8 @@ ieee80211softmac_wx_get_essid(struct net_device *net_dev,
                              char *extra)
 {
        struct ieee80211softmac_device *sm = ieee80211_priv(net_dev);
-       unsigned long flags;
 
-       /* avoid getting inconsistent information */
-       spin_lock_irqsave(&sm->lock, flags);
+       mutex_lock(&sm->associnfo.mutex);
        /* If all fails, return ANY (empty) */
        data->essid.length = 0;
        data->essid.flags = 0;  /* active */
@@ -152,12 +151,13 @@ ieee80211softmac_wx_get_essid(struct net_device *net_dev,
        }
        
        /* If we're associating/associated, return that */
-       if (sm->associated || sm->associnfo.associating) {
+       if (sm->associnfo.associated || sm->associnfo.associating) {
                data->essid.length = sm->associnfo.associate_essid.len;
                data->essid.flags = 1;  /* active */
                memcpy(extra, sm->associnfo.associate_essid.data, sm->associnfo.associate_essid.len);
        }
-       spin_unlock_irqrestore(&sm->lock, flags);
+       mutex_unlock(&sm->associnfo.mutex);
+
        return 0;
 }
 EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_essid);
@@ -322,15 +322,15 @@ ieee80211softmac_wx_get_wap(struct net_device *net_dev,
 {
        struct ieee80211softmac_device *mac = ieee80211_priv(net_dev);
        int err = 0;
-       unsigned long flags;
 
-       spin_lock_irqsave(&mac->lock, flags);
+       mutex_lock(&mac->associnfo.mutex);
        if (mac->associnfo.bssvalid)
                memcpy(data->ap_addr.sa_data, mac->associnfo.bssid, ETH_ALEN);
        else
                memset(data->ap_addr.sa_data, 0xff, ETH_ALEN);
        data->ap_addr.sa_family = ARPHRD_ETHER;
-       spin_unlock_irqrestore(&mac->lock, flags);
+       mutex_unlock(&mac->associnfo.mutex);
+
        return err;
 }
 EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_wap);
@@ -342,28 +342,27 @@ ieee80211softmac_wx_set_wap(struct net_device *net_dev,
                            char *extra)
 {
        struct ieee80211softmac_device *mac = ieee80211_priv(net_dev);
-       unsigned long flags;
 
        /* sanity check */
        if (data->ap_addr.sa_family != ARPHRD_ETHER) {
                return -EINVAL;
        }
 
-       spin_lock_irqsave(&mac->lock, flags);
+       mutex_lock(&mac->associnfo.mutex);
        if (is_broadcast_ether_addr(data->ap_addr.sa_data)) {
                /* the bssid we have is not to be fixed any longer,
                 * and we should reassociate to the best AP. */
                mac->associnfo.bssfixed = 0;
                /* force reassociation */
                mac->associnfo.bssvalid = 0;
-               if (mac->associated)
+               if (mac->associnfo.associated)
                        schedule_work(&mac->associnfo.work);
        } else if (is_zero_ether_addr(data->ap_addr.sa_data)) {
                /* the bssid we have is no longer fixed */
                mac->associnfo.bssfixed = 0;
         } else {
                if (!memcmp(mac->associnfo.bssid, data->ap_addr.sa_data, ETH_ALEN)) {
-                       if (mac->associnfo.associating || mac->associated) {
+                       if (mac->associnfo.associating || mac->associnfo.associated) {
                        /* bssid unchanged and associated or associating - just return */
                                goto out;
                        }
@@ -378,7 +377,8 @@ ieee80211softmac_wx_set_wap(struct net_device *net_dev,
         }
 
  out:
-       spin_unlock_irqrestore(&mac->lock, flags);
+       mutex_unlock(&mac->associnfo.mutex);
+
        return 0;
 }
 EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_wap);
@@ -394,7 +394,8 @@ ieee80211softmac_wx_set_genie(struct net_device *dev,
        int err = 0;
        char *buf;
        int i;
-       
+
+       mutex_lock(&mac->associnfo.mutex);
        spin_lock_irqsave(&mac->lock, flags);
        /* bleh. shouldn't be locked for that kmalloc... */
 
@@ -432,6 +433,8 @@ ieee80211softmac_wx_set_genie(struct net_device *dev,
 
  out:  
        spin_unlock_irqrestore(&mac->lock, flags);
+       mutex_unlock(&mac->associnfo.mutex);
+
        return err;
 }
 EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_genie);
@@ -446,7 +449,8 @@ ieee80211softmac_wx_get_genie(struct net_device *dev,
        unsigned long flags;
        int err = 0;
        int space = wrqu->data.length;
-       
+
+       mutex_lock(&mac->associnfo.mutex);
        spin_lock_irqsave(&mac->lock, flags);
        
        wrqu->data.length = 0;
@@ -459,6 +463,8 @@ ieee80211softmac_wx_get_genie(struct net_device *dev,
                        err = -E2BIG;
        }
        spin_unlock_irqrestore(&mac->lock, flags);
+       mutex_lock(&mac->associnfo.mutex);
+
        return err;
 }
 EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_genie);
@@ -473,10 +479,13 @@ ieee80211softmac_wx_set_mlme(struct net_device *dev,
        struct iw_mlme *mlme = (struct iw_mlme *)extra;
        u16 reason = cpu_to_le16(mlme->reason_code);
        struct ieee80211softmac_network *net;
+       int err = -EINVAL;
+
+       mutex_lock(&mac->associnfo.mutex);
 
        if (memcmp(mac->associnfo.bssid, mlme->addr.sa_data, ETH_ALEN)) {
                printk(KERN_DEBUG PFX "wx_set_mlme: requested operation on net we don't use\n");
-               return -EINVAL;
+               goto out;
        }
 
        switch (mlme->cmd) {
@@ -484,14 +493,22 @@ ieee80211softmac_wx_set_mlme(struct net_device *dev,
                net = ieee80211softmac_get_network_by_bssid_locked(mac, mlme->addr.sa_data);
                if (!net) {
                        printk(KERN_DEBUG PFX "wx_set_mlme: we should know the net here...\n");
-                       return -EINVAL;
+                       goto out;
                }
                return ieee80211softmac_deauth_req(mac, net, reason);
        case IW_MLME_DISASSOC:
                ieee80211softmac_send_disassoc_req(mac, reason);
-               return 0;
+               mac->associnfo.associated = 0;
+               mac->associnfo.associating = 0;
+               err = 0;
+               goto out;
        default:
-               return -EOPNOTSUPP;
+               err = -EOPNOTSUPP;
        }
+
+out:
+       mutex_unlock(&mac->associnfo.mutex);
+
+       return err;
 }
 EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_mlme);
index a8e2e879a64764c31bbcc2626cb6779a5aba04fb..e2077a3aa8c097156c34e4e12fd1f4a36320af08 100644 (file)
@@ -43,6 +43,7 @@
 #include <net/tcp.h>
 #include <net/netlabel.h>
 #include <net/cipso_ipv4.h>
+#include <asm/atomic.h>
 #include <asm/bug.h>
 
 struct cipso_v4_domhsh_entry {
@@ -79,7 +80,7 @@ struct cipso_v4_map_cache_entry {
        unsigned char *key;
        size_t key_len;
 
-       struct netlbl_lsm_cache lsm_data;
+       struct netlbl_lsm_cache *lsm_data;
 
        u32 activity;
        struct list_head list;
@@ -188,13 +189,14 @@ static void cipso_v4_doi_domhsh_free(struct rcu_head *entry)
  * @entry: the entry to free
  *
  * Description:
- * This function frees the memory associated with a cache entry.
+ * This function frees the memory associated with a cache entry including the
+ * LSM cache data if there are no longer any users, i.e. reference count == 0.
  *
  */
 static void cipso_v4_cache_entry_free(struct cipso_v4_map_cache_entry *entry)
 {
-       if (entry->lsm_data.free)
-               entry->lsm_data.free(entry->lsm_data.data);
+       if (entry->lsm_data)
+               netlbl_secattr_cache_free(entry->lsm_data);
        kfree(entry->key);
        kfree(entry);
 }
@@ -315,8 +317,8 @@ static int cipso_v4_cache_check(const unsigned char *key,
                    entry->key_len == key_len &&
                    memcmp(entry->key, key, key_len) == 0) {
                        entry->activity += 1;
-                       secattr->cache.free = entry->lsm_data.free;
-                       secattr->cache.data = entry->lsm_data.data;
+                       atomic_inc(&entry->lsm_data->refcount);
+                       secattr->cache = entry->lsm_data;
                        if (prev_entry == NULL) {
                                spin_unlock_bh(&cipso_v4_cache[bkt].lock);
                                return 0;
@@ -383,8 +385,8 @@ int cipso_v4_cache_add(const struct sk_buff *skb,
        memcpy(entry->key, cipso_ptr, cipso_ptr_len);
        entry->key_len = cipso_ptr_len;
        entry->hash = cipso_v4_map_cache_hash(cipso_ptr, cipso_ptr_len);
-       entry->lsm_data.free = secattr->cache.free;
-       entry->lsm_data.data = secattr->cache.data;
+       atomic_inc(&secattr->cache->refcount);
+       entry->lsm_data = secattr->cache;
 
        bkt = entry->hash & (CIPSO_V4_CACHE_BUCKETBITS - 1);
        spin_lock_bh(&cipso_v4_cache[bkt].lock);
@@ -771,13 +773,15 @@ static int cipso_v4_map_cat_rbm_valid(const struct cipso_v4_doi *doi_def,
 {
        int cat = -1;
        u32 bitmap_len_bits = bitmap_len * 8;
-       u32 cipso_cat_size = doi_def->map.std->cat.cipso_size;
-       u32 *cipso_array = doi_def->map.std->cat.cipso;
+       u32 cipso_cat_size;
+       u32 *cipso_array;
 
        switch (doi_def->type) {
        case CIPSO_V4_MAP_PASS:
                return 0;
        case CIPSO_V4_MAP_STD:
+               cipso_cat_size = doi_def->map.std->cat.cipso_size;
+               cipso_array = doi_def->map.std->cat.cipso;
                for (;;) {
                        cat = cipso_v4_bitmap_walk(bitmap,
                                                   bitmap_len_bits,
@@ -823,19 +827,21 @@ static int cipso_v4_map_cat_rbm_hton(const struct cipso_v4_doi *doi_def,
        u32 net_spot_max = 0;
        u32 host_clen_bits = host_cat_len * 8;
        u32 net_clen_bits = net_cat_len * 8;
-       u32 host_cat_size = doi_def->map.std->cat.local_size;
-       u32 *host_cat_array = doi_def->map.std->cat.local;
+       u32 host_cat_size;
+       u32 *host_cat_array;
 
        switch (doi_def->type) {
        case CIPSO_V4_MAP_PASS:
-               net_spot_max = host_cat_len - 1;
-               while (net_spot_max > 0 && host_cat[net_spot_max] == 0)
+               net_spot_max = host_cat_len;
+               while (net_spot_max > 0 && host_cat[net_spot_max - 1] == 0)
                        net_spot_max--;
                if (net_spot_max > net_cat_len)
                        return -EINVAL;
                memcpy(net_cat, host_cat, net_spot_max);
                return net_spot_max;
        case CIPSO_V4_MAP_STD:
+               host_cat_size = doi_def->map.std->cat.local_size;
+               host_cat_array = doi_def->map.std->cat.local;
                for (;;) {
                        host_spot = cipso_v4_bitmap_walk(host_cat,
                                                         host_clen_bits,
@@ -891,8 +897,8 @@ static int cipso_v4_map_cat_rbm_ntoh(const struct cipso_v4_doi *doi_def,
        int net_spot = -1;
        u32 net_clen_bits = net_cat_len * 8;
        u32 host_clen_bits = host_cat_len * 8;
-       u32 net_cat_size = doi_def->map.std->cat.cipso_size;
-       u32 *net_cat_array = doi_def->map.std->cat.cipso;
+       u32 net_cat_size;
+       u32 *net_cat_array;
 
        switch (doi_def->type) {
        case CIPSO_V4_MAP_PASS:
@@ -901,6 +907,8 @@ static int cipso_v4_map_cat_rbm_ntoh(const struct cipso_v4_doi *doi_def,
                memcpy(host_cat, net_cat, net_cat_len);
                return net_cat_len;
        case CIPSO_V4_MAP_STD:
+               net_cat_size = doi_def->map.std->cat.cipso_size;
+               net_cat_array = doi_def->map.std->cat.cipso;
                for (;;) {
                        net_spot = cipso_v4_bitmap_walk(net_cat,
                                                        net_clen_bits,
index 9c399a70dd5d5962f3e47ad9e82cae0ae8b46c7b..af0190d8b6c02ebdb2df31a96b2df8f4e67ddf1b 100644 (file)
@@ -482,9 +482,7 @@ static int rtm_to_fib_config(struct sk_buff *skb, struct nlmsghdr *nlh,
        memset(cfg, 0, sizeof(*cfg));
 
        rtm = nlmsg_data(nlh);
-       cfg->fc_family = rtm->rtm_family;
        cfg->fc_dst_len = rtm->rtm_dst_len;
-       cfg->fc_src_len = rtm->rtm_src_len;
        cfg->fc_tos = rtm->rtm_tos;
        cfg->fc_table = rtm->rtm_table;
        cfg->fc_protocol = rtm->rtm_protocol;
@@ -501,9 +499,6 @@ static int rtm_to_fib_config(struct sk_buff *skb, struct nlmsghdr *nlh,
                case RTA_DST:
                        cfg->fc_dst = nla_get_be32(attr);
                        break;
-               case RTA_SRC:
-                       cfg->fc_src = nla_get_be32(attr);
-                       break;
                case RTA_OIF:
                        cfg->fc_oif = nla_get_u32(attr);
                        break;
index 2b1a54b59c48c4f2a65d6f8838bbcfd567a71183..f072f3875af8dfd5c6505787230cc578d8085c1c 100644 (file)
@@ -94,10 +94,8 @@ int inet_peer_minttl = 120 * HZ;     /* TTL under high load: 120 sec */
 int inet_peer_maxttl = 10 * 60 * HZ;   /* usual time to live: 10 min */
 
 static struct inet_peer *inet_peer_unused_head;
-/* Exported for inet_putpeer inline function.  */
-struct inet_peer **inet_peer_unused_tailp = &inet_peer_unused_head;
-DEFINE_SPINLOCK(inet_peer_unused_lock);
-#define PEER_MAX_CLEANUP_WORK 30
+static struct inet_peer **inet_peer_unused_tailp = &inet_peer_unused_head;
+static DEFINE_SPINLOCK(inet_peer_unused_lock);
 
 static void peer_check_expire(unsigned long dummy);
 static DEFINE_TIMER(peer_periodic_timer, peer_check_expire, 0, 0);
@@ -340,7 +338,8 @@ static int cleanup_once(unsigned long ttl)
        spin_lock_bh(&inet_peer_unused_lock);
        p = inet_peer_unused_head;
        if (p != NULL) {
-               if (time_after(p->dtime + ttl, jiffies)) {
+               __u32 delta = (__u32)jiffies - p->dtime;
+               if (delta < ttl) {
                        /* Do not prune fresh entries. */
                        spin_unlock_bh(&inet_peer_unused_lock);
                        return -1;
@@ -432,7 +431,7 @@ out_free:
 /* Called with local BH disabled. */
 static void peer_check_expire(unsigned long dummy)
 {
-       int i;
+       unsigned long now = jiffies;
        int ttl;
 
        if (peer_total >= inet_peer_threshold)
@@ -441,7 +440,10 @@ static void peer_check_expire(unsigned long dummy)
                ttl = inet_peer_maxttl
                                - (inet_peer_maxttl - inet_peer_minttl) / HZ *
                                        peer_total / inet_peer_threshold * HZ;
-       for (i = 0; i < PEER_MAX_CLEANUP_WORK && !cleanup_once(ttl); i++);
+       while (!cleanup_once(ttl)) {
+               if (jiffies != now)
+                       break;
+       }
 
        /* Trigger the timer after inet_peer_gc_mintime .. inet_peer_gc_maxtime
         * interval depending on the total number of entries (more entries,
@@ -455,3 +457,16 @@ static void peer_check_expire(unsigned long dummy)
                                peer_total / inet_peer_threshold * HZ;
        add_timer(&peer_periodic_timer);
 }
+
+void inet_putpeer(struct inet_peer *p)
+{
+       spin_lock_bh(&inet_peer_unused_lock);
+       if (atomic_dec_and_test(&p->refcnt)) {
+               p->unused_prevp = inet_peer_unused_tailp;
+               p->unused_next = NULL;
+               *inet_peer_unused_tailp = p;
+               inet_peer_unused_tailp = &p->unused_next;
+               p->dtime = (__u32)jiffies;
+       }
+       spin_unlock_bh(&inet_peer_unused_lock);
+}
index f5fba051df3da84e7000241cb54ac82edc7babe6..d5b5dec075b81848d8345651872257285a0f361d 100644 (file)
@@ -611,8 +611,8 @@ static int ipgre_rcv(struct sk_buff *skb)
                 * - When dealing with WCCPv2, Skip extra 4 bytes in GRE header
                 */
                if (flags == 0 &&
-                   skb->protocol == __constant_htons(ETH_P_WCCP)) {
-                       skb->protocol = __constant_htons(ETH_P_IP);
+                   skb->protocol == htons(ETH_P_WCCP)) {
+                       skb->protocol = htons(ETH_P_IP);
                        if ((*(h + offset) & 0xF0) != 0x40) 
                                offset += 4;
                }
index e433cb0ff894b19899f30788ea824b14fa237873..6d398f10aa9170881b8f383382b2c96286460a7d 100644 (file)
@@ -274,7 +274,7 @@ static int ip_vs_ftp_in(struct ip_vs_app *app, struct ip_vs_conn *cp,
        while (data <= data_limit - 6) {
                if (strnicmp(data, "PASV\r\n", 6) == 0) {
                        /* Passive mode on */
-                       IP_VS_DBG(7, "got PASV at %zd of %zd\n",
+                       IP_VS_DBG(7, "got PASV at %td of %td\n",
                                  data - data_start,
                                  data_limit - data_start);
                        cp->app_data = &ip_vs_ftp_pasv;
index 17e1a687ab4553e76f53a40029c4f87599d49df9..0849f1cced13364b014ef787157e1d7c76995f4e 100644 (file)
@@ -1196,6 +1196,8 @@ err1:
 static void __exit arp_tables_fini(void)
 {
        nf_unregister_sockopt(&arpt_sockopts);
+       xt_unregister_target(&arpt_error_target);
+       xt_unregister_target(&arpt_standard_target);
        xt_proto_fini(NF_ARP);
 }
 
index 53b6dffea6c2174fcf49f30e7844010c015a3772..262d0d44ec1b5924aff8a3d7efe4ec6a1fbb2733 100644 (file)
@@ -44,13 +44,6 @@ MODULE_LICENSE("GPL");
 
 static char __initdata version[] = "0.90";
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
-
 static inline int
 ctnetlink_dump_tuples_proto(struct sk_buff *skb, 
                            const struct ip_conntrack_tuple *tuple,
@@ -398,7 +391,6 @@ nfattr_failure:
 
 static int ctnetlink_done(struct netlink_callback *cb)
 {
-       DEBUGP("entered %s\n", __FUNCTION__);
        if (cb->args[1])
                ip_conntrack_put((struct ip_conntrack *)cb->args[1]);
        return 0;
@@ -411,9 +403,6 @@ ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
        struct ip_conntrack_tuple_hash *h;
        struct list_head *i;
 
-       DEBUGP("entered %s, last bucket=%lu id=%u\n", __FUNCTION__, 
-                       cb->args[0], *id);
-
        read_lock_bh(&ip_conntrack_lock);
        last = (struct ip_conntrack *)cb->args[1];
        for (; cb->args[0] < ip_conntrack_htable_size; cb->args[0]++) {
@@ -452,7 +441,6 @@ out:
        if (last)
                ip_conntrack_put(last);
 
-       DEBUGP("leaving, last bucket=%lu id=%u\n", cb->args[0], *id);
        return skb->len;
 }
 
@@ -466,8 +454,6 @@ ctnetlink_parse_tuple_ip(struct nfattr *attr, struct ip_conntrack_tuple *tuple)
 {
        struct nfattr *tb[CTA_IP_MAX];
 
-       DEBUGP("entered %s\n", __FUNCTION__);
-
        nfattr_parse_nested(tb, CTA_IP_MAX, attr);
 
        if (nfattr_bad_size(tb, CTA_IP_MAX, cta_min_ip))
@@ -481,8 +467,6 @@ ctnetlink_parse_tuple_ip(struct nfattr *attr, struct ip_conntrack_tuple *tuple)
                return -EINVAL;
        tuple->dst.ip = *(__be32 *)NFA_DATA(tb[CTA_IP_V4_DST-1]);
 
-       DEBUGP("leaving\n");
-
        return 0;
 }
 
@@ -503,8 +487,6 @@ ctnetlink_parse_tuple_proto(struct nfattr *attr,
        struct ip_conntrack_protocol *proto;
        int ret = 0;
 
-       DEBUGP("entered %s\n", __FUNCTION__);
-
        nfattr_parse_nested(tb, CTA_PROTO_MAX, attr);
 
        if (nfattr_bad_size(tb, CTA_PROTO_MAX, cta_min_proto))
@@ -531,8 +513,6 @@ ctnetlink_parse_tuple(struct nfattr *cda[], struct ip_conntrack_tuple *tuple,
        struct nfattr *tb[CTA_TUPLE_MAX];
        int err;
 
-       DEBUGP("entered %s\n", __FUNCTION__);
-
        memset(tuple, 0, sizeof(*tuple));
 
        nfattr_parse_nested(tb, CTA_TUPLE_MAX, cda[type-1]);
@@ -557,10 +537,6 @@ ctnetlink_parse_tuple(struct nfattr *cda[], struct ip_conntrack_tuple *tuple,
        else
                tuple->dst.dir = IP_CT_DIR_ORIGINAL;
 
-       DUMP_TUPLE(tuple);
-
-       DEBUGP("leaving\n");
-
        return 0;
 }
 
@@ -577,8 +553,6 @@ static int ctnetlink_parse_nat_proto(struct nfattr *attr,
        struct nfattr *tb[CTA_PROTONAT_MAX];
        struct ip_nat_protocol *npt;
 
-       DEBUGP("entered %s\n", __FUNCTION__);
-
        nfattr_parse_nested(tb, CTA_PROTONAT_MAX, attr);
 
        if (nfattr_bad_size(tb, CTA_PROTONAT_MAX, cta_min_protonat))
@@ -597,7 +571,6 @@ static int ctnetlink_parse_nat_proto(struct nfattr *attr,
 
        ip_nat_proto_put(npt);
 
-       DEBUGP("leaving\n");
        return 0;
 }
 
@@ -613,8 +586,6 @@ ctnetlink_parse_nat(struct nfattr *nat,
        struct nfattr *tb[CTA_NAT_MAX];
        int err;
 
-       DEBUGP("entered %s\n", __FUNCTION__);
-
        memset(range, 0, sizeof(*range));
        
        nfattr_parse_nested(tb, CTA_NAT_MAX, nat);
@@ -640,7 +611,6 @@ ctnetlink_parse_nat(struct nfattr *nat,
        if (err < 0)
                return err;
 
-       DEBUGP("leaving\n");
        return 0;
 }
 #endif
@@ -650,8 +620,6 @@ ctnetlink_parse_help(struct nfattr *attr, char **helper_name)
 {
        struct nfattr *tb[CTA_HELP_MAX];
 
-       DEBUGP("entered %s\n", __FUNCTION__);
-
        nfattr_parse_nested(tb, CTA_HELP_MAX, attr);
 
        if (!tb[CTA_HELP_NAME-1])
@@ -679,8 +647,6 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
        struct ip_conntrack *ct;
        int err = 0;
 
-       DEBUGP("entered %s\n", __FUNCTION__);
-
        if (nfattr_bad_size(cda, CTA_MAX, cta_min))
                return -EINVAL;
 
@@ -698,10 +664,8 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
                return err;
 
        h = ip_conntrack_find_get(&tuple, NULL);
-       if (!h) {
-               DEBUGP("tuple not found in conntrack hash\n");
+       if (!h)
                return -ENOENT;
-       }
 
        ct = tuplehash_to_ctrack(h);
        
@@ -716,7 +680,6 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
                ct->timeout.function((unsigned long)ct);
 
        ip_conntrack_put(ct);
-       DEBUGP("leaving\n");
 
        return 0;
 }
@@ -731,8 +694,6 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
        struct sk_buff *skb2 = NULL;
        int err = 0;
 
-       DEBUGP("entered %s\n", __FUNCTION__);
-
        if (nlh->nlmsg_flags & NLM_F_DUMP) {
                struct nfgenmsg *msg = NLMSG_DATA(nlh);
                u32 rlen;
@@ -770,11 +731,9 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
                return err;
 
        h = ip_conntrack_find_get(&tuple, NULL);
-       if (!h) {
-               DEBUGP("tuple not found in conntrack hash");
+       if (!h)
                return -ENOENT;
-       }
-       DEBUGP("tuple found\n");
+
        ct = tuplehash_to_ctrack(h);
 
        err = -ENOMEM;
@@ -795,7 +754,6 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
        if (err < 0)
                goto out;
 
-       DEBUGP("leaving\n");
        return 0;
 
 free:
@@ -866,8 +824,6 @@ ctnetlink_change_helper(struct ip_conntrack *ct, struct nfattr *cda[])
        char *helpname;
        int err;
 
-       DEBUGP("entered %s\n", __FUNCTION__);
-
        /* don't change helper of sibling connections */
        if (ct->master)
                return -EINVAL;
@@ -938,8 +894,6 @@ ctnetlink_change_conntrack(struct ip_conntrack *ct, struct nfattr *cda[])
 {
        int err;
 
-       DEBUGP("entered %s\n", __FUNCTION__);
-
        if (cda[CTA_HELP-1]) {
                err = ctnetlink_change_helper(ct, cda);
                if (err < 0)
@@ -969,7 +923,6 @@ ctnetlink_change_conntrack(struct ip_conntrack *ct, struct nfattr *cda[])
                ct->mark = ntohl(*(__be32 *)NFA_DATA(cda[CTA_MARK-1]));
 #endif
 
-       DEBUGP("all done\n");
        return 0;
 }
 
@@ -981,8 +934,6 @@ ctnetlink_create_conntrack(struct nfattr *cda[],
        struct ip_conntrack *ct;
        int err = -EINVAL;
 
-       DEBUGP("entered %s\n", __FUNCTION__);
-
        ct = ip_conntrack_alloc(otuple, rtuple);
        if (ct == NULL || IS_ERR(ct))
                return -ENOMEM; 
@@ -1017,7 +968,6 @@ ctnetlink_create_conntrack(struct nfattr *cda[],
        if (ct->helper)
                ip_conntrack_helper_put(ct->helper);
 
-       DEBUGP("conntrack with id %u inserted\n", ct->id);
        return 0;
 
 err:   
@@ -1033,8 +983,6 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
        struct ip_conntrack_tuple_hash *h = NULL;
        int err = 0;
 
-       DEBUGP("entered %s\n", __FUNCTION__);
-
        if (nfattr_bad_size(cda, CTA_MAX, cta_min))
                return -EINVAL;
 
@@ -1058,7 +1006,6 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
 
        if (h == NULL) {
                write_unlock_bh(&ip_conntrack_lock);
-               DEBUGP("no such conntrack, create new\n");
                err = -ENOENT;
                if (nlh->nlmsg_flags & NLM_F_CREATE)
                        err = ctnetlink_create_conntrack(cda, &otuple, &rtuple);
@@ -1074,7 +1021,6 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
 
        /* We manipulate the conntrack inside the global conntrack table lock,
         * so there's no need to increase the refcount */
-       DEBUGP("conntrack found\n");
        err = -EEXIST;
        if (!(nlh->nlmsg_flags & NLM_F_EXCL))
                err = ctnetlink_change_conntrack(tuplehash_to_ctrack(h), cda);
@@ -1249,8 +1195,6 @@ ctnetlink_exp_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
        struct list_head *i;
        u_int32_t *id = (u_int32_t *) &cb->args[0];
 
-       DEBUGP("entered %s, last id=%llu\n", __FUNCTION__, *id);
-
        read_lock_bh(&ip_conntrack_lock);
        list_for_each_prev(i, &ip_conntrack_expect_list) {
                exp = (struct ip_conntrack_expect *) i;
@@ -1266,8 +1210,6 @@ ctnetlink_exp_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
 out:   
        read_unlock_bh(&ip_conntrack_lock);
 
-       DEBUGP("leaving, last id=%llu\n", *id);
-
        return skb->len;
 }
 
@@ -1285,8 +1227,6 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
        struct sk_buff *skb2;
        int err = 0;
 
-       DEBUGP("entered %s\n", __FUNCTION__);
-
        if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp))
                return -EINVAL;
 
@@ -1437,8 +1377,6 @@ ctnetlink_create_expect(struct nfattr *cda[])
        struct ip_conntrack *ct;
        int err = 0;
 
-       DEBUGP("entered %s\n", __FUNCTION__);
-
        /* caller guarantees that those three CTA_EXPECT_* exist */
        err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE);
        if (err < 0)
@@ -1490,8 +1428,6 @@ ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb,
        struct ip_conntrack_expect *exp;
        int err = 0;
 
-       DEBUGP("entered %s\n", __FUNCTION__);   
-
        if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp))
                return -EINVAL;
 
@@ -1520,8 +1456,6 @@ ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb,
                err = ctnetlink_change_expect(exp, cda);
        write_unlock_bh(&ip_conntrack_lock);
 
-       DEBUGP("leaving\n");
-       
        return err;
 }
 
index 78a44b01c03516bf18aecd65b7191800c42da947..4b90927619b80d2e0461bdd395dc7a82a68e340c 100644 (file)
@@ -1932,6 +1932,9 @@ compat_do_ipt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
 {
        int ret;
 
+       if (!capable(CAP_NET_ADMIN))
+               return -EPERM;
+
        switch (cmd) {
        case IPT_SO_GET_INFO:
                ret = get_info(user, len, 1);
index 12a818a2462f2a8caf9f8fea514d401fd1d7311b..1aa4517fbcdb454f02e70933484cae5a9b4b2382 100644 (file)
@@ -28,7 +28,7 @@ static inline int
 set_ect_ip(struct sk_buff **pskb, const struct ipt_ECN_info *einfo)
 {
        struct iphdr *iph = (*pskb)->nh.iph;
-       __be16 oldtos;
+       u_int16_t oldtos;
 
        if ((iph->tos & IPT_ECN_IP_MASK) != (einfo->ip_ect & IPT_ECN_IP_MASK)) {
                if (!skb_make_writable(pskb, sizeof(struct iphdr)))
@@ -37,8 +37,8 @@ set_ect_ip(struct sk_buff **pskb, const struct ipt_ECN_info *einfo)
                oldtos = iph->tos;
                iph->tos &= ~IPT_ECN_IP_MASK;
                iph->tos |= (einfo->ip_ect & IPT_ECN_IP_MASK);
-               iph->check = nf_csum_update(oldtos ^ htons(0xFFFF), iph->tos,
-                                           iph->check);
+               iph->check = nf_csum_update(htons(oldtos) ^ htons(0xFFFF),
+                                           htons(iph->tos), iph->check);
        } 
        return 1;
 }
index 6b8b14ccc3d3ff9a0fa0610a0e08df6d274cf2ef..83b80b3a5d2f1de5b5aebd891ae164c78771288c 100644 (file)
@@ -30,7 +30,7 @@ target(struct sk_buff **pskb,
 {
        const struct ipt_tos_target_info *tosinfo = targinfo;
        struct iphdr *iph = (*pskb)->nh.iph;
-       __be16 oldtos;
+       u_int16_t oldtos;
 
        if ((iph->tos & IPTOS_TOS_MASK) != tosinfo->tos) {
                if (!skb_make_writable(pskb, sizeof(struct iphdr)))
@@ -38,8 +38,8 @@ target(struct sk_buff **pskb,
                iph = (*pskb)->nh.iph;
                oldtos = iph->tos;
                iph->tos = (iph->tos & IPTOS_PREC_MASK) | tosinfo->tos;
-               iph->check = nf_csum_update(oldtos ^ htons(0xFFFF), iph->tos,
-                                           iph->check);
+               iph->check = nf_csum_update(htons(oldtos) ^ htons(0xFFFF),
+                                           htons(iph->tos), iph->check);
        }
        return IPT_CONTINUE;
 }
index c41ddba02e9d3553dac0f4aca6d7c5c8b9975584..925ee4dfc32c15039e68ddc47274239833f9cab9 100644 (file)
@@ -566,9 +566,15 @@ static inline u32 rt_score(struct rtable *rt)
 
 static inline int compare_keys(struct flowi *fl1, struct flowi *fl2)
 {
-       return memcmp(&fl1->nl_u.ip4_u, &fl2->nl_u.ip4_u, sizeof(fl1->nl_u.ip4_u)) == 0 &&
-              fl1->oif     == fl2->oif &&
-              fl1->iif     == fl2->iif;
+       return ((fl1->nl_u.ip4_u.daddr ^ fl2->nl_u.ip4_u.daddr) |
+               (fl1->nl_u.ip4_u.saddr ^ fl2->nl_u.ip4_u.saddr) |
+#ifdef CONFIG_IP_ROUTE_FWMARK
+               (fl1->nl_u.ip4_u.fwmark ^ fl2->nl_u.ip4_u.fwmark) |
+#endif
+               (*(u16 *)&fl1->nl_u.ip4_u.tos ^
+                *(u16 *)&fl2->nl_u.ip4_u.tos) |
+               (fl1->oif ^ fl2->oif) |
+               (fl1->iif ^ fl2->iif)) == 0;
 }
 
 #ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
index c83938b8fcb1201ddf403c6423cd83790397595b..22ef8bd26620ab122d56ef2220ef2f43e9ab4442 100644 (file)
@@ -355,7 +355,7 @@ void tcp_v4_err(struct sk_buff *skb, u32 info)
                return;
        }
        if (sk->sk_state == TCP_TIME_WAIT) {
-               inet_twsk_put((struct inet_timewait_sock *)sk);
+               inet_twsk_put(inet_twsk(sk));
                return;
        }
 
@@ -373,7 +373,7 @@ void tcp_v4_err(struct sk_buff *skb, u32 info)
        seq = ntohl(th->seq);
        if (sk->sk_state != TCP_LISTEN &&
            !between(seq, tp->snd_una, tp->snd_nxt)) {
-               NET_INC_STATS(LINUX_MIB_OUTOFWINDOWICMPS);
+               NET_INC_STATS_BH(LINUX_MIB_OUTOFWINDOWICMPS);
                goto out;
        }
 
@@ -578,7 +578,7 @@ static void tcp_v4_send_ack(struct sk_buff *skb, u32 seq, u32 ack,
        struct tcphdr *th = skb->h.th;
        struct {
                struct tcphdr th;
-               u32 tsopt[3];
+               u32 tsopt[TCPOLEN_TSTAMP_ALIGNED >> 2];
        } rep;
        struct ip_reply_arg arg;
 
@@ -960,7 +960,7 @@ static struct sock *tcp_v4_hnd_req(struct sock *sk, struct sk_buff *skb)
                        bh_lock_sock(nsk);
                        return nsk;
                }
-               inet_twsk_put((struct inet_timewait_sock *)nsk);
+               inet_twsk_put(inet_twsk(nsk));
                return NULL;
        }
 
@@ -1154,26 +1154,24 @@ discard_and_relse:
 
 do_time_wait:
        if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) {
-               inet_twsk_put((struct inet_timewait_sock *) sk);
+               inet_twsk_put(inet_twsk(sk));
                goto discard_it;
        }
 
        if (skb->len < (th->doff << 2) || tcp_checksum_complete(skb)) {
                TCP_INC_STATS_BH(TCP_MIB_INERRS);
-               inet_twsk_put((struct inet_timewait_sock *) sk);
+               inet_twsk_put(inet_twsk(sk));
                goto discard_it;
        }
-       switch (tcp_timewait_state_process((struct inet_timewait_sock *)sk,
-                                          skb, th)) {
+       switch (tcp_timewait_state_process(inet_twsk(sk), skb, th)) {
        case TCP_TW_SYN: {
                struct sock *sk2 = inet_lookup_listener(&tcp_hashinfo,
                                                        skb->nh.iph->daddr,
                                                        th->dest,
                                                        inet_iif(skb));
                if (sk2) {
-                       inet_twsk_deschedule((struct inet_timewait_sock *)sk,
-                                            &tcp_death_row);
-                       inet_twsk_put((struct inet_timewait_sock *)sk);
+                       inet_twsk_deschedule(inet_twsk(sk), &tcp_death_row);
+                       inet_twsk_put(inet_twsk(sk));
                        sk = sk2;
                        goto process;
                }
index 9a253faefc81c9c2f95d82e9cbb7878d677b25a1..ca406157724c5399eb6c5a0ae443cbb65f9aa3f2 100644 (file)
@@ -273,10 +273,10 @@ static void tcp_build_and_update_options(__be32 *ptr, struct tcp_sock *tp,
                                         __u32 tstamp)
 {
        if (tp->rx_opt.tstamp_ok) {
-               *ptr++ = __constant_htonl((TCPOPT_NOP << 24) |
-                                         (TCPOPT_NOP << 16) |
-                                         (TCPOPT_TIMESTAMP << 8) |
-                                         TCPOLEN_TIMESTAMP);
+               *ptr++ = htonl((TCPOPT_NOP << 24) |
+                              (TCPOPT_NOP << 16) |
+                              (TCPOPT_TIMESTAMP << 8) |
+                              TCPOLEN_TIMESTAMP);
                *ptr++ = htonl(tstamp);
                *ptr++ = htonl(tp->rx_opt.ts_recent);
        }
@@ -325,18 +325,27 @@ static void tcp_syn_build_options(__be32 *ptr, int mss, int ts, int sack,
        *ptr++ = htonl((TCPOPT_MSS << 24) | (TCPOLEN_MSS << 16) | mss);
        if (ts) {
                if(sack)
-                       *ptr++ = __constant_htonl((TCPOPT_SACK_PERM << 24) | (TCPOLEN_SACK_PERM << 16) |
-                                                 (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP);
+                       *ptr++ = htonl((TCPOPT_SACK_PERM << 24) |
+                                      (TCPOLEN_SACK_PERM << 16) |
+                                      (TCPOPT_TIMESTAMP << 8) |
+                                      TCPOLEN_TIMESTAMP);
                else
-                       *ptr++ = __constant_htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
-                                                 (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP);
+                       *ptr++ = htonl((TCPOPT_NOP << 24) |
+                                      (TCPOPT_NOP << 16) |
+                                      (TCPOPT_TIMESTAMP << 8) |
+                                      TCPOLEN_TIMESTAMP);
                *ptr++ = htonl(tstamp);         /* TSVAL */
                *ptr++ = htonl(ts_recent);      /* TSECR */
        } else if(sack)
-               *ptr++ = __constant_htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
-                                         (TCPOPT_SACK_PERM << 8) | TCPOLEN_SACK_PERM);
+               *ptr++ = htonl((TCPOPT_NOP << 24) |
+                              (TCPOPT_NOP << 16) |
+                              (TCPOPT_SACK_PERM << 8) |
+                              TCPOLEN_SACK_PERM);
        if (offer_wscale)
-               *ptr++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_WINDOW << 16) | (TCPOLEN_WINDOW << 8) | (wscale));
+               *ptr++ = htonl((TCPOPT_NOP << 24) |
+                              (TCPOPT_WINDOW << 16) |
+                              (TCPOLEN_WINDOW << 8) |
+                              (wscale));
 }
 
 /* This routine actually transmits TCP packets queued in by
@@ -1087,10 +1096,14 @@ static int tcp_tso_should_defer(struct sock *sk, struct tcp_sock *tp, struct sk_
        u32 send_win, cong_win, limit, in_flight;
 
        if (TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN)
-               return 0;
+               goto send_now;
 
        if (icsk->icsk_ca_state != TCP_CA_Open)
-               return 0;
+               goto send_now;
+
+       /* Defer for less than two clock ticks. */
+       if (!tp->tso_deferred && ((jiffies<<1)>>1) - (tp->tso_deferred>>1) > 1)
+               goto send_now;
 
        in_flight = tcp_packets_in_flight(tp);
 
@@ -1106,7 +1119,7 @@ static int tcp_tso_should_defer(struct sock *sk, struct tcp_sock *tp, struct sk_
 
        /* If a full-sized TSO skb can be sent, do it. */
        if (limit >= 65536)
-               return 0;
+               goto send_now;
 
        if (sysctl_tcp_tso_win_divisor) {
                u32 chunk = min(tp->snd_wnd, tp->snd_cwnd * tp->mss_cache);
@@ -1116,7 +1129,7 @@ static int tcp_tso_should_defer(struct sock *sk, struct tcp_sock *tp, struct sk_
                 */
                chunk /= sysctl_tcp_tso_win_divisor;
                if (limit >= chunk)
-                       return 0;
+                       goto send_now;
        } else {
                /* Different approach, try not to defer past a single
                 * ACK.  Receiver should ACK every other full sized
@@ -1124,11 +1137,17 @@ static int tcp_tso_should_defer(struct sock *sk, struct tcp_sock *tp, struct sk_
                 * then send now.
                 */
                if (limit > tcp_max_burst(tp) * tp->mss_cache)
-                       return 0;
+                       goto send_now;
        }
 
        /* Ok, it looks like it is advisable to defer.  */
+       tp->tso_deferred = 1 | (jiffies<<1);
+
        return 1;
+
+send_now:
+       tp->tso_deferred = 0;
+       return 0;
 }
 
 /* Create a new MTU probe if we are ready.
index 7a7a00147e55c7d63758d2d3bad84884d3b1a4c6..1bed0cdf53e30c42f7d9f0ea82f2c75b59429d7f 100644 (file)
@@ -52,7 +52,7 @@ __xfrm4_find_bundle(struct flowi *fl, struct xfrm_policy *policy)
                    xdst->u.rt.fl.fl4_dst == fl->fl4_dst &&
                    xdst->u.rt.fl.fl4_src == fl->fl4_src &&
                    xdst->u.rt.fl.fl4_tos == fl->fl4_tos &&
-                   xfrm_bundle_ok(xdst, fl, AF_INET, 0)) {
+                   xfrm_bundle_ok(policy, xdst, fl, AF_INET, 0)) {
                        dst_clone(dst);
                        break;
                }
index a460e8132b4d471c0b282f47c58996ddd4f35315..6e48f52e197c3dc435f234c7a664b508273959d7 100644 (file)
@@ -153,6 +153,19 @@ config INET6_XFRM_MODE_ROUTEOPTIMIZATION
        ---help---
          Support for MIPv6 route optimization mode.
 
+config IPV6_SIT
+       tristate "IPv6: IPv6-in-IPv4 tunnel (SIT driver)"
+       depends on IPV6
+       default y
+       ---help---
+         Tunneling means encapsulating data of one protocol type within
+         another protocol and sending it over a channel that understands the
+         encapsulating protocol. This driver implements encapsulation of IPv6
+         into IPv4 packets. This is useful if you want to connect two IPv6
+         networks over an IPv4-only path.
+
+         Saying M here will produce a module called sit.ko. If unsure, say Y.
+
 config IPV6_TUNNEL
        tristate "IPv6: IPv6-in-IPv6 tunnel"
        select INET6_TUNNEL
@@ -162,9 +175,16 @@ config IPV6_TUNNEL
 
          If unsure, say N.
 
+config IPV6_MULTIPLE_TABLES
+       bool "IPv6: Multiple Routing Tables"
+       depends on IPV6 && EXPERIMENTAL
+       select FIB_RULES
+       ---help---
+         Support multiple routing tables.
+
 config IPV6_SUBTREES
        bool "IPv6: source address based routing"
-       depends on IPV6 && EXPERIMENTAL
+       depends on IPV6_MULTIPLE_TABLES
        ---help---
          Enable routing by source address or prefix.
 
@@ -176,13 +196,6 @@ config IPV6_SUBTREES
 
          If unsure, say N.
 
-config IPV6_MULTIPLE_TABLES
-       bool "IPv6: Multiple Routing Tables"
-       depends on IPV6 && EXPERIMENTAL
-       select FIB_RULES
-       ---help---
-         Support multiple routing tables.
-
 config IPV6_ROUTE_FWMARK
        bool "IPv6: use netfilter MARK value as routing key"
        depends on IPV6_MULTIPLE_TABLES && NETFILTER
index 87274e47fe32736d7ec0261f44ef3d34ecd0ef64..addcc011bc01c2146577e0d1e2253cef64e0a93d 100644 (file)
@@ -4,7 +4,7 @@
 
 obj-$(CONFIG_IPV6) += ipv6.o
 
-ipv6-objs :=   af_inet6.o anycast.o ip6_output.o ip6_input.o addrconf.o sit.o \
+ipv6-objs :=   af_inet6.o anycast.o ip6_output.o ip6_input.o addrconf.o \
                route.o ip6_fib.o ipv6_sockglue.o ndisc.o udp.o raw.o \
                protocol.o icmp.o mcast.o reassembly.o tcp_ipv6.o \
                exthdrs.o sysctl_net_ipv6.o datagram.o proc.o \
@@ -29,6 +29,7 @@ obj-$(CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION) += xfrm6_mode_ro.o
 obj-$(CONFIG_INET6_XFRM_MODE_BEET) += xfrm6_mode_beet.o
 obj-$(CONFIG_NETFILTER)        += netfilter/
 
+obj-$(CONFIG_IPV6_SIT) += sit.o
 obj-$(CONFIG_IPV6_TUNNEL) += ip6_tunnel.o
 
 obj-y += exthdrs_core.o
index e03c33b2465bc72415c8e27dce382db233959a69..b312a5f7a759caa298d42d4ce6763baac0b9ba04 100644 (file)
@@ -396,8 +396,10 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev)
        ndev->regen_timer.data = (unsigned long) ndev;
        if ((dev->flags&IFF_LOOPBACK) ||
            dev->type == ARPHRD_TUNNEL ||
-           dev->type == ARPHRD_NONE ||
-           dev->type == ARPHRD_SIT) {
+#if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE)
+           dev->type == ARPHRD_SIT ||
+#endif
+           dev->type == ARPHRD_NONE) {
                printk(KERN_INFO
                       "%s: Disabled Privacy Extensions\n",
                       dev->name);
@@ -1546,8 +1548,10 @@ addrconf_prefix_route(struct in6_addr *pfx, int plen, struct net_device *dev,
           This thing is done here expecting that the whole
           class of non-broadcast devices need not cloning.
         */
+#if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE)
        if (dev->type == ARPHRD_SIT && (dev->flags & IFF_POINTOPOINT))
                cfg.fc_flags |= RTF_NONEXTHOP;
+#endif
 
        ip6_route_add(&cfg);
 }
@@ -1569,6 +1573,7 @@ static void addrconf_add_mroute(struct net_device *dev)
        ip6_route_add(&cfg);
 }
 
+#if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE)
 static void sit_route_add(struct net_device *dev)
 {
        struct fib6_config cfg = {
@@ -1582,6 +1587,7 @@ static void sit_route_add(struct net_device *dev)
        /* prefix length - 96 bits "::d.d.d.d" */
        ip6_route_add(&cfg);
 }
+#endif
 
 static void addrconf_add_lroute(struct net_device *dev)
 {
@@ -1852,6 +1858,7 @@ int addrconf_set_dstaddr(void __user *arg)
        if (dev == NULL)
                goto err_exit;
 
+#if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE)
        if (dev->type == ARPHRD_SIT) {
                struct ifreq ifr;
                mm_segment_t    oldfs;
@@ -1881,6 +1888,7 @@ int addrconf_set_dstaddr(void __user *arg)
                        err = dev_open(dev);
                }
        }
+#endif
 
 err_exit:
        rtnl_unlock();
@@ -2010,6 +2018,7 @@ int addrconf_del_ifaddr(void __user *arg)
        return err;
 }
 
+#if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE)
 static void sit_add_v4_addrs(struct inet6_dev *idev)
 {
        struct inet6_ifaddr * ifp;
@@ -2078,6 +2087,7 @@ static void sit_add_v4_addrs(struct inet6_dev *idev)
                }
         }
 }
+#endif
 
 static void init_loopback(struct net_device *dev)
 {
@@ -2141,6 +2151,7 @@ static void addrconf_dev_config(struct net_device *dev)
                addrconf_add_linklocal(idev, &addr);
 }
 
+#if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE)
 static void addrconf_sit_config(struct net_device *dev)
 {
        struct inet6_dev *idev;
@@ -2166,6 +2177,7 @@ static void addrconf_sit_config(struct net_device *dev)
        } else
                sit_route_add(dev);
 }
+#endif
 
 static inline int
 ipv6_inherit_linklocal(struct inet6_dev *idev, struct net_device *link_dev)
@@ -2260,9 +2272,11 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
                }
 
                switch(dev->type) {
+#if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE)
                case ARPHRD_SIT:
                        addrconf_sit_config(dev);
                        break;
+#endif
                case ARPHRD_TUNNEL6:
                        addrconf_ip6_tnl_config(dev);
                        break;
index e94eccb99707991c80409ebce8a157e1beaba3e7..858cae29581c8e129289ce09cf644fd5d70c9184 100644 (file)
@@ -850,7 +850,6 @@ static int __init inet6_init(void)
        err = addrconf_init();
        if (err)
                goto addrconf_fail;
-       sit_init();
 
        /* Init v6 extension headers. */
        ipv6_rthdr_init();
@@ -927,7 +926,6 @@ static void __exit inet6_exit(void)
        mip6_fini();
 #endif
        /* Cleanup code parts. */
-       sit_cleanup();
        ip6_flowlabel_cleanup();
        addrconf_cleanup();
        ip6_route_cleanup();
index d8c1057e8b008520f2f9c3a8e21e6de1bd90f757..1896ecb52899069a80b577748885b0d2489a6754 100644 (file)
@@ -117,12 +117,15 @@ static int fib6_rule_match(struct fib_rule *rule, struct flowi *fl, int flags)
 {
        struct fib6_rule *r = (struct fib6_rule *) rule;
 
-       if (!ipv6_prefix_equal(&fl->fl6_dst, &r->dst.addr, r->dst.plen))
+       if (r->dst.plen &&
+           !ipv6_prefix_equal(&fl->fl6_dst, &r->dst.addr, r->dst.plen))
                return 0;
 
-       if ((flags & RT6_LOOKUP_F_HAS_SADDR) &&
-           !ipv6_prefix_equal(&fl->fl6_src, &r->src.addr, r->src.plen))
-               return 0;
+       if (r->src.plen) {
+               if (!(flags & RT6_LOOKUP_F_HAS_SADDR) ||
+                   !ipv6_prefix_equal(&fl->fl6_src, &r->src.addr, r->src.plen))
+                       return 0;
+       }
 
        if (r->tclass && r->tclass != ((ntohl(fl->fl6_flowlabel) >> 20) & 0xff))
                return 0;
index 8fcae7a6510b9fdeb793bfc395de458daee4ddc2..f98ca30d7c1f300377daf7f51d49afc2e4af5c21 100644 (file)
@@ -169,7 +169,6 @@ static __inline__ void rt6_release(struct rt6_info *rt)
 
 static struct fib6_table fib6_main_tbl = {
        .tb6_id         = RT6_TABLE_MAIN,
-       .tb6_lock       = RW_LOCK_UNLOCKED,
        .tb6_root       = {
                .leaf           = &ip6_null_entry,
                .fn_flags       = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO,
@@ -187,6 +186,12 @@ static void fib6_link_table(struct fib6_table *tb)
 {
        unsigned int h;
 
+       /*
+        * Initialize table lock at a single place to give lockdep a key,
+        * tables aren't visible prior to being linked to the list.
+        */
+       rwlock_init(&tb->tb6_lock);
+
        h = tb->tb6_id & (FIB_TABLE_HASHSZ - 1);
 
        /*
@@ -199,7 +204,6 @@ static void fib6_link_table(struct fib6_table *tb)
 #ifdef CONFIG_IPV6_MULTIPLE_TABLES
 static struct fib6_table fib6_local_tbl = {
        .tb6_id         = RT6_TABLE_LOCAL,
-       .tb6_lock       = RW_LOCK_UNLOCKED,
        .tb6_root       = {
                .leaf           = &ip6_null_entry,
                .fn_flags       = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO,
@@ -213,7 +217,6 @@ static struct fib6_table *fib6_alloc_table(u32 id)
        table = kzalloc(sizeof(*table), GFP_ATOMIC);
        if (table != NULL) {
                table->tb6_id = id;
-               table->tb6_lock = RW_LOCK_UNLOCKED;
                table->tb6_root.leaf = &ip6_null_entry;
                table->tb6_root.fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO;
        }
index 0304b5fe8d6aa01d77378d4ff939e8f5f04c1d4f..41a8a5f06602b2a98c36225925765783cb21d075 100644 (file)
@@ -967,8 +967,6 @@ static void ndisc_recv_na(struct sk_buff *skb)
                    ipv6_devconf.forwarding && ipv6_devconf.proxy_ndp &&
                    pneigh_lookup(&nd_tbl, &msg->target, dev, 0)) {
                        /* XXX: idev->cnf.prixy_ndp */
-                       WARN_ON(skb->dst != NULL &&
-                               ((struct rt6_info *)skb->dst)->rt6i_idev);
                        goto out;
                }
 
index d6b4b4f48d18cb6d9736c520b854d0899c98bc23..c953466b7afdbde3c77e6494c3f24a46908d9097 100644 (file)
@@ -141,6 +141,10 @@ struct rt6_info ip6_null_entry = {
 
 #ifdef CONFIG_IPV6_MULTIPLE_TABLES
 
+static int ip6_pkt_prohibit(struct sk_buff *skb);
+static int ip6_pkt_prohibit_out(struct sk_buff *skb);
+static int ip6_pkt_blk_hole(struct sk_buff *skb);
+
 struct rt6_info ip6_prohibit_entry = {
        .u = {
                .dst = {
@@ -150,8 +154,8 @@ struct rt6_info ip6_prohibit_entry = {
                        .obsolete       = -1,
                        .error          = -EACCES,
                        .metrics        = { [RTAX_HOPLIMIT - 1] = 255, },
-                       .input          = ip6_pkt_discard,
-                       .output         = ip6_pkt_discard_out,
+                       .input          = ip6_pkt_prohibit,
+                       .output         = ip6_pkt_prohibit_out,
                        .ops            = &ip6_dst_ops,
                        .path           = (struct dst_entry*)&ip6_prohibit_entry,
                }
@@ -170,8 +174,8 @@ struct rt6_info ip6_blk_hole_entry = {
                        .obsolete       = -1,
                        .error          = -EINVAL,
                        .metrics        = { [RTAX_HOPLIMIT - 1] = 255, },
-                       .input          = ip6_pkt_discard,
-                       .output         = ip6_pkt_discard_out,
+                       .input          = ip6_pkt_blk_hole,
+                       .output         = ip6_pkt_blk_hole,
                        .ops            = &ip6_dst_ops,
                        .path           = (struct dst_entry*)&ip6_blk_hole_entry,
                }
@@ -484,7 +488,7 @@ int rt6_route_rcv(struct net_device *dev, u8 *opt, int len,
 do { \
        if (rt == &ip6_null_entry) { \
                struct fib6_node *pn; \
-               while (fn) { \
+               while (1) { \
                        if (fn->fn_flags & RTN_TL_ROOT) \
                                goto out; \
                        pn = fn->parent; \
@@ -529,13 +533,17 @@ struct rt6_info *rt6_lookup(struct in6_addr *daddr, struct in6_addr *saddr,
                .nl_u = {
                        .ip6_u = {
                                .daddr = *daddr,
-                               /* TODO: saddr */
                        },
                },
        };
        struct dst_entry *dst;
        int flags = strict ? RT6_LOOKUP_F_IFACE : 0;
 
+       if (saddr) {
+               memcpy(&fl.fl6_src, saddr, sizeof(*saddr));
+               flags |= RT6_LOOKUP_F_HAS_SADDR;
+       }
+
        dst = fib6_rule_lookup(&fl, flags, ip6_pol_route_lookup);
        if (dst->error == 0)
                return (struct rt6_info *) dst;
@@ -614,8 +622,6 @@ static struct rt6_info *rt6_alloc_clone(struct rt6_info *ort, struct in6_addr *d
                ipv6_addr_copy(&rt->rt6i_dst.addr, daddr);
                rt->rt6i_dst.plen = 128;
                rt->rt6i_flags |= RTF_CACHE;
-               if (rt->rt6i_flags & RTF_REJECT)
-                       rt->u.dst.error = ort->u.dst.error;
                rt->u.dst.flags |= DST_HOST;
                rt->rt6i_nexthop = neigh_clone(ort->rt6i_nexthop);
        }
@@ -697,6 +703,7 @@ out2:
 void ip6_route_input(struct sk_buff *skb)
 {
        struct ipv6hdr *iph = skb->nh.ipv6h;
+       int flags = RT6_LOOKUP_F_HAS_SADDR;
        struct flowi fl = {
                .iif = skb->dev->ifindex,
                .nl_u = {
@@ -711,7 +718,9 @@ void ip6_route_input(struct sk_buff *skb)
                },
                .proto = iph->nexthdr,
        };
-       int flags = rt6_need_strict(&iph->daddr) ? RT6_LOOKUP_F_IFACE : 0;
+
+       if (rt6_need_strict(&iph->daddr))
+               flags |= RT6_LOOKUP_F_IFACE;
 
        skb->dst = fib6_rule_lookup(&fl, flags, ip6_pol_route_input);
 }
@@ -794,6 +803,9 @@ struct dst_entry * ip6_route_output(struct sock *sk, struct flowi *fl)
        if (rt6_need_strict(&fl->fl6_dst))
                flags |= RT6_LOOKUP_F_IFACE;
 
+       if (!ipv6_addr_any(&fl->fl6_src))
+               flags |= RT6_LOOKUP_F_HAS_SADDR;
+
        return fib6_rule_lookup(fl, flags, ip6_pol_route_output);
 }
 
@@ -1345,6 +1357,7 @@ static struct rt6_info *ip6_route_redirect(struct in6_addr *dest,
                                           struct in6_addr *gateway,
                                           struct net_device *dev)
 {
+       int flags = RT6_LOOKUP_F_HAS_SADDR;
        struct ip6rd_flowi rdfl = {
                .fl = {
                        .oif = dev->ifindex,
@@ -1357,7 +1370,9 @@ static struct rt6_info *ip6_route_redirect(struct in6_addr *dest,
                },
                .gateway = *gateway,
        };
-       int flags = rt6_need_strict(dest) ? RT6_LOOKUP_F_IFACE : 0;
+
+       if (rt6_need_strict(dest))
+               flags |= RT6_LOOKUP_F_IFACE;
 
        return (struct rt6_info *)fib6_rule_lookup((struct flowi *)&rdfl, flags, __ip6_route_redirect);
 }
@@ -1527,6 +1542,7 @@ static struct rt6_info * ip6_rt_copy(struct rt6_info *ort)
                rt->u.dst.output = ort->u.dst.output;
 
                memcpy(rt->u.dst.metrics, ort->u.dst.metrics, RTAX_MAX*sizeof(u32));
+               rt->u.dst.error = ort->u.dst.error;
                rt->u.dst.dev = ort->u.dst.dev;
                if (rt->u.dst.dev)
                        dev_hold(rt->u.dst.dev);
@@ -1730,24 +1746,50 @@ int ipv6_route_ioctl(unsigned int cmd, void __user *arg)
  *     Drop the packet on the floor
  */
 
-static int ip6_pkt_discard(struct sk_buff *skb)
+static inline int ip6_pkt_drop(struct sk_buff *skb, int code)
 {
        int type = ipv6_addr_type(&skb->nh.ipv6h->daddr);
        if (type == IPV6_ADDR_ANY || type == IPV6_ADDR_RESERVED)
                IP6_INC_STATS(IPSTATS_MIB_INADDRERRORS);
 
        IP6_INC_STATS(IPSTATS_MIB_OUTNOROUTES);
-       icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_NOROUTE, 0, skb->dev);
+       icmpv6_send(skb, ICMPV6_DEST_UNREACH, code, 0, skb->dev);
        kfree_skb(skb);
        return 0;
 }
 
+static int ip6_pkt_discard(struct sk_buff *skb)
+{
+       return ip6_pkt_drop(skb, ICMPV6_NOROUTE);
+}
+
 static int ip6_pkt_discard_out(struct sk_buff *skb)
 {
        skb->dev = skb->dst->dev;
        return ip6_pkt_discard(skb);
 }
 
+#ifdef CONFIG_IPV6_MULTIPLE_TABLES
+
+static int ip6_pkt_prohibit(struct sk_buff *skb)
+{
+       return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED);
+}
+
+static int ip6_pkt_prohibit_out(struct sk_buff *skb)
+{
+       skb->dev = skb->dst->dev;
+       return ip6_pkt_prohibit(skb);
+}
+
+static int ip6_pkt_blk_hole(struct sk_buff *skb)
+{
+       kfree_skb(skb);
+       return 0;
+}
+
+#endif
+
 /*
  *     Allocate a dst for local (unicast / anycast) address.
  */
index 836eecd7e62bfaa100a616d5aeda26ecc652ada9..b481a4d780c239f229d9d28aae7c0239fc589f76 100644 (file)
@@ -850,3 +850,7 @@ int __init sit_init(void)
        inet_del_protocol(&sit_protocol, IPPROTO_IPV6);
        goto out;
 }
+
+module_init(sit_init);
+module_exit(sit_cleanup);
+MODULE_LICENSE("GPL");
index 3b6575478fcc381aae64ee2c0d7b2b791d5f1846..4c2a7c0cafef2db93c05e95f1345b02affca3ea9 100644 (file)
@@ -329,7 +329,7 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
        }
 
        if (sk->sk_state == TCP_TIME_WAIT) {
-               inet_twsk_put((struct inet_timewait_sock *)sk);
+               inet_twsk_put(inet_twsk(sk));
                return;
        }
 
@@ -653,7 +653,7 @@ static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32
        int tot_len = sizeof(struct tcphdr);
 
        if (ts)
-               tot_len += 3*4;
+               tot_len += TCPOLEN_TSTAMP_ALIGNED;
 
        buff = alloc_skb(MAX_HEADER + sizeof(struct ipv6hdr) + tot_len,
                         GFP_ATOMIC);
@@ -749,7 +749,7 @@ static struct sock *tcp_v6_hnd_req(struct sock *sk,struct sk_buff *skb)
                        bh_lock_sock(nsk);
                        return nsk;
                }
-               inet_twsk_put((struct inet_timewait_sock *)nsk);
+               inet_twsk_put(inet_twsk(nsk));
                return NULL;
        }
 
@@ -1283,18 +1283,17 @@ discard_and_relse:
 
 do_time_wait:
        if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) {
-               inet_twsk_put((struct inet_timewait_sock *)sk);
+               inet_twsk_put(inet_twsk(sk));
                goto discard_it;
        }
 
        if (skb->len < (th->doff<<2) || tcp_checksum_complete(skb)) {
                TCP_INC_STATS_BH(TCP_MIB_INERRS);
-               inet_twsk_put((struct inet_timewait_sock *)sk);
+               inet_twsk_put(inet_twsk(sk));
                goto discard_it;
        }
 
-       switch (tcp_timewait_state_process((struct inet_timewait_sock *)sk,
-                                          skb, th)) {
+       switch (tcp_timewait_state_process(inet_twsk(sk), skb, th)) {
        case TCP_TW_SYN:
        {
                struct sock *sk2;
index 6a252e2134d11cf8629d64c3dc56592f6625fec8..d400f8fae1291ed265a9bdfe1133a9e6b6306359 100644 (file)
 static struct dst_ops xfrm6_dst_ops;
 static struct xfrm_policy_afinfo xfrm6_policy_afinfo;
 
-static int xfrm6_dst_lookup(struct xfrm_dst **dst, struct flowi *fl)
+static int xfrm6_dst_lookup(struct xfrm_dst **xdst, struct flowi *fl)
 {
-       int err = 0;
-       *dst = (struct xfrm_dst*)ip6_route_output(NULL, fl);
-       if (!*dst)
-               err = -ENETUNREACH;
+       struct dst_entry *dst = ip6_route_output(NULL, fl);
+       int err = dst->error;
+       if (!err)
+               *xdst = (struct xfrm_dst *) dst;
+       else
+               dst_release(dst);
        return err;
 }
 
@@ -73,7 +75,7 @@ __xfrm6_find_bundle(struct flowi *fl, struct xfrm_policy *policy)
                                 xdst->u.rt6.rt6i_src.plen);
                if (ipv6_addr_equal(&xdst->u.rt6.rt6i_dst.addr, &fl_dst_prefix) &&
                    ipv6_addr_equal(&xdst->u.rt6.rt6i_src.addr, &fl_src_prefix) &&
-                   xfrm_bundle_ok(xdst, fl, AF_INET6,
+                   xfrm_bundle_ok(policy, xdst, fl, AF_INET6,
                                   (xdst->u.rt6.rt6i_dst.plen != 128 ||
                                    xdst->u.rt6.rt6i_src.plen != 128))) {
                        dst_clone(dst);
index a154b1d71c0f8d9af8e0f0c429886c5cdbe8b44c..56292ab7d6522861d5d5be01983d54e170869ef0 100644 (file)
@@ -43,7 +43,7 @@ struct ias_value irias_missing = { IAS_MISSING, 0, 0, 0, {0}};
  *
  * Faster, check boundary... Jean II
  */
-static char *strndup(char *str, int max)
+static char *strndup(char *str, size_t max)
 {
        char *new_str;
        int len;
index ff98e70b0931f8e74cfc14c3d9b9337b50c12e41..20ff7cca1d070e156e4d18dca77cd33991c79992 100644 (file)
@@ -2928,11 +2928,6 @@ static struct xfrm_policy *pfkey_compile_policy(struct sock *sk, int opt,
                if (*dir)
                        goto out;
        }
-       else {
-               *dir = security_xfrm_sock_policy_alloc(xp, sk);
-               if (*dir)
-                       goto out;
-       }
 
        *dir = pol->sadb_x_policy_dir-1;
        return xp;
index ce94732b8e231d68c7cda461f5168103cf8b45f8..f619c6527266255427cacff4c0acb89025c82755 100644 (file)
@@ -209,7 +209,9 @@ config NETFILTER_XT_TARGET_SECMARK
 
 config NETFILTER_XT_TARGET_CONNSECMARK
        tristate '"CONNSECMARK" target support'
-       depends on NETFILTER_XTABLES && (NF_CONNTRACK_SECMARK || IP_NF_CONNTRACK_SECMARK)
+       depends on NETFILTER_XTABLES && \
+                  ((NF_CONNTRACK && NF_CONNTRACK_SECMARK) || \
+                   (IP_NF_CONNTRACK && IP_NF_CONNTRACK_SECMARK))
        help
          The CONNSECMARK target copies security markings from packets
          to connections, and restores security markings from connections
index 1721f7c78c77b5dcc5ca59d3a82962d7230ee29a..bd0156a28ecdbb1c90b1f927d0d5520e4a8984c5 100644 (file)
@@ -47,13 +47,6 @@ MODULE_LICENSE("GPL");
 
 static char __initdata version[] = "0.93";
 
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
-
 static inline int
 ctnetlink_dump_tuples_proto(struct sk_buff *skb, 
                            const struct nf_conntrack_tuple *tuple,
@@ -410,7 +403,6 @@ static int ctnetlink_done(struct netlink_callback *cb)
 {
        if (cb->args[1])
                nf_ct_put((struct nf_conn *)cb->args[1]);
-       DEBUGP("entered %s\n", __FUNCTION__);
        return 0;
 }
 
@@ -425,9 +417,6 @@ ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
        struct nfgenmsg *nfmsg = NLMSG_DATA(cb->nlh);
        u_int8_t l3proto = nfmsg->nfgen_family;
 
-       DEBUGP("entered %s, last bucket=%lu id=%u\n", __FUNCTION__, 
-                       cb->args[0], *id);
-
        read_lock_bh(&nf_conntrack_lock);
        last = (struct nf_conn *)cb->args[1];
        for (; cb->args[0] < nf_conntrack_htable_size; cb->args[0]++) {
@@ -471,7 +460,6 @@ out:
        if (last)
                nf_ct_put(last);
 
-       DEBUGP("leaving, last bucket=%lu id=%u\n", cb->args[0], *id);
        return skb->len;
 }
 
@@ -482,8 +470,6 @@ ctnetlink_parse_tuple_ip(struct nfattr *attr, struct nf_conntrack_tuple *tuple)
        struct nf_conntrack_l3proto *l3proto;
        int ret = 0;
 
-       DEBUGP("entered %s\n", __FUNCTION__);
-
        nfattr_parse_nested(tb, CTA_IP_MAX, attr);
 
        l3proto = nf_ct_l3proto_find_get(tuple->src.l3num);
@@ -493,8 +479,6 @@ ctnetlink_parse_tuple_ip(struct nfattr *attr, struct nf_conntrack_tuple *tuple)
 
        nf_ct_l3proto_put(l3proto);
 
-       DEBUGP("leaving\n");
-
        return ret;
 }
 
@@ -510,8 +494,6 @@ ctnetlink_parse_tuple_proto(struct nfattr *attr,
        struct nf_conntrack_protocol *proto;
        int ret = 0;
 
-       DEBUGP("entered %s\n", __FUNCTION__);
-
        nfattr_parse_nested(tb, CTA_PROTO_MAX, attr);
 
        if (nfattr_bad_size(tb, CTA_PROTO_MAX, cta_min_proto))
@@ -538,8 +520,6 @@ ctnetlink_parse_tuple(struct nfattr *cda[], struct nf_conntrack_tuple *tuple,
        struct nfattr *tb[CTA_TUPLE_MAX];
        int err;
 
-       DEBUGP("entered %s\n", __FUNCTION__);
-
        memset(tuple, 0, sizeof(*tuple));
 
        nfattr_parse_nested(tb, CTA_TUPLE_MAX, cda[type-1]);
@@ -566,10 +546,6 @@ ctnetlink_parse_tuple(struct nfattr *cda[], struct nf_conntrack_tuple *tuple,
        else
                tuple->dst.dir = IP_CT_DIR_ORIGINAL;
 
-       NF_CT_DUMP_TUPLE(tuple);
-
-       DEBUGP("leaving\n");
-
        return 0;
 }
 
@@ -586,8 +562,6 @@ static int ctnetlink_parse_nat_proto(struct nfattr *attr,
        struct nfattr *tb[CTA_PROTONAT_MAX];
        struct ip_nat_protocol *npt;
 
-       DEBUGP("entered %s\n", __FUNCTION__);
-
        nfattr_parse_nested(tb, CTA_PROTONAT_MAX, attr);
 
        if (nfattr_bad_size(tb, CTA_PROTONAT_MAX, cta_min_protonat))
@@ -606,7 +580,6 @@ static int ctnetlink_parse_nat_proto(struct nfattr *attr,
 
        ip_nat_proto_put(npt);
 
-       DEBUGP("leaving\n");
        return 0;
 }
 
@@ -622,8 +595,6 @@ ctnetlink_parse_nat(struct nfattr *nat,
        struct nfattr *tb[CTA_NAT_MAX];
        int err;
 
-       DEBUGP("entered %s\n", __FUNCTION__);
-
        memset(range, 0, sizeof(*range));
        
        nfattr_parse_nested(tb, CTA_NAT_MAX, nat);
@@ -649,7 +620,6 @@ ctnetlink_parse_nat(struct nfattr *nat,
        if (err < 0)
                return err;
 
-       DEBUGP("leaving\n");
        return 0;
 }
 #endif
@@ -659,8 +629,6 @@ ctnetlink_parse_help(struct nfattr *attr, char **helper_name)
 {
        struct nfattr *tb[CTA_HELP_MAX];
 
-       DEBUGP("entered %s\n", __FUNCTION__);
-
        nfattr_parse_nested(tb, CTA_HELP_MAX, attr);
 
        if (!tb[CTA_HELP_NAME-1])
@@ -690,8 +658,6 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
        u_int8_t u3 = nfmsg->nfgen_family;
        int err = 0;
 
-       DEBUGP("entered %s\n", __FUNCTION__);
-
        if (nfattr_bad_size(cda, CTA_MAX, cta_min))
                return -EINVAL;
 
@@ -709,10 +675,8 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
                return err;
 
        h = nf_conntrack_find_get(&tuple, NULL);
-       if (!h) {
-               DEBUGP("tuple not found in conntrack hash\n");
+       if (!h)
                return -ENOENT;
-       }
 
        ct = nf_ct_tuplehash_to_ctrack(h);
        
@@ -727,7 +691,6 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
                ct->timeout.function((unsigned long)ct);
 
        nf_ct_put(ct);
-       DEBUGP("leaving\n");
 
        return 0;
 }
@@ -744,8 +707,6 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
        u_int8_t u3 = nfmsg->nfgen_family;
        int err = 0;
 
-       DEBUGP("entered %s\n", __FUNCTION__);
-
        if (nlh->nlmsg_flags & NLM_F_DUMP) {
                u32 rlen;
 
@@ -779,11 +740,9 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
                return err;
 
        h = nf_conntrack_find_get(&tuple, NULL);
-       if (!h) {
-               DEBUGP("tuple not found in conntrack hash");
+       if (!h)
                return -ENOENT;
-       }
-       DEBUGP("tuple found\n");
+
        ct = nf_ct_tuplehash_to_ctrack(h);
 
        err = -ENOMEM;
@@ -804,7 +763,6 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
        if (err < 0)
                goto out;
 
-       DEBUGP("leaving\n");
        return 0;
 
 free:
@@ -876,8 +834,6 @@ ctnetlink_change_helper(struct nf_conn *ct, struct nfattr *cda[])
        char *helpname;
        int err;
 
-       DEBUGP("entered %s\n", __FUNCTION__);
-
        if (!help) {
                /* FIXME: we need to reallocate and rehash */
                return -EBUSY;
@@ -954,8 +910,6 @@ ctnetlink_change_conntrack(struct nf_conn *ct, struct nfattr *cda[])
 {
        int err;
 
-       DEBUGP("entered %s\n", __FUNCTION__);
-
        if (cda[CTA_HELP-1]) {
                err = ctnetlink_change_helper(ct, cda);
                if (err < 0)
@@ -985,7 +939,6 @@ ctnetlink_change_conntrack(struct nf_conn *ct, struct nfattr *cda[])
                ct->mark = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_MARK-1]));
 #endif
 
-       DEBUGP("all done\n");
        return 0;
 }
 
@@ -997,8 +950,6 @@ ctnetlink_create_conntrack(struct nfattr *cda[],
        struct nf_conn *ct;
        int err = -EINVAL;
 
-       DEBUGP("entered %s\n", __FUNCTION__);
-
        ct = nf_conntrack_alloc(otuple, rtuple);
        if (ct == NULL || IS_ERR(ct))
                return -ENOMEM; 
@@ -1028,7 +979,6 @@ ctnetlink_create_conntrack(struct nfattr *cda[],
        add_timer(&ct->timeout);
        nf_conntrack_hash_insert(ct);
 
-       DEBUGP("conntrack with id %u inserted\n", ct->id);
        return 0;
 
 err:   
@@ -1046,8 +996,6 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
        u_int8_t u3 = nfmsg->nfgen_family;
        int err = 0;
 
-       DEBUGP("entered %s\n", __FUNCTION__);
-
        if (nfattr_bad_size(cda, CTA_MAX, cta_min))
                return -EINVAL;
 
@@ -1071,7 +1019,6 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
 
        if (h == NULL) {
                write_unlock_bh(&nf_conntrack_lock);
-               DEBUGP("no such conntrack, create new\n");
                err = -ENOENT;
                if (nlh->nlmsg_flags & NLM_F_CREATE)
                        err = ctnetlink_create_conntrack(cda, &otuple, &rtuple);
@@ -1087,7 +1034,6 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
 
        /* We manipulate the conntrack inside the global conntrack table lock,
         * so there's no need to increase the refcount */
-       DEBUGP("conntrack found\n");
        err = -EEXIST;
        if (!(nlh->nlmsg_flags & NLM_F_EXCL))
                err = ctnetlink_change_conntrack(nf_ct_tuplehash_to_ctrack(h), cda);
@@ -1268,8 +1214,6 @@ ctnetlink_exp_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
        struct nfgenmsg *nfmsg = NLMSG_DATA(cb->nlh);
        u_int8_t l3proto = nfmsg->nfgen_family;
 
-       DEBUGP("entered %s, last id=%llu\n", __FUNCTION__, *id);
-
        read_lock_bh(&nf_conntrack_lock);
        list_for_each_prev(i, &nf_conntrack_expect_list) {
                exp = (struct nf_conntrack_expect *) i;
@@ -1287,8 +1231,6 @@ ctnetlink_exp_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
 out:   
        read_unlock_bh(&nf_conntrack_lock);
 
-       DEBUGP("leaving, last id=%llu\n", *id);
-
        return skb->len;
 }
 
@@ -1308,8 +1250,6 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
        u_int8_t u3 = nfmsg->nfgen_family;
        int err = 0;
 
-       DEBUGP("entered %s\n", __FUNCTION__);
-
        if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp))
                return -EINVAL;
 
@@ -1460,8 +1400,6 @@ ctnetlink_create_expect(struct nfattr *cda[], u_int8_t u3)
        struct nf_conn_help *help;
        int err = 0;
 
-       DEBUGP("entered %s\n", __FUNCTION__);
-
        /* caller guarantees that those three CTA_EXPECT_* exist */
        err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE, u3);
        if (err < 0)
@@ -1516,8 +1454,6 @@ ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb,
        u_int8_t u3 = nfmsg->nfgen_family;
        int err = 0;
 
-       DEBUGP("entered %s\n", __FUNCTION__);   
-
        if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp))
                return -EINVAL;
 
@@ -1546,8 +1482,6 @@ ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb,
                err = ctnetlink_change_expect(exp, cda);
        write_unlock_bh(&nf_conntrack_lock);
 
-       DEBUGP("leaving\n");
-       
        return err;
 }
 
index db9b896e57c8527ecfc9db2d7c0decbaca77b8e2..39e117502bd7c821afc4c1adef330585bdedf2f2 100644 (file)
@@ -68,7 +68,7 @@ static int __init xt_nfqueue_init(void)
 
 static void __exit xt_nfqueue_fini(void)
 {
-       xt_register_targets(xt_nfqueue_target, ARRAY_SIZE(xt_nfqueue_target));
+       xt_unregister_targets(xt_nfqueue_target, ARRAY_SIZE(xt_nfqueue_target));
 }
 
 module_init(xt_nfqueue_init);
index 92a5726ef237e2fb6f894c205bf26d9b97971075..a8f03057dbdedd8c4887b0585ab48e60d1bd5b03 100644 (file)
@@ -147,7 +147,7 @@ static int __init xt_connmark_init(void)
 
 static void __exit xt_connmark_fini(void)
 {
-       xt_register_matches(xt_connmark_match, ARRAY_SIZE(xt_connmark_match));
+       xt_unregister_matches(xt_connmark_match, ARRAY_SIZE(xt_connmark_match));
 }
 
 module_init(xt_connmark_init);
index 54fb7de3c2b1d42be1b4dc131810cf70e9618614..ff971103fd0ce4e9732e6d621c6df38c6ac45723 100644 (file)
@@ -200,7 +200,7 @@ void netlbl_cache_invalidate(void)
 int netlbl_cache_add(const struct sk_buff *skb,
                     const struct netlbl_lsm_secattr *secattr)
 {
-       if (secattr->cache.data == NULL)
+       if (secattr->cache == NULL)
                return -ENOMSG;
 
        if (CIPSO_V4_OPTEXIST(skb))
index bb3ddd4784b1cebfd4668dc15df844b484b36267..9b9c555c713f0a4666c00657da1b37037928b722 100644 (file)
@@ -786,11 +786,10 @@ static long htb_do_events(struct htb_sched *q, int level)
        for (i = 0; i < 500; i++) {
                struct htb_class *cl;
                long diff;
-               struct rb_node *p = q->wait_pq[level].rb_node;
+               struct rb_node *p = rb_first(&q->wait_pq[level]);
+
                if (!p)
                        return 0;
-               while (p->rb_left)
-                       p = p->rb_left;
 
                cl = rb_entry(p, struct htb_class, pq_node);
                if (time_after(cl->pq_key, q->jiffies)) {
index 45939bafbdf894dfcb61a0ed993d1d79204aa5a8..ef8874babf6ae8c7c23ae26fe1baaea03334dd2f 100644 (file)
@@ -170,6 +170,8 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch)
                return NET_XMIT_BYPASS;
        }
 
+       skb_orphan(skb);
+
        /*
         * If we need to duplicate packet, then re-insert at top of the
         * qdisc tree, since parent queuer expects that only one
index 249e5033c1a86d7d3d4ec66b20549705a51cf0a2..78071c6e6cf10522a3e35162c12ec06cba383a1b 100644 (file)
@@ -215,17 +215,17 @@ static struct dst_entry *sctp_v6_get_dst(struct sctp_association *asoc,
        }
 
        dst = ip6_route_output(NULL, &fl);
-       if (dst) {
+       if (!dst->error) {
                struct rt6_info *rt;
                rt = (struct rt6_info *)dst;
                SCTP_DEBUG_PRINTK(
                        "rt6_dst:" NIP6_FMT " rt6_src:" NIP6_FMT "\n",
                        NIP6(rt->rt6i_dst.addr), NIP6(rt->rt6i_src.addr));
-       } else {
-               SCTP_DEBUG_PRINTK("NO ROUTE\n");
+               return dst;
        }
-
-       return dst;
+       SCTP_DEBUG_PRINTK("NO ROUTE\n");
+       dst_release(dst);
+       return NULL;
 }
 
 /* Returns the number of consecutive initial bits that match in the 2 ipv6
index a356d8d310a95f0cc04033f091fa229ea7a510ea..7f49e769080ea631e9827e9e483bcb1577a9721b 100644 (file)
@@ -344,7 +344,7 @@ static int sctp_assocs_seq_show(struct seq_file *seq, void *v)
                           assoc, sk, sctp_sk(sk)->type, sk->sk_state,
                           assoc->state, hash, assoc->assoc_id,
                           assoc->sndbuf_used,
-                          (sk->sk_rcvbuf - assoc->rwnd),
+                          atomic_read(&assoc->rmem_alloc),
                           sock_i_uid(sk), sock_i_ino(sk),
                           epb->bind_addr.port,
                           assoc->peer.port);
index 3fe906d6506982f9e1c7a0bdcf6e67b6d2772d58..9f34dec6ff8ec0cd70acfb72e594f016c60a36a8 100644 (file)
@@ -821,7 +821,7 @@ out:
  * addrs is a pointer to an array of one or more socket addresses. Each
  * address is contained in its appropriate structure (i.e. struct
  * sockaddr_in or struct sockaddr_in6) the family of the address type
- * must be used to distengish the address length (note that this
+ * must be used to distinguish the address length (note that this
  * representation is termed a "packed array" of addresses). The caller
  * specifies the number of addresses in the array with addrcnt.
  *
@@ -5362,6 +5362,20 @@ static void sctp_wfree(struct sk_buff *skb)
        sctp_association_put(asoc);
 }
 
+/* Do accounting for the receive space on the socket.
+ * Accounting for the association is done in ulpevent.c
+ * We set this as a destructor for the cloned data skbs so that
+ * accounting is done at the correct time.
+ */
+void sctp_sock_rfree(struct sk_buff *skb)
+{
+       struct sock *sk = skb->sk;
+       struct sctp_ulpevent *event = sctp_skb2event(skb);
+
+       atomic_sub(event->rmem_len, &sk->sk_rmem_alloc);
+}
+
+
 /* Helper function to wait for space in the sndbuf.  */
 static int sctp_wait_for_sndbuf(struct sctp_association *asoc, long *timeo_p,
                                size_t msg_len)
@@ -5634,10 +5648,10 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk,
        sctp_skb_for_each(skb, &oldsk->sk_receive_queue, tmp) {
                event = sctp_skb2event(skb);
                if (event->asoc == assoc) {
-                       sock_rfree(skb);
+                       sctp_sock_rfree(skb);
                        __skb_unlink(skb, &oldsk->sk_receive_queue);
                        __skb_queue_tail(&newsk->sk_receive_queue, skb);
-                       skb_set_owner_r(skb, newsk);
+                       sctp_skb_set_owner_r(skb, newsk);
                }
        }
 
@@ -5665,10 +5679,10 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk,
                sctp_skb_for_each(skb, &oldsp->pd_lobby, tmp) {
                        event = sctp_skb2event(skb);
                        if (event->asoc == assoc) {
-                               sock_rfree(skb);
+                               sctp_sock_rfree(skb);
                                __skb_unlink(skb, &oldsp->pd_lobby);
                                __skb_queue_tail(queue, skb);
-                               skb_set_owner_r(skb, newsk);
+                               sctp_skb_set_owner_r(skb, newsk);
                        }
                }
 
index ee236784a6bb91ea8bbf3787b776aabf65971ae9..a015283a90870bcb5f9c5c85d08d5742c865813a 100644 (file)
@@ -55,10 +55,13 @@ static void sctp_ulpevent_release_frag_data(struct sctp_ulpevent *event);
 
 
 /* Initialize an ULP event from an given skb.  */
-SCTP_STATIC void sctp_ulpevent_init(struct sctp_ulpevent *event, int msg_flags)
+SCTP_STATIC void sctp_ulpevent_init(struct sctp_ulpevent *event,
+                                   int msg_flags,
+                                   unsigned int len)
 {
        memset(event, 0, sizeof(struct sctp_ulpevent));
        event->msg_flags = msg_flags;
+       event->rmem_len = len;
 }
 
 /* Create a new sctp_ulpevent.  */
@@ -73,7 +76,7 @@ SCTP_STATIC struct sctp_ulpevent *sctp_ulpevent_new(int size, int msg_flags,
                goto fail;
 
        event = sctp_skb2event(skb);
-       sctp_ulpevent_init(event, msg_flags);
+       sctp_ulpevent_init(event, msg_flags, skb->truesize);
 
        return event;
 
@@ -101,17 +104,16 @@ static inline void sctp_ulpevent_set_owner(struct sctp_ulpevent *event,
        sctp_association_hold((struct sctp_association *)asoc);
        skb = sctp_event2skb(event);
        event->asoc = (struct sctp_association *)asoc;
-       atomic_add(skb->truesize, &event->asoc->rmem_alloc);
-       skb_set_owner_r(skb, asoc->base.sk);
+       atomic_add(event->rmem_len, &event->asoc->rmem_alloc);
+       sctp_skb_set_owner_r(skb, asoc->base.sk);
 }
 
 /* A simple destructor to give up the reference to the association. */
 static inline void sctp_ulpevent_release_owner(struct sctp_ulpevent *event)
 {
        struct sctp_association *asoc = event->asoc;
-       struct sk_buff *skb = sctp_event2skb(event);
 
-       atomic_sub(skb->truesize, &asoc->rmem_alloc);
+       atomic_sub(event->rmem_len, &asoc->rmem_alloc);
        sctp_association_put(asoc);
 }
 
@@ -372,7 +374,7 @@ struct sctp_ulpevent *sctp_ulpevent_make_remote_error(
 
        /* Embed the event fields inside the cloned skb.  */
        event = sctp_skb2event(skb);
-       sctp_ulpevent_init(event, MSG_NOTIFICATION);
+       sctp_ulpevent_init(event, MSG_NOTIFICATION, skb->truesize);
 
        sre = (struct sctp_remote_error *)
                skb_push(skb, sizeof(struct sctp_remote_error));
@@ -464,7 +466,7 @@ struct sctp_ulpevent *sctp_ulpevent_make_send_failed(
 
        /* Embed the event fields inside the cloned skb.  */
        event = sctp_skb2event(skb);
-       sctp_ulpevent_init(event, MSG_NOTIFICATION);
+       sctp_ulpevent_init(event, MSG_NOTIFICATION, skb->truesize);
 
        ssf = (struct sctp_send_failed *)
                skb_push(skb, sizeof(struct sctp_send_failed));
@@ -682,8 +684,11 @@ struct sctp_ulpevent *sctp_ulpevent_make_rcvmsg(struct sctp_association *asoc,
        /* Embed the event fields inside the cloned skb.  */
        event = sctp_skb2event(skb);
 
-       /* Initialize event with flags 0.  */
-       sctp_ulpevent_init(event, 0);
+       /* Initialize event with flags 0  and correct length
+        * Since this is a clone of the original skb, only account for
+        * the data of this chunk as other chunks will be accounted separately.
+        */
+       sctp_ulpevent_init(event, 0, skb->len + sizeof(struct sk_buff));
 
        sctp_ulpevent_receive_data(event, asoc);
 
index 575e556aeb3eb58c30dd80f86c6158defb3c664f..e1d144275f97aab998d4edc5155e608a316945e9 100644 (file)
@@ -309,7 +309,7 @@ static struct sctp_ulpevent *sctp_make_reassembled_event(struct sk_buff_head *qu
                        if (!new)
                                return NULL;    /* try again later */
 
-                       new->sk = f_frag->sk;
+                       sctp_skb_set_owner_r(new, f_frag->sk);
 
                        skb_shinfo(new)->frag_list = pos;
                } else
index 447d9aef46051ebc9fd810bc96b01e92113c61f1..1f0f079ffa654d1aa412ff3aa5344aaaee34dd4e 100644 (file)
@@ -1146,10 +1146,11 @@ out:
        return ret;
 }
 
-u32 *
+static __be32 *
 svcauth_gss_prepare_to_wrap(struct xdr_buf *resbuf, struct gss_svc_data *gsd)
 {
-       u32 *p, verf_len;
+       __be32 *p;
+       u32 verf_len;
 
        p = gsd->verf_start;
        gsd->verf_start = NULL;
index 919d5ba7ca0a206cb40aff51e67ac90bbc4f67b3..e52afab413ded56212cad69a2801df58bc6b6d6c 100644 (file)
@@ -101,11 +101,13 @@ void rpc_getport(struct rpc_task *task)
        /* Autobind on cloned rpc clients is discouraged */
        BUG_ON(clnt->cl_parent != clnt);
 
-       if (xprt_test_and_set_binding(xprt)) {
-               task->tk_status = -EACCES;      /* tell caller to check again */
-               rpc_sleep_on(&xprt->binding, task, NULL, NULL);
-               return;
-       }
+       /* Put self on queue before sending rpcbind request, in case
+        * pmap_getport_done completes before we return from rpc_run_task */
+       rpc_sleep_on(&xprt->binding, task, NULL, NULL);
+
+       status = -EACCES;               /* tell caller to check again */
+       if (xprt_test_and_set_binding(xprt))
+               goto bailout_nofree;
 
        /* Someone else may have bound if we slept */
        status = 0;
@@ -134,8 +136,6 @@ void rpc_getport(struct rpc_task *task)
                goto bailout;
        rpc_release_task(child);
 
-       rpc_sleep_on(&xprt->binding, task, NULL, NULL);
-
        task->tk_xprt->stat.bind_count++;
        return;
 
index c2c8bb20d07f7171aad6a74e9c4cf323fd4f03ca..eb44ec929ca115a5944b7dd8f380a79d3b057249 100644 (file)
@@ -282,7 +282,10 @@ __svc_create(struct svc_program *prog, unsigned int bufsize, int npools,
        serv->sv_program   = prog;
        serv->sv_nrthreads = 1;
        serv->sv_stats     = prog->pg_stats;
-       serv->sv_bufsz     = bufsize? bufsize : 4096;
+       if (bufsize > RPCSVC_MAXPAYLOAD)
+               bufsize = RPCSVC_MAXPAYLOAD;
+       serv->sv_max_payload = bufsize? bufsize : 4096;
+       serv->sv_max_mesg  = roundup(serv->sv_max_payload + PAGE_SIZE, PAGE_SIZE);
        serv->sv_shutdown  = shutdown;
        xdrsize = 0;
        while (prog) {
@@ -414,9 +417,9 @@ svc_init_buffer(struct svc_rqst *rqstp, unsigned int size)
        int pages;
        int arghi;
        
-       if (size > RPCSVC_MAXPAYLOAD)
-               size = RPCSVC_MAXPAYLOAD;
-       pages = 2 + (size+ PAGE_SIZE -1) / PAGE_SIZE;
+       pages = size / PAGE_SIZE + 1; /* extra page as we hold both request and reply.
+                                      * We assume one is at most one page
+                                      */
        arghi = 0;
        BUG_ON(pages > RPCSVC_MAXPAGES);
        while (pages) {
@@ -463,7 +466,7 @@ __svc_create_thread(svc_thread_fn func, struct svc_serv *serv,
 
        if (!(rqstp->rq_argp = kmalloc(serv->sv_xdrsize, GFP_KERNEL))
         || !(rqstp->rq_resp = kmalloc(serv->sv_xdrsize, GFP_KERNEL))
-        || !svc_init_buffer(rqstp, serv->sv_bufsz))
+        || !svc_init_buffer(rqstp, serv->sv_max_mesg))
                goto out_thread;
 
        serv->sv_nrthreads++;
@@ -825,6 +828,11 @@ svc_process(struct svc_rqst *rqstp)
                *statp = procp->pc_func(rqstp, rqstp->rq_argp, rqstp->rq_resp);
 
                /* Encode reply */
+               if (*statp == rpc_drop_reply) {
+                       if (procp->pc_release)
+                               procp->pc_release(rqstp, NULL, rqstp->rq_resp);
+                       goto dropit;
+               }
                if (*statp == rpc_success && (xdr = procp->pc_encode)
                 && !xdr(rqstp, resv->iov_base+resv->iov_len, rqstp->rq_resp)) {
                        dprintk("svc: failed to encode reply\n");
@@ -938,8 +946,8 @@ u32 svc_max_payload(const struct svc_rqst *rqstp)
 
        if (rqstp->rq_sock->sk_sock->type == SOCK_DGRAM)
                max = RPCSVC_MAXPAYLOAD_UDP;
-       if (rqstp->rq_server->sv_bufsz < max)
-               max = rqstp->rq_server->sv_bufsz;
+       if (rqstp->rq_server->sv_max_payload < max)
+               max = rqstp->rq_server->sv_max_payload;
        return max;
 }
 EXPORT_SYMBOL_GPL(svc_max_payload);
index b39e7e2b648f67020a7706314cf142e81f017793..96521f16342b63e80f18f77888fa7b5b06dbd333 100644 (file)
@@ -192,13 +192,13 @@ svc_sock_enqueue(struct svc_sock *svsk)
        svsk->sk_pool = pool;
 
        set_bit(SOCK_NOSPACE, &svsk->sk_sock->flags);
-       if (((atomic_read(&svsk->sk_reserved) + serv->sv_bufsz)*2
+       if (((atomic_read(&svsk->sk_reserved) + serv->sv_max_mesg)*2
             > svc_sock_wspace(svsk))
            && !test_bit(SK_CLOSE, &svsk->sk_flags)
            && !test_bit(SK_CONN, &svsk->sk_flags)) {
                /* Don't enqueue while not enough space for reply */
                dprintk("svc: socket %p  no space, %d*2 > %ld, not enqueued\n",
-                       svsk->sk_sk, atomic_read(&svsk->sk_reserved)+serv->sv_bufsz,
+                       svsk->sk_sk, atomic_read(&svsk->sk_reserved)+serv->sv_max_mesg,
                        svc_sock_wspace(svsk));
                svsk->sk_pool = NULL;
                clear_bit(SK_BUSY, &svsk->sk_flags);
@@ -220,7 +220,7 @@ svc_sock_enqueue(struct svc_sock *svsk)
                                rqstp, rqstp->rq_sock);
                rqstp->rq_sock = svsk;
                atomic_inc(&svsk->sk_inuse);
-               rqstp->rq_reserved = serv->sv_bufsz;
+               rqstp->rq_reserved = serv->sv_max_mesg;
                atomic_add(rqstp->rq_reserved, &svsk->sk_reserved);
                BUG_ON(svsk->sk_pool != pool);
                wake_up(&rqstp->rq_wait);
@@ -639,8 +639,8 @@ svc_udp_recvfrom(struct svc_rqst *rqstp)
             * which will access the socket.
             */
            svc_sock_setbufsize(svsk->sk_sock,
-                               (serv->sv_nrthreads+3) * serv->sv_bufsz,
-                               (serv->sv_nrthreads+3) * serv->sv_bufsz);
+                               (serv->sv_nrthreads+3) * serv->sv_max_mesg,
+                               (serv->sv_nrthreads+3) * serv->sv_max_mesg);
 
        if ((rqstp->rq_deferred = svc_deferred_dequeue(svsk))) {
                svc_sock_received(svsk);
@@ -749,8 +749,8 @@ svc_udp_init(struct svc_sock *svsk)
         * svc_udp_recvfrom will re-adjust if necessary
         */
        svc_sock_setbufsize(svsk->sk_sock,
-                           3 * svsk->sk_server->sv_bufsz,
-                           3 * svsk->sk_server->sv_bufsz);
+                           3 * svsk->sk_server->sv_max_mesg,
+                           3 * svsk->sk_server->sv_max_mesg);
 
        set_bit(SK_DATA, &svsk->sk_flags); /* might have come in before data_ready set up */
        set_bit(SK_CHNGBUF, &svsk->sk_flags);
@@ -973,7 +973,7 @@ svc_tcp_recvfrom(struct svc_rqst *rqstp)
                return 0;
        }
 
-       if (test_bit(SK_CONN, &svsk->sk_flags)) {
+       if (svsk->sk_sk->sk_state == TCP_LISTEN) {
                svc_tcp_accept(svsk);
                svc_sock_received(svsk);
                return 0;
@@ -993,8 +993,8 @@ svc_tcp_recvfrom(struct svc_rqst *rqstp)
                 * as soon a a complete request arrives.
                 */
                svc_sock_setbufsize(svsk->sk_sock,
-                                   (serv->sv_nrthreads+3) * serv->sv_bufsz,
-                                   3 * serv->sv_bufsz);
+                                   (serv->sv_nrthreads+3) * serv->sv_max_mesg,
+                                   3 * serv->sv_max_mesg);
 
        clear_bit(SK_DATA, &svsk->sk_flags);
 
@@ -1032,7 +1032,7 @@ svc_tcp_recvfrom(struct svc_rqst *rqstp)
                }
                svsk->sk_reclen &= 0x7fffffff;
                dprintk("svc: TCP record, %d bytes\n", svsk->sk_reclen);
-               if (svsk->sk_reclen > serv->sv_bufsz) {
+               if (svsk->sk_reclen > serv->sv_max_mesg) {
                        printk(KERN_NOTICE "RPC: bad TCP reclen 0x%08lx (large)\n",
                               (unsigned long) svsk->sk_reclen);
                        goto err_delete;
@@ -1171,8 +1171,8 @@ svc_tcp_init(struct svc_sock *svsk)
                 * svc_tcp_recvfrom will re-adjust if necessary
                 */
                svc_sock_setbufsize(svsk->sk_sock,
-                                   3 * svsk->sk_server->sv_bufsz,
-                                   3 * svsk->sk_server->sv_bufsz);
+                                   3 * svsk->sk_server->sv_max_mesg,
+                                   3 * svsk->sk_server->sv_max_mesg);
 
                set_bit(SK_CHNGBUF, &svsk->sk_flags);
                set_bit(SK_DATA, &svsk->sk_flags);
@@ -1234,7 +1234,7 @@ svc_recv(struct svc_rqst *rqstp, long timeout)
 
 
        /* now allocate needed pages.  If we get a failure, sleep briefly */
-       pages = 2 + (serv->sv_bufsz + PAGE_SIZE -1) / PAGE_SIZE;
+       pages = (serv->sv_max_mesg + PAGE_SIZE) / PAGE_SIZE;
        for (i=0; i < pages ; i++)
                while (rqstp->rq_pages[i] == NULL) {
                        struct page *p = alloc_page(GFP_KERNEL);
@@ -1263,7 +1263,7 @@ svc_recv(struct svc_rqst *rqstp, long timeout)
        if ((svsk = svc_sock_dequeue(pool)) != NULL) {
                rqstp->rq_sock = svsk;
                atomic_inc(&svsk->sk_inuse);
-               rqstp->rq_reserved = serv->sv_bufsz;    
+               rqstp->rq_reserved = serv->sv_max_mesg;
                atomic_add(rqstp->rq_reserved, &svsk->sk_reserved);
        } else {
                /* No data pending. Go to sleep */
index 28100e01922516045b9530f46df41fadb8738729..757fc91ef25d8621e9af5f1e162bda754b90f0fa 100644 (file)
@@ -1366,7 +1366,7 @@ int xs_setup_udp(struct rpc_xprt *xprt, struct rpc_timeout *to)
        if (xprt->slot == NULL)
                return -ENOMEM;
 
-       if (ntohs(addr->sin_port != 0))
+       if (ntohs(addr->sin_port) != 0)
                xprt_set_bound(xprt);
        xprt->port = xs_get_random_port();
 
index 75a5968c2139b92640f58cb961fafe01660b1d3f..39744a33bd3693864997d6ec2d1d2339f2f2eb48 100644 (file)
@@ -2,7 +2,7 @@
  * net/tipc/bearer.c: TIPC bearer code
  * 
  * Copyright (c) 1996-2006, Ericsson AB
- * Copyright (c) 2004-2005, Wind River Systems
+ * Copyright (c) 2004-2006, Wind River Systems
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -191,14 +191,14 @@ void tipc_media_addr_printf(struct print_buf *pb, struct tipc_media_addr *a)
        if ((i < media_count) && (m_ptr->addr2str != NULL)) {
                char addr_str[MAX_ADDR_STR];
 
-               tipc_printf(pb, "%s(%s) ", m_ptr->name, 
+               tipc_printf(pb, "%s(%s)", m_ptr->name,
                            m_ptr->addr2str(a, addr_str, sizeof(addr_str)));
        } else {
                unchar *addr = (unchar *)&a->dev_addr;
 
-               tipc_printf(pb, "UNKNOWN(%u):", media_type);
+               tipc_printf(pb, "UNKNOWN(%u)", media_type);
                for (i = 0; i < (sizeof(*a) - sizeof(a->type)); i++) {
-                       tipc_printf(pb, "%02x ", addr[i]);
+                       tipc_printf(pb, "-%02x", addr[i]);
                }
        }
 }
index 285e1bc2d8808502f53e952eed76a1dd72308534..ed1351ed05e10ab651f9aa388a21f2c6460d5c9c 100644 (file)
@@ -2,7 +2,7 @@
  * net/tipc/config.c: TIPC configuration management code
  * 
  * Copyright (c) 2002-2006, Ericsson AB
- * Copyright (c) 2004-2005, Wind River Systems
+ * Copyright (c) 2004-2006, Wind River Systems
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -613,7 +613,8 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area
                rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_net_id);
                break;
        default:
-               rep_tlv_buf = NULL;
+               rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
+                                                         " (unknown command)");
                break;
        }
 
index 0539a8362858997cbe6baa2d2445c75c081e3996..6f5b7ee311802388b80ad5d72e2a8a15ae48b89e 100644 (file)
@@ -57,7 +57,7 @@ void tipc_socket_stop(void);
 int  tipc_netlink_start(void);
 void tipc_netlink_stop(void);
 
-#define TIPC_MOD_VER "1.6.1"
+#define TIPC_MOD_VER "1.6.2"
 
 #ifndef CONFIG_TIPC_ZONES
 #define CONFIG_TIPC_ZONES 3
@@ -90,7 +90,7 @@ int tipc_random;
 atomic_t tipc_user_count = ATOMIC_INIT(0);
 
 const char tipc_alphabet[] = 
-       "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_";
+       "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.";
 
 /* configurable TIPC parameters */
 
index 762aac2572be88f768d6e6d0d2c3337508b7965a..4638947c2326e0ea534f490b02abc767270d2c1a 100644 (file)
@@ -65,7 +65,7 @@
 #define assert(i)  BUG_ON(!(i))
 
 struct tipc_msg;
-extern struct print_buf *TIPC_CONS, *TIPC_LOG;
+extern struct print_buf *TIPC_NULL, *TIPC_CONS, *TIPC_LOG;
 extern struct print_buf *TIPC_TEE(struct print_buf *, struct print_buf *);
 void tipc_msg_print(struct print_buf*,struct tipc_msg *,const char*);
 void tipc_printf(struct print_buf *, const char *fmt, ...);
@@ -83,9 +83,9 @@ void tipc_dump(struct print_buf*,const char *fmt, ...);
 #define warn(fmt, arg...) tipc_printf(TIPC_OUTPUT, KERN_WARNING "TIPC: " fmt, ## arg)
 #define info(fmt, arg...) tipc_printf(TIPC_OUTPUT, KERN_NOTICE "TIPC: " fmt, ## arg)
 
-#define dbg(fmt, arg...)  do {if (DBG_OUTPUT) tipc_printf(DBG_OUTPUT, fmt, ## arg);} while(0)
-#define msg_dbg(msg, txt) do {if (DBG_OUTPUT) tipc_msg_print(DBG_OUTPUT, msg, txt);} while(0)
-#define dump(fmt, arg...) do {if (DBG_OUTPUT) tipc_dump(DBG_OUTPUT, fmt, ##arg);} while(0)
+#define dbg(fmt, arg...)  do {if (DBG_OUTPUT != TIPC_NULL) tipc_printf(DBG_OUTPUT, fmt, ## arg);} while(0)
+#define msg_dbg(msg, txt) do {if (DBG_OUTPUT != TIPC_NULL) tipc_msg_print(DBG_OUTPUT, msg, txt);} while(0)
+#define dump(fmt, arg...) do {if (DBG_OUTPUT != TIPC_NULL) tipc_dump(DBG_OUTPUT, fmt, ##arg);} while(0)
 
 
 /*     
@@ -94,11 +94,11 @@ void tipc_dump(struct print_buf*,const char *fmt, ...);
  * here, or on a per .c file basis, by redefining these symbols.  The following
  * print buffer options are available:
  *
- * NULL                                : Output to null print buffer (i.e. print nowhere)
- * TIPC_CONS                   : Output to system console
- * TIPC_LOG                    : Output to TIPC log buffer 
- * &buf                                : Output to user-defined buffer (struct print_buf *)
- * TIPC_TEE(&buf_a,&buf_b)     : Output to two print buffers (eg. TIPC_TEE(TIPC_CONS,TIPC_LOG) )
+ * TIPC_NULL              : null buffer (i.e. print nowhere)
+ * TIPC_CONS              : system console
+ * TIPC_LOG               : TIPC log buffer
+ * &buf                           : user-defined buffer (struct print_buf *)
+ * TIPC_TEE(&buf_a,&buf_b) : list of buffers (eg. TIPC_TEE(TIPC_CONS,TIPC_LOG))
  */
 
 #ifndef TIPC_OUTPUT
@@ -106,7 +106,7 @@ void tipc_dump(struct print_buf*,const char *fmt, ...);
 #endif
 
 #ifndef DBG_OUTPUT
-#define DBG_OUTPUT NULL
+#define DBG_OUTPUT TIPC_NULL
 #endif
 
 #else
@@ -136,7 +136,7 @@ void tipc_dump(struct print_buf*,const char *fmt, ...);
 #define TIPC_OUTPUT TIPC_CONS
 
 #undef  DBG_OUTPUT
-#define DBG_OUTPUT NULL
+#define DBG_OUTPUT TIPC_NULL
 
 #endif                   
 
@@ -275,11 +275,15 @@ static inline void k_term_timer(struct timer_list *timer)
 /*
  * TIPC message buffer code
  *
- * TIPC message buffer headroom leaves room for 14 byte Ethernet header, 
+ * TIPC message buffer headroom reserves space for a link-level header
+ * (in case the message is sent off-node),
  * while ensuring TIPC header is word aligned for quicker access
+ *
+ * The largest header currently supported is 18 bytes, which is used when
+ * the standard 14 byte Ethernet header has 4 added bytes for VLAN info
  */
 
-#define BUF_HEADROOM 16u 
+#define BUF_HEADROOM 20u
 
 struct tipc_skb_cb {
        void *handle;
index 55130655e1edbe306a484f552c2a20080496cb15..d8af4c28695d21202aeeb4a3ce155c1b46a780c1 100644 (file)
@@ -1,8 +1,8 @@
 /*
- * net/tipc/dbg.c: TIPC print buffer routines for debuggign
+ * net/tipc/dbg.c: TIPC print buffer routines for debugging
  * 
  * Copyright (c) 1996-2006, Ericsson AB
- * Copyright (c) 2005, Wind River Systems
+ * Copyright (c) 2005-2006, Wind River Systems
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
 #include "config.h"
 #include "dbg.h"
 
-#define MAX_STRING 512
-
-static char print_string[MAX_STRING];
+static char print_string[TIPC_PB_MAX_STR];
 static DEFINE_SPINLOCK(print_lock);
 
+static struct print_buf null_buf = { NULL, 0, NULL, NULL };
+struct print_buf *TIPC_NULL = &null_buf;
+
 static struct print_buf cons_buf = { NULL, 0, NULL, NULL };
 struct print_buf *TIPC_CONS = &cons_buf;
 
@@ -62,68 +63,83 @@ struct print_buf *TIPC_LOG = &log_buf;
 /*
  * Locking policy when using print buffers.
  *
- * 1) Routines of the form printbuf_XXX() rely on the caller to prevent
- *    simultaneous use of the print buffer(s) being manipulated.
- * 2) tipc_printf() uses 'print_lock' to prevent simultaneous use of
- *    'print_string' and to protect its print buffer(s).
- * 3) TIPC_TEE() uses 'print_lock' to protect its print buffer(s).
- * 4) Routines of the form log_XXX() uses 'print_lock' to protect TIPC_LOG.
+ * The following routines use 'print_lock' for protection:
+ * 1) tipc_printf()  - to protect its print buffer(s) and 'print_string'
+ * 2) TIPC_TEE()     - to protect its print buffer(s)
+ * 3) tipc_dump()    - to protect its print buffer(s) and 'print_string'
+ * 4) tipc_log_XXX() - to protect TIPC_LOG
+ *
+ * All routines of the form tipc_printbuf_XXX() rely on the caller to prevent
+ * simultaneous use of the print buffer(s) being manipulated.
  */
 
 /**
  * tipc_printbuf_init - initialize print buffer to empty
+ * @pb: pointer to print buffer structure
+ * @raw: pointer to character array used by print buffer
+ * @size: size of character array
+ *
+ * Makes the print buffer a null device that discards anything written to it
+ * if the character array is too small (or absent).
  */
 
-void tipc_printbuf_init(struct print_buf *pb, char *raw, u32 sz)
+void tipc_printbuf_init(struct print_buf *pb, char *raw, u32 size)
 {
-       if (!pb || !raw || (sz < (MAX_STRING + 1)))
-               return;
-
-       pb->crs = pb->buf = raw;
-       pb->size = sz;
+       pb->buf = raw;
+       pb->crs = raw;
+       pb->size = size;
        pb->next = NULL;
-       pb->buf[0] = 0;
-       pb->buf[sz-1] = ~0;
+
+       if (size < TIPC_PB_MIN_SIZE) {
+               pb->buf = NULL;
+       } else if (raw) {
+               pb->buf[0] = 0;
+               pb->buf[size-1] = ~0;
+       }
 }
 
 /**
  * tipc_printbuf_reset - reinitialize print buffer to empty state
+ * @pb: pointer to print buffer structure
  */
 
 void tipc_printbuf_reset(struct print_buf *pb)
 {
-       if (pb && pb->buf)
-               tipc_printbuf_init(pb, pb->buf, pb->size);
+       tipc_printbuf_init(pb, pb->buf, pb->size);
 }
 
 /**
  * tipc_printbuf_empty - test if print buffer is in empty state
+ * @pb: pointer to print buffer structure
+ *
+ * Returns non-zero if print buffer is empty.
  */
 
 int tipc_printbuf_empty(struct print_buf *pb)
 {
-       return (!pb || !pb->buf || (pb->crs == pb->buf));
+       return (!pb->buf || (pb->crs == pb->buf));
 }
 
 /**
  * tipc_printbuf_validate - check for print buffer overflow
+ * @pb: pointer to print buffer structure
  * 
  * Verifies that a print buffer has captured all data written to it. 
  * If data has been lost, linearize buffer and prepend an error message
  * 
- * Returns length of print buffer data string (including trailing NULL)
+ * Returns length of print buffer data string (including trailing NUL)
  */
 
 int tipc_printbuf_validate(struct print_buf *pb)
 {
-        char *err = "             *** PRINT BUFFER WRAPPED AROUND ***\n";
+        char *err = "\n\n*** PRINT BUFFER OVERFLOW ***\n\n";
         char *cp_buf;
         struct print_buf cb;
 
-       if (!pb || !pb->buf)
+       if (!pb->buf)
                return 0;
 
-       if (pb->buf[pb->size - 1] == '\0') {
+       if (pb->buf[pb->size - 1] == 0) {
                 cp_buf = kmalloc(pb->size, GFP_ATOMIC);
                 if (cp_buf != NULL){
                         tipc_printbuf_init(&cb, cp_buf, pb->size);
@@ -141,6 +157,8 @@ int tipc_printbuf_validate(struct print_buf *pb)
 
 /**
  * tipc_printbuf_move - move print buffer contents to another print buffer
+ * @pb_to: pointer to destination print buffer structure
+ * @pb_from: pointer to source print buffer structure
  * 
  * Current contents of destination print buffer (if any) are discarded.
  * Source print buffer becomes empty if a successful move occurs.
@@ -152,21 +170,22 @@ void tipc_printbuf_move(struct print_buf *pb_to, struct print_buf *pb_from)
 
        /* Handle the cases where contents can't be moved */
 
-       if (!pb_to || !pb_to->buf)
+       if (!pb_to->buf)
                return;
 
-       if (!pb_from || !pb_from->buf) {
+       if (!pb_from->buf) {
                tipc_printbuf_reset(pb_to);
                return;
        }
 
        if (pb_to->size < pb_from->size) {
                tipc_printbuf_reset(pb_to);
-               tipc_printf(pb_to, "*** PRINT BUFFER OVERFLOW ***");
+               tipc_printf(pb_to, "*** PRINT BUFFER MOVE ERROR ***");
                return;
        }
 
        /* Copy data from char after cursor to end (if used) */
+
        len = pb_from->buf + pb_from->size - pb_from->crs - 2;
        if ((pb_from->buf[pb_from->size-1] == 0) && (len > 0)) {
                strcpy(pb_to->buf, pb_from->crs + 1);
@@ -175,6 +194,7 @@ void tipc_printbuf_move(struct print_buf *pb_to, struct print_buf *pb_from)
                pb_to->crs = pb_to->buf;
 
        /* Copy data from start to cursor (always) */
+
        len = pb_from->crs - pb_from->buf;
        strcpy(pb_to->crs, pb_from->buf);
        pb_to->crs += len;
@@ -184,6 +204,8 @@ void tipc_printbuf_move(struct print_buf *pb_to, struct print_buf *pb_from)
 
 /**
  * tipc_printf - append formatted output to print buffer chain
+ * @pb: pointer to chain of print buffers (may be NULL)
+ * @fmt: formatted info to be printed
  */
 
 void tipc_printf(struct print_buf *pb, const char *fmt, ...)
@@ -195,8 +217,8 @@ void tipc_printf(struct print_buf *pb, const char *fmt, ...)
 
        spin_lock_bh(&print_lock);
        FORMAT(print_string, chars_to_add, fmt);
-       if (chars_to_add >= MAX_STRING)
-               strcpy(print_string, "*** STRING TOO LONG ***");
+       if (chars_to_add >= TIPC_PB_MAX_STR)
+               strcpy(print_string, "*** PRINT BUFFER STRING TOO LONG ***");
 
        while (pb) {
                if (pb == TIPC_CONS)
@@ -206,6 +228,10 @@ void tipc_printf(struct print_buf *pb, const char *fmt, ...)
                        if (chars_to_add <= chars_left) {
                                strcpy(pb->crs, print_string);
                                pb->crs += chars_to_add;
+                       } else if (chars_to_add >= (pb->size - 1)) {
+                               strcpy(pb->buf, print_string + chars_to_add + 1
+                                      - pb->size);
+                               pb->crs = pb->buf + pb->size - 1;
                        } else {
                                strcpy(pb->buf, print_string + chars_left);
                                 save_char = print_string[chars_left];
@@ -224,6 +250,10 @@ void tipc_printf(struct print_buf *pb, const char *fmt, ...)
 
 /**
  * TIPC_TEE - perform next output operation on both print buffers  
+ * @b0: pointer to chain of print buffers (may be NULL)
+ * @b1: pointer to print buffer to add to chain
+ *
+ * Returns pointer to print buffer chain.
  */
 
 struct print_buf *TIPC_TEE(struct print_buf *b0, struct print_buf *b1)
@@ -232,8 +262,6 @@ struct print_buf *TIPC_TEE(struct print_buf *b0, struct print_buf *b1)
 
        if (!b0 || (b0 == b1))
                return b1;
-       if (!b1)
-               return b0;
 
        spin_lock_bh(&print_lock);
        while (pb->next) {
@@ -256,7 +284,7 @@ static void print_to_console(char *crs, int len)
        int rest = len;
 
        while (rest > 0) {
-               int sz = rest < MAX_STRING ? rest : MAX_STRING;
+               int sz = rest < TIPC_PB_MAX_STR ? rest : TIPC_PB_MAX_STR;
                char c = crs[sz];
 
                crs[sz] = 0;
@@ -275,36 +303,48 @@ static void printbuf_dump(struct print_buf *pb)
 {
        int len;
 
+       if (!pb->buf) {
+               printk("*** PRINT BUFFER NOT ALLOCATED ***");
+               return;
+       }
+
        /* Dump print buffer from char after cursor to end (if used) */
+
        len = pb->buf + pb->size - pb->crs - 2;
        if ((pb->buf[pb->size - 1] == 0) && (len > 0))
                print_to_console(pb->crs + 1, len);
 
        /* Dump print buffer from start to cursor (always) */
+
        len = pb->crs - pb->buf;
        print_to_console(pb->buf, len);
 }
 
 /**
  * tipc_dump - dump non-console print buffer(s) to console
+ * @pb: pointer to chain of print buffers
  */
 
 void tipc_dump(struct print_buf *pb, const char *fmt, ...)
 {
+       struct print_buf *pb_next;
        int len;
 
        spin_lock_bh(&print_lock);
-       FORMAT(TIPC_CONS->buf, len, fmt);
-       printk(TIPC_CONS->buf);
+       FORMAT(print_string, len, fmt);
+       printk(print_string);
 
        for (; pb; pb = pb->next) {
-               if (pb == TIPC_CONS)
-                       continue;
-               printk("\n---- Start of dump,%s log ----\n\n", 
-                      (pb == TIPC_LOG) ? "global" : "local");
-               printbuf_dump(pb);
-               tipc_printbuf_reset(pb);
-               printk("\n-------- End of dump --------\n");
+               if (pb != TIPC_CONS) {
+                       printk("\n---- Start of %s log dump ----\n\n",
+                              (pb == TIPC_LOG) ? "global" : "local");
+                       printbuf_dump(pb);
+                       tipc_printbuf_reset(pb);
+                       printk("\n---- End of dump ----\n");
+               }
+               pb_next = pb->next;
+               pb->next = NULL;
+               pb = pb_next;
        }
        spin_unlock_bh(&print_lock);
 }
@@ -324,7 +364,8 @@ void tipc_log_stop(void)
 }
 
 /**
- * tipc_log_reinit - set TIPC log print buffer to specified size
+ * tipc_log_reinit - (re)initialize TIPC log print buffer
+ * @log_size: print buffer size to use
  */
 
 void tipc_log_reinit(int log_size)
@@ -332,10 +373,11 @@ void tipc_log_reinit(int log_size)
        tipc_log_stop();
 
        if (log_size) {
-               if (log_size <= MAX_STRING)
-                       log_size = MAX_STRING + 1;
+               if (log_size < TIPC_PB_MIN_SIZE)
+                       log_size = TIPC_PB_MIN_SIZE;
                spin_lock_bh(&print_lock);
-               tipc_printbuf_init(TIPC_LOG, kmalloc(log_size, GFP_ATOMIC), log_size);
+               tipc_printbuf_init(TIPC_LOG, kmalloc(log_size, GFP_ATOMIC),
+                                  log_size);
                spin_unlock_bh(&print_lock);
        }
 }
index 227f050d2a52742552a8af61650f1b12bc135c6c..467c0bc78a79feb7e8938a9100ae4e42cb3541df 100644 (file)
@@ -2,7 +2,7 @@
  * net/tipc/dbg.h: Include file for TIPC print buffer routines
  * 
  * Copyright (c) 1997-2006, Ericsson AB
- * Copyright (c) 2005, Wind River Systems
+ * Copyright (c) 2005-2006, Wind River Systems
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
 #ifndef _TIPC_DBG_H
 #define _TIPC_DBG_H
 
+/**
+ * struct print_buf - TIPC print buffer structure
+ * @buf: pointer to character array containing print buffer contents
+ * @size: size of character array
+ * @crs: pointer to first unused space in character array (i.e. final NUL)
+ * @next: used to link print buffers when printing to more than one at a time
+ */
+
 struct print_buf {
        char *buf;
        u32 size;
@@ -44,7 +52,10 @@ struct print_buf {
        struct print_buf *next;
 };
 
-void tipc_printbuf_init(struct print_buf *pb, char *buf, u32 sz);
+#define TIPC_PB_MIN_SIZE 64    /* minimum size for a print buffer's array */
+#define TIPC_PB_MAX_STR 512    /* max printable string (with trailing NUL) */
+
+void tipc_printbuf_init(struct print_buf *pb, char *buf, u32 size);
 void tipc_printbuf_reset(struct print_buf *pb);
 int  tipc_printbuf_empty(struct print_buf *pb);
 int  tipc_printbuf_validate(struct print_buf *pb);
index ee94de92ae9916f9c53f3fcd7b46cb917005eba5..3b0cd12f37dafeb788ddbe2334a57cd5ffacae4c 100644 (file)
@@ -131,6 +131,28 @@ static struct sk_buff *tipc_disc_init_msg(u32 type,
        return buf;
 }
 
+/**
+ * disc_dupl_alert - issue node address duplication alert
+ * @b_ptr: pointer to bearer detecting duplication
+ * @node_addr: duplicated node address
+ * @media_addr: media address advertised by duplicated node
+ */
+
+static void disc_dupl_alert(struct bearer *b_ptr, u32 node_addr,
+                           struct tipc_media_addr *media_addr)
+{
+       char node_addr_str[16];
+       char media_addr_str[64];
+       struct print_buf pb;
+
+       addr_string_fill(node_addr_str, node_addr);
+       tipc_printbuf_init(&pb, media_addr_str, sizeof(media_addr_str));
+       tipc_media_addr_printf(&pb, media_addr);
+       tipc_printbuf_validate(&pb);
+       warn("Duplicate %s using %s seen on <%s>\n",
+            node_addr_str, media_addr_str, b_ptr->publ.name);
+}
+
 /**
  * tipc_disc_recv_msg - handle incoming link setup message (request or response)
  * @buf: buffer containing message
@@ -157,8 +179,11 @@ void tipc_disc_recv_msg(struct sk_buff *buf)
                return;
        if (!tipc_addr_node_valid(orig))
                return;
-       if (orig == tipc_own_addr)
+       if (orig == tipc_own_addr) {
+               if (memcmp(&media_addr, &b_ptr->publ.addr, sizeof(media_addr)))
+                       disc_dupl_alert(b_ptr, tipc_own_addr, &media_addr);
                return;
+       }
        if (!in_scope(dest, tipc_own_addr))
                return;
        if (is_slave(tipc_own_addr) && is_slave(orig))
@@ -170,7 +195,8 @@ void tipc_disc_recv_msg(struct sk_buff *buf)
                struct sk_buff *rbuf;
                struct tipc_media_addr *addr;
                struct node *n_ptr = tipc_node_find(orig);
-               int link_up;
+               int link_fully_up;
+
                dbg(" in own cluster\n");
                if (n_ptr == NULL) {
                        n_ptr = tipc_node_create(orig);
@@ -190,14 +216,19 @@ void tipc_disc_recv_msg(struct sk_buff *buf)
                }
                addr = &link->media_addr;
                if (memcmp(addr, &media_addr, sizeof(*addr))) {
+                       if (tipc_link_is_up(link) || (!link->started)) {
+                               disc_dupl_alert(b_ptr, orig, &media_addr);
+                               spin_unlock_bh(&n_ptr->lock);
+                               return;
+                       }
                        warn("Resetting link <%s>, peer interface address changed\n",
                             link->name);
                        memcpy(addr, &media_addr, sizeof(*addr));
                        tipc_link_reset(link);     
                }
-               link_up = tipc_link_is_up(link);
+               link_fully_up = (link->state == WORKING_WORKING);
                spin_unlock_bh(&n_ptr->lock);                
-               if ((type == DSC_RESP_MSG) || link_up)
+               if ((type == DSC_RESP_MSG) || link_fully_up)
                        return;
                rbuf = tipc_disc_init_msg(DSC_RESP_MSG, 1, orig, b_ptr);
                if (rbuf != NULL) {
index 53bc8cb5adbc7bc98e2ede758f89e7ba3b1d05c4..1bb983c8130b32be1b70e776b04ee573f6530c42 100644 (file)
@@ -132,7 +132,7 @@ static void link_print(struct link *l_ptr, struct print_buf *buf,
  * allow the output from multiple links to be intermixed.  For this reason
  * routines of the form "dbg_link_XXX()" have been created that will capture
  * debug info into a link's personal print buffer, which can then be dumped
- * into the TIPC system log (LOG) upon request.
+ * into the TIPC system log (TIPC_LOG) upon request.
  *
  * To enable per-link debugging, use LINK_LOG_BUF_SIZE to specify the size
  * of the print buffer used by each link.  If LINK_LOG_BUF_SIZE is set to 0,
@@ -141,7 +141,7 @@ static void link_print(struct link *l_ptr, struct print_buf *buf,
  * when there is only a single link in the system being debugged.
  *
  * Notes:
- * - When enabled, LINK_LOG_BUF_SIZE should be set to at least 1000 (bytes)
+ * - When enabled, LINK_LOG_BUF_SIZE should be set to at least TIPC_PB_MIN_SIZE
  * - "l_ptr" must be valid when using dbg_link_XXX() macros  
  */
 
@@ -159,13 +159,13 @@ static void link_print(struct link *l_ptr, struct print_buf *buf,
 
 static void dbg_print_link(struct link *l_ptr, const char *str)
 {
-       if (DBG_OUTPUT)
+       if (DBG_OUTPUT != TIPC_NULL)
                link_print(l_ptr, DBG_OUTPUT, str);
 }
 
 static void dbg_print_buf_chain(struct sk_buff *root_buf)
 {
-       if (DBG_OUTPUT) {
+       if (DBG_OUTPUT != TIPC_NULL) {
                struct sk_buff *buf = root_buf;
 
                while (buf) {
index f0b063bcc2a9982c36b7b65bd51bcb3c7ec3a610..03bd659c43ca5901d7941508c8d4d2a03e247d68 100644 (file)
@@ -122,7 +122,7 @@ void tipc_named_publish(struct publication *publ)
        struct sk_buff *buf;
        struct distr_item *item;
 
-       list_add(&publ->local_list, &publ_root);
+       list_add_tail(&publ->local_list, &publ_root);
        publ_cnt++;
 
        buf = named_prepare_buf(PUBLICATION, ITEM_SIZE, 0);
index fc6d09630ccd5e114afca1e631845778d0d21525..886bda5e88dbfc0939a9da349effb352453cdc47 100644 (file)
@@ -648,7 +648,7 @@ struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space)
                return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
                                                   " (network address)");
 
-        if (!tipc_nodes)
+        if (tipc_mode != TIPC_NET_MODE)
                 return tipc_cfg_reply_none();
        
        /* Get space for all unicast links + multicast link */
index b9c8c6b9e94fdf87c931cdc3c409a373a8043bdc..c1a1a76759b59259e87a7b12bc190e6c9fcc07cc 100644 (file)
@@ -505,8 +505,13 @@ static void port_timeout(unsigned long ref)
        struct port *p_ptr = tipc_port_lock(ref);
        struct sk_buff *buf = NULL;
 
-       if (!p_ptr || !p_ptr->publ.connected)
+       if (!p_ptr)
+               return;
+
+       if (!p_ptr->publ.connected) {
+               tipc_port_unlock(p_ptr);
                return;
+       }
 
        /* Last probe answered ? */
        if (p_ptr->probing_state == PROBING) {
index 32d778448a00957c353187998620c3f18b9ec0ec..2a6a5a6b4c125bac4f9e2e59241091b71a6d1c99 100644 (file)
@@ -2,7 +2,7 @@
  * net/tipc/socket.c: TIPC socket API
  * 
  * Copyright (c) 2001-2006, Ericsson AB
- * Copyright (c) 2004-2005, Wind River Systems
+ * Copyright (c) 2004-2006, Wind River Systems
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -629,6 +629,9 @@ static int send_stream(struct kiocb *iocb, struct socket *sock,
                         return -ENOTCONN;
         }
 
+       if (unlikely(m->msg_name))
+               return -EISCONN;
+
        /* 
         * Send each iovec entry using one or more messages
         *
@@ -641,6 +644,8 @@ static int send_stream(struct kiocb *iocb, struct socket *sock,
        curr_iovlen = m->msg_iovlen;
        my_msg.msg_iov = &my_iov;
        my_msg.msg_iovlen = 1;
+       my_msg.msg_flags = m->msg_flags;
+       my_msg.msg_name = NULL;
        bytes_sent = 0;
 
        while (curr_iovlen--) {
@@ -941,7 +946,7 @@ static int recv_stream(struct kiocb *iocb, struct socket *sock,
        int sz_to_copy;
        int sz_copied = 0;
        int needed;
-       char *crs = m->msg_iov->iov_base;
+       char __user *crs = m->msg_iov->iov_base;
        unsigned char *buf_crs;
        u32 err;
        int res;
@@ -1203,7 +1208,8 @@ static u32 dispatch(struct tipc_port *tport, struct sk_buff *buf)
        atomic_inc(&tipc_queue_size);
        skb_queue_tail(&sock->sk->sk_receive_queue, buf);
 
-        wake_up_interruptible(sock->sk->sk_sleep);
+       if (waitqueue_active(sock->sk->sk_sleep))
+               wake_up_interruptible(sock->sk->sk_sleep);
        return TIPC_OK;
 }
 
@@ -1218,7 +1224,8 @@ static void wakeupdispatch(struct tipc_port *tport)
 {
        struct tipc_sock *tsock = (struct tipc_sock *)tport->usr_handle;
 
-        wake_up_interruptible(tsock->sk.sk_sleep);
+       if (waitqueue_active(tsock->sk.sk_sleep))
+               wake_up_interruptible(tsock->sk.sk_sleep);
 }
 
 /**
@@ -1496,7 +1503,7 @@ static int setsockopt(struct socket *sock,
                return -ENOPROTOOPT;
        if (ol < sizeof(value))
                return -EINVAL;
-        if ((res = get_user(value, (u32 *)ov)))
+        if ((res = get_user(value, (u32 __user *)ov)))
                return res;
 
        if (down_interruptible(&tsock->sem)) 
@@ -1541,7 +1548,7 @@ static int setsockopt(struct socket *sock,
  */
 
 static int getsockopt(struct socket *sock, 
-                     int lvl, int opt, char __user *ov, int *ol)
+                     int lvl, int opt, char __user *ov, int __user *ol)
 {
        struct tipc_sock *tsock = tipc_sk(sock->sk);
         int len;
index c51600ba5f4a63cc0557e01cd2c0c6cd0c081fdf..7a918f12a5dfca8bdfdc87cd6973f2f9ac262220 100644 (file)
@@ -155,7 +155,7 @@ void tipc_subscr_report_overlap(struct subscription *sub,
            sub->seq.upper, found_lower, found_upper);
        if (!tipc_subscr_overlap(sub, found_lower, found_upper))
                return;
-       if (!must && (sub->filter != TIPC_SUB_PORTS))
+       if (!must && !(sub->filter & TIPC_SUB_PORTS))
                return;
        subscr_send_event(sub, found_lower, found_upper, event, port_ref, node);
 }
@@ -176,6 +176,13 @@ static void subscr_timeout(struct subscription *sub)
        if (subscriber == NULL)
                return;
 
+       /* Validate timeout (in case subscription is being cancelled) */
+
+       if (sub->timeout == TIPC_WAIT_FOREVER) {
+               tipc_ref_unlock(subscriber_ref);
+               return;
+       }
+
        /* Unlink subscription from name table */
 
        tipc_nametbl_unsubscribe(sub);
@@ -198,6 +205,20 @@ static void subscr_timeout(struct subscription *sub)
        atomic_dec(&topsrv.subscription_count);
 }
 
+/**
+ * subscr_del - delete a subscription within a subscription list
+ *
+ * Called with subscriber locked.
+ */
+
+static void subscr_del(struct subscription *sub)
+{
+       tipc_nametbl_unsubscribe(sub);
+       list_del(&sub->subscription_list);
+       kfree(sub);
+       atomic_dec(&topsrv.subscription_count);
+}
+
 /**
  * subscr_terminate - terminate communication with a subscriber
  * 
@@ -227,12 +248,9 @@ static void subscr_terminate(struct subscriber *subscriber)
                        k_cancel_timer(&sub->timer);
                        k_term_timer(&sub->timer);
                }
-               tipc_nametbl_unsubscribe(sub);
-               list_del(&sub->subscription_list);
-               dbg("Term: Removed sub %u,%u,%u from subscriber %x list\n",
+               dbg("Term: Removing sub %u,%u,%u from subscriber %x list\n",
                    sub->seq.type, sub->seq.lower, sub->seq.upper, subscriber);
-               kfree(sub);
-               atomic_dec(&topsrv.subscription_count);
+               subscr_del(sub);
        }
 
        /* Sever connection to subscriber */
@@ -252,6 +270,49 @@ static void subscr_terminate(struct subscriber *subscriber)
        kfree(subscriber);
 }
 
+/**
+ * subscr_cancel - handle subscription cancellation request
+ *
+ * Called with subscriber locked.  Routine must temporarily release this lock
+ * to enable the subscription timeout routine to finish without deadlocking;
+ * the lock is then reclaimed to allow caller to release it upon return.
+ *
+ * Note that fields of 's' use subscriber's endianness!
+ */
+
+static void subscr_cancel(struct tipc_subscr *s,
+                         struct subscriber *subscriber)
+{
+       struct subscription *sub;
+       struct subscription *sub_temp;
+       int found = 0;
+
+       /* Find first matching subscription, exit if not found */
+
+       list_for_each_entry_safe(sub, sub_temp, &subscriber->subscription_list,
+                                subscription_list) {
+               if (!memcmp(s, &sub->evt.s, sizeof(struct tipc_subscr))) {
+                       found = 1;
+                       break;
+               }
+       }
+       if (!found)
+               return;
+
+       /* Cancel subscription timer (if used), then delete subscription */
+
+       if (sub->timeout != TIPC_WAIT_FOREVER) {
+               sub->timeout = TIPC_WAIT_FOREVER;
+               spin_unlock_bh(subscriber->lock);
+               k_cancel_timer(&sub->timer);
+               k_term_timer(&sub->timer);
+               spin_lock_bh(subscriber->lock);
+       }
+       dbg("Cancel: removing sub %u,%u,%u from subscriber %x list\n",
+           sub->seq.type, sub->seq.lower, sub->seq.upper, subscriber);
+       subscr_del(sub);
+}
+
 /**
  * subscr_subscribe - create subscription for subscriber
  * 
@@ -263,6 +324,21 @@ static void subscr_subscribe(struct tipc_subscr *s,
 {
        struct subscription *sub;
 
+       /* Determine/update subscriber's endianness */
+
+       if (s->filter & (TIPC_SUB_PORTS | TIPC_SUB_SERVICE))
+               subscriber->swap = 0;
+       else
+               subscriber->swap = 1;
+
+       /* Detect & process a subscription cancellation request */
+
+       if (s->filter & htohl(TIPC_SUB_CANCEL, subscriber->swap)) {
+               s->filter &= ~htohl(TIPC_SUB_CANCEL, subscriber->swap);
+               subscr_cancel(s, subscriber);
+               return;
+       }
+
        /* Refuse subscription if global limit exceeded */
 
        if (atomic_read(&topsrv.subscription_count) >= tipc_max_subscriptions) {
@@ -281,13 +357,6 @@ static void subscr_subscribe(struct tipc_subscr *s,
                return;
        }
 
-       /* Determine/update subscriber's endianness */
-
-       if ((s->filter == TIPC_SUB_PORTS) || (s->filter == TIPC_SUB_SERVICE))
-               subscriber->swap = 0;
-       else
-               subscriber->swap = 1;
-
        /* Initialize subscription object */
 
        memset(sub, 0, sizeof(*sub));
@@ -296,8 +365,8 @@ static void subscr_subscribe(struct tipc_subscr *s,
        sub->seq.upper = htohl(s->seq.upper, subscriber->swap);
        sub->timeout = htohl(s->timeout, subscriber->swap);
        sub->filter = htohl(s->filter, subscriber->swap);
-       if ((((sub->filter != TIPC_SUB_PORTS) 
-             && (sub->filter != TIPC_SUB_SERVICE)))
+       if ((!(sub->filter & TIPC_SUB_PORTS)
+            == !(sub->filter & TIPC_SUB_SERVICE))
            || (sub->seq.lower > sub->seq.upper)) {
                warn("Subscription rejected, illegal request\n");
                kfree(sub);
index 2a7861661f14e5f268fd376117bdd70367165893..7736b23c3f0386a7c0bab1840425fdb69e7a7cd8 100644 (file)
@@ -883,30 +883,32 @@ out:
 }
 EXPORT_SYMBOL(xfrm_policy_walk);
 
-/* Find policy to apply to this flow. */
-
+/*
+ * Find policy to apply to this flow.
+ *
+ * Returns 0 if policy found, else an -errno.
+ */
 static int xfrm_policy_match(struct xfrm_policy *pol, struct flowi *fl,
                             u8 type, u16 family, int dir)
 {
        struct xfrm_selector *sel = &pol->selector;
-       int match;
+       int match, ret = -ESRCH;
 
        if (pol->family != family ||
            pol->type != type)
-               return 0;
+               return ret;
 
        match = xfrm_selector_match(sel, fl, family);
-       if (match) {
-               if (!security_xfrm_policy_lookup(pol, fl->secid, dir))
-                       return 1;
-       }
+       if (match)
+               ret = security_xfrm_policy_lookup(pol, fl->secid, dir);
 
-       return 0;
+       return ret;
 }
 
 static struct xfrm_policy *xfrm_policy_lookup_bytype(u8 type, struct flowi *fl,
                                                     u16 family, u8 dir)
 {
+       int err;
        struct xfrm_policy *pol, *ret;
        xfrm_address_t *daddr, *saddr;
        struct hlist_node *entry;
@@ -922,7 +924,15 @@ static struct xfrm_policy *xfrm_policy_lookup_bytype(u8 type, struct flowi *fl,
        chain = policy_hash_direct(daddr, saddr, family, dir);
        ret = NULL;
        hlist_for_each_entry(pol, entry, chain, bydst) {
-               if (xfrm_policy_match(pol, fl, type, family, dir)) {
+               err = xfrm_policy_match(pol, fl, type, family, dir);
+               if (err) {
+                       if (err == -ESRCH)
+                               continue;
+                       else {
+                               ret = ERR_PTR(err);
+                               goto fail;
+                       }
+               } else {
                        ret = pol;
                        priority = ret->priority;
                        break;
@@ -930,36 +940,53 @@ static struct xfrm_policy *xfrm_policy_lookup_bytype(u8 type, struct flowi *fl,
        }
        chain = &xfrm_policy_inexact[dir];
        hlist_for_each_entry(pol, entry, chain, bydst) {
-               if (xfrm_policy_match(pol, fl, type, family, dir) &&
-                   pol->priority < priority) {
+               err = xfrm_policy_match(pol, fl, type, family, dir);
+               if (err) {
+                       if (err == -ESRCH)
+                               continue;
+                       else {
+                               ret = ERR_PTR(err);
+                               goto fail;
+                       }
+               } else if (pol->priority < priority) {
                        ret = pol;
                        break;
                }
        }
        if (ret)
                xfrm_pol_hold(ret);
+fail:
        read_unlock_bh(&xfrm_policy_lock);
 
        return ret;
 }
 
-static void xfrm_policy_lookup(struct flowi *fl, u16 family, u8 dir,
+static int xfrm_policy_lookup(struct flowi *fl, u16 family, u8 dir,
                               void **objp, atomic_t **obj_refp)
 {
        struct xfrm_policy *pol;
+       int err = 0;
 
 #ifdef CONFIG_XFRM_SUB_POLICY
        pol = xfrm_policy_lookup_bytype(XFRM_POLICY_TYPE_SUB, fl, family, dir);
-       if (pol)
+       if (IS_ERR(pol)) {
+               err = PTR_ERR(pol);
+               pol = NULL;
+       }
+       if (pol || err)
                goto end;
 #endif
        pol = xfrm_policy_lookup_bytype(XFRM_POLICY_TYPE_MAIN, fl, family, dir);
-
+       if (IS_ERR(pol)) {
+               err = PTR_ERR(pol);
+               pol = NULL;
+       }
 #ifdef CONFIG_XFRM_SUB_POLICY
 end:
 #endif
        if ((*objp = (void *) pol) != NULL)
                *obj_refp = &pol->refcnt;
+       return err;
 }
 
 static inline int policy_to_flow_dir(int dir)
@@ -989,12 +1016,16 @@ static struct xfrm_policy *xfrm_sk_policy_lookup(struct sock *sk, int dir, struc
                                                sk->sk_family);
                int err = 0;
 
-               if (match)
-                 err = security_xfrm_policy_lookup(pol, fl->secid, policy_to_flow_dir(dir));
-
-               if (match && !err)
-                       xfrm_pol_hold(pol);
-               else
+               if (match) {
+                       err = security_xfrm_policy_lookup(pol, fl->secid,
+                                       policy_to_flow_dir(dir));
+                       if (!err)
+                               xfrm_pol_hold(pol);
+                       else if (err == -ESRCH)
+                               pol = NULL;
+                       else
+                               pol = ERR_PTR(err);
+               } else
                        pol = NULL;
        }
        read_unlock_bh(&xfrm_policy_lock);
@@ -1286,8 +1317,11 @@ restart:
        pol_dead = 0;
        xfrm_nr = 0;
 
-       if (sk && sk->sk_policy[1])
+       if (sk && sk->sk_policy[1]) {
                policy = xfrm_sk_policy_lookup(sk, XFRM_POLICY_OUT, fl);
+               if (IS_ERR(policy))
+                       return PTR_ERR(policy);
+       }
 
        if (!policy) {
                /* To accelerate a bit...  */
@@ -1297,6 +1331,8 @@ restart:
 
                policy = flow_cache_lookup(fl, dst_orig->ops->family,
                                           dir, xfrm_policy_lookup);
+               if (IS_ERR(policy))
+                       return PTR_ERR(policy);
        }
 
        if (!policy)
@@ -1343,6 +1379,10 @@ restart:
                                                            fl, family,
                                                            XFRM_POLICY_OUT);
                        if (pols[1]) {
+                               if (IS_ERR(pols[1])) {
+                                       err = PTR_ERR(pols[1]);
+                                       goto error;
+                               }
                                if (pols[1]->action == XFRM_POLICY_BLOCK) {
                                        err = -EPERM;
                                        goto error;
@@ -1574,13 +1614,19 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
        }
 
        pol = NULL;
-       if (sk && sk->sk_policy[dir])
+       if (sk && sk->sk_policy[dir]) {
                pol = xfrm_sk_policy_lookup(sk, dir, &fl);
+               if (IS_ERR(pol))
+                       return 0;
+       }
 
        if (!pol)
                pol = flow_cache_lookup(&fl, family, fl_dir,
                                        xfrm_policy_lookup);
 
+       if (IS_ERR(pol))
+               return 0;
+
        if (!pol) {
                if (skb->sp && secpath_has_nontransport(skb->sp, 0, &xerr_idx)) {
                        xfrm_secpath_reject(xerr_idx, skb, &fl);
@@ -1599,6 +1645,8 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
                                                    &fl, family,
                                                    XFRM_POLICY_IN);
                if (pols[1]) {
+                       if (IS_ERR(pols[1]))
+                               return 0;
                        pols[1]->curlft.use_time = (unsigned long)xtime.tv_sec;
                        npols ++;
                }
@@ -1706,7 +1754,7 @@ static struct dst_entry *xfrm_dst_check(struct dst_entry *dst, u32 cookie)
 
 static int stale_bundle(struct dst_entry *dst)
 {
-       return !xfrm_bundle_ok((struct xfrm_dst *)dst, NULL, AF_UNSPEC, 0);
+       return !xfrm_bundle_ok(NULL, (struct xfrm_dst *)dst, NULL, AF_UNSPEC, 0);
 }
 
 void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev)
@@ -1828,7 +1876,8 @@ EXPORT_SYMBOL(xfrm_init_pmtu);
  * still valid.
  */
 
-int xfrm_bundle_ok(struct xfrm_dst *first, struct flowi *fl, int family, int strict)
+int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *first,
+               struct flowi *fl, int family, int strict)
 {
        struct dst_entry *dst = &first->u.dst;
        struct xfrm_dst *last;
@@ -1845,7 +1894,7 @@ int xfrm_bundle_ok(struct xfrm_dst *first, struct flowi *fl, int family, int str
 
                if (fl && !xfrm_selector_match(&dst->xfrm->sel, fl, family))
                        return 0;
-               if (fl && !security_xfrm_flow_state_match(fl, dst->xfrm))
+               if (fl && !security_xfrm_flow_state_match(fl, dst->xfrm, pol))
                        return 0;
                if (dst->xfrm->km.state != XFRM_STATE_VALID)
                        return 0;
index 39b8bf3a9ded2c7d92b61f8477e138c772c45d3f..84bbf8474f3eb659fea321cac5629ff1e96a0d48 100644 (file)
@@ -614,6 +614,14 @@ out:
        return x;
 }
 
+static void xfrm_hash_grow_check(int have_hash_collision)
+{
+       if (have_hash_collision &&
+           (xfrm_state_hmask + 1) < xfrm_state_hashmax &&
+           xfrm_state_num > xfrm_state_hmask)
+               schedule_work(&xfrm_hash_work);
+}
+
 static void __xfrm_state_insert(struct xfrm_state *x)
 {
        unsigned int h;
@@ -642,10 +650,7 @@ static void __xfrm_state_insert(struct xfrm_state *x)
 
        xfrm_state_num++;
 
-       if (x->bydst.next != NULL &&
-           (xfrm_state_hmask + 1) < xfrm_state_hashmax &&
-           xfrm_state_num > xfrm_state_hmask)
-               schedule_work(&xfrm_hash_work);
+       xfrm_hash_grow_check(x->bydst.next != NULL);
 }
 
 /* xfrm_state_lock is held */
@@ -753,6 +758,10 @@ static struct xfrm_state *__find_acq_core(unsigned short family, u8 mode, u32 re
                h = xfrm_src_hash(daddr, saddr, family);
                hlist_add_head(&x->bysrc, xfrm_state_bysrc+h);
                wake_up(&km_waitq);
+
+               xfrm_state_num++;
+
+               xfrm_hash_grow_check(x->bydst.next != NULL);
        }
 
        return x;
index d54b3a70d5dfb6cda89a8661a0ee380c078d791d..2b2e59d8ffbc8ca197c8b84b98248c92511ce365 100644 (file)
@@ -1992,15 +1992,6 @@ static struct xfrm_policy *xfrm_compile_policy(struct sock *sk, int opt,
        xp->type = XFRM_POLICY_TYPE_MAIN;
        copy_templates(xp, ut, nr);
 
-       if (!xp->security) {
-               int err = security_xfrm_sock_policy_alloc(xp, sk);
-               if (err) {
-                       kfree(xp);
-                       *dir = err;
-                       return NULL;
-               }
-       }
-
        *dir = p->dir;
 
        return xp;
index 6a026f69b563e67cf098f110901b490a887bd8f0..4241e0dfeeaf1edeae16c4fd61a505b1985bb28f 100644 (file)
@@ -168,7 +168,7 @@ $(objhdr-y) $(header-y) $(unifdef-y): $(KBUILDFILES)
        $(call cmd,gen)
 
 else
-$(objhdr-y) :          $(INSTALL_HDR_PATH)/$(_dst)/%.h: $(srctree)/$(obj)/%.h $(KBUILDFILES)
+$(objhdr-y) :          $(INSTALL_HDR_PATH)/$(_dst)/%.h: $(objtree)/$(obj)/%.h $(KBUILDFILES)
        $(call cmd,o_hdr_install)
 
 $(header-y) :          $(INSTALL_HDR_PATH)/$(_dst)/%.h: $(srctree)/$(obj)/%.h $(KBUILDFILES)
index 6c5469b1473bee648984676165942cebed2b5971..65e0a79c36cf8525480181945b53ab25eef8bcd2 100644 (file)
@@ -44,7 +44,7 @@ include scripts/Kbuild.include
 include scripts/Makefile.lib
 
 kernelsymfile := $(objtree)/Module.symvers
-modulesymfile := $(KBUILD_EXTMOD)/Module.symvers
+modulesymfile := $(firstword $(KBUILD_EXTMOD))/Module.symvers
 
 # Step 1), find all modules listed in $(MODVERDIR)/
 __modules := $(sort $(shell grep -h '\.ko' /dev/null $(wildcard $(MODVERDIR)/*.mod)))
index 8dea47f9d3e49a36803ed4c90223d9858a83d3de..fd695e1070f76de6d64f2b6d95b2b2a5fbf84a9f 100644 (file)
@@ -24,6 +24,7 @@
 #include <ctype.h>
 #include <stdlib.h>
 #include <string.h>
+#include <stdbool.h>
 
 #ifdef __sun__
 #define CURS_MACROS
index 00d1ad19b2cc8babe05a17190ca48c5029eae9a1..187f5de4612c2247bee0e003ac397db6ff70cbc1 100755 (executable)
@@ -1262,7 +1262,9 @@ sub output_intro_text(%) {
 }
 
 ##
-# generic output function for typedefs
+# generic output function for all types (function, struct/union, typedef, enum);
+# calls the generated, variable output_ function name based on
+# functype and output_mode
 sub output_declaration {
     no strict 'refs';
     my $name = shift;
@@ -1278,8 +1280,7 @@ sub output_declaration {
 }
 
 ##
-# generic output function - calls the right one based
-# on current output mode.
+# generic output function - calls the right one based on current output mode.
 sub output_intro {
     no strict 'refs';
     my $func = "output_intro_".$output_mode;
@@ -1518,6 +1519,9 @@ sub dump_function($$) {
     $prototype =~ s/^asmlinkage +//;
     $prototype =~ s/^inline +//;
     $prototype =~ s/^__inline__ +//;
+    $prototype =~ s/^__inline +//;
+    $prototype =~ s/^__always_inline +//;
+    $prototype =~ s/^noinline +//;
     $prototype =~ s/__devinit +//;
     $prototype =~ s/^#define +//; #ak added
     $prototype =~ s/__attribute__ \(\([a-z,]*\)\)//;
@@ -1778,8 +1782,9 @@ sub process_file($) {
                $in_doc_sect = 1;
                $contents = $newcontents;
                if ($contents ne "") {
-                   if (substr($contents, 0, 1) eq " ") {
-                       $contents = substr($contents, 1);
+                   while ((substr($contents, 0, 1) eq " ") ||
+                       substr($contents, 0, 1) eq "\t") {
+                           $contents = substr($contents, 1);
                    }
                    $contents .= "\n";
                }
index aeee70565509dd8e6c843591e142f452fb721e96..43874c1e6e23999def36ff43b6918d806dcaf54b 100644 (file)
@@ -881,7 +881,8 @@ static int dummy_xfrm_state_pol_flow_match(struct xfrm_state *x,
        return 1;
 }
 
-static int dummy_xfrm_flow_state_match(struct flowi *fl, struct xfrm_state *xfrm)
+static int dummy_xfrm_flow_state_match(struct flowi *fl, struct xfrm_state *xfrm,
+                               struct xfrm_policy *xp)
 {
        return 1;
 }
index 81eb59890162e506126d734de92fd002c02994b4..526b28019acaa55ac0c7db6da9b7933fef8936c8 100644 (file)
@@ -19,7 +19,8 @@ int selinux_xfrm_state_delete(struct xfrm_state *x);
 int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 fl_secid, u8 dir);
 int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x,
                        struct xfrm_policy *xp, struct flowi *fl);
-int selinux_xfrm_flow_state_match(struct flowi *fl, struct xfrm_state *xfrm);
+int selinux_xfrm_flow_state_match(struct flowi *fl, struct xfrm_state *xfrm,
+                       struct xfrm_policy *xp);
 
 
 /*
index cfed1d30fa6ad7af8e8aae11810bf58ba61dc27a..d539346ab3a2b5143f1d2232239ee8bdc217e4c8 100644 (file)
@@ -93,11 +93,15 @@ int ebitmap_export(const struct ebitmap *src,
        size_t bitmap_byte;
        unsigned char bitmask;
 
+       if (src->highbit == 0) {
+               *dst = NULL;
+               *dst_len = 0;
+               return 0;
+       }
+
        bitmap_len = src->highbit / 8;
        if (src->highbit % 7)
                bitmap_len += 1;
-       if (bitmap_len == 0)
-               return -EINVAL;
 
        bitmap = kzalloc((bitmap_len & ~(sizeof(MAPTYPE) - 1)) +
                         sizeof(MAPTYPE),
index c713af23250a331d81df2ec82d439cc38768571c..2cca8e251624037d3967d8fde0d21d8ed8ddf2a6 100644 (file)
@@ -640,8 +640,13 @@ int mls_export_cat(const struct context *context,
 {
        int rc = -EPERM;
 
-       if (!selinux_mls_enabled)
+       if (!selinux_mls_enabled) {
+               *low = NULL;
+               *low_len = 0;
+               *high = NULL;
+               *high_len = 0;
                return 0;
+       }
 
        if (low != NULL) {
                rc = ebitmap_export(&context->range.level[0].cat,
@@ -661,10 +666,16 @@ int mls_export_cat(const struct context *context,
        return 0;
 
 export_cat_failure:
-       if (low != NULL)
+       if (low != NULL) {
                kfree(*low);
-       if (high != NULL)
+               *low = NULL;
+               *low_len = 0;
+       }
+       if (high != NULL) {
                kfree(*high);
+               *high = NULL;
+               *high_len = 0;
+       }
        return rc;
 }
 
index b18895302555618f02ee0d03590bc2e04ee3d1c6..ba48961f9d0593f99a30b0c3983a09c63425f766 100644 (file)
@@ -618,6 +618,7 @@ void policydb_destroy(struct policydb *p)
                        c = c->next;
                        ocontext_destroy(ctmp,i);
                }
+               p->ocontexts[i] = NULL;
        }
 
        g = p->genfs;
@@ -633,6 +634,7 @@ void policydb_destroy(struct policydb *p)
                g = g->next;
                kfree(gtmp);
        }
+       p->genfs = NULL;
 
        cond_policydb_destroy(p);
 
index 0c219a1b32435e0e83eaa980b15b8031b11ed539..b1f6fb36c6997cc40ea8cf350adf12a9218bf8bc 100644 (file)
@@ -2172,7 +2172,12 @@ struct netlbl_cache {
  */
 static void selinux_netlbl_cache_free(const void *data)
 {
-       struct netlbl_cache *cache = NETLBL_CACHE(data);
+       struct netlbl_cache *cache;
+
+       if (data == NULL)
+               return;
+
+       cache = NETLBL_CACHE(data);
        switch (cache->type) {
        case NETLBL_CACHE_T_MLS:
                ebitmap_destroy(&cache->data.mls_label.level[0].cat);
@@ -2197,17 +2202,20 @@ static void selinux_netlbl_cache_add(struct sk_buff *skb, struct context *ctx)
        struct netlbl_lsm_secattr secattr;
 
        netlbl_secattr_init(&secattr);
+       secattr.cache = netlbl_secattr_cache_alloc(GFP_ATOMIC);
+       if (secattr.cache == NULL)
+               goto netlbl_cache_add_return;
 
        cache = kzalloc(sizeof(*cache), GFP_ATOMIC);
        if (cache == NULL)
-               goto netlbl_cache_add_failure;
-       secattr.cache.free = selinux_netlbl_cache_free;
-       secattr.cache.data = (void *)cache;
+               goto netlbl_cache_add_return;
+       secattr.cache->free = selinux_netlbl_cache_free;
+       secattr.cache->data = (void *)cache;
 
        cache->type = NETLBL_CACHE_T_MLS;
        if (ebitmap_cpy(&cache->data.mls_label.level[0].cat,
                        &ctx->range.level[0].cat) != 0)
-               goto netlbl_cache_add_failure;
+               goto netlbl_cache_add_return;
        cache->data.mls_label.level[1].cat.highbit =
                cache->data.mls_label.level[0].cat.highbit;
        cache->data.mls_label.level[1].cat.node =
@@ -2215,13 +2223,10 @@ static void selinux_netlbl_cache_add(struct sk_buff *skb, struct context *ctx)
        cache->data.mls_label.level[0].sens = ctx->range.level[0].sens;
        cache->data.mls_label.level[1].sens = ctx->range.level[0].sens;
 
-       if (netlbl_cache_add(skb, &secattr) != 0)
-               goto netlbl_cache_add_failure;
-
-       return;
+       netlbl_cache_add(skb, &secattr);
 
-netlbl_cache_add_failure:
-       netlbl_secattr_destroy(&secattr, 1);
+netlbl_cache_add_return:
+       netlbl_secattr_destroy(&secattr);
 }
 
 /**
@@ -2263,8 +2268,8 @@ static int selinux_netlbl_secattr_to_sid(struct sk_buff *skb,
 
        POLICY_RDLOCK;
 
-       if (secattr->cache.data) {
-               cache = NETLBL_CACHE(secattr->cache.data);
+       if (secattr->cache) {
+               cache = NETLBL_CACHE(secattr->cache->data);
                switch (cache->type) {
                case NETLBL_CACHE_T_SID:
                        *sid = cache->data.sid;
@@ -2331,7 +2336,7 @@ static int selinux_netlbl_secattr_to_sid(struct sk_buff *skb,
                        selinux_netlbl_cache_add(skb, &ctx_new);
                ebitmap_destroy(&ctx_new.range.level[0].cat);
        } else {
-               *sid = SECINITSID_UNLABELED;
+               *sid = SECSID_NULL;
                rc = 0;
        }
 
@@ -2369,7 +2374,7 @@ static int selinux_netlbl_skbuff_getsid(struct sk_buff *skb,
                                                   &secattr,
                                                   base_sid,
                                                   sid);
-       netlbl_secattr_destroy(&secattr, 0);
+       netlbl_secattr_destroy(&secattr);
 
        return rc;
 }
@@ -2394,31 +2399,33 @@ static int selinux_netlbl_socket_setsid(struct socket *sock, u32 sid)
        if (!ss_initialized)
                return 0;
 
+       netlbl_secattr_init(&secattr);
+
        POLICY_RDLOCK;
 
        ctx = sidtab_search(&sidtab, sid);
        if (ctx == NULL)
                goto netlbl_socket_setsid_return;
 
-       netlbl_secattr_init(&secattr);
        secattr.domain = kstrdup(policydb.p_type_val_to_name[ctx->type - 1],
                                 GFP_ATOMIC);
        mls_export_lvl(ctx, &secattr.mls_lvl, NULL);
        secattr.mls_lvl_vld = 1;
-       mls_export_cat(ctx,
-                      &secattr.mls_cat,
-                      &secattr.mls_cat_len,
-                      NULL,
-                      NULL);
+       rc = mls_export_cat(ctx,
+                           &secattr.mls_cat,
+                           &secattr.mls_cat_len,
+                           NULL,
+                           NULL);
+       if (rc != 0)
+               goto netlbl_socket_setsid_return;
 
        rc = netlbl_socket_setattr(sock, &secattr);
        if (rc == 0)
                sksec->nlbl_state = NLBL_LABELED;
 
-       netlbl_secattr_destroy(&secattr, 0);
-
 netlbl_socket_setsid_return:
        POLICY_RDUNLOCK;
+       netlbl_secattr_destroy(&secattr);
        return rc;
 }
 
@@ -2514,10 +2521,10 @@ void selinux_netlbl_sock_graft(struct sock *sk, struct socket *sock)
        if (netlbl_sock_getattr(sk, &secattr) == 0 &&
            selinux_netlbl_secattr_to_sid(NULL,
                                          &secattr,
-                                         sksec->sid,
+                                         SECINITSID_UNLABELED,
                                          &nlbl_peer_sid) == 0)
                sksec->peer_sid = nlbl_peer_sid;
-       netlbl_secattr_destroy(&secattr, 0);
+       netlbl_secattr_destroy(&secattr);
 
        sksec->nlbl_state = NLBL_REQUIRE;
 
@@ -2547,9 +2554,6 @@ u32 selinux_netlbl_inet_conn_request(struct sk_buff *skb, u32 sock_sid)
        if (rc != 0)
                return SECSID_NULL;
 
-       if (peer_sid == SECINITSID_UNLABELED)
-               return SECSID_NULL;
-
        return peer_sid;
 }
 
@@ -2611,11 +2615,13 @@ int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec,
        u32 netlbl_sid;
        u32 recv_perm;
 
-       rc = selinux_netlbl_skbuff_getsid(skb, SECINITSID_NETMSG, &netlbl_sid);
+       rc = selinux_netlbl_skbuff_getsid(skb,
+                                         SECINITSID_UNLABELED,
+                                         &netlbl_sid);
        if (rc != 0)
                return rc;
 
-       if (netlbl_sid == SECINITSID_UNLABELED)
+       if (netlbl_sid == SECSID_NULL)
                return 0;
 
        switch (sksec->sclass) {
@@ -2653,10 +2659,6 @@ int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec,
 u32 selinux_netlbl_socket_getpeersec_stream(struct socket *sock)
 {
        struct sk_security_struct *sksec = sock->sk->sk_security;
-
-       if (sksec->peer_sid == SECINITSID_UNLABELED)
-               return SECSID_NULL;
-
        return sksec->peer_sid;
 }
 
@@ -2672,16 +2674,10 @@ u32 selinux_netlbl_socket_getpeersec_stream(struct socket *sock)
 u32 selinux_netlbl_socket_getpeersec_dgram(struct sk_buff *skb)
 {
        int peer_sid;
-       struct sock *sk = skb->sk;
-       struct inode_security_struct *isec;
 
-       if (sk == NULL || sk->sk_socket == NULL)
-               return SECSID_NULL;
-
-       isec = SOCK_INODE(sk->sk_socket)->i_security;
-       if (selinux_netlbl_skbuff_getsid(skb, isec->sid, &peer_sid) != 0)
-               return SECSID_NULL;
-       if (peer_sid == SECINITSID_UNLABELED)
+       if (selinux_netlbl_skbuff_getsid(skb,
+                                        SECINITSID_UNLABELED,
+                                        &peer_sid) != 0)
                return SECSID_NULL;
 
        return peer_sid;
index 3e742b850af6e9632ecfd5e4d8b08b02fa0f00cd..675b995a67c3ec1836fd6d7034e1dbab8cc6a0a3 100644 (file)
@@ -77,8 +77,8 @@ static inline int selinux_authorizable_xfrm(struct xfrm_state *x)
  */
 int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 fl_secid, u8 dir)
 {
-       int rc = 0;
-       u32 sel_sid = SECINITSID_UNLABELED;
+       int rc;
+       u32 sel_sid;
        struct xfrm_sec_ctx *ctx;
 
        /* Context sid is either set to label or ANY_ASSOC */
@@ -88,11 +88,21 @@ int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 fl_secid, u8 dir)
 
                sel_sid = ctx->ctx_sid;
        }
+       else
+               /*
+                * All flows should be treated as polmatch'ing an
+                * otherwise applicable "non-labeled" policy. This
+                * would prevent inadvertent "leaks".
+                */
+               return 0;
 
        rc = avc_has_perm(fl_secid, sel_sid, SECCLASS_ASSOCIATION,
                          ASSOCIATION__POLMATCH,
                          NULL);
 
+       if (rc == -EACCES)
+               rc = -ESRCH;
+
        return rc;
 }
 
@@ -108,15 +118,20 @@ int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x, struct xfrm_policy *
        u32 pol_sid;
        int err;
 
-       if (x->security)
-               state_sid = x->security->ctx_sid;
-       else
-               state_sid = SECINITSID_UNLABELED;
-
-       if (xp->security)
+       if (xp->security) {
+               if (!x->security)
+                       /* unlabeled SA and labeled policy can't match */
+                       return 0;
+               else
+                       state_sid = x->security->ctx_sid;
                pol_sid = xp->security->ctx_sid;
-       else
-               pol_sid = SECINITSID_UNLABELED;
+       } else
+               if (x->security)
+                       /* unlabeled policy and labeled SA can't match */
+                       return 0;
+               else
+                       /* unlabeled policy and unlabeled SA match all flows */
+                       return 1;
 
        err = avc_has_perm(state_sid, pol_sid, SECCLASS_ASSOCIATION,
                          ASSOCIATION__POLMATCH,
@@ -125,7 +140,11 @@ int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x, struct xfrm_policy *
        if (err)
                return 0;
 
-       return selinux_xfrm_flow_state_match(fl, x);
+       err = avc_has_perm(fl->secid, state_sid, SECCLASS_ASSOCIATION,
+                         ASSOCIATION__SENDTO,
+                         NULL)? 0:1;
+
+       return err;
 }
 
 /*
@@ -133,12 +152,22 @@ int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x, struct xfrm_policy *
  * can use a given security association.
  */
 
-int selinux_xfrm_flow_state_match(struct flowi *fl, struct xfrm_state *xfrm)
+int selinux_xfrm_flow_state_match(struct flowi *fl, struct xfrm_state *xfrm,
+                                 struct xfrm_policy *xp)
 {
        int rc = 0;
        u32 sel_sid = SECINITSID_UNLABELED;
        struct xfrm_sec_ctx *ctx;
 
+       if (!xp->security)
+               if (!xfrm->security)
+                       return 1;
+               else
+                       return 0;
+       else
+               if (!xfrm->security)
+                       return 0;
+
        /* Context sid is either set to label or ANY_ASSOC */
        if ((ctx = xfrm->security)) {
                if (!selinux_authorizable_ctx(ctx))
index 7c26089527f6389ee20be50423615ca344132178..40eb47eccf9a9acfe0304284054607ecaa7e79f2 100644 (file)
@@ -283,9 +283,7 @@ static void ftr_gpio_exit(struct gpio_runtime *rt)
        mutex_destroy(&rt->line_out_notify.mutex);
 }
 
-static irqreturn_t ftr_handle_notify_irq(int xx,
-                                        void *data,
-                                        struct pt_regs *regs)
+static irqreturn_t ftr_handle_notify_irq(int xx, void *data)
 {
        struct gpio_notification *notif = data;
 
index 23190aa6bc7b8607e1cc951182597a0226b75b1b..e593a1333fe3e30667244764f2f7057f1f55b8f3 100644 (file)
@@ -93,7 +93,7 @@ static void i2sbus_release_dev(struct device *dev)
        kfree(i2sdev);
 }
 
-static irqreturn_t i2sbus_bus_intr(int irq, void *devid, struct pt_regs *regs)
+static irqreturn_t i2sbus_bus_intr(int irq, void *devid)
 {
        struct i2sbus_dev *dev = devid;
        u32 intreg;
@@ -165,8 +165,7 @@ static int i2sbus_add_dev(struct macio_dev *macio,
        static const char *rnames[] = { "i2sbus: %s (control)",
                                        "i2sbus: %s (tx)",
                                        "i2sbus: %s (rx)" };
-       static irqreturn_t (*ints[])(int irq, void *devid,
-                                    struct pt_regs *regs) = {
+       static irq_handler_t ints[] = {
                i2sbus_bus_intr,
                i2sbus_tx_intr,
                i2sbus_rx_intr
index 3049015a04f16536b41e476b0bdd28a2ae921596..5eff30b10201c849b89b83a7e7d01a1ba2377ec6 100644 (file)
@@ -642,13 +642,13 @@ static inline void handle_interrupt(struct i2sbus_dev *i2sdev, int in)
        spin_unlock(&i2sdev->low_lock);
 }
 
-irqreturn_t i2sbus_tx_intr(int irq, void *devid, struct pt_regs *regs)
+irqreturn_t i2sbus_tx_intr(int irq, void *devid)
 {
        handle_interrupt((struct i2sbus_dev *)devid, 0);
        return IRQ_HANDLED;
 }
 
-irqreturn_t i2sbus_rx_intr(int irq, void *devid, struct pt_regs * regs)
+irqreturn_t i2sbus_rx_intr(int irq, void *devid)
 {
        handle_interrupt((struct i2sbus_dev *)devid, 1);
        return IRQ_HANDLED;
index 0c69d209be503db173fb6e7ca979425a7ed9a73a..ec20ee615d7fa282ec96a6120a6ee231fc68ab74 100644 (file)
@@ -97,9 +97,9 @@ i2sbus_attach_codec(struct soundbus_dev *dev, struct snd_card *card,
 extern void
 i2sbus_detach_codec(struct soundbus_dev *dev, void *data);
 extern irqreturn_t
-i2sbus_tx_intr(int irq, void *devid, struct pt_regs *regs);
+i2sbus_tx_intr(int irq, void *devid);
 extern irqreturn_t
-i2sbus_rx_intr(int irq, void *devid, struct pt_regs *regs);
+i2sbus_rx_intr(int irq, void *devid);
 
 /* control specific functions */
 extern int i2sbus_control_init(struct macio_dev* dev,
index 8435fdd1c87c1d13667104641e933dfe8580c5f6..53675cf4de44c1bc4968c3227f45ab46fb573921 100644 (file)
@@ -221,7 +221,7 @@ static void aaci_fifo_irq(struct aaci *aaci, u32 mask)
        }
 }
 
-static irqreturn_t aaci_irq(int irq, void *devid, struct pt_regs *regs)
+static irqreturn_t aaci_irq(int irq, void *devid)
 {
        struct aaci *aaci = devid;
        u32 mask;
index 599aff8290e8d42dcd4a1660bef1e064ddad661b..dede954b2c657e0c1db1f135c38da9f630e5442b 100644 (file)
@@ -152,7 +152,7 @@ static void pxa2xx_ac97_reset(struct snd_ac97 *ac97)
        GCR |= GCR_SDONE_IE|GCR_CDONE_IE;
 }
 
-static irqreturn_t pxa2xx_ac97_irq(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t pxa2xx_ac97_irq(int irq, void *dev_id)
 {
        long status;
 
index 4938ef10b813f5604ee58f30aa19357b35373e89..e8cf904b835804dc7329ec35d0eaca216a9ce188 100644 (file)
@@ -137,7 +137,7 @@ static int pxa2xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
        return ret;
 }
 
-static void pxa2xx_pcm_dma_irq(int dma_ch, void *dev_id, struct pt_regs *regs)
+static void pxa2xx_pcm_dma_irq(int dma_ch, void *dev_id)
 {
        struct snd_pcm_substream *substream = dev_id;
        struct pxa2xx_runtime_data *rtd = substream->runtime->private_data;
index 6973a9686b679c6f3fc7a5415a1795ce043e6a76..48ef0a09a7a71ad964aac00a79404945e6102d22 100644 (file)
@@ -1018,10 +1018,6 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
        }
        switch (info->type) {
        case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
-               private_size = sizeof(char);
-               if (info->count > 128)
-                       return -EINVAL;
-               break;
        case SNDRV_CTL_ELEM_TYPE_INTEGER:
                private_size = sizeof(long);
                if (info->count > 128)
index 9aa9d94891f0a8eb01b41faac8fcefe54e1aa2a1..46b47689362c293259fe828802788b32f06de560 100644 (file)
@@ -158,6 +158,7 @@ static int snd_hwdep_release(struct inode *inode, struct file * file)
 {
        int err = -ENXIO;
        struct snd_hwdep *hw = file->private_data;
+       struct module *mod = hw->card->module;
        mutex_lock(&hw->open_mutex);
        if (hw->ops.release) {
                err = hw->ops.release(hw, file);
@@ -167,7 +168,7 @@ static int snd_hwdep_release(struct inode *inode, struct file * file)
                hw->used--;
        snd_card_file_remove(hw->card, file);
        mutex_unlock(&hw->open_mutex);
-       module_put(hw->card->module);
+       module_put(mod);
        return err;
 }
 
index 938f77580966fd2e66dca0d84f1f13997208ad4a..3827c0ceec8ff3cf5fc33e1f4b96e131439fe3a7 100644 (file)
@@ -33,7 +33,7 @@ struct snd_hwdep_dsp_image32 {
 static int snd_hwdep_dsp_load_compat(struct snd_hwdep *hw,
                                     struct snd_hwdep_dsp_image32 __user *src)
 {
-       struct snd_hwdep_dsp_image *dst;
+       struct snd_hwdep_dsp_image __user *dst;
        compat_caddr_t ptr;
        u32 val;
 
index e43662b33f16e6ce7bf3b975175639194d6ced3f..0b4aab3225e5270a998e77e06e7821973b3e2146 100644 (file)
@@ -120,7 +120,10 @@ int snd_iprintf(struct snd_info_buffer *buffer, char *fmt,...)
        len = buffer->len - buffer->size;
        va_start(args, fmt);
        for (;;) {
-               res = vsnprintf(buffer->buffer + buffer->curr, len, fmt, args);
+               va_list ap;
+               va_copy(ap, args);
+               res = vsnprintf(buffer->buffer + buffer->curr, len, fmt, ap);
+               va_end(ap);
                if (res < len)
                        break;
                err = resize_info_buffer(buffer, buffer->len + PAGE_SIZE);
index d7607a25acdf7086e05cbe16d2d64c7e19ed5897..3058d626a90a009abf2c8f4700ee9af4cf11fbc8 100644 (file)
 #include <sound/control.h>
 #include <sound/info.h>
 
-struct snd_shutdown_f_ops {
-       struct file_operations f_ops;
-       struct snd_shutdown_f_ops *next;
-};
+static DEFINE_SPINLOCK(shutdown_lock);
+static LIST_HEAD(shutdown_files);
+
+static struct file_operations snd_shutdown_f_ops;
 
 static unsigned int snd_cards_lock;    /* locked for registering/using */
 struct snd_card *snd_cards[SNDRV_CARDS];
@@ -198,6 +198,25 @@ static ssize_t snd_disconnect_write(struct file *file, const char __user *buf,
        return -ENODEV;
 }
 
+static int snd_disconnect_release(struct inode *inode, struct file *file)
+{
+       struct snd_monitor_file *df = NULL, *_df;
+
+       spin_lock(&shutdown_lock);
+       list_for_each_entry(_df, &shutdown_files, shutdown_list) {
+               if (_df->file == file) {
+                       df = _df;
+                       break;
+               }
+       }
+       spin_unlock(&shutdown_lock);
+
+       if (likely(df))
+               return df->disconnected_f_op->release(inode, file);
+
+       panic("%s(%p, %p) failed!", __FUNCTION__, inode, file);
+}
+
 static unsigned int snd_disconnect_poll(struct file * file, poll_table * wait)
 {
        return POLLERR | POLLNVAL;
@@ -219,6 +238,22 @@ static int snd_disconnect_fasync(int fd, struct file *file, int on)
        return -ENODEV;
 }
 
+static struct file_operations snd_shutdown_f_ops =
+{
+       .owner =        THIS_MODULE,
+       .llseek =       snd_disconnect_llseek,
+       .read =         snd_disconnect_read,
+       .write =        snd_disconnect_write,
+       .release =      snd_disconnect_release,
+       .poll =         snd_disconnect_poll,
+       .unlocked_ioctl = snd_disconnect_ioctl,
+#ifdef CONFIG_COMPAT
+       .compat_ioctl = snd_disconnect_ioctl,
+#endif
+       .mmap =         snd_disconnect_mmap,
+       .fasync =       snd_disconnect_fasync
+};
+
 /**
  *  snd_card_disconnect - disconnect all APIs from the file-operations (user space)
  *  @card: soundcard structure
@@ -234,9 +269,6 @@ int snd_card_disconnect(struct snd_card *card)
 {
        struct snd_monitor_file *mfile;
        struct file *file;
-       struct snd_shutdown_f_ops *s_f_ops;
-       struct file_operations *f_ops;
-       const struct file_operations *old_f_ops;
        int err;
 
        spin_lock(&card->files_lock);
@@ -261,34 +293,14 @@ int snd_card_disconnect(struct snd_card *card)
 
                /* it's critical part, use endless loop */
                /* we have no room to fail */
-               s_f_ops = kmalloc(sizeof(struct snd_shutdown_f_ops), GFP_ATOMIC);
-               if (s_f_ops == NULL)
-                       panic("Atomic allocation failed for snd_shutdown_f_ops!");
-
-               f_ops = &s_f_ops->f_ops;
-
-               memset(f_ops, 0, sizeof(*f_ops));
-               f_ops->owner = file->f_op->owner;
-               f_ops->release = file->f_op->release;
-               f_ops->llseek = snd_disconnect_llseek;
-               f_ops->read = snd_disconnect_read;
-               f_ops->write = snd_disconnect_write;
-               f_ops->poll = snd_disconnect_poll;
-               f_ops->unlocked_ioctl = snd_disconnect_ioctl;
-#ifdef CONFIG_COMPAT
-               f_ops->compat_ioctl = snd_disconnect_ioctl;
-#endif
-               f_ops->mmap = snd_disconnect_mmap;
-               f_ops->fasync = snd_disconnect_fasync;
+               mfile->disconnected_f_op = mfile->file->f_op;
 
-               s_f_ops->next = card->s_f_ops;
-               card->s_f_ops = s_f_ops;
-               
-               f_ops = fops_get(f_ops);
+               spin_lock(&shutdown_lock);
+               list_add(&mfile->shutdown_list, &shutdown_files);
+               spin_unlock(&shutdown_lock);
 
-               old_f_ops = file->f_op;
-               file->f_op = f_ops;     /* must be atomic */
-               fops_put(old_f_ops);
+               fops_get(&snd_shutdown_f_ops);
+               mfile->file->f_op = &snd_shutdown_f_ops;
                
                mfile = mfile->next;
        }
@@ -326,8 +338,6 @@ EXPORT_SYMBOL(snd_card_disconnect);
  */
 static int snd_card_do_free(struct snd_card *card)
 {
-       struct snd_shutdown_f_ops *s_f_ops;
-
 #if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
        if (snd_mixer_oss_notify_callback)
                snd_mixer_oss_notify_callback(card, SND_MIXER_OSS_NOTIFY_FREE);
@@ -351,11 +361,6 @@ static int snd_card_do_free(struct snd_card *card)
                snd_printk(KERN_WARNING "unable to free card info\n");
                /* Not fatal error */
        }
-       while (card->s_f_ops) {
-               s_f_ops = card->s_f_ops;
-               card->s_f_ops = s_f_ops->next;
-               kfree(s_f_ops);
-       }
        kfree(card);
        return 0;
 }
@@ -670,6 +675,7 @@ int snd_card_file_add(struct snd_card *card, struct file *file)
        if (mfile == NULL)
                return -ENOMEM;
        mfile->file = file;
+       mfile->disconnected_f_op = NULL;
        mfile->next = NULL;
        spin_lock(&card->files_lock);
        if (card->shutdown) {
@@ -716,6 +722,12 @@ int snd_card_file_remove(struct snd_card *card, struct file *file)
                pfile = mfile;
                mfile = mfile->next;
        }
+       if (mfile && mfile->disconnected_f_op) {
+               fops_put(mfile->disconnected_f_op);
+               spin_lock(&shutdown_lock);
+               list_del(&mfile->shutdown_list);
+               spin_unlock(&shutdown_lock);
+       }
        if (card->files == NULL)
                last_close = 1;
        spin_unlock(&card->files_lock);
index 4bf07ca9b17d625bcfc49b30bc5e13729faf089c..3daa9fa56c0bbbc5567c241c7e098ff41b8132a3 100644 (file)
@@ -125,12 +125,10 @@ static void _snd_mpu401_uart_interrupt(struct snd_mpu401 *mpu)
  * snd_mpu401_uart_interrupt - generic MPU401-UART interrupt handler
  * @irq: the irq number
  * @dev_id: mpu401 instance
- * @regs: the reigster
  *
  * Processes the interrupt for MPU401-UART i/o.
  */
-irqreturn_t snd_mpu401_uart_interrupt(int irq, void *dev_id,
-                                     struct pt_regs *regs)
+irqreturn_t snd_mpu401_uart_interrupt(int irq, void *dev_id)
 {
        struct snd_mpu401 *mpu = dev_id;
        
@@ -146,12 +144,10 @@ EXPORT_SYMBOL(snd_mpu401_uart_interrupt);
  * snd_mpu401_uart_interrupt_tx - generic MPU401-UART transmit irq handler
  * @irq: the irq number
  * @dev_id: mpu401 instance
- * @regs: the reigster
  *
  * Processes the interrupt for MPU401-UART output.
  */
-irqreturn_t snd_mpu401_uart_interrupt_tx(int irq, void *dev_id,
-                                        struct pt_regs *regs)
+irqreturn_t snd_mpu401_uart_interrupt_tx(int irq, void *dev_id)
 {
        struct snd_mpu401 *mpu = dev_id;
        
index e064d6c5685bcf4939422798989caf7b0e00a94d..a9ff391258e707c3ac7bf696e457e61de0fe0d92 100644 (file)
@@ -570,7 +570,7 @@ static void snd_mtpav_read_bytes(struct mtpav *mcrd)
        } while (sbyt & SIGS_BYTE);
 }
 
-static irqreturn_t snd_mtpav_irqh(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t snd_mtpav_irqh(int irq, void *dev_id)
 {
        struct mtpav *mcard = dev_id;
 
index ab8d4effcf9ec55c58b5d0758dc67e4d07f9fc8f..5327c6f841f40aad39888b5005137c78d2dcbe9e 100644 (file)
@@ -838,7 +838,7 @@ static int __devinit snd_mts64_rawmidi_create(struct snd_card *card)
 /*********************************************************************
  * parport stuff
  *********************************************************************/
-static void snd_mts64_interrupt(int irq, void *private, struct pt_regs *r)
+static void snd_mts64_interrupt(int irq, void *private)
 {
        struct mts64 *mts = ((struct snd_card*)private)->private_data;
        u16 ret;
index 52afb4bd2079acd0cc47bd3d8b0e7bbc462da9a2..74028b2219c2358b8ad4a67b9f99d024a7540cee 100644 (file)
@@ -292,7 +292,7 @@ static void snd_uart16550_io_loop(snd_uart16550_t * uart)
  * Note that some devices need OUT2 to be set before they will generate
  * interrupts at all. (Possibly tied to an internal pull-up on CTS?)
  */
-static irqreturn_t snd_uart16550_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t snd_uart16550_interrupt(int irq, void *dev_id)
 {
        snd_uart16550_t *uart;
 
index a60168268dddee8f66eda75dd1d42ac0e6f2fd40..ed19bc17400ba8cf2112a29f7b8ff21f577b97c9 100644 (file)
@@ -537,7 +537,7 @@ static void vx_interrupt(unsigned long private_data)
 /**
  * snd_vx_irq_handler - interrupt handler
  */
-irqreturn_t snd_vx_irq_handler(int irq, void *dev, struct pt_regs *regs)
+irqreturn_t snd_vx_irq_handler(int irq, void *dev)
 {
        struct vx_core *chip = dev;
 
index 557c4de229607bb9d8f5c1eaee83c4f7ee0fbd6d..57371f1a441f4ed0da9a4a81791e0415886e75ae 100644 (file)
@@ -13,6 +13,7 @@ config SND_CS4231_LIB
 
 config SND_ADLIB
        tristate "AdLib FM card"
+       depends on SND
        select SND_OPL3_LIB
        help
          Say Y here to include support for AdLib FM cards.
index b33a5fb59ec2144cf35d53acc9eafe74daca4f3e..59034507175b617b331c1dad07028344813e8f57 100644 (file)
@@ -120,6 +120,8 @@ static int __devinit snd_card_ad1816a_pnp(int dev, struct snd_card_ad1816a *acar
        struct pnp_resource_table *cfg = kmalloc(sizeof(*cfg), GFP_KERNEL);
        int err;
 
+       if (!cfg)
+               return -ENOMEM;
        acard->dev = pnp_request_card_device(card, id->devs[0].id, NULL);
        if (acard->dev == NULL) {
                kfree(cfg);
index fd9b61eda0f37b907a1479ff4c6b3e3fec2fd20b..b524e0d9ee44262ac87a30904a05cc125fee8a9f 100644 (file)
@@ -315,7 +315,7 @@ static snd_pcm_uframes_t snd_ad1816a_capture_pointer(struct snd_pcm_substream *s
 }
 
 
-static irqreturn_t snd_ad1816a_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t snd_ad1816a_interrupt(int irq, void *dev_id)
 {
        struct snd_ad1816a *chip = dev_id;
        unsigned char status;
index a6fbd5d1d62f2dfec49e74f1988b3854c6a58edc..666b3bcc19f0d64216874418024ebd1260d4edbb 100644 (file)
@@ -583,7 +583,7 @@ static int snd_ad1848_capture_prepare(struct snd_pcm_substream *substream)
        return 0;
 }
 
-static irqreturn_t snd_ad1848_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t snd_ad1848_interrupt(int irq, void *dev_id)
 {
        struct snd_ad1848 *chip = dev_id;
 
index 3c1e9fd56fe00143e3c1a26ca81c5acc9affa4e8..d1f6dfcec46edfd73e55fce385be78e618b76189 100644 (file)
@@ -289,6 +289,8 @@ static int __devinit snd_cmi8330_pnp(int dev, struct snd_cmi8330 *acard,
        struct pnp_resource_table * cfg = kmalloc(sizeof(struct pnp_resource_table), GFP_KERNEL);
        int err;
 
+       if (!cfg)
+               return -ENOMEM;
        acard->cap = pnp_request_card_device(card, id->devs[0].id, NULL);
        if (acard->cap == NULL) {
                kfree(cfg);
index fbb20176cca4e6b8ac6a63ff5e4bcb37d5b1f186..75c7c5f01989a478dd664aa58a7b503e22b0c478 100644 (file)
@@ -920,7 +920,7 @@ static void snd_cs4231_overrange(struct snd_cs4231 *chip)
                chip->capture_substream->runtime->overrange++;
 }
 
-irqreturn_t snd_cs4231_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t snd_cs4231_interrupt(int irq, void *dev_id)
 {
        struct snd_cs4231 *chip = dev_id;
        unsigned char status;
index 7e985d3bc5105206877951ecfbce6d20389b15a2..a2ab99f2ac35fc2f513465be6c1092856651b297 100644 (file)
@@ -479,7 +479,7 @@ static int snd_es1688_capture_trigger(struct snd_pcm_substream *substream,
        return snd_es1688_trigger(chip, cmd, 0x0f);
 }
 
-static irqreturn_t snd_es1688_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t snd_es1688_interrupt(int irq, void *dev_id)
 {
        struct snd_es1688 *chip = dev_id;
 
index 85818200333f33c6b1defe1de9fcd494c4496fd4..725c115ff97da3277723d54903081afbc41a84d5 100644 (file)
@@ -754,7 +754,7 @@ static int snd_es18xx_playback_trigger(struct snd_pcm_substream *substream,
                return snd_es18xx_playback2_trigger(chip, substream, cmd);
 }
 
-static irqreturn_t snd_es18xx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t snd_es18xx_interrupt(int irq, void *dev_id)
 {
        struct snd_es18xx *chip = dev_id;
        unsigned char status;
@@ -799,7 +799,7 @@ static irqreturn_t snd_es18xx_interrupt(int irq, void *dev_id, struct pt_regs *r
 
        /* MPU */
        if ((status & MPU_IRQ) && chip->rmidi)
-               snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data, regs);
+               snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data);
 
        /* Hardware volume */
        if (status & HWV_IRQ) {
@@ -2154,6 +2154,7 @@ static int __devinit snd_audiodrive_pnpc(int dev, struct snd_audiodrive *acard,
        }
        /* Control port initialization */
        if (pnp_activate_dev(acard->devc) < 0) {
+               kfree(cfg);
                snd_printk(KERN_ERR PFX "PnP control configure failure (out of resources?)\n");
                return -EAGAIN;
        }
index 42db37552efbde1ae8416ae01f6d3b58aee8454f..537d3cfe41f3871eca74e355277530c7796892f7 100644 (file)
@@ -30,7 +30,7 @@
 #define STAT_ADD(x)    while (0) { ; }
 #endif
 
-irqreturn_t snd_gus_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t snd_gus_interrupt(int irq, void *dev_id)
 {
        struct snd_gus_card * gus = dev_id;
        unsigned char status;
index ac11cae8589a1fd379042bad77d6e47c8432eda1..c1c69e3cbfd040c3ee7636d0a7c0feec6a6fac8a 100644 (file)
@@ -105,9 +105,9 @@ static int __init snd_gusmax_detect(struct snd_gus_card * gus)
        return 0;
 }
 
-static irqreturn_t snd_gusmax_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t snd_gusmax_interrupt(int irq, void *dev_id)
 {
-       struct snd_gusmax *maxcard = (struct snd_gusmax *) dev_id;
+       struct snd_gusmax *maxcard = dev_id;
        int loop, max = 5;
        int handled = 0;
 
@@ -115,12 +115,12 @@ static irqreturn_t snd_gusmax_interrupt(int irq, void *dev_id, struct pt_regs *r
                loop = 0;
                if (inb(maxcard->gus_status_reg)) {
                        handled = 1;
-                       snd_gus_interrupt(irq, maxcard->gus, regs);
+                       snd_gus_interrupt(irq, maxcard->gus);
                        loop++;
                }
                if (inb(maxcard->pcm_status_reg) & 0x01) { /* IRQ bit is set? */
                        handled = 1;
-                       snd_cs4231_interrupt(irq, maxcard->cs4231, regs);
+                       snd_cs4231_interrupt(irq, maxcard->cs4231);
                        loop++;
                }
        } while (loop && --max > 0);
index ea69f25506fb1a3b388413cdb2605ee6b293ba63..4ec2d79431fc1b1ca8cd335fca51c330ec9222c7 100644 (file)
@@ -299,9 +299,9 @@ static int __devinit snd_interwave_detect(struct snd_interwave *iwcard,
        return -ENODEV;
 }
 
-static irqreturn_t snd_interwave_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t snd_interwave_interrupt(int irq, void *dev_id)
 {
-       struct snd_interwave *iwcard = (struct snd_interwave *) dev_id;
+       struct snd_interwave *iwcard = dev_id;
        int loop, max = 5;
        int handled = 0;
 
@@ -309,12 +309,12 @@ static irqreturn_t snd_interwave_interrupt(int irq, void *dev_id, struct pt_regs
                loop = 0;
                if (inb(iwcard->gus_status_reg)) {
                        handled = 1;
-                       snd_gus_interrupt(irq, iwcard->gus, regs);
+                       snd_gus_interrupt(irq, iwcard->gus);
                        loop++;
                }
                if (inb(iwcard->pcm_status_reg) & 0x01) {       /* IRQ bit is set? */
                        handled = 1;
-                       snd_cs4231_interrupt(irq, iwcard->cs4231, regs);
+                       snd_cs4231_interrupt(irq, iwcard->cs4231);
                        loop++;
                }
        } while (loop && --max > 0);
@@ -564,6 +564,8 @@ static int __devinit snd_interwave_pnp(int dev, struct snd_interwave *iwcard,
        struct pnp_resource_table * cfg = kmalloc(sizeof(struct pnp_resource_table), GFP_KERNEL);
        int err;
 
+       if (!cfg)
+               return -ENOMEM;
        iwcard->dev = pnp_request_card_device(card, id->devs[0].id, NULL);
        if (iwcard->dev == NULL) {
                kfree(cfg);
index da92bf6c392b87d761ff21de1a96b9127731ab12..419b4ebbf00eaf7fe874d41d857adc3f8a224fb5 100644 (file)
@@ -294,7 +294,7 @@ static int __devinit snd_opl3sa2_detect(struct snd_opl3sa2 *chip)
        return 0;
 }
 
-static irqreturn_t snd_opl3sa2_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t snd_opl3sa2_interrupt(int irq, void *dev_id)
 {
        unsigned short status;
        struct snd_opl3sa2 *chip = dev_id;
@@ -312,12 +312,12 @@ static irqreturn_t snd_opl3sa2_interrupt(int irq, void *dev_id, struct pt_regs *
 
        if ((status & 0x10) && chip->rmidi != NULL) {
                handled = 1;
-               snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data, regs);
+               snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data);
        }
 
        if (status & 0x07) {    /* TI,CI,PI */
                handled = 1;
-               snd_cs4231_interrupt(irq, chip->cs4231, regs);
+               snd_cs4231_interrupt(irq, chip->cs4231);
        }
 
        if (status & 0x40) { /* hardware volume change */
index 9d528ae00bff1c7bcd63c4da1d512f2e761bac8d..df227377c3331d8d46030c3d37bb6bb8d298df65 100644 (file)
@@ -1090,7 +1090,7 @@ static void snd_opti93x_overrange(struct snd_opti93x *chip)
        spin_unlock_irqrestore(&chip->lock, flags);
 }
 
-static irqreturn_t snd_opti93x_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t snd_opti93x_interrupt(int irq, void *dev_id)
 {
        struct snd_opti93x *codec = dev_id;
        unsigned char status;
@@ -1683,6 +1683,8 @@ static int __init snd_card_opti9xx_pnp(struct snd_opti9xx *chip, struct pnp_card
        struct pnp_resource_table *cfg = kmalloc(sizeof(*cfg), GFP_KERNEL);
        int err;
 
+       if (!cfg)
+               return -ENOMEM;
        chip->dev = pnp_request_card_device(card, pid->devs[0].id, NULL);
        if (chip->dev == NULL) {
                kfree(cfg);
index d4d65b84265a8dd972d6904b65ead1be6b3b2a98..d4b218726ce75b02b186ff543d37d487ea32d744 100644 (file)
@@ -70,8 +70,7 @@ MODULE_DEVICE_TABLE(pnp_card, snd_es968_pnpids);
 
 #define        DRIVER_NAME     "snd-card-es968"
 
-static irqreturn_t snd_card_es968_interrupt(int irq, void *dev_id,
-                                           struct pt_regs *regs)
+static irqreturn_t snd_card_es968_interrupt(int irq, void *dev_id)
 {
        struct snd_sb *chip = dev_id;
 
index f183f1845a36e4f1656f303fcbf463925a9945b0..383911b9e74dcc709c1e32412953660b2c49796f 100644 (file)
@@ -395,7 +395,7 @@ static int snd_sb16_capture_trigger(struct snd_pcm_substream *substream,
        return result;
 }
 
-irqreturn_t snd_sb16dsp_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t snd_sb16dsp_interrupt(int irq, void *dev_id)
 {
        struct snd_sb *chip = dev_id;
        unsigned char status;
@@ -405,7 +405,7 @@ irqreturn_t snd_sb16dsp_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        status = snd_sbmixer_read(chip, SB_DSP4_IRQSTATUS);
        spin_unlock(&chip->mixer_lock);
        if ((status & SB_IRQTYPE_MPUIN) && chip->rmidi_callback)
-               chip->rmidi_callback(irq, chip->rmidi->private_data, regs);
+               chip->rmidi_callback(irq, chip->rmidi->private_data);
        if (status & SB_IRQTYPE_8BIT) {
                ok = 0;
                if (chip->mode & SB_MODE_PLAYBACK_8) {
index 141400c014261aacffe3a42134ea34570c07a8fa..268ebd34703ec1fa821b5c31083b16e7bd6bb3a8 100644 (file)
@@ -63,7 +63,7 @@ struct snd_sb8 {
        struct snd_sb *chip;
 };
 
-static irqreturn_t snd_sb8_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t snd_sb8_interrupt(int irq, void *dev_id)
 {
        struct snd_sb *chip = dev_id;
 
index f17de2bdd9e08a80f93286fdc16a167e83881f46..c62a9e3d2ae4fd2aaa98202e5c01d53617e45643 100644 (file)
@@ -205,7 +205,7 @@ static int snd_sbdsp_dev_free(struct snd_device *device)
 int snd_sbdsp_create(struct snd_card *card,
                     unsigned long port,
                     int irq,
-                    irqreturn_t (*irq_handler)(int, void *, struct pt_regs *),
+                    irq_handler_t irq_handler,
                     int dma8,
                     int dma16,
                     unsigned short hardware,
index 8742fa5174910791ff6680ff962846a85e291e6a..4fcd0f4e868c4c67c29403b12ede58c16aeeb00f 100644 (file)
@@ -109,7 +109,7 @@ static int __init snd_sgalaxy_sbdsp_command(unsigned long port, unsigned char va
        return 0;
 }
 
-static irqreturn_t snd_sgalaxy_dummy_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t snd_sgalaxy_dummy_interrupt(int irq, void *dev_id)
 {
        return IRQ_NONE;
 }
index a8f8d2fa9d7649dcdd8afb47dfa6b34e513dad45..85db535aea9b595271b9ccecd43ec548dcd30b6e 100644 (file)
@@ -263,9 +263,7 @@ snd_wavefront_pnp (int dev, snd_wavefront_card_t *acard, struct pnp_card_link *c
 
 #endif /* CONFIG_PNP */
 
-static irqreturn_t snd_wavefront_ics2115_interrupt(int irq, 
-                                           void *dev_id, 
-                                           struct pt_regs *regs)
+static irqreturn_t snd_wavefront_ics2115_interrupt(int irq, void *dev_id)
 {
        snd_wavefront_card_t *acard;
 
index ff6e6fc198a18a2f20cd9276bcee6ce84e66102d..8a61a119186135984c42b7299a9c692cf8853f20 100644 (file)
@@ -220,7 +220,7 @@ au1000_dma_start(struct audio_stream *stream)
 }
 
 static irqreturn_t
-au1000_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+au1000_dma_interrupt(int irq, void *dev_id)
 {
        struct audio_stream *stream = (struct audio_stream *) dev_id;
        struct snd_pcm_substream *substream = stream->substream;
index 29057836c64425c2ddceab96d397d74fe0c10608..caabf31193f7d3fd8d29f6dd6685cc672154d7c7 100644 (file)
@@ -521,7 +521,7 @@ static struct audio_driver ad1816_audio_driver =
 /* Interrupt handler */
 
 
-static irqreturn_t ad1816_interrupt (int irq, void *dev_id, struct pt_regs *dummy)
+static irqreturn_t ad1816_interrupt (int irq, void *dev_id)
 {
        unsigned char   status;
        ad1816_info     *devc = (ad1816_info *)dev_id;
index 257b7536fb18b505033e3a4233aa67187309f3cb..0ffa9970bf0ff307cee68b9698c3bffc63f3eee9 100644 (file)
@@ -195,7 +195,7 @@ static void     ad1848_halt(int dev);
 static void     ad1848_halt_input(int dev);
 static void     ad1848_halt_output(int dev);
 static void     ad1848_trigger(int dev, int bits);
-static irqreturn_t adintr(int irq, void *dev_id, struct pt_regs *dummy);
+static irqreturn_t adintr(int irq, void *dev_id);
 
 #ifndef EXCLUDE_TIMERS
 static int ad1848_tmr_install(int dev);
@@ -2196,7 +2196,7 @@ void ad1848_unload(int io_base, int irq, int dma_playback, int dma_capture, int
                printk(KERN_ERR "ad1848: Can't find device to be unloaded. Base=%x\n", io_base);
 }
 
-static irqreturn_t adintr(int irq, void *dev_id, struct pt_regs *dummy)
+static irqreturn_t adintr(int irq, void *dev_id)
 {
        unsigned char status;
        ad1848_info *devc;
index f56f870b48400e844a52d3547566fbefbb59ccf9..09263d72a519983a10e96347d9ee4f8cd3f1ed9d 100644 (file)
@@ -929,7 +929,7 @@ static struct pci_device_id ad1889_id_tbl[] = {
 };
 MODULE_DEVICE_TABLE(pci, ad1889_id_tbl);
 
-static irqreturn_t ad1889_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t ad1889_interrupt(int irq, void *dev_id)
 {
        u32 stat;
        ad1889_dev_t *dev = (ad1889_dev_t *)dev_id;
index 324a81fd3a3b0e305adbd90859a361b45659e780..6ad38411423989b7d3232e92c7cd43f820574634 100644 (file)
@@ -824,7 +824,7 @@ static char *irq_name[] = { "", "", "", "OFLOW", "", "", "", "", "", "", "",
                            "RISCI", "FBUS", "FTRGT", "FDSR", "PPERR",
                            "RIPERR", "PABORT", "OCERR", "SCERR" };
 
-static irqreturn_t btaudio_irq(int irq, void *dev_id, struct pt_regs * regs)
+static irqreturn_t btaudio_irq(int irq, void *dev_id)
 {
        int count = 0;
        u32 stat,astat;
index 43193581f836f3d923cfb2cae57e799e1351e01f..6e3c41f530e6ee3106cafd6b87c5a5cf4989f13a 100644 (file)
@@ -1613,7 +1613,7 @@ static void cs_handle_midi(struct cs_card *card)
                 wake_up(&card->midi.owait);
 }
 
-static irqreturn_t cs_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t cs_interrupt(int irq, void *dev_id)
 {
        struct cs_card *card = (struct cs_card *)dev_id;
        /* Single channel card */
index dc31373069a5f3231fa1a7bb044e99e8dd3b08af..285239d64b8279d133c24617010e7058bfcbe448 100644 (file)
@@ -133,7 +133,7 @@ static int FalconSetFormat(int format);
 static int FalconSetVolume(int volume);
 static void AtaPlayNextFrame(int index);
 static void AtaPlay(void);
-static irqreturn_t AtaInterrupt(int irq, void *dummy, struct pt_regs *fp);
+static irqreturn_t AtaInterrupt(int irq, void *dummy);
 
 /*** Mid level stuff *********************************************************/
 
@@ -1257,7 +1257,7 @@ static void AtaPlay(void)
 }
 
 
-static irqreturn_t AtaInterrupt(int irq, void *dummy, struct pt_regs *fp)
+static irqreturn_t AtaInterrupt(int irq, void *dummy)
 {
 #if 0
        /* ++TeSche: if you should want to test this... */
index 9ae659f82430384c9c57bacf7131c2708da6cf6e..37773b1deea51e25e4d864fb405ab75528bca756 100644 (file)
@@ -281,9 +281,9 @@ static int PMacSetFormat(int format);
 static int PMacSetVolume(int volume);
 static void PMacPlay(void);
 static void PMacRecord(void);
-static irqreturn_t pmac_awacs_tx_intr(int irq, void *devid, struct pt_regs *regs);
-static irqreturn_t pmac_awacs_rx_intr(int irq, void *devid, struct pt_regs *regs);
-static irqreturn_t pmac_awacs_intr(int irq, void *devid, struct pt_regs *regs);
+static irqreturn_t pmac_awacs_tx_intr(int irq, void *devid);
+static irqreturn_t pmac_awacs_rx_intr(int irq, void *devid);
+static irqreturn_t pmac_awacs_intr(int irq, void *devid);
 static void awacs_write(int val);
 static int awacs_get_volume(int reg, int lshift);
 static int awacs_volume_setter(int volume, int n, int mute, int lshift);
@@ -398,7 +398,7 @@ read_audio_gpio(int gpio_addr)
  * Headphone interrupt via GPIO (Tumbler, Snapper, DACA)
  */
 static irqreturn_t
-headphone_intr(int irq, void *devid, struct pt_regs *regs)
+headphone_intr(int irq, void *devid)
 {
        unsigned long flags;
 
@@ -465,7 +465,7 @@ tas_dmasound_init(void)
                        val = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, gpio_headphone_detect, 0);
                        pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, gpio_headphone_detect, val | 0x80);
                        /* Trigger it */
-                       headphone_intr(0,NULL,NULL);
+                       headphone_intr(0, NULL);
                }
        }
        if (!gpio_headphone_irq) {
@@ -1037,7 +1037,7 @@ static void PMacRecord(void)
 */
 
 static irqreturn_t
-pmac_awacs_tx_intr(int irq, void *devid, struct pt_regs *regs)
+pmac_awacs_tx_intr(int irq, void *devid)
 {
        int i = write_sq.front;
        int stat;
@@ -1129,7 +1129,7 @@ printk("dmasound_pmac: tx-irq: xfer died - patching it up...\n") ;
 
 
 static irqreturn_t
-pmac_awacs_rx_intr(int irq, void *devid, struct pt_regs *regs)
+pmac_awacs_rx_intr(int irq, void *devid)
 {
        int stat ;
        /* For some reason on my PowerBook G3, I get one interrupt
@@ -1212,7 +1212,7 @@ printk("dmasound_pmac: rx-irq: DIED - attempting resurection\n");
 
 
 static irqreturn_t
-pmac_awacs_intr(int irq, void *devid, struct pt_regs *regs)
+pmac_awacs_intr(int irq, void *devid)
 {
        int ctrl;
        int status;
@@ -1499,7 +1499,7 @@ static int awacs_sleep_notify(struct pmu_sleep_notifier *self, int when)
                                write_audio_gpio(gpio_audio_reset, !gpio_audio_reset_pol);
                                msleep(150);
                                tas_leave_sleep(); /* Stub for now */
-                               headphone_intr(0,NULL,NULL);
+                               headphone_intr(0, NULL);
                                break;
                        case AWACS_DACA:
                                msleep(10); /* Check this !!! */
index 68e1d8f6c359aa1b6b8be19a5b29c63e337afda3..90fc058e1159a60b7bd6c52917a061a24d1e9c49 100644 (file)
@@ -82,7 +82,7 @@ static int AmiSetVolume(int volume);
 static int AmiSetTreble(int treble);
 static void AmiPlayNextFrame(int index);
 static void AmiPlay(void);
-static irqreturn_t AmiInterrupt(int irq, void *dummy, struct pt_regs *fp);
+static irqreturn_t AmiInterrupt(int irq, void *dummy);
 
 #ifdef CONFIG_HEARTBEAT
 
@@ -556,7 +556,7 @@ static void AmiPlay(void)
 }
 
 
-static irqreturn_t AmiInterrupt(int irq, void *dummy, struct pt_regs *fp)
+static irqreturn_t AmiInterrupt(int irq, void *dummy)
 {
        int minframes = 1;
 
index e2081f32b0c45904246961f450889956e962ba6b..b3379dd7ca5e1d49d5cc8d0a13c533b891ef8875 100644 (file)
@@ -48,8 +48,8 @@ static int Q40SetFormat(int format);
 static int Q40SetVolume(int volume);
 static void Q40PlayNextFrame(int index);
 static void Q40Play(void);
-static irqreturn_t Q40StereoInterrupt(int irq, void *dummy, struct pt_regs *fp);
-static irqreturn_t Q40MonoInterrupt(int irq, void *dummy, struct pt_regs *fp);
+static irqreturn_t Q40StereoInterrupt(int irq, void *dummy);
+static irqreturn_t Q40MonoInterrupt(int irq, void *dummy);
 static void Q40Interrupt(void);
 
 
@@ -451,7 +451,7 @@ static void Q40Play(void)
        spin_unlock_irqrestore(&dmasound.lock, flags);
 }
 
-static irqreturn_t Q40StereoInterrupt(int irq, void *dummy, struct pt_regs *fp)
+static irqreturn_t Q40StereoInterrupt(int irq, void *dummy)
 {
        spin_lock(&dmasound.lock);
         if (q40_sc>1){
@@ -463,7 +463,7 @@ static irqreturn_t Q40StereoInterrupt(int irq, void *dummy, struct pt_regs *fp)
        spin_unlock(&dmasound.lock);
        return IRQ_HANDLED;
 }
-static irqreturn_t Q40MonoInterrupt(int irq, void *dummy, struct pt_regs *fp)
+static irqreturn_t Q40MonoInterrupt(int irq, void *dummy)
 {
        spin_lock(&dmasound.lock);
         if (q40_sc>0){
index d19b464ba01b5f0851b5c2e4f4aecc6c9a731829..fb2ce638f01c4b868affe1e001f151cfa6789b55 100644 (file)
@@ -37,7 +37,7 @@
 
 /* Interrupt handler */
 
-irqreturn_t emu10k1_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t emu10k1_interrupt(int irq, void *dev_id)
 {
        struct emu10k1_card *card = (struct emu10k1_card *) dev_id;
        u32 irqstatus, irqstatus_tmp;
index c4ce94d6e10cb6415e3aa29457842da519ab5998..6c59df7b00011965f04cad5f5f3a3bd17319ae5d 100644 (file)
@@ -167,7 +167,7 @@ extern struct file_operations emu10k1_midi_fops;
 static struct midi_operations emu10k1_midi_operations;
 #endif
 
-extern irqreturn_t emu10k1_interrupt(int, void *, struct pt_regs *s);
+extern irqreturn_t emu10k1_interrupt(int, void *);
 
 static int __devinit emu10k1_audio_init(struct emu10k1_card *card)
 {
index a2ffe723dad54c6e976d66cf4e43efbce0ec922b..ddf6b0a0bca5a1c363bf9c58378e51aa5e73cf6c 100644 (file)
@@ -1100,9 +1100,9 @@ static void es1371_handle_midi(struct es1371_state *s)
        outb((s->midi.ocnt > 0) ? UCTRL_RXINTEN | UCTRL_ENA_TXINT : UCTRL_RXINTEN, s->io+ES1371_REG_UART_CONTROL);
 }
 
-static irqreturn_t es1371_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t es1371_interrupt(int irq, void *dev_id)
 {
-        struct es1371_state *s = (struct es1371_state *)dev_id;
+        struct es1371_state *s = dev_id;
        unsigned int intsrc, sctl;
        
        /* fastpath out, to ease interrupt sharing */
index 80ab402dae9a5123760dcd9acfa019467656a2ff..784bdd707055ede1e4ae3cdf176fd3ba262e26d1 100644 (file)
@@ -370,9 +370,9 @@ static void hal2_adc_interrupt(struct hal2_codec *adc)
        wake_up(&adc->dma_wait);
 }
 
-static irqreturn_t hal2_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t hal2_interrupt(int irq, void *dev_id)
 {
-       struct hal2_card *hal2 = (struct hal2_card*)dev_id;
+       struct hal2_card *hal2 = dev_id;
        irqreturn_t ret = IRQ_NONE;
 
        /* decide what caused this interrupt */
index ddcddc2347f7ec3450624b296f6e385b0013575a..240cc7939b69e6137ca8adfd33f4d6c44b8d172f 100644 (file)
@@ -1523,9 +1523,9 @@ static void i810_channel_interrupt(struct i810_card *card)
 #endif
 }
 
-static irqreturn_t i810_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t i810_interrupt(int irq, void *dev_id)
 {
-       struct i810_card *card = (struct i810_card *)dev_id;
+       struct i810_card *card = dev_id;
        u32 status;
 
        spin_lock(&card->lock);
index 162d07cc489f6fba5411c8ccb8b884868d0ef11c..e96220541971498a0c25c31f98ebb36cc11d6f6f 100644 (file)
@@ -432,10 +432,10 @@ static void mpu401_input_loop(struct mpu_config *devc)
        devc->m_busy = 0;
 }
 
-static irqreturn_t mpuintr(int irq, void *dev_id, struct pt_regs *dummy)
+static irqreturn_t mpuintr(int irq, void *dev_id)
 {
        struct mpu_config *devc;
-       int dev = (int) dev_id;
+       int dev = (int)(unsigned long) dev_id;
        int handled = 0;
 
        devc = &dev_conf[dev];
index 84c0e9522ef7e674cc75e86606e5585b3aae410c..0ad1e9ee74f7f4b5b1c983761a6c562072b22eee 100644 (file)
@@ -3,10 +3,9 @@
 int probe_uart401 (struct address_info *hw_config, struct module *owner);
 void unload_uart401 (struct address_info *hw_config);
 
-irqreturn_t uart401intr (int irq, void *dev_id, struct pt_regs * dummy);
+irqreturn_t uart401intr (int irq, void *dev_id);
 
 /*     From mpu401.c */
 int probe_mpu401(struct address_info *hw_config, struct resource *ports);
 int attach_mpu401(struct address_info * hw_config, struct module *owner);
 void unload_mpu401(struct address_info *hw_info);
-
index 6d7763dae8952f7913058e21d00f72cb9b474789..d5146790f5e3e678dc9a463aeb96b0f6948efe05 100644 (file)
@@ -1087,7 +1087,7 @@ static __inline__ void eval_dsp_msg(register WORD wMessage)
        }
 }
 
-static irqreturn_t intr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t intr(int irq, void *dev_id)
 {
        /* Send ack to DSP */
        msnd_inb(dev.io + HP_RXL);
index 6f7f2f0423e41b211d80c050edf22c730a00f4dc..da9728e17727a9a60d3d1d9cb1ca79f8725c6820 100644 (file)
@@ -848,7 +848,7 @@ static inline void vrc5477_ac97_dac_interrupt(struct vrc5477_ac97_state *s)
                wake_up_interruptible(&dac->wait);
 }
 
-static irqreturn_t vrc5477_ac97_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t vrc5477_ac97_interrupt(int irq, void *dev_id)
 {
        struct vrc5477_ac97_state *s = (struct vrc5477_ac97_state *)dev_id;
        u32 irqStatus;
index 21e07b5081f2bdb5ad44fc453bd0c7ca60ec5ac8..1dade9033995467956df1065e0f41210b0ec36f3 100644 (file)
@@ -115,7 +115,7 @@ struct nm256_info
     int has_irq;
 
     /* The card interrupt service routine. */
-    irqreturn_t (*introutine) (int, void *, struct pt_regs *);
+    irq_handler_t introutine;
 
     /* Current audio config, cached. */
     struct sinfo {
index 7760dddf2b32e4ddf1f44ef845c346e18e3f80a4..44cd15505001bc4f5e206d07257c5de5951a3782 100644 (file)
@@ -45,8 +45,8 @@ static struct audio_driver nm256_audio_driver;
 
 static int nm256_grabInterrupt (struct nm256_info *card);
 static int nm256_releaseInterrupt (struct nm256_info *card);
-static irqreturn_t nm256_interrupt (int irq, void *dev_id, struct pt_regs *dummy);
-static irqreturn_t nm256_interrupt_zx (int irq, void *dev_id, struct pt_regs *dummy);
+static irqreturn_t nm256_interrupt (int irq, void *dev_id);
+static irqreturn_t nm256_interrupt_zx (int irq, void *dev_id);
 
 /* These belong in linux/pci.h. */
 #define PCI_DEVICE_ID_NEOMAGIC_NM256AV_AUDIO 0x8005
@@ -526,7 +526,7 @@ nm256_initHw (struct nm256_info *card)
  */
 
 static irqreturn_t
-nm256_interrupt (int irq, void *dev_id, struct pt_regs *dummy)
+nm256_interrupt (int irq, void *dev_id)
 {
     struct nm256_info *card = (struct nm256_info *)dev_id;
     u16 status;
@@ -629,7 +629,7 @@ nm256_interrupt (int irq, void *dev_id, struct pt_regs *dummy)
  */
 
 static irqreturn_t
-nm256_interrupt_zx (int irq, void *dev_id, struct pt_regs *dummy)
+nm256_interrupt_zx (int irq, void *dev_id)
 {
     struct nm256_info *card = (struct nm256_info *)dev_id;
     u32 status;
index 4ebb9638746ecbb97dc58fe98489c1425ce2a0c8..25f3a22c52ee0891fbc5ceeee6ea47a12fc5ee14 100644 (file)
@@ -88,7 +88,7 @@ void pas_write(unsigned char data, int ioaddr)
 
 /******************* Begin of the Interrupt Handler ********************/
 
-static irqreturn_t pasintr(int irq, void *dev_id, struct pt_regs *dummy)
+static irqreturn_t pasintr(int irq, void *dev_id)
 {
        int             status;
 
index bbe5b7596d0e1167b321281da38a15ab70cde29d..440537c72604f467bdf359414d216fc5c8662546 100644 (file)
@@ -132,7 +132,7 @@ static void sb_intr (sb_devc *devc)
 
                if (src & 4)                                            /* MPU401 interrupt */
                        if(devc->midi_irq_cookie)
-                               uart401intr(devc->irq, devc->midi_irq_cookie, NULL);
+                               uart401intr(devc->irq, devc->midi_irq_cookie);
 
                if (!(src & 3))
                        return; /* Not a DSP interrupt */
@@ -200,7 +200,7 @@ static void pci_intr(sb_devc *devc)
                sb_intr(devc);
 }
 
-static irqreturn_t sbintr(int irq, void *dev_id, struct pt_regs *dummy)
+static irqreturn_t sbintr(int irq, void *dev_id)
 {
        sb_devc *devc = dev_id;
 
index 83ff8a71f716b9b4d29ce8b9e05a78b21ee74fcb..51f554154c48dfa0a7c56d082231268fc9a55c5a 100644 (file)
@@ -26,7 +26,7 @@
 #include <asm/cpu/dac.h>
 #include <asm/cpu/timer.h>
 #include <asm/machvec.h>
-#include <asm/hp6xx/hp6xx.h>
+#include <asm/hp6xx.h>
 #include <asm/hd64461.h>
 
 #define MODNAME "sh_dac_audio"
@@ -263,7 +263,7 @@ struct file_operations dac_audio_fops = {
       .release =       dac_audio_release,
 };
 
-static irqreturn_t timer1_interrupt(int irq, void *dev, struct pt_regs *regs)
+static irqreturn_t timer1_interrupt(int irq, void *dev)
 {
        unsigned long timer_status;
 
index 3edf8d4ac9987d3909de91a5a48db4d2818656af..471c274c5000e5ebe1dd0f69c5d4e8c57a51c556 100644 (file)
@@ -2505,7 +2505,7 @@ static /*const */ struct file_operations cs4297a_audio_fops = {
        .release        = cs4297a_release,
 };
 
-static void cs4297a_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static void cs4297a_interrupt(int irq, void *dev_id)
 {
        struct cs4297a_state *s = (struct cs4297a_state *) dev_id;
         u32 status;
index 147c816a1f2293914ba3b902dd987180ecb40cae..7a363a178afd4cb9400ada31d58034e233653331 100644 (file)
@@ -1811,7 +1811,7 @@ cyber_address_interrupt(struct trident_card *card)
 }
 
 static irqreturn_t
-trident_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+trident_interrupt(int irq, void *dev_id)
 {
        struct trident_card *card = (struct trident_card *) dev_id;
        u32 event;
index 8e18b6e25818f365c123a5fc5d7868e56bc0a9bb..a446b826d5fc87645738dacae9fbe3b31378b4ce 100644 (file)
@@ -96,7 +96,7 @@ static void uart401_input_loop(uart401_devc * devc)
                printk(KERN_WARNING "Too much work in interrupt on uart401 (0x%X). UART jabbering ??\n", devc->base);
 }
 
-irqreturn_t uart401intr(int irq, void *dev_id, struct pt_regs *dummy)
+irqreturn_t uart401intr(int irq, void *dev_id)
 {
        uart401_devc *devc = dev_id;
 
index 501d3e654a67ba2e66849fad9cddb3945752bb50..f3f914aa92ee3aaf25a81fa80f02bde9b27b3077 100644 (file)
@@ -104,7 +104,7 @@ static void uart6850_input_loop(void)
        }
 }
 
-static irqreturn_t m6850intr(int irq, void *dev_id, struct pt_regs *dummy)
+static irqreturn_t m6850intr(int irq, void *dev_id)
 {
        if (input_avail())
                uart6850_input_loop();
index 2fec42fc348284bd6a4c20d2ba1aadbf781e51c6..17837d4b5ed311effabe0b548fae61660a1fd1fa 100644 (file)
@@ -1912,7 +1912,7 @@ static void via_intr_channel (struct via_info *card, struct via_channel *chan)
 }
 
 
-static irqreturn_t  via_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t  via_interrupt(int irq, void *dev_id)
 {
        struct via_info *card = dev_id;
        u32 status32;
@@ -1927,7 +1927,7 @@ static irqreturn_t  via_interrupt(int irq, void *dev_id, struct pt_regs *regs)
         {
 #ifdef CONFIG_MIDI_VIA82CXXX
                 if (card->midi_devc)
-                       uart401intr(irq, card->midi_devc, regs);
+                       uart401intr(irq, card->midi_devc);
 #endif
                return IRQ_HANDLED;
        }
@@ -1950,7 +1950,7 @@ static irqreturn_t  via_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        return IRQ_HANDLED;
 }
 
-static irqreturn_t via_new_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t via_new_interrupt(int irq, void *dev_id)
 {
        struct via_info *card = dev_id;
        u32 status32;
index 8932d89408efb294d2673d7da8f25625cd154046..bb4a0969f4616602c8c583844c35585a77325903 100644 (file)
@@ -372,7 +372,7 @@ static void vidc_audio_trigger(int dev, int enable_bits)
                        adev->flags |= DMA_ACTIVE;
 
                        dma_interrupt = vidc_audio_dma_interrupt;
-                       vidc_sound_dma_irq(0, NULL, NULL);
+                       vidc_sound_dma_irq(0, NULL);
                        iomd_writeb(DMA_CR_E | 0x10, IOMD_SD0CR);
 
                        local_irq_restore(flags);
index d5b8064dc5650bebe99cae1fcb23ec60a4215719..0d1424751ecd3d5ad4a84705f9f6768e0c591cde 100644 (file)
@@ -33,7 +33,7 @@ extern unsigned long vidc_fill_2x16_s(unsigned long ibuf, unsigned long iend,
  * DMA Interrupt handler
  */
 
-extern irqreturn_t vidc_sound_dma_irq(int irqnr, void *ref, struct pt_regs *regs);
+extern irqreturn_t vidc_sound_dma_irq(int irqnr, void *ref);
 
 /*
  * Filler routine pointer
index 5f140c7586b385a52d1ca9cf94bc1048b5edbebc..6dfb9f4b03ec9c0fae1df528ec9245f226ab50ed 100644 (file)
@@ -2233,12 +2233,12 @@ static void vwsnd_audio_write_intr(vwsnd_dev_t *devc, unsigned int status)
                pcm_output(devc, underflown, 0);
 }
 
-static irqreturn_t vwsnd_audio_intr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t vwsnd_audio_intr(int irq, void *dev_id)
 {
-       vwsnd_dev_t *devc = (vwsnd_dev_t *) dev_id;
+       vwsnd_dev_t *devc = dev_id;
        unsigned int status;
 
-       DBGEV("(irq=%d, dev_id=0x%p, regs=0x%p)\n", irq, dev_id, regs);
+       DBGEV("(irq=%d, dev_id=0x%p)\n", irq, dev_id);
 
        status = li_get_clear_intr_status(&devc->lith);
        vwsnd_audio_read_intr(devc, status);
index 59a2f28eb5a5a8bb1e7fb6ecc36f7c964c1b8612..c5bf363d32c2fb055e9639a2040e4501fb989fd7 100644 (file)
@@ -833,7 +833,7 @@ static struct audio_driver waveartist_audio_driver = {
 
 
 static irqreturn_t
-waveartist_intr(int irq, void *dev_id, struct pt_regs *regs)
+waveartist_intr(int irq, void *dev_id)
 {
        wavnc_info *devc = (wavnc_info *)dev_id;
        int        irqstatus, status;
index ce73f3eae78c50b1143a87fa2e9a0675d0a9f9bd..cf603337b321d01bba027480e29fc5abbe593b98 100644 (file)
@@ -193,7 +193,7 @@ harmony_set_control(struct snd_harmony *h)
 }
 
 static irqreturn_t
-snd_harmony_interrupt(int irq, void *dev, struct pt_regs *regs)
+snd_harmony_interrupt(int irq, void *dev)
 {
        u32 dstatus;
        struct snd_harmony *h = dev;
index a79e91850ba361bbdb05dfdd65a3ed59638fc47e..6577b232535784b6f6bcf7b2db70448e423afcf1 100644 (file)
@@ -570,8 +570,7 @@ int snd_ac97_put_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value
                        ac97->power_up &= ~(1 << (reg>>1));
                else
                        ac97->power_up |= 1 << (reg>>1);
-               if (power_save)
-                       update_power_regs(ac97);
+               update_power_regs(ac97);
        }
 #endif
        return err;
@@ -2337,10 +2336,7 @@ int snd_ac97_update_power(struct snd_ac97 *ac97, int reg, int powerup)
                }
        }
 
-       if (! power_save)
-               return 0;
-
-       if (! powerup && ac97->power_workq)
+       if (power_save && !powerup && ac97->power_workq)
                /* adjust power-down bits after two seconds delay
                 * (for avoiding loud click noises for many (OSS) apps
                 *  that open/close frequently)
index dc28b111a06ddeea8e94783bf994bf78a7130166..15be6ba87c82f85e95fd661a311f19133a285f4a 100644 (file)
@@ -530,7 +530,7 @@ AC97_ENUM("ALC Headphone Mux", wm9711_enum[1]),
 AC97_SINGLE("ALC Headphone Volume", AC97_VIDEO, 7, 7, 1),
 
 AC97_SINGLE("Out3 Switch", AC97_AUX, 15, 1, 1),
-AC97_SINGLE("Out3 ZC Switch", AC97_AUX, 7, 1, 1),
+AC97_SINGLE("Out3 ZC Switch", AC97_AUX, 7, 1, 0),
 AC97_ENUM("Out3 Mux", wm9711_enum[2]),
 AC97_ENUM("Out3 LR Mux", wm9711_enum[3]),
 AC97_SINGLE("Out3 Volume", AC97_AUX, 0, 31, 1),
@@ -575,13 +575,14 @@ AC97_SINGLE("Playback Attenuate (-6dB) Switch", AC97_MASTER_TONE, 6, 1, 0),
 
 AC97_SINGLE("ADC Switch", AC97_REC_GAIN, 15, 1, 1),
 AC97_ENUM("Capture Volume Steps", wm9711_enum[6]),
-AC97_DOUBLE("Capture Volume", AC97_REC_GAIN, 8, 0, 15, 1),
+AC97_DOUBLE("Capture Volume", AC97_REC_GAIN, 8, 0, 63, 1),
 AC97_SINGLE("Capture ZC Switch", AC97_REC_GAIN, 7, 1, 0),
 
 AC97_SINGLE("Mic 1 to Phone Switch", AC97_MIC, 14, 1, 1),
 AC97_SINGLE("Mic 2 to Phone Switch", AC97_MIC, 13, 1, 1),
 AC97_ENUM("Mic Select Source", wm9711_enum[7]),
-AC97_SINGLE("Mic 1 Volume", AC97_MIC, 8, 32, 1),
+AC97_SINGLE("Mic 1 Volume", AC97_MIC, 8, 31, 1),
+AC97_SINGLE("Mic 2 Volume", AC97_MIC, 0, 31, 1),
 AC97_SINGLE("Mic 20dB Boost Switch", AC97_MIC, 7, 1, 0),
 
 AC97_SINGLE("Master ZC Switch", AC97_MASTER, 7, 1, 0),
index 0786d0edaca5aef42a26c28c11915200f1a3bc98..cbf8331c3d336aab210b3acf886e44c5f8e2f4ea 100644 (file)
@@ -596,9 +596,7 @@ static struct snd_pcm_ops snd_ad1889_capture_ops = {
 };
 
 static irqreturn_t
-snd_ad1889_interrupt(int irq, 
-                    void *dev_id, 
-                    struct pt_regs *regs)
+snd_ad1889_interrupt(int irq, void *dev_id)
 {
        unsigned long st;
        struct snd_ad1889 *chip = dev_id;
index 74668398eac5da125b790cf5fe3cf5d7325f9ab0..a7edd56542d4f571b27c93ffee5a868204a6e216 100644 (file)
@@ -1047,9 +1047,7 @@ static void snd_ali_interrupt(struct snd_ali * codec)
 }
 
 
-static irqreturn_t snd_ali_card_interrupt(int irq,
-                                  void *dev_id,
-                                  struct pt_regs *regs)
+static irqreturn_t snd_ali_card_interrupt(int irq, void *dev_id)
 {
        struct snd_ali  *codec = dev_id;
 
@@ -2034,8 +2032,10 @@ static int ali_suspend(struct pci_dev *pci, pm_message_t state)
        outl(0xffffffff, ALI_REG(chip, ALI_STOP));
 
        spin_unlock_irq(&chip->reg_lock);
+
        pci_disable_device(pci);
        pci_save_state(pci);
+       pci_set_power_state(pci, pci_choose_state(pci, state));
        return 0;
 }
 
@@ -2050,8 +2050,15 @@ static int ali_resume(struct pci_dev *pci)
        if (! im)
                return 0;
 
+       pci_set_power_state(pci, PCI_D0);
        pci_restore_state(pci);
-       pci_enable_device(pci);
+       if (pci_enable_device(pci) < 0) {
+               printk(KERN_ERR "ali5451: pci_enable_device failed, "
+                      "disabling device\n");
+               snd_card_disconnect(card);
+               return -EIO;
+       }
+       pci_set_master(pci);
 
        spin_lock_irq(&chip->reg_lock);
        
index 96cfb8ae5055441020e6a81cf4ce5336d4131e1b..95f70f3cc37eb9621f24651b51db19d367caade2 100644 (file)
@@ -204,8 +204,7 @@ static int snd_als300_dev_free(struct snd_device *device)
        return snd_als300_free(chip);
 }
 
-static irqreturn_t snd_als300_interrupt(int irq, void *dev_id,
-                                               struct pt_regs *regs)
+static irqreturn_t snd_als300_interrupt(int irq, void *dev_id)
 {
        u8 status;
        struct snd_als300 *chip = dev_id;
@@ -236,8 +235,7 @@ static irqreturn_t snd_als300_interrupt(int irq, void *dev_id,
        return IRQ_HANDLED;
 }
 
-static irqreturn_t snd_als300plus_interrupt(int irq, void *dev_id,
-                                               struct pt_regs *regs)
+static irqreturn_t snd_als300plus_interrupt(int irq, void *dev_id)
 {
        u8 general, mpu, dram;
        struct snd_als300 *chip = dev_id;
@@ -770,9 +768,9 @@ static int snd_als300_suspend(struct pci_dev *pci, pm_message_t state)
        snd_pcm_suspend_all(chip->pcm);
        snd_ac97_suspend(chip->ac97);
 
-       pci_set_power_state(pci, PCI_D3hot);
        pci_disable_device(pci);
        pci_save_state(pci);
+       pci_set_power_state(pci, pci_choose_state(pci, state));
        return 0;
 }
 
@@ -781,9 +779,14 @@ static int snd_als300_resume(struct pci_dev *pci)
        struct snd_card *card = pci_get_drvdata(pci);
        struct snd_als300 *chip = card->private_data;
 
-       pci_restore_state(pci);
-       pci_enable_device(pci);
        pci_set_power_state(pci, PCI_D0);
+       pci_restore_state(pci);
+       if (pci_enable_device(pci) < 0) {
+               printk(KERN_ERR "als300: pci_enable_device failed, "
+                      "disabling device\n");
+               snd_card_disconnect(card);
+               return -EIO;
+       }
        pci_set_master(pci);
 
        snd_als300_init(chip);
index 9e596f750cbd1825c8ebd47ed94aff597daf9604..8fb55d3b454be4038fff919b1925355f72f4c9ce 100644 (file)
@@ -385,7 +385,7 @@ static snd_pcm_uframes_t snd_als4000_playback_pointer(struct snd_pcm_substream *
  * SB IRQ status.
  * And do we *really* need the lock here for *reading* SB_DSP4_IRQSTATUS??
  * */
-static irqreturn_t snd_als4000_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t snd_als4000_interrupt(int irq, void *dev_id)
 {
        struct snd_sb *chip = dev_id;
        unsigned gcr_status;
@@ -399,7 +399,7 @@ static irqreturn_t snd_als4000_interrupt(int irq, void *dev_id, struct pt_regs *
        if ((gcr_status & 0x40) && (chip->capture_substream)) /* capturing */
                snd_pcm_period_elapsed(chip->capture_substream);
        if ((gcr_status & 0x10) && (chip->rmidi)) /* MPU401 interrupt */
-               snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data, regs);
+               snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data);
        /* release the gcr */
        outb(gcr_status, chip->alt_port + 0xe);
        
@@ -804,9 +804,9 @@ static int snd_als4000_suspend(struct pci_dev *pci, pm_message_t state)
        snd_pcm_suspend_all(chip->pcm);
        snd_sbmixer_suspend(chip);
 
-       pci_set_power_state(pci, PCI_D3hot);
        pci_disable_device(pci);
        pci_save_state(pci);
+       pci_set_power_state(pci, pci_choose_state(pci, state));
        return 0;
 }
 
@@ -816,9 +816,14 @@ static int snd_als4000_resume(struct pci_dev *pci)
        struct snd_card_als4000 *acard = card->private_data;
        struct snd_sb *chip = acard->chip;
 
-       pci_restore_state(pci);
-       pci_enable_device(pci);
        pci_set_power_state(pci, PCI_D0);
+       pci_restore_state(pci);
+       if (pci_enable_device(pci) < 0) {
+               printk(KERN_ERR "als4000: pci_enable_device failed, "
+                      "disabling device\n");
+               snd_card_disconnect(card);
+               return -EIO;
+       }
        pci_set_master(pci);
 
        snd_als4000_configure(chip);
index 347e25ff073dba9e5af492908f2a9190f1473413..e3e99f396711edecb7b0f06578ff40776488858c 100644 (file)
@@ -1300,7 +1300,7 @@ static int __devinit snd_atiixp_pcm_new(struct atiixp *chip)
 /*
  * interrupt handler
  */
-static irqreturn_t snd_atiixp_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t snd_atiixp_interrupt(int irq, void *dev_id)
 {
        struct atiixp *chip = dev_id;
        unsigned int status;
@@ -1442,9 +1442,9 @@ static int snd_atiixp_suspend(struct pci_dev *pci, pm_message_t state)
        snd_atiixp_aclink_down(chip);
        snd_atiixp_chip_stop(chip);
 
-       pci_set_power_state(pci, PCI_D3hot);
        pci_disable_device(pci);
        pci_save_state(pci);
+       pci_set_power_state(pci, pci_choose_state(pci, state));
        return 0;
 }
 
@@ -1454,9 +1454,14 @@ static int snd_atiixp_resume(struct pci_dev *pci)
        struct atiixp *chip = card->private_data;
        int i;
 
-       pci_restore_state(pci);
-       pci_enable_device(pci);
        pci_set_power_state(pci, PCI_D0);
+       pci_restore_state(pci);
+       if (pci_enable_device(pci) < 0) {
+               printk(KERN_ERR "atiixp: pci_enable_device failed, "
+                      "disabling device\n");
+               snd_card_disconnect(card);
+               return -EIO;
+       }
        pci_set_master(pci);
 
        snd_atiixp_aclink_reset(chip);
index a89d67c4598ba410d6bcf3a0ef94dbf76624e332..dc54f2c68ed7a4fbaf3ba03415c932caa325bb3c 100644 (file)
@@ -1017,7 +1017,7 @@ static int __devinit snd_atiixp_pcm_new(struct atiixp_modem *chip)
 /*
  * interrupt handler
  */
-static irqreturn_t snd_atiixp_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t snd_atiixp_interrupt(int irq, void *dev_id)
 {
        struct atiixp_modem *chip = dev_id;
        unsigned int status;
@@ -1128,9 +1128,9 @@ static int snd_atiixp_suspend(struct pci_dev *pci, pm_message_t state)
        snd_atiixp_aclink_down(chip);
        snd_atiixp_chip_stop(chip);
 
-       pci_set_power_state(pci, PCI_D3hot);
        pci_disable_device(pci);
        pci_save_state(pci);
+       pci_set_power_state(pci, pci_choose_state(pci, state));
        return 0;
 }
 
@@ -1140,9 +1140,14 @@ static int snd_atiixp_resume(struct pci_dev *pci)
        struct atiixp_modem *chip = card->private_data;
        int i;
 
-       pci_restore_state(pci);
-       pci_enable_device(pci);
        pci_set_power_state(pci, PCI_D0);
+       pci_restore_state(pci);
+       if (pci_enable_device(pci) < 0) {
+               printk(KERN_ERR "atiixp-modem: pci_enable_device failed, "
+                      "disabling device\n");
+               snd_card_disconnect(card);
+               return -EIO;
+       }
        pci_set_master(pci);
 
        snd_atiixp_aclink_reset(chip);
index ef189d7f09d387bad1ce3f85e70bc15284565d88..6ed5ad59f5b5c5051bb17f7762b2f2b46da6d360 100644 (file)
@@ -128,6 +128,7 @@ static int snd_vortex_dev_free(struct snd_device *device)
        // Take down PCI interface.
        synchronize_irq(vortex->irq);
        free_irq(vortex->irq, vortex);
+       iounmap(vortex->mmio);
        pci_release_regions(vortex->pci_dev);
        pci_disable_device(vortex->pci_dev);
        kfree(vortex);
index b1cfc3c79d07e6ad4bc8a2cf12dcc3136afeb3ce..5ccf0b1ec670f7ed27baecc1f96ece3a9c11c335 100644 (file)
@@ -236,8 +236,7 @@ static void vortex_spdif_init(vortex_t * vortex, int spdif_sr, int spdif_mode);
 static int vortex_core_init(vortex_t * card);
 static int vortex_core_shutdown(vortex_t * card);
 static void vortex_enable_int(vortex_t * card);
-static irqreturn_t vortex_interrupt(int irq, void *dev_id,
-                                   struct pt_regs *regs);
+static irqreturn_t vortex_interrupt(int irq, void *dev_id);
 static int vortex_alsafmt_aspfmt(int alsafmt);
 
 /* Connection  stuff. */
index 5299cce583d357a18aca34f832cfa56011bf46ce..4a336eaae9d21eda656c88a08cf12a187697e0d0 100644 (file)
@@ -2385,7 +2385,7 @@ static void vortex_disable_int(vortex_t * card)
                hwread(card->mmio, VORTEX_CTRL) & ~CTRL_IRQ_ENABLE);
 }
 
-static irqreturn_t vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t vortex_interrupt(int irq, void *dev_id)
 {
        vortex_t *vortex = dev_id;
        int i, handled;
@@ -2462,7 +2462,7 @@ static irqreturn_t vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        }
        if (source & IRQ_MIDI) {
                snd_mpu401_uart_interrupt(vortex->irq,
-                                         vortex->rmidi->private_data, regs);
+                                         vortex->rmidi->private_data);
                handled = 1;
        }
 
index bac8e9cfd9218c3856f22021726eae1833959d22..2414ee6307565861c872b0b498f518d1c959ca3c 100644 (file)
@@ -1191,7 +1191,7 @@ snd_azf3328_capture_pointer(struct snd_pcm_substream *substream)
 }
 
 static irqreturn_t
-snd_azf3328_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+snd_azf3328_interrupt(int irq, void *dev_id)
 {
        struct snd_azf3328 *chip = dev_id;
        u8 status, which;
@@ -1256,7 +1256,7 @@ snd_azf3328_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        /* MPU401 has less critical IRQ requirements
         * than timer and playback/recording, right? */
        if (status & IRQ_MPU401) {
-               snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data, regs);
+               snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data);
 
                /* hmm, do we have to ack the IRQ here somehow?
                 * If so, then I don't know how... */
@@ -1903,9 +1903,9 @@ snd_azf3328_suspend(struct pci_dev *pci, pm_message_t state)
        for (reg = 0; reg < AZF_IO_SIZE_SYNTH_PM / 2; reg++)
                chip->saved_regs_synth[reg] = inw(chip->synth_port + reg * 2);
 
-       pci_set_power_state(pci, PCI_D3hot);
        pci_disable_device(pci);
        pci_save_state(pci);
+       pci_set_power_state(pci, pci_choose_state(pci, state));
        return 0;
 }
 
@@ -1916,9 +1916,14 @@ snd_azf3328_resume(struct pci_dev *pci)
        struct snd_azf3328 *chip = card->private_data;
        int reg;
 
-       pci_restore_state(pci);
-       pci_enable_device(pci);
        pci_set_power_state(pci, PCI_D0);
+       pci_restore_state(pci);
+       if (pci_enable_device(pci) < 0) {
+               printk(KERN_ERR "azt3328: pci_enable_device failed, "
+                      "disabling device\n");
+               snd_card_disconnect(card);
+               return -EIO;
+       }
        pci_set_master(pci);
 
        for (reg = 0; reg < AZF_IO_SIZE_IO2_PM / 2; reg++)
index 97a280a246cb57002fa9028317c0660add7d7ac8..d33a37086df9afc4c5eaa40edcfacfc9ae931234 100644 (file)
@@ -269,7 +269,7 @@ static void snd_bt87x_pci_error(struct snd_bt87x *chip, unsigned int status)
        }
 }
 
-static irqreturn_t snd_bt87x_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t snd_bt87x_interrupt(int irq, void *dev_id)
 {
        struct snd_bt87x *chip = dev_id;
        unsigned int status, irq_status;
index 12bbbb6afd2df348df3526cf88a3da8a0a6bd7c0..6fa4a302f7de06d7371007b49a8109ea2a2d031b 100644 (file)
@@ -1058,8 +1058,7 @@ static int snd_ca0106_dev_free(struct snd_device *device)
        return snd_ca0106_free(chip);
 }
 
-static irqreturn_t snd_ca0106_interrupt(int irq, void *dev_id,
-                                         struct pt_regs *regs)
+static irqreturn_t snd_ca0106_interrupt(int irq, void *dev_id)
 {
        unsigned int status;
 
index 876b64464b6f2a6562aa5daecfedb355f0f96938..0093cd1f92db3ac352124dda27df0d9e42e6454a 100644 (file)
@@ -1294,7 +1294,7 @@ static int snd_cmipci_capture_spdif_hw_free(struct snd_pcm_substream *subs)
 /*
  * interrupt handler
  */
-static irqreturn_t snd_cmipci_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t snd_cmipci_interrupt(int irq, void *dev_id)
 {
        struct cmipci *cm = dev_id;
        unsigned int status, mask = 0;
@@ -1315,7 +1315,7 @@ static irqreturn_t snd_cmipci_interrupt(int irq, void *dev_id, struct pt_regs *r
        spin_unlock(&cm->reg_lock);
 
        if (cm->rmidi && (status & CM_UARTINT))
-               snd_mpu401_uart_interrupt(irq, cm->rmidi->private_data, regs);
+               snd_mpu401_uart_interrupt(irq, cm->rmidi->private_data);
 
        if (cm->pcm) {
                if ((status & CM_CHINT0) && cm->channel[0].running)
@@ -3122,9 +3122,9 @@ static int snd_cmipci_suspend(struct pci_dev *pci, pm_message_t state)
        /* disable ints */
        snd_cmipci_write(cm, CM_REG_INT_HLDCLR, 0);
 
-       pci_set_power_state(pci, PCI_D3hot);
        pci_disable_device(pci);
        pci_save_state(pci);
+       pci_set_power_state(pci, pci_choose_state(pci, state));
        return 0;
 }
 
@@ -3134,9 +3134,14 @@ static int snd_cmipci_resume(struct pci_dev *pci)
        struct cmipci *cm = card->private_data;
        int i;
 
-       pci_restore_state(pci);
-       pci_enable_device(pci);
        pci_set_power_state(pci, PCI_D0);
+       pci_restore_state(pci);
+       if (pci_enable_device(pci) < 0) {
+               printk(KERN_ERR "cmipci: pci_enable_device failed, "
+                      "disabling device\n");
+               snd_card_disconnect(card);
+               return -EIO;
+       }
        pci_set_master(pci);
 
        /* reset / initialize to a sane state */
index 1990430a21c1d08ca61a69577b9272508300519b..0905fa88129dde9a9550dba00b776082e2d02893 100644 (file)
@@ -493,7 +493,7 @@ struct cs4281 {
 
 };
 
-static irqreturn_t snd_cs4281_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t snd_cs4281_interrupt(int irq, void *dev_id);
 
 static struct pci_device_id snd_cs4281_ids[] = {
        { 0x1013, 0x6005, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },   /* CS4281 */
@@ -1814,7 +1814,7 @@ static int __devinit snd_cs4281_midi(struct cs4281 * chip, int device,
  *  Interrupt handler
  */
 
-static irqreturn_t snd_cs4281_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t snd_cs4281_interrupt(int irq, void *dev_id)
 {
        struct cs4281 *chip = dev_id;
        unsigned int status, dma, val;
@@ -2050,6 +2050,7 @@ static int cs4281_suspend(struct pci_dev *pci, pm_message_t state)
 
        pci_disable_device(pci);
        pci_save_state(pci);
+       pci_set_power_state(pci, pci_choose_state(pci, state));
        return 0;
 }
 
@@ -2060,8 +2061,14 @@ static int cs4281_resume(struct pci_dev *pci)
        unsigned int i;
        u32 ulCLK;
 
+       pci_set_power_state(pci, PCI_D0);
        pci_restore_state(pci);
-       pci_enable_device(pci);
+       if (pci_enable_device(pci) < 0) {
+               printk(KERN_ERR "cs4281: pci_enable_device failed, "
+                      "disabling device\n");
+               snd_card_disconnect(card);
+               return -EIO;
+       }
        pci_set_master(pci);
 
        ulCLK = snd_cs4281_peekBA0(chip, BA0_CLKCR1);
index 4851847180d24c3bb33041b7d3df2b1d34b9dd9c..2807b9756ef09d96e2f48646084d201aa7daefd0 100644 (file)
@@ -1149,7 +1149,7 @@ static int snd_cs46xx_capture_prepare(struct snd_pcm_substream *substream)
        return 0;
 }
 
-static irqreturn_t snd_cs46xx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t snd_cs46xx_interrupt(int irq, void *dev_id)
 {
        struct snd_cs46xx *chip = dev_id;
        u32 status1;
@@ -3687,8 +3687,10 @@ int snd_cs46xx_suspend(struct pci_dev *pci, pm_message_t state)
        /* disable CLKRUN */
        chip->active_ctrl(chip, -chip->amplifier);
        chip->amplifier = amp_saved; /* restore the status */
+
        pci_disable_device(pci);
        pci_save_state(pci);
+       pci_set_power_state(pci, pci_choose_state(pci, state));
        return 0;
 }
 
@@ -3698,9 +3700,16 @@ int snd_cs46xx_resume(struct pci_dev *pci)
        struct snd_cs46xx *chip = card->private_data;
        int amp_saved;
 
+       pci_set_power_state(pci, PCI_D0);
        pci_restore_state(pci);
-       pci_enable_device(pci);
+       if (pci_enable_device(pci) < 0) {
+               printk(KERN_ERR "cs46xx: pci_enable_device failed, "
+                      "disabling device\n");
+               snd_card_disconnect(card);
+               return -EIO;
+       }
        pci_set_master(pci);
+
        amp_saved = chip->amplifier;
        chip->amplifier = 0;
        chip->active_ctrl(chip, 1); /* force to on */
index 64c7826e8b8c694899f9fbfeb474a4da383b8d17..2441238f2004ab40e94e1e160c8176e00407e06e 100644 (file)
@@ -203,8 +203,7 @@ static void process_bm1_irq(struct cs5535audio *cs5535au)
        }
 }
 
-static irqreturn_t snd_cs5535audio_interrupt(int irq, void *dev_id,
-                                            struct pt_regs *regs)
+static irqreturn_t snd_cs5535audio_interrupt(int irq, void *dev_id)
 {
        u16 acc_irq_stat;
        u8 bm_stat;
index aad0e69db9c1aed2d2cb40051957d1e01e0f6776..3e4d198a4502dca0fc7def2652fe55369e9cfb4e 100644 (file)
@@ -73,9 +73,10 @@ int snd_cs5535audio_suspend(struct pci_dev *pci, pm_message_t state)
        snd_ac97_suspend(cs5535au->ac97);
        /* save important regs, then disable aclink in hw */
        snd_cs5535audio_stop_hardware(cs5535au);
+
        pci_disable_device(pci);
        pci_save_state(pci);
-
+       pci_set_power_state(pci, pci_choose_state(pci, state));
        return 0;
 }
 
@@ -87,8 +88,14 @@ int snd_cs5535audio_resume(struct pci_dev *pci)
        int timeout;
        int i;
 
+       pci_set_power_state(pci, PCI_D0);
        pci_restore_state(pci);
-       pci_enable_device(pci);
+       if (pci_enable_device(pci) < 0) {
+               printk(KERN_ERR "cs5535audio: pci_enable_device failed, "
+                      "disabling device\n");
+               snd_card_disconnect(card);
+               return -EIO;
+       }
        pci_set_master(pci);
 
        /* set LNK_WRM_RST to reset AC link */
index c3dafa29054f96c618c1c824830ec06623c47014..e5e88fe54de05d416ac39f1910f0dc9c9a83aa6c 100644 (file)
@@ -1818,8 +1818,7 @@ static struct snd_kcontrol_new snd_echo_channels_info __devinitdata = {
        IRQ Handler
 ******************************************************************************/
 
-static irqreturn_t snd_echo_interrupt(int irq, void *dev_id,
-                                     struct pt_regs *regs)
+static irqreturn_t snd_echo_interrupt(int irq, void *dev_id)
 {
        struct echoaudio *chip = dev_id;
        struct snd_pcm_substream *substream;
index 493ec0816bb3f29afab2792add265279e9d03f38..55caf341933adc608d477ab27f61b38043e27c03 100644 (file)
@@ -226,9 +226,9 @@ static int snd_emu10k1_suspend(struct pci_dev *pci, pm_message_t state)
 
        snd_emu10k1_done(emu);
 
-       pci_set_power_state(pci, PCI_D3hot);
        pci_disable_device(pci);
        pci_save_state(pci);
+       pci_set_power_state(pci, pci_choose_state(pci, state));
        return 0;
 }
 
@@ -237,11 +237,16 @@ static int snd_emu10k1_resume(struct pci_dev *pci)
        struct snd_card *card = pci_get_drvdata(pci);
        struct snd_emu10k1 *emu = card->private_data;
 
-       pci_restore_state(pci);
-       pci_enable_device(pci);
        pci_set_power_state(pci, PCI_D0);
+       pci_restore_state(pci);
+       if (pci_enable_device(pci) < 0) {
+               printk(KERN_ERR "emu10k1: pci_enable_device failed, "
+                      "disabling device\n");
+               snd_card_disconnect(card);
+               return -EIO;
+       }
        pci_set_master(pci);
-       
+
        snd_emu10k1_resume_init(emu);
        snd_emu10k1_efx_resume(emu);
        snd_ac97_resume(emu->ac97);
index be65d4db8e2770ff3defdb1f17bfd5a5f6d4ed3e..8058059c56e9b70ebc716196d996b45a0ea0af6b 100644 (file)
@@ -1461,8 +1461,8 @@ void snd_emu10k1_resume_regs(struct snd_emu10k1 *emu)
 
        /* resore for spdif */
        if (emu->audigy)
-               outl(emu->port + A_IOCFG, emu->saved_a_iocfg);
-       outl(emu->port + HCFG, emu->saved_hcfg);
+               outl(emu->saved_a_iocfg, emu->port + A_IOCFG);
+       outl(emu->saved_hcfg, emu->port + HCFG);
 
        val = emu->saved_ptr;
        for (reg = saved_regs; *reg != 0xff; reg++)
index da1610a571b8c5cd5db1a0ebf131e59570d2f030..c46905a111753b3774d487018852af7318856b39 100644 (file)
@@ -780,8 +780,7 @@ static int snd_emu10k1x_dev_free(struct snd_device *device)
        return snd_emu10k1x_free(chip);
 }
 
-static irqreturn_t snd_emu10k1x_interrupt(int irq, void *dev_id,
-                                         struct pt_regs *regs)
+static irqreturn_t snd_emu10k1x_interrupt(int irq, void *dev_id)
 {
        unsigned int status;
 
index 1076af4c36696cf2572fe5f1c8b034639c43905f..4f18f7e8bcfb11842bc261d14c5238979c65985e 100644 (file)
@@ -30,7 +30,7 @@
 #include <sound/core.h>
 #include <sound/emu10k1.h>
 
-irqreturn_t snd_emu10k1_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t snd_emu10k1_interrupt(int irq, void *dev_id)
 {
        struct snd_emu10k1 *emu = dev_id;
        unsigned int status, status2, orig_status, orig_status2;
index a8a601fc781f9ca44b10a036ae9a3d48bb550487..d2a811f222c926b4549dda3e8b3b07ebc04a3357 100644 (file)
@@ -444,7 +444,7 @@ struct ensoniq {
 #endif
 };
 
-static irqreturn_t snd_audiopci_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t snd_audiopci_interrupt(int irq, void *dev_id);
 
 static struct pci_device_id snd_audiopci_ids[] = {
 #ifdef CHIP1370
@@ -2072,9 +2072,10 @@ static int snd_ensoniq_suspend(struct pci_dev *pci, pm_message_t state)
        udelay(100);
        snd_ak4531_suspend(ensoniq->u.es1370.ak4531);
 #endif 
-       pci_set_power_state(pci, PCI_D3hot);
+
        pci_disable_device(pci);
        pci_save_state(pci);
+       pci_set_power_state(pci, pci_choose_state(pci, state));
        return 0;
 }
 
@@ -2083,9 +2084,14 @@ static int snd_ensoniq_resume(struct pci_dev *pci)
        struct snd_card *card = pci_get_drvdata(pci);
        struct ensoniq *ensoniq = card->private_data;
 
-       pci_restore_state(pci);
-       pci_enable_device(pci);
        pci_set_power_state(pci, PCI_D0);
+       pci_restore_state(pci);
+       if (pci_enable_device(pci) < 0) {
+               printk(KERN_ERR DRIVER_NAME ": pci_enable_device failed, "
+                      "disabling device\n");
+               snd_card_disconnect(card);
+               return -EIO;
+       }
        pci_set_master(pci);
 
        snd_ensoniq_chip_init(ensoniq);
@@ -2404,7 +2410,7 @@ static int __devinit snd_ensoniq_midi(struct ensoniq * ensoniq, int device,
  *  Interrupt handler
  */
 
-static irqreturn_t snd_audiopci_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t snd_audiopci_interrupt(int irq, void *dev_id)
 {
        struct ensoniq *ensoniq = dev_id;
        unsigned int status, sctrl;
index 3ce5a4e7e31f383e34a25cd633d508844d64f98f..1a8d36df4b5dab6d102cb87c879c43106afa3edf 100644 (file)
@@ -241,7 +241,7 @@ struct es1938 {
 #endif
 };
 
-static irqreturn_t snd_es1938_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t snd_es1938_interrupt(int irq, void *dev_id);
 
 static struct pci_device_id snd_es1938_ids[] = {
         { 0x125d, 0x1969, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },   /* Solo-1 */
@@ -1481,10 +1481,14 @@ static int es1938_suspend(struct pci_dev *pci, pm_message_t state)
                *d = snd_es1938_reg_read(chip, *s);
 
        outb(0x00, SLIO_REG(chip, IRQCONTROL)); /* disable irqs */
-       if (chip->irq >= 0)
+       if (chip->irq >= 0) {
+               synchronize_irq(chip->irq);
                free_irq(chip->irq, chip);
+               chip->irq = -1;
+       }
        pci_disable_device(pci);
        pci_save_state(pci);
+       pci_set_power_state(pci, pci_choose_state(pci, state));
        return 0;
 }
 
@@ -1494,10 +1498,22 @@ static int es1938_resume(struct pci_dev *pci)
        struct es1938 *chip = card->private_data;
        unsigned char *s, *d;
 
+       pci_set_power_state(pci, PCI_D0);
        pci_restore_state(pci);
-       pci_enable_device(pci);
-       request_irq(pci->irq, snd_es1938_interrupt,
-                   IRQF_DISABLED|IRQF_SHARED, "ES1938", chip);
+       if (pci_enable_device(pci) < 0) {
+               printk(KERN_ERR "es1938: pci_enable_device failed, "
+                      "disabling device\n");
+               snd_card_disconnect(card);
+               return -EIO;
+       }
+
+       if (request_irq(pci->irq, snd_es1938_interrupt,
+                       IRQF_DISABLED|IRQF_SHARED, "ES1938", chip)) {
+               printk(KERN_ERR "es1938: unable to grab IRQ %d, "
+                      "disabling device\n", pci->irq);
+               snd_card_disconnect(card);
+               return -EIO;
+       }
        chip->irq = pci->irq;
        snd_es1938_chip_init(chip);
 
@@ -1556,8 +1572,10 @@ static int snd_es1938_free(struct es1938 *chip)
 
        snd_es1938_free_gameport(chip);
 
-       if (chip->irq >= 0)
+       if (chip->irq >= 0) {
+               synchronize_irq(chip->irq);
                free_irq(chip->irq, chip);
+       }
        pci_release_regions(chip->pci);
        pci_disable_device(chip->pci);
        kfree(chip);
@@ -1602,6 +1620,7 @@ static int __devinit snd_es1938_create(struct snd_card *card,
        spin_lock_init(&chip->mixer_lock);
        chip->card = card;
        chip->pci = pci;
+       chip->irq = -1;
        if ((err = pci_request_regions(pci, "ESS Solo-1")) < 0) {
                kfree(chip);
                pci_disable_device(pci);
@@ -1642,7 +1661,7 @@ static int __devinit snd_es1938_create(struct snd_card *card,
 /* --------------------------------------------------------------------
  * Interrupt handler
  * -------------------------------------------------------------------- */
-static irqreturn_t snd_es1938_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t snd_es1938_interrupt(int irq, void *dev_id)
 {
        struct es1938 *chip = dev_id;
        unsigned char status, audiostatus;
@@ -1714,7 +1733,7 @@ static irqreturn_t snd_es1938_interrupt(int irq, void *dev_id, struct pt_regs *r
                // snd_es1938_mixer_bits(chip, ESSSB_IREG_MPU401CONTROL, 0x40, 0); /* ack? */
                if (chip->rmidi) {
                        handled = 1;
-                       snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data, regs);
+                       snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data);
                }
        }
        return IRQ_RETVAL(handled);
index f3c40385c87d4a26d63e61291caa9e9071c0252e..092da53e1464688d877cc1c0a6979fe0fa5258c4 100644 (file)
@@ -432,46 +432,6 @@ MODULE_PARM_DESC(joystick, "Enable joystick.");
 #define ESM_MODE_PLAY          0
 #define ESM_MODE_CAPTURE       1
 
-/* acpi states */
-enum {
-       ACPI_D0=0,
-       ACPI_D1,
-       ACPI_D2,
-       ACPI_D3
-};
-
-/* bits in the acpi masks */
-#define ACPI_12MHZ     ( 1 << 15)
-#define ACPI_24MHZ     ( 1 << 14)
-#define ACPI_978       ( 1 << 13)
-#define ACPI_SPDIF     ( 1 << 12)
-#define ACPI_GLUE      ( 1 << 11)
-#define ACPI__10       ( 1 << 10) /* reserved */
-#define ACPI_PCIINT    ( 1 << 9)
-#define ACPI_HV                ( 1 << 8) /* hardware volume */
-#define ACPI_GPIO      ( 1 << 7)
-#define ACPI_ASSP      ( 1 << 6)
-#define ACPI_SB                ( 1 << 5) /* sb emul */
-#define ACPI_FM                ( 1 << 4) /* fm emul */
-#define ACPI_RB                ( 1 << 3) /* ringbus / aclink */
-#define ACPI_MIDI      ( 1 << 2) 
-#define ACPI_GP                ( 1 << 1) /* game port */
-#define ACPI_WP                ( 1 << 0) /* wave processor */
-
-#define ACPI_ALL       (0xffff)
-#define ACPI_SLEEP     (~(ACPI_SPDIF|ACPI_ASSP|ACPI_SB|ACPI_FM| \
-                       ACPI_MIDI|ACPI_GP|ACPI_WP))
-#define ACPI_NONE      (ACPI__10)
-
-/* these masks indicate which units we care about at
-       which states */
-static u16 acpi_state_mask[] = {
-       [ACPI_D0] = ACPI_ALL,
-       [ACPI_D1] = ACPI_SLEEP,
-       [ACPI_D2] = ACPI_SLEEP,
-       [ACPI_D3] = ACPI_NONE
-};
-
 
 /* APU use in the driver */
 enum snd_enum_apu_type {
@@ -590,7 +550,7 @@ struct es1968 {
 #endif
 };
 
-static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id);
 
 static struct pci_device_id snd_es1968_ids[] = {
        /* Maestro 1 */
@@ -1962,7 +1922,7 @@ static void es1968_update_hw_volume(unsigned long private_data)
 /*
  * interrupt handler
  */
-static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id)
 {
        struct es1968 *chip = dev_id;
        u32 event;
@@ -1979,7 +1939,7 @@ static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id, struct pt_regs *r
        outb(0xFF, chip->io_port + 0x1A);
 
        if ((event & ESM_MPU401_IRQ) && chip->rmidi) {
-               snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data, regs);
+               snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data);
        }
 
        if (event & ESM_SOUND_IRQ) {
@@ -2159,21 +2119,6 @@ static void snd_es1968_reset(struct es1968 *chip)
        udelay(10);
 }
 
-/*
- * power management
- */
-static void snd_es1968_set_acpi(struct es1968 *chip, int state)
-{
-       u16 active_mask = acpi_state_mask[state];
-
-       pci_set_power_state(chip->pci, state);
-       /* make sure the units we care about are on 
-               XXX we might want to do this before state flipping? */
-       pci_write_config_word(chip->pci, 0x54, ~ active_mask);
-       pci_write_config_word(chip->pci, 0x56, ~ active_mask);
-}
-
-
 /*
  * initialize maestro chip
  */
@@ -2196,9 +2141,6 @@ static void snd_es1968_chip_init(struct es1968 *chip)
         * IRQs.
         */
        
-       /* do config work at full power */
-       snd_es1968_set_acpi(chip, ACPI_D0);
-
        /* Config Reg A */
        pci_read_config_word(pci, ESM_CONFIG_A, &w);
 
@@ -2397,9 +2339,10 @@ static int es1968_suspend(struct pci_dev *pci, pm_message_t state)
        snd_pcm_suspend_all(chip->pcm);
        snd_ac97_suspend(chip->ac97);
        snd_es1968_bob_stop(chip);
-       snd_es1968_set_acpi(chip, ACPI_D3);
+
        pci_disable_device(pci);
        pci_save_state(pci);
+       pci_set_power_state(pci, pci_choose_state(pci, state));
        return 0;
 }
 
@@ -2413,9 +2356,16 @@ static int es1968_resume(struct pci_dev *pci)
                return 0;
 
        /* restore all our config */
+       pci_set_power_state(pci, PCI_D0);
        pci_restore_state(pci);
-       pci_enable_device(pci);
+       if (pci_enable_device(pci) < 0) {
+               printk(KERN_ERR "es1968: pci_enable_device failed, "
+                      "disabling device\n");
+               snd_card_disconnect(card);
+               return -EIO;
+       }
        pci_set_master(pci);
+
        snd_es1968_chip_init(chip);
 
        /* need to restore the base pointers.. */ 
@@ -2514,7 +2464,6 @@ static int snd_es1968_free(struct es1968 *chip)
        if (chip->irq >= 0)
                free_irq(chip->irq, (void *)chip);
        snd_es1968_free_gameport(chip);
-       snd_es1968_set_acpi(chip, ACPI_D3);
        chip->master_switch = NULL;
        chip->master_volume = NULL;
        pci_release_regions(chip->pci);
index bdfda1997d5b2baf24f1856615e10cd739d9242e..77e3d5c1830201b206768ea1e84092e71a107bc1 100644 (file)
@@ -520,7 +520,7 @@ static snd_pcm_uframes_t snd_fm801_capture_pointer(struct snd_pcm_substream *sub
        return bytes_to_frames(substream->runtime, ptr);
 }
 
-static irqreturn_t snd_fm801_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t snd_fm801_interrupt(int irq, void *dev_id)
 {
        struct fm801 *chip = dev_id;
        unsigned short status;
@@ -561,7 +561,7 @@ static irqreturn_t snd_fm801_interrupt(int irq, void *dev_id, struct pt_regs *re
                snd_pcm_period_elapsed(chip->capture_substream);
        }
        if (chip->rmidi && (status & FM801_IRQ_MPU))
-               snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data, regs);
+               snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data);
        if (status & FM801_IRQ_VOLUME)
                ;/* TODO */
 
@@ -1531,9 +1531,9 @@ static int snd_fm801_suspend(struct pci_dev *pci, pm_message_t state)
                chip->saved_regs[i] = inw(chip->port + saved_regs[i]);
        /* FIXME: tea575x suspend */
 
-       pci_set_power_state(pci, PCI_D3hot);
        pci_disable_device(pci);
        pci_save_state(pci);
+       pci_set_power_state(pci, pci_choose_state(pci, state));
        return 0;
 }
 
@@ -1543,9 +1543,14 @@ static int snd_fm801_resume(struct pci_dev *pci)
        struct fm801 *chip = card->private_data;
        int i;
 
-       pci_restore_state(pci);
-       pci_enable_device(pci);
        pci_set_power_state(pci, PCI_D0);
+       pci_restore_state(pci);
+       if (pci_enable_device(pci) < 0) {
+               printk(KERN_ERR "fm801: pci_enable_device failed, "
+                      "disabling device\n");
+               snd_card_disconnect(card);
+               return -EIO;
+       }
        pci_set_master(pci);
 
        snd_fm801_chip_init(chip, 1);
index e9d4cb4d07e11e07dedef1c9086a7d28f3a3cbb7..0e292dc4fd872ca72a064d1ff3cd03377f3743d2 100644 (file)
@@ -86,6 +86,7 @@ MODULE_SUPPORTED_DEVICE("{{Intel, ICH6},"
                         "{ATI, SB450},"
                         "{ATI, SB600},"
                         "{ATI, RS600},"
+                        "{ATI, RS690},"
                         "{VIA, VT8251},"
                         "{VIA, VT8237A},"
                         "{SiS, SIS966},"
@@ -336,6 +337,7 @@ struct azx {
        unsigned int initialized :1;
        unsigned int single_cmd :1;
        unsigned int polling_mode :1;
+       unsigned int msi :1;
 };
 
 /* driver types */
@@ -396,6 +398,7 @@ static char *driver_short_names[] __devinitdata = {
  */
 #define upper_32bit(addr) (sizeof(addr) > 4 ? (u32)((addr) >> 32) : (u32)0)
 
+static int azx_acquire_irq(struct azx *chip, int do_disconnect);
 
 /*
  * Interface for HD codec
@@ -535,6 +538,18 @@ static unsigned int azx_rirb_get_response(struct hda_codec *codec)
                schedule_timeout_interruptible(1);
        } while (time_after_eq(timeout, jiffies));
 
+       if (chip->msi) {
+               snd_printk(KERN_WARNING "hda_intel: No response from codec, "
+                          "disabling MSI...\n");
+               free_irq(chip->irq, chip);
+               chip->irq = -1;
+               pci_disable_msi(chip->pci);
+               chip->msi = 0;
+               if (azx_acquire_irq(chip, 1) < 0)
+                       return -1;
+               goto again;
+       }
+
        if (!chip->polling_mode) {
                snd_printk(KERN_WARNING "hda_intel: azx_get_response timeout, "
                           "switching to polling mode...\n");
@@ -811,7 +826,7 @@ static void azx_init_chip(struct azx *chip)
 /*
  * interrupt handler
  */
-static irqreturn_t azx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t azx_interrupt(int irq, void *dev_id)
 {
        struct azx *chip = dev_id;
        struct azx_dev *azx_dev;
@@ -1363,6 +1378,20 @@ static int __devinit azx_init_stream(struct azx *chip)
        return 0;
 }
 
+static int azx_acquire_irq(struct azx *chip, int do_disconnect)
+{
+       if (request_irq(chip->pci->irq, azx_interrupt, IRQF_DISABLED|IRQF_SHARED,
+                       "HDA Intel", chip)) {
+               printk(KERN_ERR "hda-intel: unable to grab IRQ %d, "
+                      "disabling device\n", chip->pci->irq);
+               if (do_disconnect)
+                       snd_card_disconnect(chip->card);
+               return -1;
+       }
+       chip->irq = chip->pci->irq;
+       return 0;
+}
+
 
 #ifdef CONFIG_PM
 /*
@@ -1379,12 +1408,16 @@ static int azx_suspend(struct pci_dev *pci, pm_message_t state)
                snd_pcm_suspend_all(chip->pcm[i]);
        snd_hda_suspend(chip->bus, state);
        azx_free_cmd_io(chip);
-       if (chip->irq >= 0)
+       if (chip->irq >= 0) {
+               synchronize_irq(chip->irq);
                free_irq(chip->irq, chip);
-       if (!disable_msi)
+               chip->irq = -1;
+       }
+       if (chip->msi)
                pci_disable_msi(chip->pci);
        pci_disable_device(pci);
        pci_save_state(pci);
+       pci_set_power_state(pci, pci_choose_state(pci, state));
        return 0;
 }
 
@@ -1393,15 +1426,20 @@ static int azx_resume(struct pci_dev *pci)
        struct snd_card *card = pci_get_drvdata(pci);
        struct azx *chip = card->private_data;
 
+       pci_set_power_state(pci, PCI_D0);
        pci_restore_state(pci);
-       pci_enable_device(pci);
-       if (!disable_msi)
-               pci_enable_msi(pci);
-       /* FIXME: need proper error handling */
-       request_irq(pci->irq, azx_interrupt, IRQF_DISABLED|IRQF_SHARED,
-                   "HDA Intel", chip);
-       chip->irq = pci->irq;
+       if (pci_enable_device(pci) < 0) {
+               printk(KERN_ERR "hda-intel: pci_enable_device failed, "
+                      "disabling device\n");
+               snd_card_disconnect(card);
+               return -EIO;
+       }
        pci_set_master(pci);
+       if (chip->msi)
+               if (pci_enable_msi(pci) < 0)
+                       chip->msi = 0;
+       if (azx_acquire_irq(chip, 1) < 0)
+               return -EIO;
        azx_init_chip(chip);
        snd_hda_resume(chip->bus);
        snd_power_change_state(card, SNDRV_CTL_POWER_D0);
@@ -1431,15 +1469,14 @@ static int azx_free(struct azx *chip)
                /* disable position buffer */
                azx_writel(chip, DPLBASE, 0);
                azx_writel(chip, DPUBASE, 0);
-
-               synchronize_irq(chip->irq);
        }
 
        if (chip->irq >= 0) {
+               synchronize_irq(chip->irq);
                free_irq(chip->irq, (void*)chip);
-               if (!disable_msi)
-                       pci_disable_msi(chip->pci);
        }
+       if (chip->msi)
+               pci_disable_msi(chip->pci);
        if (chip->remap_addr)
                iounmap(chip->remap_addr);
 
@@ -1494,6 +1531,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
        chip->pci = pci;
        chip->irq = -1;
        chip->driver_type = driver_type;
+       chip->msi = !disable_msi;
 
        chip->position_fix = position_fix;
        chip->single_cmd = single_cmd;
@@ -1523,16 +1561,14 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
                goto errout;
        }
 
-       if (!disable_msi)
-               pci_enable_msi(pci);
+       if (chip->msi)
+               if (pci_enable_msi(pci) < 0)
+                       chip->msi = 0;
 
-       if (request_irq(pci->irq, azx_interrupt, IRQF_DISABLED|IRQF_SHARED,
-                       "HDA Intel", (void*)chip)) {
-               snd_printk(KERN_ERR SFX "unable to grab IRQ %d\n", pci->irq);
+       if (azx_acquire_irq(chip, 0) < 0) {
                err = -EBUSY;
                goto errout;
        }
-       chip->irq = pci->irq;
 
        pci_set_master(pci);
        synchronize_irq(chip->irq);
@@ -1677,11 +1713,13 @@ static struct pci_device_id azx_ids[] = {
        { 0x1002, 0x437b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATI }, /* ATI SB450 */
        { 0x1002, 0x4383, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATI }, /* ATI SB600 */
        { 0x1002, 0x793b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATIHDMI }, /* ATI RS600 HDMI */
+       { 0x1002, 0x7919, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATIHDMI }, /* ATI RS690 HDMI */
        { 0x1106, 0x3288, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_VIA }, /* VIA VT8251/VT8237A */
        { 0x1039, 0x7502, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_SIS }, /* SIS966 */
        { 0x10b9, 0x5461, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ULI }, /* ULI M5461 */
        { 0x10de, 0x026c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA 026c */
        { 0x10de, 0x0371, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA 0371 */
+       { 0x10de, 0x03f0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA 03f0 */
        { 0, }
 };
 MODULE_DEVICE_TABLE(pci, azx_ids);
index 511df07fa2a3fdb2a0788ea965136817ff859dd8..edd22dec8286e0161b57a0ce4570bf060a572b3b 100644 (file)
@@ -818,6 +818,8 @@ static struct hda_board_config ad1986a_cfg_tbl[] = {
          .config = AD1986A_LAPTOP_EAPD }, /* ASUS A6J */
        { .pci_subvendor = 0x1043, .pci_subdevice = 0x11f7,
          .config = AD1986A_LAPTOP_EAPD }, /* ASUS U5A */
+       { .pci_subvendor = 0x1043, .pci_subdevice = 0x1263,
+         .config = AD1986A_LAPTOP_EAPD }, /* ASUS U5F */
        { .pci_subvendor = 0x1043, .pci_subdevice = 0x1297,
          .config = AD1986A_LAPTOP_EAPD }, /* ASUS Z62F */
        { .pci_subvendor = 0x103c, .pci_subdevice = 0x30af,
index a27440ffd1c87e313e1fcd770fc1c5bb5394ec8e..7333f275decdfc36b34ad5a090272b5c182d64b6 100644 (file)
@@ -161,5 +161,6 @@ static int patch_atihdmi(struct hda_codec *codec)
  */
 struct hda_codec_preset snd_hda_preset_atihdmi[] = {
        { .id = 0x1002793c, .name = "ATI RS600 HDMI", .patch = patch_atihdmi },
+       { .id = 0x1002791a, .name = "ATI RS690 HDMI", .patch = patch_atihdmi },
        {} /* terminator */
 };
index d08d2e399c8f19ca16cf90de79f9a187aeb48042..0d728c6f697c47c001b7672bb146757ffe3ec1a6 100644 (file)
@@ -1799,7 +1799,7 @@ static int alc_build_pcms(struct hda_codec *codec)
        /* SPDIF for stream index #1 */
        if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
                codec->num_pcms = 2;
-               info++;
+               info = spec->pcm_rec + 1;
                info->name = spec->stream_name_digital;
                if (spec->multiout.dig_out_nid &&
                    spec->stream_digital_playback) {
@@ -1820,7 +1820,7 @@ static int alc_build_pcms(struct hda_codec *codec)
        if (spec->num_adc_nids > 1 && spec->stream_analog_capture &&
            spec->adc_nids) {
                codec->num_pcms = 3;
-               info++;
+               info = spec->pcm_rec + 2;
                info->name = spec->stream_name_analog;
                /* No playback stream for second PCM */
                info->stream[SNDRV_PCM_STREAM_PLAYBACK] = alc_pcm_null_playback;
@@ -5076,6 +5076,10 @@ static struct hda_board_config alc883_cfg_tbl[] = {
        { .modelname = "acer", .config = ALC883_ACER },
        { .pci_subvendor = 0x1025, .pci_subdevice = 0/*0x0102*/,
          .config = ALC883_ACER },
+       { .pci_subvendor = 0x1025, .pci_subdevice = 0x0102,
+         .config = ALC883_ACER },
+       { .pci_subvendor = 0x1025, .pci_subdevice = 0x009f,
+         .config = ALC883_ACER },
        { .modelname = "auto", .config = ALC883_AUTO },
        {}
 };
index 76ec3d75fa9ea392f7c7a8d22ddad81d38920707..cc87dff1eb567feb1c942523d604e14b60b43a37 100644 (file)
@@ -297,8 +297,13 @@ static int patch_si3054(struct hda_codec *codec)
 struct hda_codec_preset snd_hda_preset_si3054[] = {
        { .id = 0x163c3055, .name = "Si3054", .patch = patch_si3054 },
        { .id = 0x163c3155, .name = "Si3054", .patch = patch_si3054 },
+       { .id = 0x11c11040, .name = "Si3054", .patch = patch_si3054 },
        { .id = 0x11c13026, .name = "Si3054", .patch = patch_si3054 },
+       { .id = 0x11c13055, .name = "Si3054", .patch = patch_si3054 },
+       { .id = 0x11c13155, .name = "Si3054", .patch = patch_si3054 },
+       { .id = 0x10573055, .name = "Si3054", .patch = patch_si3054 },
        { .id = 0x10573057, .name = "Si3054", .patch = patch_si3054 },
+       { .id = 0x10573155, .name = "Si3054", .patch = patch_si3054 },
        {}
 };
 
index dc69392eafa37bb4b38ba12622e150cd0bd69453..8a576b78bee529e30334b28a6c520f5cf7ecb2fd 100644 (file)
@@ -420,7 +420,7 @@ static void snd_ice1712_set_input_clock_source(struct snd_ice1712 *ice, int spdi
  *  Interrupt handler
  */
 
-static irqreturn_t snd_ice1712_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t snd_ice1712_interrupt(int irq, void *dev_id)
 {
        struct snd_ice1712 *ice = dev_id;
        unsigned char status;
@@ -433,7 +433,7 @@ static irqreturn_t snd_ice1712_interrupt(int irq, void *dev_id, struct pt_regs *
                handled = 1;
                if (status & ICE1712_IRQ_MPU1) {
                        if (ice->rmidi[0])
-                               snd_mpu401_uart_interrupt(irq, ice->rmidi[0]->private_data, regs);
+                               snd_mpu401_uart_interrupt(irq, ice->rmidi[0]->private_data);
                        outb(ICE1712_IRQ_MPU1, ICEREG(ice, IRQSTAT));
                        status &= ~ICE1712_IRQ_MPU1;
                }
@@ -441,7 +441,7 @@ static irqreturn_t snd_ice1712_interrupt(int irq, void *dev_id, struct pt_regs *
                        outb(ICE1712_IRQ_TIMER, ICEREG(ice, IRQSTAT));
                if (status & ICE1712_IRQ_MPU2) {
                        if (ice->rmidi[1])
-                               snd_mpu401_uart_interrupt(irq, ice->rmidi[1]->private_data, regs);
+                               snd_mpu401_uart_interrupt(irq, ice->rmidi[1]->private_data);
                        outb(ICE1712_IRQ_MPU2, ICEREG(ice, IRQSTAT));
                        status &= ~ICE1712_IRQ_MPU2;
                }
index 71d6aedc07496c4de7ddd68907b804036f37e440..e9cbfdf370590cf78075b5677e26d5666bfc5011 100644 (file)
@@ -218,7 +218,7 @@ static unsigned int snd_vt1724_get_gpio_data(struct snd_ice1712 *ice)
  *  Interrupt handler
  */
 
-static irqreturn_t snd_vt1724_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t snd_vt1724_interrupt(int irq, void *dev_id)
 {
        struct snd_ice1712 *ice = dev_id;
        unsigned char status;
@@ -236,7 +236,7 @@ static irqreturn_t snd_vt1724_interrupt(int irq, void *dev_id, struct pt_regs *r
                 */
                if ((status & VT1724_IRQ_MPU_RX)||(status & VT1724_IRQ_MPU_TX)) {
                        if (ice->rmidi[0])
-                               snd_mpu401_uart_interrupt(irq, ice->rmidi[0]->private_data, regs);
+                               snd_mpu401_uart_interrupt(irq, ice->rmidi[0]->private_data);
                        outb(status & (VT1724_IRQ_MPU_RX|VT1724_IRQ_MPU_TX), ICEREG1724(ice, IRQSTAT));
                        status &= ~(VT1724_IRQ_MPU_RX|VT1724_IRQ_MPU_TX);
                }
index 72dbaedcbdf579ee92ea0d7c8efa352ad2920687..7f22dab0724040491851d109f2617db23a694a48 100644 (file)
@@ -801,7 +801,7 @@ static inline void snd_intel8x0_update(struct intel8x0 *chip, struct ichdev *ich
                 status & (ICH_FIFOE | ICH_BCIS | ICH_LVBCI));
 }
 
-static irqreturn_t snd_intel8x0_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t snd_intel8x0_interrupt(int irq, void *dev_id)
 {
        struct intel8x0 *chip = dev_id;
        struct ichdev *ichdev;
@@ -2476,10 +2476,14 @@ static int intel8x0_suspend(struct pci_dev *pci, pm_message_t state)
        if (chip->device_type == DEVICE_INTEL_ICH4)
                chip->sdm_saved = igetbyte(chip, ICHREG(SDM));
 
-       if (chip->irq >= 0)
+       if (chip->irq >= 0) {
+               synchronize_irq(chip->irq);
                free_irq(chip->irq, chip);
+               chip->irq = -1;
+       }
        pci_disable_device(pci);
        pci_save_state(pci);
+       pci_set_power_state(pci, pci_choose_state(pci, state));
        return 0;
 }
 
@@ -2489,11 +2493,22 @@ static int intel8x0_resume(struct pci_dev *pci)
        struct intel8x0 *chip = card->private_data;
        int i;
 
+       pci_set_power_state(pci, PCI_D0);
        pci_restore_state(pci);
-       pci_enable_device(pci);
+       if (pci_enable_device(pci) < 0) {
+               printk(KERN_ERR "intel8x0: pci_enable_device failed, "
+                      "disabling device\n");
+               snd_card_disconnect(card);
+               return -EIO;
+       }
        pci_set_master(pci);
-       request_irq(pci->irq, snd_intel8x0_interrupt, IRQF_DISABLED|IRQF_SHARED,
-                   card->shortname, chip);
+       if (request_irq(pci->irq, snd_intel8x0_interrupt,
+                       IRQF_DISABLED|IRQF_SHARED, card->shortname, chip)) {
+               printk(KERN_ERR "intel8x0: unable to grab IRQ %d, "
+                      "disabling device\n", pci->irq);
+               snd_card_disconnect(card);
+               return -EIO;
+       }
        chip->irq = pci->irq;
        synchronize_irq(chip->irq);
        snd_intel8x0_chip_init(chip, 0);
index 268e2f7241eae9872fd0a54269411991329a5823..bd467c501123f3b3523ce1268c0c7712b381ad9a 100644 (file)
@@ -511,7 +511,7 @@ static inline void snd_intel8x0_update(struct intel8x0m *chip, struct ichdev *ic
        iputbyte(chip, port + ichdev->roff_sr, ICH_FIFOE | ICH_BCIS | ICH_LVBCI);
 }
 
-static irqreturn_t snd_intel8x0_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t snd_intel8x0_interrupt(int irq, void *dev_id)
 {
        struct intel8x0m *chip = dev_id;
        struct ichdev *ichdev;
@@ -1045,10 +1045,14 @@ static int intel8x0m_suspend(struct pci_dev *pci, pm_message_t state)
        for (i = 0; i < chip->pcm_devs; i++)
                snd_pcm_suspend_all(chip->pcm[i]);
        snd_ac97_suspend(chip->ac97);
-       if (chip->irq >= 0)
+       if (chip->irq >= 0) {
+               synchronize_irq(chip->irq);
                free_irq(chip->irq, chip);
+               chip->irq = -1;
+       }
        pci_disable_device(pci);
        pci_save_state(pci);
+       pci_set_power_state(pci, pci_choose_state(pci, state));
        return 0;
 }
 
@@ -1057,11 +1061,22 @@ static int intel8x0m_resume(struct pci_dev *pci)
        struct snd_card *card = pci_get_drvdata(pci);
        struct intel8x0m *chip = card->private_data;
 
+       pci_set_power_state(pci, PCI_D0);
        pci_restore_state(pci);
-       pci_enable_device(pci);
+       if (pci_enable_device(pci) < 0) {
+               printk(KERN_ERR "intel8x0m: pci_enable_device failed, "
+                      "disabling device\n");
+               snd_card_disconnect(card);
+               return -EIO;
+       }
        pci_set_master(pci);
-       request_irq(pci->irq, snd_intel8x0_interrupt, IRQF_DISABLED|IRQF_SHARED,
-                   card->shortname, chip);
+       if (request_irq(pci->irq, snd_intel8x0_interrupt,
+                       IRQF_DISABLED|IRQF_SHARED, card->shortname, chip)) {
+               printk(KERN_ERR "intel8x0m: unable to grab IRQ %d, "
+                      "disabling device\n", pci->irq);
+               snd_card_disconnect(card);
+               return -EIO;
+       }
        chip->irq = pci->irq;
        snd_intel8x0_chip_init(chip, 0);
        snd_ac97_resume(chip->ac97);
index cfea51f447848d10d75d31b92e72cf1bf13d0c37..fa8cd8cecc21ab3691493a7b8da16c72480e1131 100644 (file)
@@ -1119,14 +1119,11 @@ static void snd_korg1212_OnDSPDownloadComplete(struct snd_korg1212 *korg1212)
        snd_korg1212_setCardState(korg1212, K1212_STATE_DSP_COMPLETE);
 }
 
-static irqreturn_t snd_korg1212_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t snd_korg1212_interrupt(int irq, void *dev_id)
 {
         u32 doorbellValue;
         struct snd_korg1212 *korg1212 = dev_id;
 
-       if(irq != korg1212->irq)
-               return IRQ_NONE;
-
         doorbellValue = readl(korg1212->inDoorbellPtr);
 
         if (!doorbellValue)
@@ -1140,7 +1137,6 @@ static irqreturn_t snd_korg1212_interrupt(int irq, void *dev_id, struct pt_regs
 
        korg1212->inIRQ++;
 
-
         switch (doorbellValue) {
                 case K1212_DB_DSPDownloadDone:
                         K1212_DEBUG_PRINTK("K1212_DEBUG: IRQ DNLD count - %ld, %x, [%s].\n",
index 45214b3b81bedfc4b2afa70f4b297025f83a5e56..8cab342bbaaf94f5c0ece3a13e093df9752c831f 100644 (file)
@@ -1685,8 +1685,7 @@ static void snd_m3_update_hw_volume(unsigned long private_data)
        spin_unlock_irqrestore(&chip->ac97_lock, flags);
 }
 
-static irqreturn_t
-snd_m3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t snd_m3_interrupt(int irq, void *dev_id)
 {
        struct snd_m3 *chip = dev_id;
        u8 status;
@@ -2590,12 +2589,9 @@ static int m3_suspend(struct pci_dev *pci, pm_message_t state)
                chip->suspend_mem[index++] = 
                        snd_m3_assp_read(chip, MEMTYPE_INTERNAL_DATA, i);
 
-       /* power down apci registers */
-       snd_m3_outw(chip, 0xffff, 0x54);
-       snd_m3_outw(chip, 0xffff, 0x56);
-
        pci_disable_device(pci);
        pci_save_state(pci);
+       pci_set_power_state(pci, pci_choose_state(pci, state));
        return 0;
 }
 
@@ -2608,8 +2604,14 @@ static int m3_resume(struct pci_dev *pci)
        if (chip->suspend_mem == NULL)
                return 0;
 
+       pci_set_power_state(pci, PCI_D0);
        pci_restore_state(pci);
-       pci_enable_device(pci);
+       if (pci_enable_device(pci) < 0) {
+               printk(KERN_ERR "maestor3: pci_enable_device failed, "
+                      "disabling device\n");
+               snd_card_disconnect(card);
+               return -EIO;
+       }
        pci_set_master(pci);
 
        /* first lets just bring everything back. .*/
index 406ac3a9d42ade4329ed16c6ef49f5e61f6a46d6..d54457317b148302f8831395768b2cf82c4d4234 100644 (file)
@@ -408,7 +408,7 @@ void snd_mixart_msg_tasklet(unsigned long arg)
 }
 
 
-irqreturn_t snd_mixart_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t snd_mixart_interrupt(int irq, void *dev_id)
 {
        struct mixart_mgr *mgr = dev_id;
        int err;
index 1fe2bcfcc57c75c83514596c2c34abbb6b7e4e13..c919b734756ff3a9b387572d0de08f2a0a937199 100644 (file)
@@ -563,7 +563,7 @@ int  snd_mixart_send_msg(struct mixart_mgr *mgr, struct mixart_msg *request, int
 int  snd_mixart_send_msg_wait_notif(struct mixart_mgr *mgr, struct mixart_msg *request, u32 notif_event);
 int  snd_mixart_send_msg_nonblock(struct mixart_mgr *mgr, struct mixart_msg *request);
 
-irqreturn_t snd_mixart_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+irqreturn_t snd_mixart_interrupt(int irq, void *dev_id);
 void snd_mixart_msg_tasklet(unsigned long arg);
 
 void snd_mixart_reset_board(struct mixart_mgr *mgr);
index 101eee0aa018a3152777b82ae43ea56c33a988a2..945d21bf187ec2251ee601bf53b0a999b4dda620 100644 (file)
@@ -236,7 +236,7 @@ struct nm256 {
 
        int irq;
        int irq_acks;
-       irqreturn_t (*interrupt)(int, void *, struct pt_regs *);
+       irq_handler_t interrupt;
        int badintrcount;               /* counter to check bogus interrupts */
        struct mutex irq_mutex;
 
@@ -1004,7 +1004,7 @@ snd_nm256_intr_check(struct nm256 *chip)
  */
 
 static irqreturn_t
-snd_nm256_interrupt(int irq, void *dev_id, struct pt_regs *dummy)
+snd_nm256_interrupt(int irq, void *dev_id)
 {
        struct nm256 *chip = dev_id;
        u16 status;
@@ -1069,7 +1069,7 @@ snd_nm256_interrupt(int irq, void *dev_id, struct pt_regs *dummy)
  */
 
 static irqreturn_t
-snd_nm256_interrupt_zx(int irq, void *dev_id, struct pt_regs *dummy)
+snd_nm256_interrupt_zx(int irq, void *dev_id)
 {
        struct nm256 *chip = dev_id;
        u32 status;
@@ -1390,6 +1390,7 @@ static int nm256_suspend(struct pci_dev *pci, pm_message_t state)
        chip->coeffs_current = 0;
        pci_disable_device(pci);
        pci_save_state(pci);
+       pci_set_power_state(pci, pci_choose_state(pci, state));
        return 0;
 }
 
@@ -1401,8 +1402,17 @@ static int nm256_resume(struct pci_dev *pci)
 
        /* Perform a full reset on the hardware */
        chip->in_resume = 1;
+
+       pci_set_power_state(pci, PCI_D0);
        pci_restore_state(pci);
-       pci_enable_device(pci);
+       if (pci_enable_device(pci) < 0) {
+               printk(KERN_ERR "nm256: pci_enable_device failed, "
+                      "disabling device\n");
+               snd_card_disconnect(card);
+               return -EIO;
+       }
+       pci_set_master(pci);
+
        snd_nm256_init_chip(chip);
 
        /* restore ac97 */
index c40f590626849efa0f5ddfe1378509ac712b44d2..0ff8dc36fde3244d947a6ca8aed9d558942ae69b 100644 (file)
@@ -1131,7 +1131,7 @@ static void pcxhr_update_timer_pos(struct pcxhr_mgr *mgr,
 }
 
 
-irqreturn_t pcxhr_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t pcxhr_interrupt(int irq, void *dev_id)
 {
        struct pcxhr_mgr *mgr = dev_id;
        unsigned int reg;
index e7415d6d18264a0bb1e87c29c7cace60635ebb7b..d9a4ab6098750a4bc0920187828422e98129e010 100644 (file)
@@ -194,7 +194,7 @@ int pcxhr_write_io_num_reg_cont(struct pcxhr_mgr *mgr, unsigned int mask,
 
 
 /* interrupt handling */
-irqreturn_t pcxhr_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+irqreturn_t pcxhr_interrupt(int irq, void *dev_id);
 void pcxhr_msg_tasklet(unsigned long arg);
 
 #endif /* __SOUND_PCXHR_CORE_H */
index fe210c853442c8c551aa0193bb1bfba3c95d82f5..56e0c01123e70246433cdb0a34c5fb0459465175 100644 (file)
@@ -1178,9 +1178,9 @@ static int riptide_suspend(struct pci_dev *pci, pm_message_t state)
        snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
        snd_pcm_suspend_all(chip->pcm);
        snd_ac97_suspend(chip->ac97);
-       pci_set_power_state(pci, PCI_D3hot);
        pci_disable_device(pci);
        pci_save_state(pci);
+       pci_set_power_state(pci, pci_choose_state(pci, state));
        return 0;
 }
 
@@ -1189,9 +1189,14 @@ static int riptide_resume(struct pci_dev *pci)
        struct snd_card *card = pci_get_drvdata(pci);
        struct snd_riptide *chip = card->private_data;
 
-       pci_restore_state(pci);
-       pci_enable_device(pci);
        pci_set_power_state(pci, PCI_D0);
+       pci_restore_state(pci);
+       if (pci_enable_device(pci) < 0) {
+               printk(KERN_ERR "riptide: pci_enable_device failed, "
+                      "disabling device\n");
+               snd_card_disconnect(card);
+               return -EIO;
+       }
        pci_set_master(pci);
        snd_riptide_initialize(chip);
        snd_ac97_resume(chip->ac97);
@@ -1736,7 +1741,7 @@ snd_riptide_pcm(struct snd_riptide *chip, int device, struct snd_pcm **rpcm)
 }
 
 static irqreturn_t
-snd_riptide_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+snd_riptide_interrupt(int irq, void *dev_id)
 {
        struct snd_riptide *chip = dev_id;
        struct cmdif *cif = chip->cif;
@@ -1751,8 +1756,7 @@ snd_riptide_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                if (chip->rmidi && IS_MPUIRQ(cif->hwport)) {
                        chip->handled_irqs++;
                        snd_mpu401_uart_interrupt(irq,
-                                                 chip->rmidi->private_data,
-                                                 regs);
+                                                 chip->rmidi->private_data);
                }
                SET_AIACK(cif->hwport);
        }
index 2a71499242fa6f626cb6b3bb30bffcfbe0aaf87c..dc8d1302e22ddc3eec6e878b281a5ee98156cac8 100644 (file)
@@ -818,8 +818,7 @@ static void snd_rme32_pcm_stop(struct rme32 * rme32, int to_pause)
                writel(0, rme32->iobase + RME32_IO_RESET_POS);
 }
 
-static irqreturn_t
-snd_rme32_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t snd_rme32_interrupt(int irq, void *dev_id)
 {
        struct rme32 *rme32 = (struct rme32 *) dev_id;
 
index f8de7c9970179d52bfb22b64753e0904efb73179..106110a89a4c5dfa1f5cbbe06e008b54dcc34464 100644 (file)
@@ -1117,8 +1117,7 @@ snd_rme96_capture_stop(struct rme96 *rme96)
 
 static irqreturn_t
 snd_rme96_interrupt(int irq,
-                   void *dev_id,
-                   struct pt_regs *regs)
+                   void *dev_id)
 {
        struct rme96 *rme96 = (struct rme96 *)dev_id;
 
index d3e07de433b0e9302e28487bea83642f8b25abdc..694aa057ed496ae476d45cb66e3b58ed37ee26b2 100644 (file)
@@ -3603,7 +3603,7 @@ static void hdsp_midi_tasklet(unsigned long arg)
                snd_hdsp_midi_input_read (&hdsp->midi[1]);
 } 
 
-static irqreturn_t snd_hdsp_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t snd_hdsp_interrupt(int irq, void *dev_id)
 {
        struct hdsp *hdsp = (struct hdsp *) dev_id;
        unsigned int status;
index 7d03ae066d53c04b4c05ef76e3af92c59f222d0e..7055d893855d1df75781a7a77d5d4818e7931ee8 100644 (file)
@@ -2556,8 +2556,7 @@ static int snd_hdspm_set_defaults(struct hdspm * hdspm)
    interupt 
  ------------------------------------------------------------*/
 
-static irqreturn_t snd_hdspm_interrupt(int irq, void *dev_id,
-                                      struct pt_regs *regs)
+static irqreturn_t snd_hdspm_interrupt(int irq, void *dev_id)
 {
        struct hdspm *hdspm = (struct hdspm *) dev_id;
        unsigned int status;
index fc15f61ad5d19b5ff14398f3a838b8ea650addf3..cf0427b4bfdef623da7d41b15d2c16da4bf535ff 100644 (file)
@@ -1882,7 +1882,7 @@ static void snd_rme9652_set_defaults(struct snd_rme9652 *rme9652)
        rme9652_set_rate(rme9652, 48000);
 }
 
-static irqreturn_t snd_rme9652_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t snd_rme9652_interrupt(int irq, void *dev_id)
 {
        struct snd_rme9652 *rme9652 = (struct snd_rme9652 *) dev_id;
 
index e5d4def1aa6fe095fb874fc79620354ffb3cd2b0..f9b8afabda9c8b4ac539e1f1fdf0f0f97c695e53 100644 (file)
@@ -580,7 +580,7 @@ static int snd_sonicvibes_trigger(struct sonicvibes * sonic, int what, int cmd)
        return result;
 }
 
-static irqreturn_t snd_sonicvibes_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t snd_sonicvibes_interrupt(int irq, void *dev_id)
 {
        struct sonicvibes *sonic = dev_id;
        unsigned char status;
@@ -601,7 +601,7 @@ static irqreturn_t snd_sonicvibes_interrupt(int irq, void *dev_id, struct pt_reg
        }
        if (sonic->rmidi) {
                if (status & SV_MIDI_IRQ)
-                       snd_mpu401_uart_interrupt(irq, sonic->rmidi->private_data, regs);
+                       snd_mpu401_uart_interrupt(irq, sonic->rmidi->private_data);
        }
        if (status & SV_UD_IRQ) {
                unsigned char udreg;
index ebbe12d78d8c6e29463071c1ca0db4a62a6a7a00..1fbc4321122f64caed4552487d3af2631fa7397f 100644 (file)
@@ -52,8 +52,7 @@ static int snd_trident_pcm_mixer_build(struct snd_trident *trident,
 static int snd_trident_pcm_mixer_free(struct snd_trident *trident,
                                      struct snd_trident_voice * voice,
                                      struct snd_pcm_substream *substream);
-static irqreturn_t snd_trident_interrupt(int irq, void *dev_id,
-                                        struct pt_regs *regs);
+static irqreturn_t snd_trident_interrupt(int irq, void *dev_id);
 static int snd_trident_sis_reset(struct snd_trident *trident);
 
 static void snd_trident_clear_voices(struct snd_trident * trident,
@@ -3737,7 +3736,7 @@ static int snd_trident_free(struct snd_trident *trident)
   
   ---------------------------------------------------------------------------*/
 
-static irqreturn_t snd_trident_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t snd_trident_interrupt(int irq, void *dev_id)
 {
        struct snd_trident *trident = dev_id;
        unsigned int audio_int, chn_int, stimer, channel, mask, tmp;
@@ -3825,7 +3824,7 @@ static irqreturn_t snd_trident_interrupt(int irq, void *dev_id, struct pt_regs *
        }
        if (audio_int & MPU401_IRQ) {
                if (trident->rmidi) {
-                       snd_mpu401_uart_interrupt(irq, trident->rmidi->private_data, regs);
+                       snd_mpu401_uart_interrupt(irq, trident->rmidi->private_data);
                } else {
                        inb(TRID_REG(trident, T4D_MPUR0));
                }
@@ -3967,15 +3966,9 @@ int snd_trident_suspend(struct pci_dev *pci, pm_message_t state)
        snd_ac97_suspend(trident->ac97);
        snd_ac97_suspend(trident->ac97_sec);
 
-       switch (trident->device) {
-       case TRIDENT_DEVICE_ID_DX:
-       case TRIDENT_DEVICE_ID_NX:
-               break;                  /* TODO */
-       case TRIDENT_DEVICE_ID_SI7018:
-               break;
-       }
        pci_disable_device(pci);
        pci_save_state(pci);
+       pci_set_power_state(pci, pci_choose_state(pci, state));
        return 0;
 }
 
@@ -3984,9 +3977,15 @@ int snd_trident_resume(struct pci_dev *pci)
        struct snd_card *card = pci_get_drvdata(pci);
        struct snd_trident *trident = card->private_data;
 
+       pci_set_power_state(pci, PCI_D0);
        pci_restore_state(pci);
-       pci_enable_device(pci);
-       pci_set_master(pci); /* to be sure */
+       if (pci_enable_device(pci) < 0) {
+               printk(KERN_ERR "trident: pci_enable_device failed, "
+                      "disabling device\n");
+               snd_card_disconnect(card);
+               return -EIO;
+       }
+       pci_set_master(pci);
 
        switch (trident->device) {
        case TRIDENT_DEVICE_ID_DX:
index 6db3d4cc4d8dd4cc8d22377d62ddfd1a6eef0407..92b0736c0fdbf244591daa7a39746eb6e763813e 100644 (file)
@@ -613,7 +613,7 @@ static void snd_via82xx_channel_reset(struct via82xx *chip, struct viadev *viade
  *  Interrupt handler
  *  Used for 686 and 8233A
  */
-static irqreturn_t snd_via686_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t snd_via686_interrupt(int irq, void *dev_id)
 {
        struct via82xx *chip = dev_id;
        unsigned int status;
@@ -623,7 +623,7 @@ static irqreturn_t snd_via686_interrupt(int irq, void *dev_id, struct pt_regs *r
        if (! (status & chip->intr_mask)) {
                if (chip->rmidi)
                        /* check mpu401 interrupt */
-                       return snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data, regs);
+                       return snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data);
                return IRQ_NONE;
        }
 
@@ -659,7 +659,7 @@ static irqreturn_t snd_via686_interrupt(int irq, void *dev_id, struct pt_regs *r
 /*
  *  Interrupt handler
  */
-static irqreturn_t snd_via8233_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t snd_via8233_interrupt(int irq, void *dev_id)
 {
        struct via82xx *chip = dev_id;
        unsigned int status;
@@ -2185,9 +2185,9 @@ static int snd_via82xx_suspend(struct pci_dev *pci, pm_message_t state)
                chip->capture_src_saved[1] = inb(chip->port + VIA_REG_CAPTURE_CHANNEL + 0x10);
        }
 
-       pci_set_power_state(pci, PCI_D3hot);
        pci_disable_device(pci);
        pci_save_state(pci);
+       pci_set_power_state(pci, pci_choose_state(pci, state));
        return 0;
 }
 
@@ -2197,9 +2197,15 @@ static int snd_via82xx_resume(struct pci_dev *pci)
        struct via82xx *chip = card->private_data;
        int i;
 
-       pci_restore_state(pci);
-       pci_enable_device(pci);
        pci_set_power_state(pci, PCI_D0);
+       pci_restore_state(pci);
+       if (pci_enable_device(pci) < 0) {
+               printk(KERN_ERR "via82xx: pci_enable_device failed, "
+                      "disabling device\n");
+               snd_card_disconnect(card);
+               return -EIO;
+       }
+       pci_set_master(pci);
 
        snd_via82xx_chip_init(chip);
 
index 016f9dac253f13d2b4d016ec07f7d4308f3dae69..feb27c966256a7df4247aed74fd564d0ebed0a13 100644 (file)
@@ -475,7 +475,7 @@ static void snd_via82xx_channel_reset(struct via82xx_modem *chip, struct viadev
  *  Interrupt handler
  */
 
-static irqreturn_t snd_via82xx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t snd_via82xx_interrupt(int irq, void *dev_id)
 {
        struct via82xx_modem *chip = dev_id;
        unsigned int status;
@@ -1032,9 +1032,10 @@ static int snd_via82xx_suspend(struct pci_dev *pci, pm_message_t state)
                snd_via82xx_channel_reset(chip, &chip->devs[i]);
        synchronize_irq(chip->irq);
        snd_ac97_suspend(chip->ac97);
-       pci_set_power_state(pci, PCI_D3hot);
+
        pci_disable_device(pci);
        pci_save_state(pci);
+       pci_set_power_state(pci, pci_choose_state(pci, state));
        return 0;
 }
 
@@ -1044,9 +1045,14 @@ static int snd_via82xx_resume(struct pci_dev *pci)
        struct via82xx_modem *chip = card->private_data;
        int i;
 
-       pci_restore_state(pci);
-       pci_enable_device(pci);
        pci_set_power_state(pci, PCI_D0);
+       pci_restore_state(pci);
+       if (pci_enable_device(pci) < 0) {
+               printk(KERN_ERR "via82xx-modem: pci_enable_device failed, "
+                      "disabling device\n");
+               snd_card_disconnect(card);
+               return -EIO;
+       }
        pci_set_master(pci);
 
        snd_via82xx_chip_init(chip);
index e7cd8acab59ae1db98bc54e669f04113ab34e406..af49e8aabf5529331876b4d9e543586cf9854735 100644 (file)
@@ -266,9 +266,9 @@ static int snd_vx222_suspend(struct pci_dev *pci, pm_message_t state)
        int err;
 
        err = snd_vx_suspend(&vx->core, state);
-       pci_set_power_state(pci, PCI_D3hot);
        pci_disable_device(pci);
        pci_save_state(pci);
+       pci_set_power_state(pci, pci_choose_state(pci, state));
        return err;
 }
 
@@ -277,9 +277,14 @@ static int snd_vx222_resume(struct pci_dev *pci)
        struct snd_card *card = pci_get_drvdata(pci);
        struct snd_vx222 *vx = card->private_data;
 
-       pci_restore_state(pci);
-       pci_enable_device(pci);
        pci_set_power_state(pci, PCI_D0);
+       pci_restore_state(pci);
+       if (pci_enable_device(pci) < 0) {
+               printk(KERN_ERR "vx222: pci_enable_device failed, "
+                      "disabling device\n");
+               snd_card_disconnect(card);
+               return -EIO;
+       }
        pci_set_master(pci);
        return snd_vx_resume(&vx->core);
 }
index 24f6fc52f898f63b189ec90ae44e323243da38e0..a40c1085fd208a852391a4e92f45ec8666b34252 100644 (file)
@@ -753,7 +753,7 @@ static void snd_ymfpci_irq_wait(struct snd_ymfpci *chip)
        }
 }
 
-static irqreturn_t snd_ymfpci_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t snd_ymfpci_interrupt(int irq, void *dev_id)
 {
        struct snd_ymfpci *chip = dev_id;
        u32 status, nvoice, mode;
@@ -799,7 +799,7 @@ static irqreturn_t snd_ymfpci_interrupt(int irq, void *dev_id, struct pt_regs *r
        snd_ymfpci_writew(chip, YDSXGR_INTFLAG, status);
 
        if (chip->rawmidi)
-               snd_mpu401_uart_interrupt(irq, chip->rawmidi->private_data, regs);
+               snd_mpu401_uart_interrupt(irq, chip->rawmidi->private_data);
        return IRQ_HANDLED;
 }
 
@@ -2218,6 +2218,7 @@ int snd_ymfpci_suspend(struct pci_dev *pci, pm_message_t state)
        snd_ymfpci_disable_dsp(chip);
        pci_disable_device(pci);
        pci_save_state(pci);
+       pci_set_power_state(pci, pci_choose_state(pci, state));
        return 0;
 }
 
@@ -2227,8 +2228,14 @@ int snd_ymfpci_resume(struct pci_dev *pci)
        struct snd_ymfpci *chip = card->private_data;
        unsigned int i;
 
+       pci_set_power_state(pci, PCI_D0);
        pci_restore_state(pci);
-       pci_enable_device(pci);
+       if (pci_enable_device(pci) < 0) {
+               printk(KERN_ERR "ymfpci: pci_enable_device failed, "
+                      "disabling device\n");
+               snd_card_disconnect(card);
+               return -EIO;
+       }
        pci_set_master(pci);
        snd_ymfpci_aclink_reset(pci);
        snd_ymfpci_codec_ready(chip, 0);
index 9a14a4f64bd3226e7760c38c7975f61d48787d88..206e2f5a113f33ed1127a4b6bc52af848f2c76a7 100644 (file)
@@ -138,7 +138,7 @@ int snd_pdacf_suspend(struct snd_pdacf *chip, pm_message_t state);
 int snd_pdacf_resume(struct snd_pdacf *chip);
 #endif
 int snd_pdacf_pcm_new(struct snd_pdacf *chip);
-irqreturn_t pdacf_interrupt(int irq, void *dev, struct pt_regs *regs);
+irqreturn_t pdacf_interrupt(int irq, void *dev);
 void pdacf_tasklet(unsigned long private_data);
 void pdacf_reinit(struct snd_pdacf *chip, int resume);
 
index 7c5f21e45cb4908c116c3298fe7dab24249397aa..5bd69206ba65943bfff05221d8b9f66e9abc245e 100644 (file)
 #include <sound/core.h>
 #include "pdaudiocf.h"
 #include <sound/initval.h>
+#include <asm/irq_regs.h>
 
 /*
  *
  */
-irqreturn_t pdacf_interrupt(int irq, void *dev, struct pt_regs *regs)
+irqreturn_t pdacf_interrupt(int irq, void *dev)
 {
        struct snd_pdacf *chip = dev;
        unsigned short stat;
@@ -45,7 +46,7 @@ irqreturn_t pdacf_interrupt(int irq, void *dev, struct pt_regs *regs)
                if (!(stat & PDAUDIOCF_IRQAKM))
                        stat |= PDAUDIOCF_IRQAKM;       /* check rate */
        }
-       if (regs != NULL)
+       if (get_irq_regs() != NULL)
                snd_ak4117_check_rate_and_errors(chip->ak4117, 0);
        return IRQ_HANDLED;
 }
index 641430631505057f478f126fc7c91270e6fc921e..c64af55865d492851e6f8b803532b8f3b36b9ac7 100644 (file)
@@ -713,7 +713,7 @@ void snd_pmac_beep_dma_stop(struct snd_pmac *chip)
  * interrupt handlers
  */
 static irqreturn_t
-snd_pmac_tx_intr(int irq, void *devid, struct pt_regs *regs)
+snd_pmac_tx_intr(int irq, void *devid)
 {
        struct snd_pmac *chip = devid;
        snd_pmac_pcm_update(chip, &chip->playback);
@@ -722,7 +722,7 @@ snd_pmac_tx_intr(int irq, void *devid, struct pt_regs *regs)
 
 
 static irqreturn_t
-snd_pmac_rx_intr(int irq, void *devid, struct pt_regs *regs)
+snd_pmac_rx_intr(int irq, void *devid)
 {
        struct snd_pmac *chip = devid;
        snd_pmac_pcm_update(chip, &chip->capture);
@@ -731,7 +731,7 @@ snd_pmac_rx_intr(int irq, void *devid, struct pt_regs *regs)
 
 
 static irqreturn_t
-snd_pmac_ctrl_intr(int irq, void *devid, struct pt_regs *regs)
+snd_pmac_ctrl_intr(int irq, void *devid)
 {
        struct snd_pmac *chip = devid;
        int ctrl = in_le32(&chip->awacs->control);
index cdff53e4a17e6ab22a78b652f4b8e5bc8af8639a..2fbe1d183fcefdb08d15986836ebc47e679b79b3 100644 (file)
@@ -1017,7 +1017,7 @@ static void tumbler_update_automute(struct snd_pmac *chip, int do_notify)
 
 
 /* interrupt - headphone plug changed */
-static irqreturn_t headphone_intr(int irq, void *devid, struct pt_regs *regs)
+static irqreturn_t headphone_intr(int irq, void *devid)
 {
        struct snd_pmac *chip = devid;
        if (chip->update_automute && chip->initialized) {
index be0bd503f013350ae67b580e3b624f8bb5bb214c..c899786f30f5fb5584595889123f954e9045b51d 100644 (file)
@@ -491,7 +491,7 @@ static void __amd7930_update_map(struct snd_amd7930 *amd)
        __amd7930_write_map(amd);
 }
 
-static irqreturn_t snd_amd7930_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t snd_amd7930_interrupt(int irq, void *dev_id)
 {
        struct snd_amd7930 *amd = dev_id;
        unsigned int elapsed;
index 9a06c3bd694406a9948dd2527e0941d947bada45..edeb3d3c4c7eb66364b2a50a67de1b5dc149444b 100644 (file)
@@ -1753,7 +1753,7 @@ out_err:
 
 #ifdef SBUS_SUPPORT
 
-static irqreturn_t snd_cs4231_sbus_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t snd_cs4231_sbus_interrupt(int irq, void *dev_id)
 {
        unsigned long flags;
        unsigned char status;
index 5a97be689b401b11d057e45ac1d59f2d4b9ad9e4..4ceb09d215d8b5b3d10ccc1a7bafb0d01e0d9a43 100644 (file)
@@ -1903,8 +1903,7 @@ static void dbri_process_interrupt_buffer(struct snd_dbri * dbri)
        }
 }
 
-static irqreturn_t snd_dbri_interrupt(int irq, void *dev_id,
-                                     struct pt_regs *regs)
+static irqreturn_t snd_dbri_interrupt(int irq, void *dev_id)
 {
        struct snd_dbri *dbri = dev_id;
        static int errcnt = 0;
index a42acf6d7b68962b22b17061eebf1090abcc88e3..c82b01c7ad3ad9871f5fe619db8929fb596cbc51 100644 (file)
@@ -653,7 +653,7 @@ static struct snd_urb_ops audio_urb_ops_high_speed[2] = {
 /*
  * complete callback from data urb
  */
-static void snd_complete_urb(struct urb *urb, struct pt_regs *regs)
+static void snd_complete_urb(struct urb *urb)
 {
        struct snd_urb_ctx *ctx = (struct snd_urb_ctx *)urb->context;
        struct snd_usb_substream *subs = ctx->subs;
@@ -676,7 +676,7 @@ static void snd_complete_urb(struct urb *urb, struct pt_regs *regs)
 /*
  * complete callback from sync urb
  */
-static void snd_complete_sync_urb(struct urb *urb, struct pt_regs *regs)
+static void snd_complete_sync_urb(struct urb *urb)
 {
        struct snd_urb_ctx *ctx = (struct snd_urb_ctx *)urb->context;
        struct snd_usb_substream *subs = ctx->subs;
index 0dcf78adb99a879365b5949e9c9092076d120508..b7c5e59b22993bd110c4668c9c859392c8c5e7ad 100644 (file)
@@ -223,7 +223,7 @@ static void dump_urb(const char *type, const u8 *data, int length)
 /*
  * Processes the data read from the device.
  */
-static void snd_usbmidi_in_urb_complete(struct urb* urb, struct pt_regs *regs)
+static void snd_usbmidi_in_urb_complete(struct urb* urb)
 {
        struct snd_usb_midi_in_endpoint* ep = urb->context;
 
@@ -247,7 +247,7 @@ static void snd_usbmidi_in_urb_complete(struct urb* urb, struct pt_regs *regs)
        snd_usbmidi_submit_urb(urb, GFP_ATOMIC);
 }
 
-static void snd_usbmidi_out_urb_complete(struct urb* urb, struct pt_regs *regs)
+static void snd_usbmidi_out_urb_complete(struct urb* urb)
 {
        struct snd_usb_midi_out_endpoint* ep = urb->context;
 
index e516d6adbb224b22309bbc9266216077ab47207f..1024c178f5c0dbdf1430b864c4d405cbdf8b0162 100644 (file)
@@ -1710,7 +1710,7 @@ static void snd_usb_mixer_memory_change(struct usb_mixer_interface *mixer,
        }
 }
 
-static void snd_usb_mixer_status_complete(struct urb *urb, struct pt_regs *regs)
+static void snd_usb_mixer_status_complete(struct urb *urb)
 {
        struct usb_mixer_interface *mixer = urb->context;
 
@@ -1772,8 +1772,7 @@ static int snd_usb_mixer_status_create(struct usb_mixer_interface *mixer)
        return 0;
 }
 
-static void snd_usb_soundblaster_remote_complete(struct urb *urb,
-                                                struct pt_regs *regs)
+static void snd_usb_soundblaster_remote_complete(struct urb *urb)
 {
        struct usb_mixer_interface *mixer = urb->context;
        const struct rc_config *rc = mixer->rc_cfg;
index cfec38d7839b094289a4f99139469771acfc2105..e011fcacce92c298e82b0463583de1a0ea72edb9 100644 (file)
@@ -172,7 +172,7 @@ static void snd_usX2Y_card_private_free(struct snd_card *card);
 /* 
  * pipe 4 is used for switching the lamps, setting samplerate, volumes ....   
  */
-static void i_usX2Y_Out04Int(struct urb *urb, struct pt_regs *regs)
+static void i_usX2Y_Out04Int(struct urb *urb)
 {
 #ifdef CONFIG_SND_DEBUG
        if (urb->status) {
@@ -184,7 +184,7 @@ static void i_usX2Y_Out04Int(struct urb *urb, struct pt_regs *regs)
 #endif
 }
 
-static void i_usX2Y_In04Int(struct urb *urb, struct pt_regs *regs)
+static void i_usX2Y_In04Int(struct urb *urb)
 {
        int                     err = 0;
        struct usX2Ydev         *usX2Y = urb->context;
index f6bd0dee563ce3a7f7b242315e1f766ae26988c2..367f8a32a6657ed66324b69280b760d47d90c288 100644 (file)
@@ -306,7 +306,7 @@ static void usX2Y_error_sequence(struct usX2Ydev *usX2Y,
        usX2Y_clients_stop(usX2Y);
 }
 
-static void i_usX2Y_urb_complete(struct urb *urb, struct pt_regs *regs)
+static void i_usX2Y_urb_complete(struct urb *urb)
 {
        struct snd_usX2Y_substream *subs = urb->context;
        struct usX2Ydev *usX2Y = subs->usX2Y;
@@ -322,7 +322,7 @@ static void i_usX2Y_urb_complete(struct urb *urb, struct pt_regs *regs)
                usX2Y_error_urb_status(usX2Y, subs, urb);
                return;
        }
-       if (likely((0xFFFF & urb->start_frame) == usX2Y->wait_iso_frame))
+       if (likely(urb->start_frame == usX2Y->wait_iso_frame))
                subs->completed_urb = urb;
        else {
                usX2Y_error_sequence(usX2Y, subs, urb);
@@ -335,13 +335,9 @@ static void i_usX2Y_urb_complete(struct urb *urb, struct pt_regs *regs)
                    atomic_read(&capsubs->state) >= state_PREPARED &&
                    (playbacksubs->completed_urb ||
                     atomic_read(&playbacksubs->state) < state_PREPARED)) {
-                       if (!usX2Y_usbframe_complete(capsubs, playbacksubs, urb->start_frame)) {
-                               if (nr_of_packs() <= urb->start_frame &&
-                                   urb->start_frame <= (2 * nr_of_packs() - 1))        // uhci and ohci
-                                       usX2Y->wait_iso_frame = urb->start_frame - nr_of_packs();
-                               else
-                                       usX2Y->wait_iso_frame +=  nr_of_packs();
-                       } else {
+                       if (!usX2Y_usbframe_complete(capsubs, playbacksubs, urb->start_frame))
+                               usX2Y->wait_iso_frame += nr_of_packs();
+                       else {
                                snd_printdd("\n");
                                usX2Y_clients_stop(usX2Y);
                        }
@@ -350,7 +346,7 @@ static void i_usX2Y_urb_complete(struct urb *urb, struct pt_regs *regs)
 }
 
 static void usX2Y_urbs_set_complete(struct usX2Ydev * usX2Y,
-                                   void (*complete)(struct urb *, struct pt_regs *))
+                                   void (*complete)(struct urb *))
 {
        int s, u;
        for (s = 0; s < 4; s++) {
@@ -370,7 +366,7 @@ static void usX2Y_subs_startup_finish(struct usX2Ydev * usX2Y)
        usX2Y->prepare_subs = NULL;
 }
 
-static void i_usX2Y_subs_startup(struct urb *urb, struct pt_regs *regs)
+static void i_usX2Y_subs_startup(struct urb *urb)
 {
        struct snd_usX2Y_substream *subs = urb->context;
        struct usX2Ydev *usX2Y = subs->usX2Y;
@@ -382,7 +378,7 @@ static void i_usX2Y_subs_startup(struct urb *urb, struct pt_regs *regs)
                        wake_up(&usX2Y->prepare_wait_queue);
                }
 
-       i_usX2Y_urb_complete(urb, regs);
+       i_usX2Y_urb_complete(urb);
 }
 
 static void usX2Y_subs_prepare(struct snd_usX2Y_substream *subs)
@@ -495,7 +491,6 @@ static int usX2Y_urbs_start(struct snd_usX2Y_substream *subs)
                if (subs != NULL && atomic_read(&subs->state) >= state_PREPARED)
                        goto start;
        }
-       usX2Y->wait_iso_frame = -1;
 
  start:
        usX2Y_subs_startup(subs);
@@ -516,10 +511,9 @@ static int usX2Y_urbs_start(struct snd_usX2Y_substream *subs)
                                snd_printk (KERN_ERR "cannot submit datapipe for urb %d, err = %d\n", i, err);
                                err = -EPIPE;
                                goto cleanup;
-                       } else {
-                               if (0 > usX2Y->wait_iso_frame)
+                       } else
+                               if (i == 0)
                                        usX2Y->wait_iso_frame = urb->start_frame;
-                       }
                        urb->transfer_flags = 0;
                } else {
                        atomic_set(&subs->state, state_STARTING1);
@@ -663,7 +657,7 @@ static struct s_c2 SetRate48000[] =
 };
 #define NOOF_SETRATE_URBS ARRAY_SIZE(SetRate48000)
 
-static void i_usX2Y_04Int(struct urb *urb, struct pt_regs *regs)
+static void i_usX2Y_04Int(struct urb *urb)
 {
        struct usX2Ydev *usX2Y = urb->context;
        
index 88b72b52590f44c4566864577223720b2d5a7c98..8f3e35e24e72ce5b46771609c2c1dfe694d5c841 100644 (file)
@@ -226,7 +226,7 @@ static inline int usX2Y_usbpcm_usbframe_complete(struct snd_usX2Y_substream *cap
 }
 
 
-static void i_usX2Y_usbpcm_urb_complete(struct urb *urb, struct pt_regs *regs)
+static void i_usX2Y_usbpcm_urb_complete(struct urb *urb)
 {
        struct snd_usX2Y_substream *subs = urb->context;
        struct usX2Ydev *usX2Y = subs->usX2Y;
@@ -243,7 +243,7 @@ static void i_usX2Y_usbpcm_urb_complete(struct urb *urb, struct pt_regs *regs)
                usX2Y_error_urb_status(usX2Y, subs, urb);
                return;
        }
-       if (likely((0xFFFF & urb->start_frame) == usX2Y->wait_iso_frame))
+       if (likely(urb->start_frame == usX2Y->wait_iso_frame))
                subs->completed_urb = urb;
        else {
                usX2Y_error_sequence(usX2Y, subs, urb);
@@ -256,13 +256,9 @@ static void i_usX2Y_usbpcm_urb_complete(struct urb *urb, struct pt_regs *regs)
        if (capsubs->completed_urb && atomic_read(&capsubs->state) >= state_PREPARED &&
            (NULL == capsubs2 || capsubs2->completed_urb) &&
            (playbacksubs->completed_urb || atomic_read(&playbacksubs->state) < state_PREPARED)) {
-               if (!usX2Y_usbpcm_usbframe_complete(capsubs, capsubs2, playbacksubs, urb->start_frame)) {
-                       if (nr_of_packs() <= urb->start_frame &&
-                           urb->start_frame <= (2 * nr_of_packs() - 1))        // uhci and ohci
-                               usX2Y->wait_iso_frame = urb->start_frame - nr_of_packs();
-                       else
-                               usX2Y->wait_iso_frame +=  nr_of_packs();
-               } else {
+               if (!usX2Y_usbpcm_usbframe_complete(capsubs, capsubs2, playbacksubs, urb->start_frame))
+                       usX2Y->wait_iso_frame += nr_of_packs();
+               else {
                        snd_printdd("\n");
                        usX2Y_clients_stop(usX2Y);
                }
@@ -294,7 +290,7 @@ static void usX2Y_usbpcm_subs_startup_finish(struct usX2Ydev * usX2Y)
        usX2Y->prepare_subs = NULL;
 }
 
-static void i_usX2Y_usbpcm_subs_startup(struct urb *urb, struct pt_regs *regs)
+static void i_usX2Y_usbpcm_subs_startup(struct urb *urb)
 {
        struct snd_usX2Y_substream *subs = urb->context;
        struct usX2Ydev *usX2Y = subs->usX2Y;
@@ -311,7 +307,7 @@ static void i_usX2Y_usbpcm_subs_startup(struct urb *urb, struct pt_regs *regs)
                wake_up(&usX2Y->prepare_wait_queue);
        }
 
-       i_usX2Y_usbpcm_urb_complete(urb, regs);
+       i_usX2Y_usbpcm_urb_complete(urb);
 }
 
 /*
@@ -433,7 +429,6 @@ static int usX2Y_usbpcm_urbs_start(struct snd_usX2Y_substream *subs)
                if (subs != NULL && atomic_read(&subs->state) >= state_PREPARED)
                        goto start;
        }
-       usX2Y->wait_iso_frame = -1;
 
  start:
        usX2Y_usbpcm_subs_startup(subs);
@@ -459,7 +454,7 @@ static int usX2Y_usbpcm_urbs_start(struct snd_usX2Y_substream *subs)
                                                goto cleanup;
                                        }  else {
                                                snd_printdd("%i\n", urb->start_frame);
-                                               if (0 > usX2Y->wait_iso_frame)
+                                               if (u == 0)
                                                        usX2Y->wait_iso_frame = urb->start_frame;
                                        }
                                        urb->transfer_flags = 0;
@@ -632,7 +627,7 @@ static int usX2Y_pcms_lock_check(struct snd_card *card)
                for (s = 0; s < 2; ++s) {
                        struct snd_pcm_substream *substream;
                        substream = pcm->streams[s].substream;
-                       if (SUBSTREAM_BUSY(substream))
+                       if (substream && SUBSTREAM_BUSY(substream))
                                err = -EBUSY;
                }
        }